例如我的一个train函数中有三个优化器,并且每一个在训练的过程中确实都使用到了,但是最终的loss函数只是针对于其中一个优化器的,那是训练了三个模型还是一个模型呢?
以pytorch为例,optimizer是指诸如adam之类的这些优化器。
那么首先需要知道这些optimizer是干什么的。优化器的作用是用来更新模型权重的,不同的优化器有不同的权重更新方案。
比如有的只是w_new=w_old+lr*△w;有的是 w_new=α*w_old+lr*△w啥的。
而优化器所需要的输入是 loss函数+梯度回传所计算出来的每个位置在当前batch下的梯度…
所以,题主的问题,这里有几个点:
model=DefineModel()
optimizer=Opt(model.parameters())
loss=LossFunc(pred,label)
loss.backward()
optimizer.step()
optimizer.zero_grad() # 清空上次更新,防止累积
model=DefineModel()
optimizer1=Opt(model.parameters()) # 注意这里的参数都一样
optimizer2=Opt(model.parameters())
optimizer3=Opt(model.parameters())
loss=LossFunc(pred,label)
loss.backward()
optimizer1.step()
optimizer1.zero_grad() # 清空上次更新,防止累积
optimizer2.step()
optimizer2.zero_grad() # 清空上次更新,防止累积
optimizer3.step()
optimizer3.zero_grad() # 清空上次更新,防止累积
* 2、第二种情况是多个优化器优化不同位置的模型参数。这样做可能是有意义的,比如以现在很火的stable-diffusion为例子,其中有三部分参数:VQGAN,UNET,TEXT-ENCODER,训练的时候VQGAN和TEXT_ENCODER是之前就训练好的,UNET是从头开始训练的;那可能为了最优的生成效果,我让VQGAN和TEXT_ENCODER也一起参与训练,但是大家的优化器和学习率都不同,来匹配彼此间不同的学习进度。
model=DefineModel()
optimizer1=Opt(model.parameters_1()) # 注意这里的参数都不一样
optimizer2=Opt(model.parameters_2())
optimizer3=Opt(model.parameters_3())
loss=LossFunc(pred,label)
loss.backward()
optimizer1.step()
optimizer1.zero_grad() # 清空上次更新,防止累积
optimizer2.step()
optimizer2.zero_grad() # 清空上次更新,防止累积
optimizer3.step()
optimizer3.zero_grad() # 清空上次更新,防止累积
那回到问题,首先这个并不是训练了多个模型,模型的参数只有一份,你最终还是只有一个模型。
如果你采用的是第一种方法,那么可能你的模型最终达不到你要的效果;
如果你采用的是第二种方法,那么你事先应该知道你模型的不同部分为什么需要不同的优化器。
没试过,不过一般模型训练一个模型不同的参数部分也可指定不同的优化器与学习率等参数。
对的,就是训练了多个模型。(个人观点,请大佬不吝赐教)
一个train函数中使用多个优化器,且在训练过程中都有调用了,那么实际上是在训练多个模型。
使用不同的优化器,相当于为不同的参数组设置不同的优化策略。一组参数及其优化器可视为一个模型,且模型共享部分网络结构,只是优化目标不同。训练过程中,每个优化器都会更新其对应的参数组。
结果:虽然只看一个模型的loss,实际上不同优化器对应的模型都得到了训练。只选了或者关注了其中一个模型而已。
以上
每个优化器都可以指定需要优化的参数包括哪些,执行完loss.backward()之后每个可训练参数都得到了梯度,下一步就是按照优化器的规则进行参数更新,所以可以是多模型,也可以是对一个模型的不同参数按照不同的优化规则更新,但是后者的做法貌似没见过。