参考资料:
《深度学习之pytorch实战计算机视觉》
先看一个只有一层的简单的神经网络训练代码。
#--coding:utf-8--
'''
一个简单的神经网络模型
'''
import torch
batch_n = 100#batchsize值
hidden_layer = 100#100个神经元
input_data = 1000#1000个特征值
output_data = 10#十分类
x = torch.randn(batch_n,input_data)#输入数据
y = torch.randn(batch_n,output_data)#标签
w1 = torch.randn(input_data,hidden_layer)
w2 = torch.randn(hidden_layer,output_data)
#训练优化权重参数
epoch_n = 20
learning_rate = 1e-6
for epoch in range(epoch_n):
h1 = x.mm(w1)#矩阵乘法
h1 = h1.clamp(min=0)#等同于加上一个reLU的激活函数
y_pred = h1.mm(w2)
loss = (y_pred-y).pow(2).sum()
print("Epoch:{},Loss:{:.4f}".format(epoch,loss))
#反向传播计算梯度
grad_y_pred = 2*(y_pred-y)
grad_w2 = h1.t().mm(grad_y_pred)
grad_h = grad_y_pred.mm(w2.t())
grad_h.clamp_(min=0)
grad_w1 = x.t().mm(grad_h)
#梯度下降法进行优化
w1 -= learning_rate*grad_w1
w2 -= learning_rate*grad_w2
其中反向传播计算梯度的代码相对繁琐。事实上,pytorch提供了非常方便的方法,用于自动计算反向传播过程中的梯度。该方法封装在torch.autograd包中。
下面看用torch.autograd包中的方法对该代码的重写。
import torch
from torch.autograd import Variable
batch_n = 100#batchsize值
hidden_layer = 100#100个神经元
input_data = 1000#1000个特征值
output_data = 10#十分类
x = Variable(torch.randn(batch_n,input_data),requires_grad = False)#输入数据
y = Variable(torch.randn(batch_n,output_data),requires_grad = False) #标签
w1 = Variable(torch.randn(input_data,hidden_layer),requires_grad = True)
w2 = Variable(torch.randn(hidden_layer,output_data),requires_grad = True)
#训练优化权重参数
epoch_n = 2000
learning_rate = 1e-6
for epoch in range(epoch_n):
h1 = x.mm(w1)#矩阵乘法
h1 = h1.clamp(min=0)#等同于加上一个reLU的激活函数
y_pred = h1.mm(w2)
loss = (y_pred-y).pow(2).sum()
print("Epoch:{},Loss:{:.4f}".format(epoch,loss))
#反向传播计算梯度
loss.backward()
#梯度下降法进行优化
w1.data -= learning_rate*w1.grad.data
w2.data -= learning_rate*w2.grad.data
w1.grad.data.zero_()
w2.grad.data.zero_()
backward函数会自动计算requires_grad值为True的变量的梯度并保存。此外每迭代一次需要将计算得到的梯度置零,否则计算的梯度值会一直叠加。