【发布时间】:2019-08-18 16:42:03
【问题描述】:
我有一个关于我最近的项目的问题。
我一直在尝试使用PyTorch 来训练我的多类分类工作。我的图像数据集中有3 标签(即0 -> none,1 -> left,2 -> right)。我使用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)
【问题讨论】:
标签: python machine-learning deep-learning pytorch loss-function