【pytorch】手动在网络中实现正向传播与反向传播代码解析

代码与教程

此博文是关于pytorch中文教程中手动在网络中实现前向传播和反向传播部分的代码解析。先贴上教程来源与代码:

代码如下:

import torch

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor # 取消注释以在GPU上运行

# N 批量大小; D_in是输入尺寸;
# H是隐藏尺寸; D_out是输出尺寸.
N, D_in, H, D_out = 64, 1000, 100, 10

# 创建随机输入和输出数据
x = torch.randn(N, D_in).type(dtype)
y = torch.randn(N, D_out).type(dtype)

# 随机初始化权重
w1 = torch.randn(D_in, H).type(dtype)
w2 = torch.randn(H, D_out).type(dtype)

learning_rate = 1e-6
for t in range(500):
    # 正向传递:计算预测y
    h = x.mm(w1)
    h_relu = h.clamp(min=0)
    y_pred = h_relu.mm(w2)

    # 计算并打印loss
    loss = (y_pred - y).pow(2).sum()
    print(t, loss)

    # 反向传播计算关于损失的w1和w2的梯度
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.t().mm(grad_y_pred)
    grad_h_relu = grad_y_pred.mm(w2.t())
    grad_h = grad_h_relu.clone()
    grad_h[h < 0] = 0
    grad_w1 = x.t().mm(grad_h)

    # 使用梯度下降更新权重
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

代码解析

这是模拟的一个一层的全连接网络,包含两个参数矩阵,一个输入,一个输出。

  • 首先创建了输入矩阵x与输出矩阵y,这里就是调用了一下torch的随机函数,创建了大小为64*1000的输入和64*10的输出,其中64为batch大小:
x = torch.randn(N, D_in).type(dtype)
y = torch.randn(N, D_out).type(dtype)
  • 然后是网络的权重矩阵w1与w2,也是调用torch的随机函数创建,大小分别为1000*100和100*10。
w1 = torch.randn(D_in, H).type(dtype)
w2 = torch.randn(H, D_out).type(dtype)
  • 接下来是比较重要的正向传播部分,首先使用输入矩阵乘以权重矩阵w1,mm()函数表示矩阵乘法,具体可以点击函数查看官方文档的介绍。然后使用clamp()作为激励函数Relu的实现,将小于0的值都截断。最后再做一次矩阵乘法得到输出y_pred,至此正向传播完成:
h = x.mm(w1)	# h [64,100]
h_relu = h.clamp(min=0)	# h_relu [64,100]
y_pred = h_relu.mm(w2)	# y_pred [62,10]
  • 正向传播之后需要计算误差值,在此处使用的是非一般形式的均方误差,也就是矩阵相减后对每个元素取平方然后再求所有元素的和。
loss = (y_pred - y).pow(2).sum()
  • 下面是最重要的反向传播部分,首先第一行均方误差对y_pred的梯度比较简单,因为对矩阵中的每一个元素来说都有:
    ∂ L o s s ∂ y _ p r e d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值