从numpy到pytorch了解BP算法及构建基础的神经网络

从numpy到pytorch了解BP算法及构建基础的神经网络

1.BP算法的定义

BP算法(即误差反向传播算法)适合于多层神经元网络的一种学习算法,它建立在梯度下降法的基础上。
BP算法的学习过程由正向传播过程和反向传播过程组成。
正向传播:计算输入通过隐藏层之后的输出结果(y_predict)。将y_predict和y_true的误差的平方和作为目标函数(loss)。
反向传播:逐层求出目标函数对各神经元权值的偏导数,构成目标函数对权值向量的梯度值,作为修改权值的依据。
网络的学习在权值修改过程中完成。误差达到所期望值时,网络学习结束。

在进行训练之前,导入必要的包

import numpy as np
import torch
import torch.nn as nn

2.numpy实现基础的神经网络和BP算法

手动推导—>>>
在这里插入图片描述

(1)随机构建一些数据

 n,d_in,h,d_out=64,1000,100,10 # 设置输入的样本数,维数,隐藏层的个数,输出层的维数
x=np.random.rand(n,d_in)  # 输入n*d_in
w1=np.random.rand(d_in,h) # 权重1
bias1=np.random.rand(n,h)   # 偏置1
w2=np.random.rand(h,d_out) # 权重2
bias2=np.random.rand(n,d_out)   # 偏置2
y=np.random.rand(n,d_out)  # 输入n*d_out

(2)进行卷积

for t in range(500):
    # 正向传播计算y_predict
    cov1=x.dot(w1)+bias1  # 第一层卷积 (点乘+偏置)
    relu_1=np.maximum(cov1,0)   # relu激活函数 (用于处理非线性关系)
    y_predict=relu_1.dot(w2) + bias2  # 预测的y
    # 计算损失函数
    loss=np.square(y_predict-y).mean()  # 此时为MSE
    print("numpy实现,第{}次的损失为:{}".format(t,loss))
    # backward pass(反向传播计算梯度)
    grad_y_predict=2*(y_predict-y)   # loss对y_predict求偏导
    grad_w2=relu_1.T.dot(grad_y_predict)  #反向计算的w2的梯度
    grad_bias2=grad_y_predict
    grad_relu1=grad_y_predict.dot(w2.T)
    grad_cov1 = grad_relu1.copy()
    grad_cov1[cov1<0]=0
    grad_w1=x.T.dot(grad_cov1)
    grad_bias1 = grad_cov1
    # 更新参数w1和w2,bias1和bias2 (w1=w1-lr*grad_w1)
    w1-=learning_rate*grad_w1
    w2 -= learning_rate * grad_w2
    bias1-= learning_rate * grad_bias1
    bias2-= learning_rate * grad_bias2

结果:
在这里插入图片描述

3.torch实现神经网络和BP算法

(1)随机创建一些训练数据

x=torch.rand(n,d_in)  # 输入n*d_in
w1=torch.rand(d_in,h) # 权重1
bias1=torch.rand(n,h)   # 偏置1
w2=torch.rand(h,d_out) # 权重2
bias2=torch.rand(n,d_out)   # 偏置2
y=torch.rand(n,d_out)  # 输入n*d_out

(2)进行卷积
pytorch很多都和numpy类似,仅进行少部分修改即可

for t in range(500):
    cov1=x.mm(w1)+bias1   # mm实现矩阵相乘
    relu_1=cov1.clamp(min=0) # relu激活函数 clamp函数为夹子
    y_predict=relu_1.mm(w2) + bias2
    # 计算损失函数
    loss=(y_predict-y).pow(2).mean().item()  # 求平方pow(2)
    print("pytorch自己构建梯度实现,第{}次的损失为:{}".format(t,loss))
    # backward pass(反向传播计算梯度)
    grad_y_predict=2*(y_predict-y)
    grad_w2=relu_1.t().mm(grad_y_predict)
    grad_bias2=grad_y_predict
    grad_relu1=grad_y_predict.mm(w2.t())   # 转置用t()
    grad_cov1 = grad_relu1.clone()   # 复制用clone()
    grad_cov1[cov1<0]=0
    grad_w1=x.t().mm(grad_cov1)
    grad_bias1 = grad_cov1
    # 更新参数w1和w2,bias1和bias2
    w1-=learning_rate*grad_w1
    w2 -= learning_rate * grad_w2
    bias1-= learning_rate * grad_bias1
    bias2-= learning_rate * grad_bias2

结果在这里插入图片描述

3.torch的api实现神经网络和BP算法

设置模型


class Net(nn.Module): # Net为torch内含有的一个模块,在进行模型定义时,可用此方法
    def __init__(self,d_in,h,d_out):
        super(Net,self).__init__()  # 继承init
        self.Linear1=nn.Linear(d_in,h)
        self.Relu=nn.ReLU()
        self.Linear2=nn.Linear(h,d_out)
    def forward(self,x):
        x=self.Relu(self.Linear1(x))
        y_pre=self.Linear2(x)
        return (y_pre)
model=Net(d_in,h,d_out)

另外一种定义模型的方法

model=torch.nn.Sequential(torch.nn.Linear(d_in,h),
                          torch.nn.ReLU(),
                          torch.nn.Linear(h,d_out))

进行训练

# 设置超参数
optimizer=torch.optim.SGD(model.parameters(),lr=learning_rate)
loss_function=nn.MSELoss()

# 进行训练
for t in range(500):
    y_predict=model(x)
    loss=loss_function(y_predict,y)
    print("pytorch实现,第{}次的损失为:{}".format(t,loss.item()))
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

结果
在这里插入图片描述

总结

用不同的方法最后都能得到Loss不断下降的结果,且在训练步数达到一定时,算法都能收敛,但是用pytorch内部的api会使得Loss下降更快,且更易收敛。

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值