梯度下降算法学习心得
分为深度和非深度两种
一. 非深度
损失函数定义为方差函数:loss=1/2(y-h)^2
参数更新部分的代码需要手撕,每个参数同时但是单独更新,梯度是用上次更新的所有θ和样本数据计算得来的,实际操作上可以在每次更新开始之前先把所有数据点对应的梯度先计算出来,批量梯度是用这些计算来的梯度的平均值来更新每个θ,随机梯度则是用单个数据点的梯度更新,最小批量是用部分数据点的梯度的平均值更新:
-
批量梯度下降
-
随机梯度下降
-
最小批量梯度下降
二. 深度
用pytorch建立网络模型后,定义该模型对应的优化器Optimizer,用来保存当前的状态,并能够根据计算得到的梯度来更新参数。如
self.optimizer = torch.optim.Adam(self.eval_net.parameters(), lr=LR) # 使用Adam优化器 (输入为评估网络的参数和学习率)
另外需要定义损失函数,跟非深度类似,只不过这里使用定义好的模块,如(函数的输入为y和h)
self.loss_func = nn.MSELoss() # 使用均方损失函数 (loss(y, h)=(y-h)^2)
定义好了这两部分后,只需要大量数据就可以用一些固定语句对网络参数进行更新了。
loss = self.loss_func(q_eval, q_target) # 输入32个评估值和32个目标值,使用均方损失函数
self.optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
self.optimizer.step() # 更新评估网络的所有参数
其中q_eval, q_target是要通过数据计算出来的,每使用optimizer.step()
一次就是更新一次网络全体参数(从这点看DQN的更新方式很像最小批量梯度下降)
神经网络的好处就是,不用手动对lossfunction求梯度,只需根据定义好的lossfunction的形式、用获取的小批量数据计算出loss的大小(一个tensor类型的数),然后直接把这个loss带到网络中反向传播即可。故,用网络做梯度下降的很大一部分工作在于设计一个合理地lossfunction
据机器学习的目的的不同,设计损失函数是很有技巧的,如监督学习和强化学习,对应的就是loss_func的输入的不同