使用pytorch读取、使用预训练模型进行finetune:以Resnet-101为例

在使用pytorch进行网络训练的时候,有时候不可避免的使用迁移学习(trainsfer learning),即使用已经训练好的模型(如resnet、inception等),固定其已经训练好的网络层参数,然后进行finetune。
以下代码是以resnet-101为例使用pytorch进行finetune的操作:

#导入必要模块
import torch
import torch.nn as nn
from torchvision import models

#读取pytorch自带的resnet-101模型,因为使用了预训练模型,所以会自动下载模型参数
model=models.resnet101(pretrained=True)

#对于模型的每个权重,使其不进行反向传播,即固定参数
for param in model.parameters():
    param.requires_grad = False
#但是参数全部固定了,也没法进行学习,所以我们不固定最后一层,即全连接层fc
for param in model.fc.parameters():
    param.requires_grad = True

如果想修改最后一层的话,可以这么修改:

class_num = 200 #假设要分类数目是200
channel_in = model.fc.in_features#获取fc层的输入通道数
#然后把resnet-101的fc层替换成300类别的fc层
model.fc = nn.Linear(channel_in,class_num)

也可以删除最后一层或者几层

#这里[:-1]代表删除最后一层
new_model = nn.Sequential(*list(model.children())[:-1])
#或删除最后两层
new_model = nn.Sequential(*list(model.children())[:-2])

当然删除了最后几层,可能还要添加,可以直接把以上代码写入新的网络里,然后再在forward代码块中添加,这个比较基础,就不详说了。

这个时候是如果按常规训练模型的方法直接使用optimizer的话会出错误的,如:

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

会报错:ValueError: optimizing a parameter that doesn't require gradients

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    main()
  File "main.py", line 20, in main
    optimizer = torch.optim.SGD(model.parameters(),lr=0.1)
  File "C:\Anaconda3\lib\site-packages\torch\optim\sgd.py", line 64, in __init__
    super(SGD, self).__init__(params, defaults)
  File "C:\Anaconda3\lib\site-packages\torch\optim\optimizer.py", line 43, in __init__
    self.add_param_group(param_group)
  File "C:\Anaconda3\lib\site-packages\torch\optim\optimizer.py", line 193, in add_param_group
    raise ValueError("optimizing a parameter that doesn't require gradients")
ValueError: optimizing a parameter that doesn't require gradients

这是因为optimizer的输入参数parameters必须都是可以修改、反向传播的,即requires_grad=True,但是我们刚才已经固定了除了最后一层的所有参数,所以会出错。
解决方法是optimizer中只输入需要反向传播的参数:

#filter()函数过滤掉parameters中requires_grad=Fasle的参数
optimizer = torch.optim.SGD(
                        filter(lambda p: p.requires_grad, model.parameters()),#重要的是这一句
                        lr=0.1)

这样就可以进行正常的训练了。

这里引申一下:接下来的代码是如何输出网络模型的卷积方式以及权重数值

for child in model.children():
    print(child)#打印网络模型的卷积方式
    for param in child.parameters():#打印权重数值
        print(param)

部分结果(第一层卷积层):

Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
Parameter containing:
tensor([[[[ 2.0222e-02, -4.3927e-03, -1.8274e-02,  ..., -1.5180e-02,
           -1.5794e-03,  9.3115e-03],
          [-4.0752e-03,  3.2116e-03, -1.5956e-02,  ..., -8.4465e-02,
           -7.4997e-02, -4.0676e-02],
          [ 3.5039e-03,  2.6746e-02,  5.0813e-02,  ...,  3.3407e-02,
            1.3659e-02,  2.7821e-02],
          ...,
          [-3.6174e-02, -1.2986e-01, -3.0369e-01,  ..., -3.7412e-01,
           -1.3025e-01,  4.2633e-02],
          [ 1.5479e-02,  2.3444e-02,  6.5222e-03,  ..., -1.6439e-01,
           -1.8245e-01, -9.7434e-02],
          [-3.0444e-02, -1.1357e-02,  4.9984e-02,  ...,  1.6412e-01,
            1.0419e-01, -1.2681e-02]],

         [[ 8.7115e-03, -5.8911e-03, -1.2204e-02,  ..., -1.3515e-02,
            1.5212e-02,  1.9115e-02],
          [-6.8970e-03,  
### 回答1: PyTorchResNet-18在CIFAR-10数据集的预训练模型是指在经过大规模的图像数据集上进行预训练后的ResNet-18模型,以便在CIFAR-10数据集上进行更好的图像分类任务。 ResNet-18是一个由18个卷积层和全连接层组成的深度神经网络。预训练模型是指在大规模数据上进行训练得到的模型参数,因此具有更好的泛化性能。CIFAR-10是一个包含10个类别的图像分类数据集,用于在小尺寸图像上进行模型训练和评估。 通过使用预训练的ResNet-18模型,在CIFAR-10数据集上进行图像分类任务时,我们可以利用预训练模型的权重参数来加快训练过程并提高准确率。预训练模型的好处是可以从大规模数据中学习到更多的特征表示,这些特征表示通常具有更高的鉴别性,因此可以更好地捕捉图像的关键特征。 对于CIFAR-10数据集,预训练模型可以有效地缩短训练时间并提高模型的收敛速度,因为在预训练模型中已经包含了对图像的一些共享特征的学习。通过在CIFAR-10数据集上进行微调,即在预训练模型的基础上进行进一步的训练,可以逐步调整模型参数以适应CIFAR-10数据集的特定要求,从而提高最终的图像分类性能。 总而言之,PyTorchResNet-18在CIFAR-10的预训练模型是通过在大规模数据上进行训练,在CIFAR-10数据集上进行图像分类任务时使用预训练模型。这个预训练模型可以帮助提高训练速度和分类准确率,并且在模型训练和微调时起到了重要作用。 ### 回答2: PyTorchResNet-18是一种在CIFAR-10数据集上进行预训练的深度神经网络模型。CIFAR-10是一个包含10个类别的图像分类数据集,包括飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船和卡车。 ResNet-18是指由18个卷积层和全连接层组成的深度残差网络。该网络的设计思想是通过残差连接(即跳过连接)来解决深度网络中的梯度消失问题,使得网络具有更好的训练效果。这意味着在每个卷积层之后,输入信号可以通过两条路径传递:一条直接连接到后续层,另一条通过卷积操作后再进行连接。这种设计可以使网络更加容易学习输入和输出之间的映射关系。 在CIFAR-10上预训练的ResNet-18模型具有多个优点。首先,这个模型具有较小的参数量和计算复杂度,适合在资源有限的环境下使用。其次,该模型经过在CIFAR-10数据集上的预训练,可以直接用于图像分类任务。通过在CIFAR-10上进行预训练,模型可以学习到一般的图像特征和模式,使其能够更好地泛化到其他类似的图像分类任务中。 通过使用预训练的ResNet-18模型,我们可以利用其已经学到的特征和知识,节省训练时间,并为我们的具体图像分类任务提供一个良好的起点。此外,该模型可以通过微调(fine-tuning)进一步优化,以适应特定任务的需求。 综上所述,PyTorchResNet-18在CIFAR-10的预训练模型是一个有价值的工具,可以用于图像分类任务,具有较小的参数量和计算复杂度,预先学习了一般的图像特征和模式,并可以通过微调进一步适应特定任务的需求。 ### 回答3: PyTorch预训练模型ResNet-18在CIFAR-10数据集上表现出色。首先,CIFAR-10是一个包含10个不同类别的图像数据集,每个类别有6000个图像,共计60000个图像。ResNet-18是一个基于深度残差网络的模型,它具有18个卷积层和全连接层。该模型在ImageNet数据集上进行了预训练,其中包含了1000个类别的图像。 当我们将预训练的ResNet-18模型应用于CIFAR-10数据集时,可以得到很好的结果。因为CIFAR-10数据集的图像尺寸较小(32x32),相对于ImageNet数据集中的图像(224x224),所以ResNet-18模型在CIFAR-10上的训练速度更快。此外,ResNet-18模型通过残差连接解决了深度网络中的梯度消失问题,这使得它在CIFAR-10数据集上的表现也非常稳定。 通过使用预训练模型,我们可以通过迁移学习的方式节省训练时间。我们可以先将ResNet-18加载到内存中,然后只需针对CIFAR-10数据集的最后一层或几层进行微调即可。这样可以有效地提高模型在CIFAR-10上的性能。 总之,PyTorch中的预训练模型ResNet-18在CIFAR-10数据集上表现优秀。它通过残差连接解决了深度网络中的梯度消失问题,具有较快的训练速度和较好的稳定性。使用预训练模型可以节省训练时间,并通过微调模型的方式进一步提高性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值