pytorch迁移学习中parameters requires_grad=False和optimizer优化参数的探讨

首先背景是迁移学习,以VGG16网络为例,固定他的特征提取层,优化他的全连接分类层。

有的书上写了:

for param in vgg.features.parameters():

    param.requeires_grad=False

然后在定义优化器的时候,又写了下面的代码:

optimizer=optim.SGD(vgg.classifier.paramters(),lr=0.001)

这样的代码虽然可以运行,但是让人很疑惑。

首先第一句代码的作用是:特征层中参数都固定住,不会发生梯度的更新;第二句代码的作用是定义一个优化器,这个优化器的作用是优化全连接层中的参数,并没有说要优化特征层中的参数。那么这里自然会让人想到,为什么两个代码要一起用呢?下面的优化器参数是网络所有参数运行起来会有什么变化吗?或者去掉上面的代码,理应也是可以正常运行的,因为并没有要改变特征层的参数。

这样的书,很容易误导人,让人以为,这两行代码都是必须写代码才可以运行的。因此我做了一些实验验证了自己的想法。

只写第一句那么,特征层不会产生梯度,但是梯度会在其中传播。也就是说如果,你对第二层限制求梯度,那么第二层不会产生改变量(梯度*学习率),但是第一层会产生梯度,也可以进行改变。

只写第二句,梯度正常产生,但是由于优化器没有涉及特征层的参数,所以特征层虽然产生了梯度,但是参数却不会改变。

但是,由一位网友的提示,required_grad这一句是确定是否计算导数的。所以有第一句可以减少计算量,也就是不用求w和b的导数了,减少了计算量。只传播误差,而不计算权重和偏执的导数。

类似的还有一些代码中训练gan的时候用到了detach,其实推敲一下也是没有必要的,可以看我的DCGAN中没有用到detachpytroch:DCGAN生成动漫头像,也可以正常运行。许多文章中对gan中detach解释也是含糊不清。可能有时候需要detach,但是也要明白为什么。 

如有不正确的地方,请指正。https://www.bilibili.com/read/cv1375522

你可能感兴趣的:(pytorch学习)