[pytorch] torch代码解析 为什么要使用optimizer.zero_grad()
optimizer.zero_grad()意思是把梯度置零,也就是把loss关于weight的导数变成0.
另外Pytorch 为什么每一轮batch需要设置optimizer.zero_grad:
根据pytorch中的backward()函数的计算,当网络参量进行反馈时,梯度是被积累的而不是被替换掉;但是在每一个batch时毫无疑问并不需要将两个batch的梯度混合起来累积,因此这里就需要每个batch设置一遍zero_grad 了。
在学习pytorch的时候注意到,对于每个batch大都执行了这样的操作:
# zero the parameter gradients
optimizer.zero_grad() # 梯度初始化为零
# forward + backward + optimize
outputs = net(inputs) # 前向传播求出预测的值
loss = criterion(outputs, labels) # 求loss
loss.backward() # 反向传播求梯度
optimizer.step() # 更新所有参数
对于这些操作我是把它理解成一种梯度下降法,贴一个手写的简单梯度下降法作为对照:
# gradient descent
weights = [0] * n
alpha = 0.0001
max_Iter = 50000
for i in range(max_Iter):
loss = 0
d_weights = [0] * n # 梯度初始化为零
for k in range(m):
h = dot(input[k], weights) # 前向传播求出预测的值
# 反向传播求梯度
d_weights = [d_weights[j] + (label[k] - h) * input[k][j] for j in range(n)]
loss += (label[k] - h) * (label[k] - h) / 2 # 求loss
d_weights = [d_weights[k]/m for k in range(n)]