多标签,多 class 图像 classifier (ConvNet) with PyTorch
Multi-label, multi-class image classifier (ConvNet) with PyTorch
我正在尝试使用 PyTorch 实现一个图像 classifier (CNN/ConvNet),我想从 csv 文件中读取我的标签。我有 4 个不同的 classes,一张图片可能属于多个 class.
我已通读 PyTorch Tutorial and this Stanford tutorial and this one,但其中 none 涵盖了我的具体案例。我已经设法构建了 torch.utils.data.Dataset
class 的自定义函数,它可以很好地从二进制 classifier 的 csv 文件中读取标签。
这是我目前使用的 torch.utils.data.Dataset
class 的代码(根据上面的第三个教程 link 稍作修改):
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
具体来说,我正在尝试从具有以下结构的文件中读取我的标签:
我的具体问题是,我不知道如何在我的 Dataset
class 中实现它。我想我错过了 csv 中标签的(手动)分配与 PyTorch 如何读取它们之间的 link,因为我对框架相当陌生。
我将不胜感激有关如何使它工作的任何帮助,或者如果实际上有涉及此的示例,我也将不胜感激 link!
也许我遗漏了一些东西,但是如果您想将列 1..N
(此处为 N = 4
)转换为标签向量或形状 (N,)
(例如,给定您的示例数据, label(img1) = [0, 0, 0, 1]
, label(img3) = [1, 0, 1, 0]
, ...), 为什么不:
将所有标签列读入self.label_arr
:
self.label_arr = np.asarray(self.data_info.iloc[:, 1:]) # columns 1 to N
Return 相应地 __getitem__()
中的标签(这里没有变化):
single_image_label = self.label_arr[index]
要训练您的分类器,您可以计算例如您的 (N,)
预测与目标标签之间的交叉熵。
我正在尝试使用 PyTorch 实现一个图像 classifier (CNN/ConvNet),我想从 csv 文件中读取我的标签。我有 4 个不同的 classes,一张图片可能属于多个 class.
我已通读 PyTorch Tutorial and this Stanford tutorial and this one,但其中 none 涵盖了我的具体案例。我已经设法构建了 torch.utils.data.Dataset
class 的自定义函数,它可以很好地从二进制 classifier 的 csv 文件中读取标签。
这是我目前使用的 torch.utils.data.Dataset
class 的代码(根据上面的第三个教程 link 稍作修改):
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
具体来说,我正在尝试从具有以下结构的文件中读取我的标签:
我的具体问题是,我不知道如何在我的 Dataset
class 中实现它。我想我错过了 csv 中标签的(手动)分配与 PyTorch 如何读取它们之间的 link,因为我对框架相当陌生。
我将不胜感激有关如何使它工作的任何帮助,或者如果实际上有涉及此的示例,我也将不胜感激 link!
也许我遗漏了一些东西,但是如果您想将列 1..N
(此处为 N = 4
)转换为标签向量或形状 (N,)
(例如,给定您的示例数据, label(img1) = [0, 0, 0, 1]
, label(img3) = [1, 0, 1, 0]
, ...), 为什么不:
将所有标签列读入
self.label_arr
:self.label_arr = np.asarray(self.data_info.iloc[:, 1:]) # columns 1 to N
Return 相应地
__getitem__()
中的标签(这里没有变化):single_image_label = self.label_arr[index]
要训练您的分类器,您可以计算例如您的 (N,)
预测与目标标签之间的交叉熵。