我对最近的项目有疑问。
我一直在尝试使用PyTorch
来训练我的多类分类工作。我的图像数据集中有3
个标签(即0
->无,1
->左,2
->右)。我使用nn.CrossEntropyLoss()
作为损失函数,使用Adam
作为优化器。但是,训练结果看起来像这样,准确性完全没有改变。
==> Building new CNN model ...
==> Initialize CUDA support for CNN model ...
==> Preparing RcCar Image dataset ...
==> Start training ...
Iteration: 1 | Loss: 1.3453235626220703 | Training accuracy: 70% | Test accuracy: 43%
==> Saving model ...
/usr/local/lib/python3.6/dist-packages/torch/serialization.py:251: UserWarning: Couldn't retrieve source code for container of type SimpleCNN. It won't be checked for correctness upon loading.
"type " + obj.__name__ + ". It won't be checked "
Iteration: 2 | Loss: 0.9048898816108704 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 3 | Loss: 0.873579740524292 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 4 | Loss: 0.8702362179756165 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 5 | Loss: 0.8713874220848083 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 6 | Loss: 0.8639134168624878 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 7 | Loss: 0.8590883612632751 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 8 | Loss: 0.8576076626777649 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 9 | Loss: 0.8523686528205872 | Training accuracy: 70% | Test accuracy: 43%
Iteration: 10 | Loss: 0.8462777137756348 | Training accuracy: 70% | Test accuracy: 43%
我在考虑这是因为我选择的损失函数不合适还是我不得不将标签一次编码为
[
[0,0,1],
[0,1,0],
...
]
像这样
我已附上我的自定义数据集部分。请,请,请帮助我。谢谢!
def RcCarImageLoader(root, batch_size_train, batch_size_test):
"""
RC Car Image Loader.
Args:
train_root:
test_root:
batch_size_train:
batch_size_test:
Return:
train_loader:
test_loader:
"""
# Normalize training set together with augmentation
transform_train = transforms.Compose([
transforms.RandomResizedCrop(64),
transforms.RandomRotation(10),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
# Normalize test set same as training set without augmentation
transform_test = transforms.Compose([
transforms.Resize(64),
transforms.CenterCrop(64),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
# Loading Tiny ImageNet dataset
print("==> Preparing RcCar Image dataset ...")
train_set = ImageLoader(csv_filename="./train.csv", transform=transform_train)
train_loader = torch.utils.data.DataLoader(
train_set, batch_size=batch_size_train, num_workers=2)
test_set = ImageLoader(csv_filename="./test.csv", transform=transform_test, train=False)
test_loader = torch.utils.data.DataLoader(
test_set, batch_size=batch_size_test, num_workers=2)
return train_loader, test_loader
def image_loader(path):
"""Image Loader helper function."""
return Image.open(path.rstrip("\n")).convert('RGB')
class ImageLoader(Dataset):
"""Image Loader for Tiny ImageNet."""
def __init__(self, csv_filename, transform=None, train=True, loader=image_loader):
"""
Image Loader Builder.
Args:
base_path: path to triplets.txt
filenames_filename: text file with each line containing the path to an image e.g., `images/class1/sample.JPEG`
triplets_filename: A text file with each line containing three images
transform: torchvision.transforms
loader: loader for each image
"""
self.transform = transform
self.loader = loader
self.train_flag = train
# load training data
if self.train_flag:
train_data = []
csv_file = pd.read_csv(csv_filename)
self.train_label = np.asarray(csv_file.iloc[:, 1])
train_img_names = np.asarray(csv_file.iloc[:, 0])
for train_img_name in train_img_names:
train_img = self.loader(os.path.join("./train/", train_img_name))
train_data.append(train_img)
self.train_data = train_data
# train_label_one_hot = [[0 for _ in range(3)] for _ in range(len(train_label))]
# for i, row in enumerate(train_label_one_hot):
# row[train_label[i]] = 1
#
# self.train_label = np.asarray(train_label_one_hot)
# load test data
else:
test_data = []
csv_file = pd.read_csv(csv_filename)
self.test_label = np.asarray(csv_file.iloc[:, 1])
test_img_names = np.asarray(csv_file.iloc[:, 0])
for test_img_name in test_img_names:
test_img = self.loader(os.path.join("./test/", test_img_name))
test_data.append(test_img)
self.test_data = test_data
# test_label_one_hot = [[0 for _ in range(3)] for _ in range(len(test_label))]
# for i, row in enumerate(test_label_one_hot):
# row[test_label[i]] = 1
#
# self.test_label = np.asarray(test_label_one_hot)
def __getitem__(self, index):
"""Get image and label in dataset."""
# get training images
if self.train_flag:
img = self.train_data[index]
label = self.train_label[index]
if self.transform is not None:
img = self.transform(img)
return (img, label)
else:
img = self.test_data[index]
label = self.test_label[index]
if self.transform is not None:
img = self.transform(img)
return (img, label)
def __len__(self):
if self.train_flag:
return len(self.train_label)
else:
return len(self.test_label)