Back Propagation 反向传播

目录

BP学习目标

BP计算图

BP的链式法则chain rule

计算流程:

前向网络传播

反向传播过程

完整的计算图举例:

代码剖析:

 练习:

练习代码:

 结果:

 总结:


BP学习目标

对权重w进行更新,随机梯度下降采用的是loss对w进行求导求梯度,使得w的更新来减少loss,并尽可能是loss最小。

          

BP计算图

         

这个结构就成为神经网络中的一层

完整的两层神经网络如下图。 具体的Matrix multiplication矩阵乘法可以参考 matrix cookbook。

           

BP的链式法则chain rule

1. 前馈网络形式,先向前计算从输入x和权重w,然后算出loss

        

2. Local gradient,求f关于x的导数和关于w的导数

         

3. 再反向将loss关于z的偏导传递

        

4. 反向传播,使用链式法则来求的loss关于x的偏导和关于w的偏导,从而产生新的输入内容

       

计算流程:

前向网络传播

              

反向传播过程

            

完整的计算图举例:

          

Tensor 张量,可以是标量,向量,也可以是三维的,还可以是更高阶的数据。

代码剖析:

1. 确定好张量w后,构建计算图、

          

因为当前张量w是一个数,所以torch.Tensor([1.0]),用中括号括起来的数值填写1.0就可以了。

默认情况下tensor不会保留计算的梯度,所以需要w.requires_grad = True 来计算获得张量的梯度。

2. 因为w是张量需要获取w的梯度,所以x*w计算后也是张量也需要获取x*w的梯度

           

3. 每调用一次loss函数,构建一次计算图。获得loss

          

4. 前馈过程,计算loss

          

5. 反馈过程,计算张量的梯度,在反向传播的过程中计算所有张量需要的梯度

          

6. 利用梯度来更新权重,因为梯度也是tensor,而进行tensor的计算需要构建计算图,但是更新权重只是数值的计算也不需要构建计算图,因此需要用tensor的data,即w.data= w.data - 0.01 * w.grad.data.

          

在更新权重之前可以使用张量直接计算,但是到权重更新时只能使用标量。

7. 将权重里面的梯度数据全部清零。在这里梯度不需要累加,所以需要显式地清零。不然得到的权重的梯度就是累加的结果。

          

8.  获取损失,继续迭代。l.item()来获取标量的损失,epoch表示迭代第几轮

          

 练习:

          

练习代码:

import torch
import matplotlib.pyplot as plt
import os

os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'

# create the data
x_data = [1.0, 2.0, 3.0]
y_data = [4.0, 9.0, 16.0]

# create the Tensor for grad
w1 = torch.Tensor([1.0])  # 初始权值
w1.requires_grad = True
w2 = torch.Tensor([1.0])
w2.requires_grad = True
b = torch.Tensor([1.0])
b.requires_grad = True


# define the linear model
def forward(x):
    return x * x * w1 + x * w2 + b  # x^2*w1 + x * w2  also is a Tensor     w1=1, w2=2, b=1


def loss(x, y):  # 构建计算图
    y_pred = forward(x)
    return (y_pred - y) ** 2


print("predict (before training)", 4, forward(4).item())

# training
epoch_list = []
loss_list = []
for epoch in range(1000):
    for x, y in zip(x_data, y_data):
        l = loss(x, y)
        l.backward()
        print('\t grad:', x, y, w1.grad.item(), w2.grad.item(), b.grad.item())
        w1.data = w1.data - 0.01 * w1.grad.data  #注意这里的grad是一个tensor,所以要取他的data
        w2.data = w2.data - 0.01 * w2.grad.data
        b.data = b.data - 0.01 * b.grad.data

        w1.grad.data.zero_() #释放之前计算的梯度
        w2.grad.data.zero_()
        b.grad.data.zero_()
        epoch_list.append(epoch)
        loss_list.append(l.item())

    print("progress:", epoch, l.item())
print("predict (after training)", 4, forward(4).item())

plt.plot(epoch_list, loss_list)
plt.ylabel("loss")
plt.xlabel("epoch")
plt.show()

 结果:

#predict (before training) 4 21.0
#训练1000epoch
#predict (after training) 4 25.152122497558594
#训练10000epoch
#predict (after training) 4 25.000938415527344
#在修改训练集的x,y值后,训练结果接近25,

 总结:

        BP学习过程由信号正向传播和误差反向传播两个阶段构成。其中信号正向传播用于获得在隐含层神经元和输出层神经元的输出信号;误差反向传播用于将网络期望输出与实际输出的误差从输出层反向传播至隐含层在至输入层,并在此过程中更新各个神经元的连接权值。

 参考:《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值