如何使用 Pytorch 将二进制迁移学习模型扩展到多个图像类别?

Posted

技术标签:

【中文标题】如何使用 Pytorch 将二进制迁移学习模型扩展到多个图像类别?【英文标题】:How to extend a binary transfer learning model with Pytorch to multiple image categories? 【发布时间】:2021-07-08 13:46:43 【问题描述】:

我正在处理一些代码,这些代码使用 ResNet-18 模型对臭名昭著的狗与猫图像分类进行分类,我想扩展它以能够对两个以上的图像类别进行分类(例如狗与猫与仓鼠与....)。特别是我有5个类别。我是迁移学习的新手,我不确定我必须对代码进行哪些更改才能使其正常工作。

import torch
import numpy as np
import torch.nn.functional as F
from torch.nn import Linear
from torch.utils.data import DataLoader, random_split
from torch.optim import Adam
from torchvision.transforms import Compose, Resize, ToTensor
from torchvision.datasets import ImageFolder
from torchvision.models import resnet18
from matplotlib import pyplot as plt
import random

transform = Compose([Resize((128,128)), ToTensor()])

ds = ImageFolder("*Image_Folder*", transform=transform)
ds_train, ds_val = random_split(ds, [3250, 1073])
dl_train = DataLoader(ds_train, batch_size= 32, shuffle=True)
dl_val = DataLoader(ds_val, batch_size= len(ds_val), shuffle= True)

model = resnet18(pretrained=True)
model.requires_grad_(False)
model.fc = Linear(model.fc.in_features, 5)
X_val, y_val = next(dl_val.__iter__())

opt = torch.optim.Adam(model.parameters(), lr=0.001)
def accuracy(yy, y):
  return torch.mean(1.0*(yy == y))
X_val.shape, y_val.shape
y_val = y_val.reshape(-1, 1).float()

for epoch in range(10):
  losses = []
  accs = []
  losses_val = []
  accs_val = []
  model.train()
  for X, y in dl_train:
    y = y.reshape(-1, 1).float()
    yy = torch.sigmoid(model(X))
    loss = F.binary_cross_entropy(yy, y)
    losses.append(loss.item()) 
    loss.backward()
    opt.step()
    opt.zero_grad()
    acc = accuracy(torch.round(yy), y)
    accs.append(acc.item())
  model.eval()
  with torch.no_grad():
    yy_val = torch.sigmoid(model(X_val))
    loss_val = F.binary_cross_entropy(yy_val, y_val)
    losses_val.append(loss_val.item()) 
    acc_val = accuracy(torch.round(yy_val), y_val)
    accs_val.append(acc_val.item())
  print(f"Epoch epoch: t-loss = np.mean(losses):.4f, t-acc = np.mean(accs):.4f, v-loss = loss_val:.4f, v-acc = acc_val:.4f")

我相信代码可以满足 for 循环,但它可能是我需要添加或更改的内容。目前loss = F.binary_cross_entropy(yy, y)这行给我一个错误ValueError: Using a target size (torch.Size([32, 1])) that is different to the input size (torch.Size([32, 5])) is deprecated. Please ensure they have the same size.

这是我正在处理的数据:https://www.kaggle.com/alxmamaev/flowers-recognition

【问题讨论】:

【参考方案1】:

二元交叉熵是为二元分类任务设计的损失函数。

为了将此模型转换为能够进行 5 类分类的模型,除了将最后一层的宽度更改为 5 之外,您还需要将损失函数更改为 多项式 评分器,例如CrossEntropyLoss().

【讨论】:

以上是关于如何使用 Pytorch 将二进制迁移学习模型扩展到多个图像类别?的主要内容,如果未能解决你的问题,请参考以下文章

PyTorch 迁移学习 (Transfer Learning) 代码详解

PyTorch 迁移学习 (Transfer Learning) 代码详解

在 PyTorch 中加载迁移学习模型进行推理的正确方法是啥?

PyTorch基础——迁移学习

PyTorch迁移学习教程(计算机视觉应用实例)

PyTorch实例3——迁移学习