卷积神经网络|猫狗分类系列--使用预训练模型构建新模型

文摘   科技   2023-04-29 15:38   河南  

在上一篇文章:卷积神经网络|猫狗分类系列--构建自己的模型,我们构建了一个极其简单的模型,用这个模型可以用来进行猫狗分类,但模型实在太简单了,最终效果可能很差。

自己从0搭建一个模型事实上是困难的,因为我们并不清楚如何搭配卷积层,全连接层,以及激活操作,池化操作,批归一化等等,虽然在大量实验中能获得一些经验,但确实花费不少时间。

如何在较短的时间搭建一个用于处理实际问题的模型是一个有点麻烦的问题

however,

借助已经训练好的模型是个不错的想法。因此我们将学习如何使用预训练好的模型来构建只需要很少数据的先进的猫狗图像分类器。

首先,加载一个预训练的模型,例如ResNet18。

借助torchvision库,我们很容易获得一组已经训练好的模型。这些模型大多数接受一个称为pretrained的参数,当这个参数为True时,它会下载为ImageNet分类问题调整好的权重。就像这样:

from torchvision import modelsnetwork1=models.resnet18(pretrained=True)

当代码第一次运行时,需要一点时间...

接着,我们需要冻结所有层,所有权重不会随训练而更新

for param in network1.parameters():    param.requires_grad=False

当然,这个模型并不是针对2分类问题,所以,我们需要将其最后一层的输出特征从1000改为2

首先我们要知道最后一层的名字:

network1ResNet(  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)...  ...  ...  (fc): Linear(in_features=512, out_features=1000, bias=True)

最后一层是个全连接层,名为fc。

所以,我们就可将最后一层替换为输出特征为2的全连接层

network1.fc=nn.Linear(512,2)

注:此时,因为该层为新的层,所以其requires_grad=True,这样整个网络仅有这一层可以更新权重

打印网络

network1ResNet(  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)  (relu): ReLU(inplace=True)  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)...  ...  ...  (fc): Linear(in_features=512, out_features=2, bias=True)

此时,network1就是一个符合猫狗分类问题的模型

总结一下代码:

from torchvision import modelsimport torch.nn as nnimport torch.optim as optim#网络搭建network1=models.resnet18(pretrained=True)
for param in network1.parameters(): param.requires_grad=False
network1.fc=nn.Linear(512,2)

其实,我们就是利用已经训练好的模型的主要目的就是它已经能够提取出非常好的特征,最后一层接受前面层提取的特征,然后误差反向传播,仅更新这一层的权重,不断迭代,最后达到一个非常好的效果。





math and code
计算机专业研究生在读,拥有深厚的计算机科学和数学背景,对编程、算法、数据结构、深度学习等领域都有着深入的了解和实践经验。对编程语言的掌握熟练而全面,无论是主流的Python、Java,还是强大的C++、Go,都能轻松驾驭。