实现多层感知机

实现隐藏层

先修要求

接下来我们会讲神经网络在多层感知器里面的数学部分。讲多层感知器我们会用到向量和矩阵。你可以通过下列讲解对此做个回顾:

  1. Khan Academy's introduction to vectors.
  2. Khan Academy's introduction to matrices.
由来

之前我们研究的是有一个输出节点网络,代码也很直观。但是现在我们有不同的输入,多个隐藏层,他们的权重需要有两个索引 wiji 表示输入单位,j 表示隐藏单位。

例如在下面这个网络图中,输入被标注为 x1,x2, x3,隐藏层节点是 h1 和 h2

指向 h1 的权重被标成了红色,这样更好区分。

为了定位权重,我们把输入节点的索引 i 和输出节点的索引 j 结合,得到:

w11

代表从 x1 到 h1 的权重;

w12

代表从 x1 到 h2 的权重。

下图包括了从输入层到隐藏层用 wij 来标注的所有权重:

之前我们可以把权重写成序列,标记为 wi

现在,权重被储存在矩阵中,由  wij 来标记。每一表示从输入层发出的权重,每一表示从输入到隐藏层的权重。这里我们由三个输入,两个因此节点,权重矩阵标示为:

三个输入两个隐藏

三个输入两个隐藏

记得比较一下上面的示意图来确定你了解不同的权重在矩阵中神经网络中的对应关系。

用 NumPy 来初始化权重,我们需要提供矩阵的维度,如果特征是包含输入的二维序列:

# Number of records and input units
# 数据点以及每个数据点有多少输入的个数
n_records, n_inputs = features.shape
# Number of hidden units
# 隐藏层个数
n_hidden = 2
weights_input_to_hidden = np.random.normal(0, n_inputs**-0.5, size=(n_inputs, n_hidden))

这样创建了一个 名为 weights_input_to_hidden 的 2D 序列,维度是 n_inputs 乘 n_hidden。记住,输入到隐藏层是所有输入乘以隐藏层权重的和。所以对每一个隐藏层节点  hj,我们需要计算:

为了实现这点,我们需要运用矩阵乘法,如果你对线性代数有点忘了,我们建议你看下之前先修部分的资料。这里你只需要了解矩阵如何相乘。

在这里,我们把输入(一个行向量)与权重相乘。要实现这个,要把输入点乘(内积)以权重矩阵的每一列。例如要计算到第一个隐藏节点的输入 j=1,你需要把这个输入与权重矩阵的第一列做点乘:

用输入与权重矩阵的第一列相乘得出到隐藏层第一个节点的输入

用输入与权重矩阵的第一列相乘得出到隐藏层第一个节点的输入

针对第二个隐藏节点的输入,你需要计算输入与第二列的点积,以此类推。

在 NumPy 中,你可以直接使用 np.dot

hidden_inputs = np.dot(inputs, weights_input_to_hidden)

你可以定义你的权重矩阵是 n_hidden 乘 n_inputs 然后把输入作为竖向量相乘:

注意:

这里权重的索引在上图中做了改变,与之前图片并不匹配。这是因为,在矩阵标注时行索引永远在列索引之前,所以用之前的方法做标识会引起误导。你只需要了解这跟之前的权重矩阵是一样的,只是做了转换,之前的第一列现在是第一行,之前的第二列现在是第二行。如果用之前的标记,权重矩阵是下面这个样子的:

用之前的标记标注的权重矩阵

用之前的标记标注的权重矩阵

切记,上面标注方式是不正确的,这里只是为了让你更清楚这个矩阵如何跟之前神经网络的权重匹配。

矩阵相乘最重要的是他们的维度相匹配。因为它们在点乘时需要有相同数量的元素。在第一个例子中,输入向量有三列,权重矩阵有三行;第二个例子中,权重矩阵有三列,输入向量有三行。如果维度不匹配,你会得到:

# Same weights and features as above, but swapped the order
hidden_inputs = np.dot(weights_input_to_hidden, features)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-1bfa0f615c45> in <module>()
----> 1 hidden_in = np.dot(weights_input_to_hidden, X)

ValueError: shapes (3,2) and (3,) not aligned: 2 (dim 1) != 3 (dim 0)

3x2 的矩阵跟 3 个元素序列是没发相乘的。因为矩阵中的两列与序列中的元素个数并不匹配。能够相乘的矩阵如下:

这里的规则是,如果是序列在左边,序列的元素个数必须与右边矩阵的行数一样。如果矩阵在左边,那么矩阵的列数,需要与右边向量的行数匹配。

构建一个列向量

看上面的介绍,你有时会需要一个列向量,尽管 NumPy 默认是行向量。你可以用 arr.T 来对序列进行转制,但对一维序列来说,转制还是行向量。所以你可以用 arr[:,None] 来创建一个列向量:


print(features)
> array([ 0.49671415, -0.1382643 ,  0.64768854])

print(features.T)
> array([ 0.49671415, -0.1382643 ,  0.64768854])

print(features[:, None])
> array([[ 0.49671415],
       [-0.1382643 ],
       [ 0.64768854]])

当然,你可以创建一个二维序列,然后用 arr.T 得到列向量。


np.array(features, ndmin=2)
> array([[ 0.49671415, -0.1382643 ,  0.64768854]])

np.array(features, ndmin=2).T
> array([[ 0.49671415],
       [-0.1382643 ],
       [ 0.64768854]])

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ncst

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值