用 python 实现一个简单的神经网络

用 python 实现一个简单的神经网络

1. 前言

让我们先看一个经典的双层神经网络模型,想必大家都很熟悉了。

在这个模型中,有一个输入层、一个输出层和一个隐藏层。但是单纯根据这个模型来看图说话,实现一个神经网络,还是比较困难的。

2. 另一种表示

现在看看这个双层神经网络的另外一种表示方法:

同前面的图相比,有几点区别:

  • 除了输入(x)、输出(y_pred)和隐藏层(h 和 h_relu)这几个表征层之外,另外还有两个网络层 w1 和 w2。可以将 w1 看做输入表示到隐藏表示之间的映射,将 w2 看做隐藏表示到输出表示之间的映射。
  • 输入向量的维度为 D_in, 输出向量维度为 D_out,隐藏层向量维度为 H。可以批量执行,每批样本量为 N。
  • 在隐藏层内部,使用了 relu 激活函数

3. 反向传播

反向传播中,最重要的是求梯度。在矩阵乘这种场景下如何求梯度呢?

h_relu * w2 = y_pred
那么,有了 y_pred 的梯度(grad_y_pred),如何求 h_relu 和 w2 的梯度呢?
很简单:
grad_h_relu = grad_y_pred * w2.T
grad_w2 = h_relu.T * grad_y_pred
等式左边变量的梯度,依赖于等式右边变量的梯度和左边其他变量的现值。具体如何乘,是否需要做转置,可根据矩阵的维度确定。

除了矩阵乘法梯度计算之外,其他梯度计算根据相应情况确定。

4. 实现

有了上面的表示,我们用 numpy 手动实现一个神经网络就比较简单了

# -*- coding: utf-8 -*-
import numpy as np
N, D_in, H, D_out = 64, 1000, 100, 10
x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 1e-6
for t in range(500):
    h = x.dot(w1)
    h_relu = np.maximum(h, 0)
    y_pred = h_relu.dot(w2)
    loss = np.square(y_pred - y).sum()
    print(t, loss)
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.T.dot(grad_y_pred)
    grad_h_relu = grad_y_pred.dot(w2.T)
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = 0
    grad_w1 = x.T.dot(grad_h)
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值