通常情况下, 我们不会从头训练整个神经网络, 更常用的做法是先让模型在一个非常大的数据集上进行预训练, 然后将预训练模型的权重作为当前任务的初始化参数, 或者作为固定的特征提取器来使用. 既通常我们需要面对的是下面两种情形:
- Finetuning the convnet: 在一个已经训练好的模型上面进行二次训练
- ConvNet as fixed feature extractor: 此时, 我们会将整个网络模型的权重参数固定, 并且将最后一层全连接层替换为我们希望的网络层. 此时, 相当于是将前面的整个网络当做是一个特征提取器使用.
Load Data
我们将会使用torch.utils.data
包来载入数据. 我们接下来需要解决的问题是训练一个模型来分类蚂蚁和蜜蜂. 我们总共拥有120张训练图片, 具有75张验证图片.
1 | data_transforms = { |
Visualize a few images
1 | def imshow(inp, title=None): |
Training the model
接下来, 让我们定义一个简单的函数来训练模型, 我们会利用LR scheduler对象torch.optim.lr_scheduler
设置lr scheduler, 并且保存最好的模型.
1 | def train_model(model, criterion, optimizer, scheduler, num_epochs=25): |
Visualizing the model predictions
下面的代码用于显示预测结果
1 | def visualize_model(model, num_images=6): |
FineTuning the convnet
加载预训练模型, 并重置最后一层全连接层
1 | # from torchvisioin import models |
Train and evaluate
调用刚刚定义的训练函数对模型进行训练1
2
3model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=25)
visualize_model(model_ft)
Convnet as Fixed Feature Extractor
假设我们需要将除了最后一层的其它层网络的参数固定(freeze), 为此, 我们需要将这些参数的requires_grad
属性设置为False
.
1 | model_conv = torchvision.models.resnet18(pretrained=True) |
Train and evaluate
1 | model_conv = train_model(model_conv, criterion, optimizer_conv, exp_lr_scheduler, num_eopch=25) |