image - pytorch 中图像和标签的自定义数据加载器。损失函数的输入困难
问题描述
我最近正在研究这个https://www.kaggle.com/gti-upm/leapgestrecog数据集。它是一个手势数据集,我正在尝试制作一个分类器。由于图像在不同类型的文件夹中可用,我制作了我的数据加载器。这里是
class DatasetLoader(Dataset):
def __init__(self,path):
self.path_list = path
self.labels = []
self.to_tensor = transforms.ToTensor()
self.resize = transforms.Resize((120,320))
self.gray = transforms.Grayscale(num_output_channels = 1)
self._init_dataset()
def _init_dataset(self):
labels = set()
for diro in os.listdir("/kaggle/input/leapgestrecog/leapGestRecog"):
for d in os.listdir(os.path.join("/kaggle/input/leapgestrecog/leapGestRecog",diro)):
if len(d.split('_'))>2:
labels.add("_".join(d.split("_")[-2:]))
else:
labels.add(d.split("_")[-1])
labels = list(labels)
## help me on this line with some codes
def __getitem__(self,idx):
if torch.is_tensor(idx):
idx = idx.tolist()
img_name = self.path_list[idx]
img = Image.open(img_name)
img = self.resize(img)
img = self.gray(img)
img = self.to_tensor(img)
if len(img_name.split('/')[-2].split('_')) > 2:
label = "_".join(img_name.split('/')[-2].split('_')[-2:])
else:
label = img_name.split('/')[-2].split('_')[-1]
label = ## Here also
return img,label
def __len__(self):
return len(self.path_list)
我从这个数据集加载器获得的标签有问题。由于我创建了一个模型,该模型采用 10 个类别的 n 批数据,因此在损失计算期间,我需要我的标签大小为(n,10)。我不知道该怎么办。这是我的网络设计:
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1 = nn.Conv2d(1,32,5)
self.pool = nn.MaxPool2d(2,2)
self.conv2 = nn.Conv2d(32,64,3)
self.conv3 = nn.Conv2d(64,64,3)
self.fc1 = nn.Linear(64*38*13,128)
self.fc2 = nn.Linear(128,10)
def forward(self,x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
x = x.view(64,64*38*13)
x = F.relu(self.fc1(x))
return F.log_softmax(self.fc2(x),dim = 1)
如果 y 是图像的标签。为了训练我们的网络,我们用 y 和输出提供损失函数。但是我们得到的输出大小是 (64,10) ,所以我需要有关数据加载器的label
帮助
解决方案
我看到您对 PyTorch 中多类损失函数的输入维度有一些误解。分类问题最常用的损失函数是nn.CrossEntropyLoss()
,它期望原始 logits 大小(n, c)
(例如(64, 10)
)作为输入 1,目标(真实标签)大小(n)
(例如(10)
)。
所以与其做做,不如直接做做使用return F.log_softmax(self.fc2(x),dim = 1)
会更稳定。无需重塑标签,您可以通过执行以下操作直接计算损失:return x
CrossEntropyLoss
criterion = nn.CrossEntropyLoss()
# Let x be (64, 10) output from model
# Let y be (10,) label
loss = criterion(x, y)
推荐阅读
- c++ - Xcode 找不到或包含 SDL2
- mysql - CONCAT with JOIN:每个 id 只创建一行,尽管 id 有多个行
- r - 如何调整 LaTex beamer 主题以将其应用于 rmarkdown::beamer_presentation
- excel - 多个 Excel 文件的批处理脚本(1 个变量)
- python - 根据值的不同长度将键和值数组分解为多个数组
- sftp - WinSCP命令行用于从以当前日期命名的文件夹上传文件
- javascript - Linked List Javascript,变量中断的重新分配?
- node.js - WebDriverIO 在运行 npm test 时给出 mocha 框架错误(无代理)
- sql - 插入表时的 SQL 最佳实践/性能。是否使用临时表
- javascript - 在 Javascript 国际象棋引擎 chess.js 中移动排序