简体   繁体   English

带有PyTorch的多标签,多类别图像分类器(ConvNet)

[英]Multi-label, multi-class image classifier (ConvNet) with PyTorch

I am trying to implement an image classifier (CNN/ConvNet) with PyTorch where I want to read my labels from a csv-file. 我正在尝试使用PyTorch实现图像分类器(CNN / ConvNet),在这里我想从csv文件读取标签。 I have 4 different classes and an image may belong to more than one class. 我有4个不同的类别,一张图片可能属于多个类别。

I have read through the PyTorch Tutorial and this Stanford tutorial and this one , but none of them cover my specific case. 我已经阅读了PyTorch教程本斯坦福教程以及 教程 ,但都没有涵盖我的具体情况。 I have managed to build a custom function of the torch.utils.data.Dataset class which works fine for reading the labels from a csv-file for a binary classifier only though. 我设法建立了torch.utils.data.Dataset类的自定义函数,该函数仅对于从二进制分类器的csv文件读取标签有效。

This is the code for the torch.utils.data.Dataset class I have so far (slightly modified from the third tutorial linked above): 这是我到目前为止拥有的torch.utils.data.Dataset类的代码(与上面链接的第三个教程稍作修改):

import torch
import torchvision.transforms as transforms
import torch.utils.data as data
from PIL import Image
import numpy as np
import pandas as pd


class MyCustomDataset(data.Dataset):
# __init__ function is where the initial logic happens like reading a csv,
# assigning transforms etc.
def __init__(self, csv_path):
    # Transforms
    self.random_crop = transforms.RandomCrop(800)
    self.to_tensor = transforms.ToTensor()
    # Read the csv file
    self.data_info = pd.read_csv(csv_path, header=None)
    # First column contains the image paths
    self.image_arr = np.asarray(self.data_info.iloc[:, 0])
    # Second column is the labels
    self.label_arr = np.asarray(self.data_info.iloc[:, 1])
    # Calculate len
    self.data_len = len(self.data_info.index)


# __getitem__ function returns the data and labels. This function is
# called from dataloader like this
def __getitem__(self, index):
    # Get image name from the pandas df
    single_image_name = self.image_arr[index]
    # Open image
    img_as_img = Image.open(single_image_name)
    img_cropped = self.random_crop(img_as_img)
    img_as_tensor = self.to_tensor(img_cropped)

    # Get label(class) of the image based on the cropped pandas column
    single_image_label = self.label_arr[index]

    return (img_as_tensor, single_image_label)

def __len__(self):
    return self.data_len

Specifically, I am trying to read my labels from a file with the following structure: 具体来说,我正在尝试从具有以下结构的文件中读取标签:

CSV数据

And my specific problem is, that I can't figure out how to implement this into my Dataset class. 我的具体问题是,我无法弄清楚如何将其实现到我的Dataset类中。 I think I am missing the link between the (manual) assignment of the labels in the csv and how they are read by PyTorch, as I am rather new to the framework. 我想我在csv中的标签的(手动)分配与PyTorch如何读取它们之间缺少联系,因为我对框架不是很熟悉。
I'd appreciate any help on how to get this to work, or if there are actually examples covering this, a link would be highly appreciated as well! 我非常感谢您提供有关如何使其正常工作的帮助,或者如果确实有涉及此方面的示例,那么也将非常感谢您提供链接!

Maybe I am missing something, but if you want to convert your columns 1..N ( N = 4 here) into a label vector or shape (N,) (eg given your example data, label(img1) = [0, 0, 0, 1] , label(img3) = [1, 0, 1, 0] , ...), why not: 也许我缺少了一些东西,但是如果您想将列1..N (此处N = 4 )转换为标签向量或形状(N,) (例如,给出示例数据, label(img1) = [0, 0, 0, 1]label(img3) = [1, 0, 1, 0] ,...),为什么不:

  1. Read all the label columns into self.label_arr : 将所有标签列读入self.label_arr

     self.label_arr = np.asarray(self.data_info.iloc[:, 1:]) # columns 1 to N 
  2. Return accordingly the labels in __getitem__() (no change here): 相应地返回__getitem__()的标签(此处不变):

     single_image_label = self.label_arr[index] 

To train your classifier, you could then compute eg the cross-entropy between your (N,) predictions and the target labels. 为了训练您的分类器,您可以然后计算例如(N,)预测与目标标签之间的交叉熵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM