python 手动实现三层神经网络(梯度下降法)

Python 手动实现三层神经网络(梯度下降法)

最近在学习人工神经网络,由于是第一次入门这个,还是遇到了一些困难。要想真正了解BP网络的原理,最好是有代码手动实现其过程。当我在网上查阅相关代码的时候,发现许多代码对新手不太友好,要么过于简洁,要么用了框架。针对上面的这种情况,我觉定把我这段时间学到的代码及原理进行整理一下。
关于梯度下降法的原理,还是有必要在这里简单介绍一下,如果看不太懂的话建议先去复习原理部分。
梯度下降法简单的来说就是通过损失函数对梯度求导,来获得其梯度。而梯度有什么用呢? 从数学上我们知道,梯度是函数上升的方向,那么我们知道了梯度,取他的相反的值,就可以朝着函数下降的方向,得到函数的极小值,从而获得一个相对的最优解。

废话不多说了,先给出代码

import numpy as np
N,D_in,H,D_out = 64,1000,100,10  # 定义输入数据为64个 1000个输入神经元,100隐层神经元,输出10个神经元

# 初始权值参数
w_1 = np.random.randn(D_in,H)
w_2 = np.random.randn(H,D_out)

learning_rate = 1e-6
# 生成数据
x = np.random.randn(N,D_in)
y = np.random.randn(N,D_out)
# 循环迭代
for i in range(500):
    # 前向传播
    h = x.dot(w_1)     # N*H
    h_relu = np.maximum(h,0)  #  relu 激活函数 ,h_relu 激活函数输出值 N*H
    y_pred = h_relu.dot(w_2) # N*D
    # 计算误差
    loss = np.square( y_pred - y ).sum()
    if (i+1)% 50 ==0:
        print('第{}次,loss值为{}'.format(i,loss))
    # 反向传播
    # 先计算各种梯度
    grad_y_pred = 2.0*(y_pred - y)  # 64*10 L对预测输出的导数
    grad_w_2 = h_relu.T.dot(grad_y_pred) # 10*64*64*10=10*10 L对W2的导数
    grad_h_relu = grad_y_pred.dot(w_2.T) # L对隐层输出的导数
    grad_h = grad_h_relu.copy() # 复制grad_h_relu
    grad_h[h<0] = 0  # relu激活函数求导
    grad_w_1 = x.T.dot(grad_h) 
    
    # 跟新权重
    w_1 -= learning_rate*grad_w_1
    w_2 -= learning_rate*grad_w_2

下面对代码部分进行简要解释:
首先在这里说明一下,bp网络的梯度求解方法,可以通过derta直接算出来,也可以通过链导法则算出来。这个代码是基于链导法则的,每次求出一个导数,然后通过链导法则相乘得到下一个的导数,直至乘到L对W的导数,算出其导数就很容易对它进行跟新了。

grad_h[h<0] = 0 # relu激活函数求导
#这里是由于激活函数是用的ReLU 函数,对它求导只会留下大于0的部分,小于0的部分取0,大于0 的部分就是其本身

希望看懂的小伙伴能够留个赞

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值