分类标签使用交叉熵损失,准确性不变深度学习pytorch

时间:2019-03-28 00:57:27

标签: python machine-learning deep-learning pytorch loss-function

我对最近的项目有疑问。

我一直在尝试使用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)

1 个答案:

答案 0 :(得分:0)

您对损失函数和一键编码的猜测是正确的。进行一次热编码,并使用BCEloss,让我知道。