Pytorch使用预训练模型加速训练的技巧

版权声明:转载注明出处 https://blog.csdn.net/york1996/article/details/83033497

当属于预训练模型属于下面的情况的时候,可以采用这个加速的技巧:

固定前部分的层,只改变网络后面层的参数。

比如,使用vgg16的预训练模型,固定特征提取层,改变后面的全连接层。要注意的是,如果固定的是特征提取层+一个全连接层,也可以使用这个技巧,只要固定的是前一部分。

具体的做法是:
 把所有的数据都输入进去特征层,把得到的输出保存成张量保存在内存(如果太多还可以保存在本地)中,无论有多少批次,前面的这个过程只进行一次。然后把这些作为训练数据,相当于只训练了mlp,随着批次的增加,相对速度将会提高的很明显。

这样做也很好理解,因为前提是不改变卷积层的参数,所以一般的训练过程中,n个epoch,对一张图片来说就会在特征层中传播n次,由于卷积层参数不改变,所以得到的结果也是一样的。

通过这样的操作就消除了大量的计算冗余,加速也是理所当然的。猜想,这样不仅省去了feedforward,而且还会省去backforward,这样说的理由是,虽然代码中不更新卷积层的参数,并且卷积层在网络的最前端,可能大家都会觉得不会有梯度的计算了,如果required_grad=false,那么却是是不用计算梯度的,但是因为网络自己可能并不知道卷积层前面没有其他层了,所以误差可能还是要计算的。如果不计算,源代码就应该有对需要梯度的网络层位置的判断。

进一步的,如果网络中有某些模块对于数据来说不会因为批次改变而发生变化,也可以进行训练一次,多次使用的策略。
还没有跑类似的代码,可能遇到的问题:

  1. 数据太多,所有数据的输出保存起来超过了内存。这个时候需要权衡一下从硬盘读取张量快,还是提取特征快。做一下折中。
  2. label数据对应问题。这个应该可以通过一些编程来实现:把每个图片的特征和label保存在一个元组里面等等。

参考书籍:《Deep Learning with Pytorch》112页附近

https://www.bilibili.com/read/cv1374357

猜你喜欢

转载自blog.csdn.net/york1996/article/details/83033497