1、参考文档
(BETA) QUANTIZED TRANSFER LEARNING FOR COMPUTER VISION TUTORIAL
TRANSFER LEARNING FOR COMPUTER VISION TUTORIAL
https://cs231n.github.io/transfer-learning/
2、迁移学习方法
ConvNet as fixed feature extractor
将预训练模型最后一层全连接层去掉,然后将最后一层以外(特征提取部分)的权重参数全部冻结。最后一个完全连接的层被一个具有随机权重的新的层取代,并且只有这个层被训练。
Finetuning the ConvNet
这种策略不仅是在新的数据集上替换和重新训练卷积网络中的分类器(也就是最后的全连接层,防止分类类别不同),还会继续反向传播来微调预训练网络的权重(一般将学习率设置为较小的数字)。可以微调卷积网络的所有层,也可以保持一些早期的层的固定(由于过拟合的问题),只微调网络的一些更高级别。这是因为卷积网络的早期特征包含更多通用特征,但后期的层对原始数据集中包含的细节越来越具体。
方法选择
需考虑的两个主要因素:
- 新数据集的大小
- 与原始数据集的相似性(图像内容和类别方面的相似性)
如果新的数据集很小,与原始数据集相似,对卷积网络进行微调会容易过拟合。最好的方法是训练最后一层分类器。
如果新的数据集很大,与原始数据集相似,可以对整个网络进行微调,并且不会过拟合
如果新的数据集很小,但与原始数据集差异很大。由于数据集小,最好的方法是只训练分类器,但由于与原始数据集差异大,因此从网络较早的某个层的激活中训练
如果新的数据集很大,但与原始数据集的差异很大,可以重头开始训练卷积网络。
3、迁移学习pytorch实现
3.1、ConvNet as fixed feature extractor
在量化过程中使用这种迁移学习方法,不需要为量化模型设置requires_grad=False,因为没有可训练的参数。
量化插入的去量化层需要在头部(卷积网络除了特征提取部分之外的最后几层)之前。
修改预训练模型
将最后的层使用Sequential封装。
def create_combined_model(model_fe):
# Step 1. Isolate the feature extractor.
model_fe_features = nn.Sequential(
model_fe.quant, # Quantize the input
model_fe.conv1,
model_fe.bn1,
model_fe.relu,
model_fe.maxpool,
model_fe.layer1,
model_fe.layer2,
model_fe.layer3,
model_fe.layer4,
model_fe.avgpool,
model_fe.dequant, # Dequantize the output
)
# Step 2. Create a new "head"
new_head = nn.Sequential(
nn.Dropout(p=0.5),
nn.Linear(num_ftrs, 2),
)
# Step 3. Combine, and don't forget the quant stubs.
new_model = nn.Sequential(
model_fe_features,
nn.Flatten(1),
new_head,
)
return new_model
3.2、Finetuning the ConvNet
加载预训练模型并重置最后的全连接层
model_ft = models.resnet18(weights='IMAGENET1K_V1')
num_ftrs = model_ft.fc.in_features
# Here the size of each output sample is set to 2.
# Alternatively, it can be generalized to ``nn.Linear(num_ftrs, len(class_names))``.
model_ft.fc = nn.Linear(num_ftrs, 2)
model_ft = model_ft.to(device)
criterion = nn.CrossEntropyLoss()
# Observe that all parameters are being optimized
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
# Decay LR by a factor of 0.1 every 7 epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
model_ft.fc = nn.Linear(num_ftrs, 2)将全连接层输出变成2,即变为二分类
训练并验证