本博客为OUC2022秋季软件工程06组第四次作业
一、猫狗大战挑战赛
下载数据集
接下来就是数据处理,使用torchvision 进行预处理,图片将被整理成 224 X 224 X 3 的大小,同时还将进行归一化处理。
然后我们开始创建VGG Model。我们直接使用预训练好的 VGG 模型。
在这部分代码中,对输入的5个图片利用VGG模型进行预测,同时,使用softmax对结果进行处理,随后展示了识别结果。可以看到,识别结果是比较非常准确的。
我们的目标是使用预训练好的模型,因此,需要把最后的 nn.Linear 层由1000类,替换为2类。为了在训练中冻结前面层的参数,需要设置 required_grad=False。这样,反向传播训练梯度时,前面层的权重就不会自动更新了。训练中,只会更新最后一层的参数。
接下来我们训练并测试全连接层,先创建损失函数和优化器,然后训练模型再测试模型。
结果如下:
最后我们可视化模型的预测结果
二、研习社猫狗大战赛
本质上与老师的代码类似只不过在训练的时候多加了
if epoch_acc >= 0.96: #当准确率超过一定数值时,保存模型
localtime = time.strftime('%Y-%m-%d_%H:%M:%S')
path = log_dir + str(epoch) + '_' + str(epoch_acc) + '_' + localtime
torch.save(model,path)
保存每个准确率较高的模型
可以看到我保存了一个0.972准确率的model
model_vgg_new = torch.load(r'/content/drive/MyDrive/model/19_0.9722222222222222_2022-10-21_09:16:21')#加载之前保存的模型
然后我将其读出,使用它预测数据。
dic = {}
def test(model,dataloader,size):
model.eval()
predictions = np.zeros(size)
print(predictions)
cnt = 0
for inputs,_ in tqdm(dataloader): #inputs是tensor,torch.Size([1, 3, 224, 224])
inputs = inputs.to(device)
outputs = model(inputs)
_,preds = torch.max(outputs.data,1)#preds是tensor([0], device='cuda:0')是tensor
#这里是切割路径,因为dset中的数据不是按1-2000顺序排列的
key = dsets_mine.imgs[cnt][0].split("\\")[-1].split('.')[0]
dic[key] = preds[0]#preds[0]是tensor(0, device='cuda:0')是tensor
cnt = cnt +1
test(model_vgg_new,loader_test,size=2000)
保存进一个csv文件。
with open("/content/drive/MyDrive/csv/result.csv",'a+') as f:
for key in range(2000):
f.write("{},{}\n".format(key,dic["/content/drive/MyDrive/data/cat_dog/test/"+str(key)]))
提交结果如下:
最后达到了97分。
这次算是我的初次尝试,对于其中很多原理都没有搞懂。
三、思考
随机梯度下降法虽然应对大型数据集时,训练速度很快,能明显提高学习的效率,但是其也具有缺点:
(1)SGD在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。
(2)SGD也没能单独克服局部最优解的问题。因此我们可以根据需求使用其他合适的方法来应对他的这些缺点。
对于学习率的选取,我们可以参考自适应学习率优化算法。根据模型实际学习情况实时更新学习率,从而提高训练速度。目前的自适应学习率优化算法主要有:AdaGrad算法,RMSProp算法,Adam算法以及AdaDelta算法。
对于随机梯度下降法所存在的缺点,我们可以使用动量优化法。动量优化方法是在梯度下降法的基础上进行的改变,具有加速梯度下降的作用。一般有标准动量优化方法Momentum和NAG动量优化方法。