18_神经网络–多层感知器

之前的例子我们通过XOR(异或门)的感知器结构显示了通过增加神经网络层数,可以用于解决非线性问题。本节我们讲解多层感知器构造及如何实现。

image

典型多层感知器构造
1. 输入层
2. 输出层
3. 隐藏层(中间层)

这个神经网络的计算方式与我们上节课并没有什么不同,只是现在将隐藏层的激活函数输出值作为输出层的输入值。
隐藏层的输入计算方式仍然与之前相同,等于权重值乘以输入值+偏置,而且与之前相同,需要使用sigmoid等激活函数得到每个隐藏层感知器的输出。

image

隐藏层的激活函数输出值乘以第二组权重,传递到输出层,并再次使用激活函数求得最终输出值。

image

image

通过堆叠更多的隐藏层,神经网络可以学习更加复杂的模式,解决更深层次的问题,这就是深度学习的由来。

image

集成隐藏层

起源

在之前的章节中,我们的网络只有一个输出节点,现在我们有多个输入单元和多个隐藏单元,它们之间的权重将需要两个索引:wiJ 在这里,i表示输入单元,j是隐藏单元。

举个例子,以下图片显示了我们的网络结构。输入单元包括x1,x2,x3,隐藏层单元包括h1,h2

image

这些线条显示输入到h1的权重值与输入到h2的权重值是不相同的。现在我们对这些权重值进行索引。把输入索引为i,隐藏层索引为j。
– w11:从x1输入到h1的权重值
– w12:从x1输入到h2的权重值

整个网络看起来就应该是这样:

image

在以前我们可以将权重写入到数组中,索引为wi;但现在,我们必须把它保存在矩阵中,索引为wij。矩阵中每一行表示从某个输入节点引出到不同隐藏层节点的全部权重值。我们的网络的权重矩阵看起来应该是这样:

image

在numpy中初始化权重矩阵,我们要提供矩阵的大小。以2D矩阵为例:

# 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))

这段代码创建了一个n_inputs*n_hidden大小的2D的数组。每个隐藏层节点的h值可以计算为:

image

通过点乘方法使得输入向量(1D)乘以矩阵中的列:

image

image

其他隐藏层节点计算以此类推。在numpy中可以用np.dot实现

hidden_inputs = np.dot(inputs, weights_input_to_hidden)

矩阵乘法中最关键的是要保证相乘的两个矩阵维数匹配。为了使矩阵乘法工作,在点积中必须有相同数量的元素。在上面的例子中,输入向量中有三列,权重矩阵中有三行。如果数据不匹配,计算会报错。正常的可以相乘的维数应该是这样的:

image

规则是,如果从左边乘以一个数组,则数组必须具有与矩阵中的行相同的元素数量。如果从左边乘以矩阵,矩阵中的列数必须等于右边数组中的元素数。

生成列向量

从上面例子可以看到,有时候我们需要得到列向量。默认情况下numpy数组可以视作是行向量,我们可以通过转置比如arr.T得到列向量。但是在1D数组中,这样的转置会返回一个新的行向量,为此我们可以截取一部分作为列向量: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]])

编码

本节我们将建立一个432网络,每一层都使用sigmoid激活函数,我们需要计算以下数值:
1. 计算输入层到隐藏层
2. 计算隐藏层的输出
3. 计算输出层的输入
4. 计算整个神经网络的输出

import numpy as np

def sigmoid(x):
    """
    Calculate sigmoid
    """
    return 1/(1+np.exp(-x))

# Network size
N_input = 4
N_hidden = 3
N_output = 2

np.random.seed(42)
# Make some fake data
X = np.random.randn(4)

weights_input_to_hidden = np.random.normal(0, scale=0.1, size=(N_input, N_hidden))
weights_hidden_to_output = np.random.normal(0, scale=0.1, size=(N_hidden, N_output))


# TODO: Make a forward pass through the network

hidden_layer_in = np.dot(X, weights_input_to_hidden)
hidden_layer_out = sigmoid(hidden_layer_in)

print('Hidden-layer Output:')
print(hidden_layer_out)

output_layer_in = np.dot(hidden_layer_out, weights_hidden_to_output)
output_layer_out = sigmoid(output_layer_in)

print('Output-layer Output:')
print(output_layer_out)
0 回复

发表评论

Want to join the discussion?
Feel free to contribute!

发表评论

邮箱地址不会被公开。 必填项已用*标注