本文共 3826 字,大约阅读时间需要 12 分钟。
Pytorch Autograd库 (自动求导机制) 是训练神经网络时,反向误差传播(BP)算法的核心。
本文通过logistic回归模型来介绍Pytorch的自动求导机制。首先,本文介绍了tensor与求导相关的属性。其次,通过logistic回归模型来帮助理解BP算法中的前向传播以及反向传播中的导数计算。
以下均为初学者笔记。
note: 以下用x代表创建的tensor张量。
假设有一个损失函数如下(Logistic回归):
由损失函数构建简单计算图模型如下:
现在我们通过上述例子来理解前向传播和反向传播。在上述简单的神经网络模型中,我们需要对权值参数w1,w2以及阈值参数b进行更新。神经网络训练的总体过程如下:先由输入层逐级前向传播计算loss输出,再有输出层loss反向计算各层梯度传播误差,以此更新各层的权值参数w和阈值参数b。
在该模型中我们需要求出loss对w1、w2以及b的偏导,以此利用SGD更新各参数。对于根据链式法则的逐级求导过程不再赘述,有详细的计算过程以及解释。
现在我们利用pytorch实现logistic回归模型,并手动实现参数更新。
import torchimport numpy as np# 可能网络上有许多资料在Tensor外再额外封装一层Variable,然而从Pytorch0.4版本以后,Variable已经合并进Tensor了,因此以后的代码可以直接用Tensor,不必要再封装一层Variable。# 读入数据 x_t,y_tx_t = torch.tensor(np.array([[1,1],[1,0],[0,1],[0,0]]),requires_grad=False,dtype=torch.float)y_t = torch.tensor([[0],[1],[0],[1]],requires_grad=False,dtype=torch.float)print(x_t.size())# 定义权值参数w和阈值参数bw = torch.randn([2,1], requires_grad=True,dtype=torch.float)b = torch.zeros(1, requires_grad=True,dtype=torch.float)print(w.size())# 构建逻辑回归模型def logistic_model(x_t): a = torch.matmul(x_t,w) + b return torch.sigmoid(a)y_p = logistic_model(x_t)# 计算误差def get_loss(y_p, y_t): return -torch.mean(y_t * torch.log(y_p)+(1-y_t) * torch.log(1-y_p))loss = get_loss(y_p, y_t)print(loss)# 自动求导loss.backward()# note:如果loss为一个标量(一般都是),那么loss.backward()不需要指定任何参数。然而如果有多个损失,即loss为一个向量tensor([loss1, loss2,loss3]),则需要指定一个gradient参数,它是与loss形状匹配的张量,如tensor([1.0,1.0,0.1]),里面数字我个人理解为代表各损失的权重。# 查看 w 和 b 的梯度print(w.grad)print(b.grad)# 更新一次参数w.data = w.data - 1e-2 * w.grad.datab.data = b.data - 1e-2 * b.grad.data'''note:存在两个问题:1. 如果没有前面先更新一次参数,后面直接进行迭代更新的话,会报错,具体原因也没搞懂。2. 利用pycharm运行pytorch代码,调用了backward()之后,程序运行完成进程并不会终止,需要手动到任务管理器中kill进程,具体原因也不清楚。'''# epochfor e in range(10000): # 进行 10000 次更新 y_p = logistic_model(x_t) loss = get_loss(y_p, y_t) w.grad.zero_() # 归零梯度 b.grad.zero_() # 归零梯度 loss.backward() w.data = w.data - 1e-2 * w.grad.data # 更新 w b.data = b.data - 1e-2 * b.grad.data # 更新 b print('epoch: {}, loss: {}'.format(e, loss.data.item()))print(w)print(b)'''每500次迭代打印出输出结果,我们看到损失函数在迭代中逐步下降:epoch: 0, loss: 0.9426676034927368epoch: 500, loss: 0.5936437249183655epoch: 1000, loss: 0.4318988025188446epoch: 1500, loss: 0.33194077014923096epoch: 2000, loss: 0.265964150428772epoch: 2500, loss: 0.22003984451293945epoch: 3000, loss: 0.18663322925567627epoch: 3500, loss: 0.1614413857460022epoch: 4000, loss: 0.14187511801719666epoch: 4500, loss: 0.12630191445350647epoch: 5000, loss: 0.11365044862031937epoch: 5500, loss: 0.10319262742996216epoch: 6000, loss: 0.09441888332366943epoch: 6500, loss: 0.08696318417787552epoch: 7000, loss: 0.08055643737316132epoch: 7500, loss: 0.07499672472476959epoch: 8000, loss: 0.07013023644685745epoch: 8500, loss: 0.06583743542432785epoch: 9000, loss: 0.06202460825443268epoch: 9500, loss: 0.05861698091030121至此,手动实现梯度下降,logistic模型搭建完成,之后将尝试利用pytorch框架搭建神经网络。'''
转载地址:http://yqvez.baihongyu.com/