我是初学者,我正在尝试实现AlexNet进行图像分类。 AlexNet的pytorch实现如下:
class AlexNet(nn.Module):
def __init__(self, num_classes=1000):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), 256 * 6 * 6)
x = self.classifier(x)
return x
但是,我正在尝试为输入大小为(3,448,224),类别数= 8的情况实现网络。
我不知道如何在正向方法中更改x.view以及应该降低多少层以获得最佳性能。请帮忙。
答案 0 :(得分:0)
如https://github.com/pytorch/vision/releases中所述:
因此,
torchvision
(最新版本)中提供的大多数经过预训练的模型已经添加了self.avgpool = nn.AdaptiveAvgPool2d((size, size))
,以解决与输入大小的不兼容问题。因此,您不必太在乎它。
下面是代码,非常简短。
import torchvision
import torch.nn as nn
num_classes = 8
model = torchvision.models.alexnet(pretrained=True)
# replace the last classifier
model.classifier[6] = nn.Linear(4096, num_classes)
# now you can trained it with your dataset of size (3, 448, 224)
有两种流行的方法可以进行迁移学习。假设我们在非常大的数据集M
中训练了模型D_large
,现在我们想将模型M
学到的“知识”转移到我们的新模型M'
中,例如D_other
(其大小比D_large
小)的其他数据集。
使用M
的(大部分)部分作为新M'
的体系结构,并使用在D_large
上训练的权重初始化这些部分。我们可以开始在数据集M'
上训练模型D_other
,并让其从M
学习上述部分的权重,以在新数据集上找到最佳权重。这通常称为微调模型M'
。
与上述方法相同,除了在训练M'
之前冻结那些部分的所有参数,然后开始在数据集M'
上训练D_other
。在这两种情况下,M
中的那些部分大部分都是模型M'
(基础)中的第一部分。但是,在这种情况下,我们将M
的那些部分作为模型来从输入数据集(或特征提取器)中提取特征。从这两种方法获得的精度可能会有所不同。但是,此方法可确保模型不会在小型数据集上过拟合。就准确性而言,这是一个很好的观点。另一方面,当冻结M
的权重时,我们不需要在前向传递中存储一些中间值(每个隐藏层的隐藏输出),也不需要计算{ {1}}。这样可以提高训练速度并减少训练过程中所需的内存。
与gradients
一起,Facebook团队已经在ImageNet上提供了许多预训练的模型,例如ResNet,VGG。
要在模型尺寸方面最满足您的要求,最好使用模型系列中参数最少的VGG11和ResNet。
我仅以VGG11为例:
Alexnet
获取预训练的模型。torchvision
层替换模型中的最后一层以执行分类。这意味着您可以重用Linear
至M
的大部分内容。 M'
在旧的import torchvision
# obtain the pretrained model
model = torchvision.models.vgg11(pretrained=True)
# freeze the params
for param in net.parameters():
param.requires_grad = False
# replace with your classifier
num_classes = 8
net.classifier[6] = nn.Linear(in_features=4096, out_features=num_classes)
# start training with your dataset
软件包版本中,没有torchvision
使得难以训练我们的输入大小,这与训练ImageNet中使用的self.avgpool = nn.AdaptiveAvgPool2d((size, size))
不同。您可以做一些事情,如下所示:
[3, 224, 224]
在
class OurVGG11(nn.Module):
def __init__(self, num_classes=8):
super(OurVGG11, self).__init__()
self.vgg11 = torchvision.models.vgg11(pretrained=True)
for param in self.vgg11.parameters():
param.requires_grad = False
# Add a avgpool here
self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
# Replace the classifier layer
self.vgg11.classifier[-1] = nn.Linear(4096, num_classes)
def forward(self, x):
x = self.vgg11.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), 512 * 7 * 7)
x = self.vgg11.classifier(x)
return x
model = OurVGG11()
# now start training `model` on our dataset.
中尝试使用不同的模型。