个人做法是用hotdog_w代替finetune_net.fc的第一行权重
for _ in range(0):
with torch.no_grad():
finetune_net.fc.weight[0] = hotdog_w.reshape(-1)
训练结果:loss 0.135, train acc 0.945, test acc 0.948
729.7 examples/sec on [device(type=‘cuda’, index=0)]
原始finetune结果:loss 0.170, train acc 0.940, test acc 0.929
614.3 examples/sec on [device(type=‘cuda’, index=0)]
1.使用4e-4的学习率,速度变快了(176.2->190.3 examples/sec),准确度提升了(train acc 0.933->0.951)
2.更改了超参数:weight decay(0.001->0.01)
速度提升明显,泛化能力提升了,但是在训练集上的精确度下降了。
我觉得这样子是合理的,提升L2重要性,即降低了过拟合可能性,即提升了泛化能力
3.我尝试了给出的代码,但是报错element 0 of tensors does not require grad and does not have a grad_fn,这是说在d2l.train_batch_ch13中,反向传播时候遇到了没有梯度的张量
我猜想需要自己构建训练函数
4.单独切割出来热狗参数,em,我不会
检查将模型移动到gpu的代码是否在,没有的话显式地进行移动:
device = torch.device("cuda:0" is torch.cuda.is_available() else "cpu")
model.to(device)
如果已经如上面显式地进行了移动,还在cpu上的话。检查你的torch是否安装了支持gpu版本的,安装是否正确 ,命令行输入以下指令测试,返回True
的话就已经正确安装:
torch.cuda.is_available()
我是直接把训练函数的学习率调为0了,这样就不会更新了。你的报错应该是在train_batch_ch13中计算l.sum().backward()的时候报错了,我们已经把requires_grad参数设置为False了,如果还试图求backward的话,自然会报错。另一种方法就是去修改train_batch_ch13。
因为预训练模型是在 imagenet 上训练的,然后 imagenet 的 transform 中进行了这样的一个 normalize,所以在这个数据集也进行了同样参数的 normalize.
预训练模型本就是希望迁移原来学好的东西,提取特征的部分尽量不要改变.
所以进行同样的 normalize 也是希望对源模型减少扰动
1 Like
请问把这里的learning_rate改为0是不是就是不更新fc层前的参数?
关于练习第四题,事实上,ImageNet
数据集中有一个“热狗”类别。我们可以通过以下代码获取其输出层中的相应权重参数,但是我们怎样才能利用这个权重参数?
我是这样处理的,把热狗的[1,512]权重拿出来,再用xavier_uniform获得一个[1,512]的tensor,两者拼接成[2,512]的weight给微调模型
按理说精度应该会很高才对,但我的测试结果很差,我是哪一步操作不对吗,我尝试过互换两个[1,512]权重的位置,结果也是很差
Xiyu
November 21, 2023, 1:17pm
#30
关于第四题,事实上我猜想应该通过修改fine-tuning中得最后一个全连接层来实现权重参数的利用,
即:
weight = pretrained_net.fc.weight
hotdog_w = torch.split(weight.data, 1, dim=0)[934]
finetune_net = torchvision.models.resnet18(pretrained=True)
finetune_net.fc = nn.Linear(hotdog_w.shape[1], 2)
nn.init.xavier_uniform_(finetune_net.fc.weight);
通过这个方法,最后的参数在训练集上略有上升。