Sigmoid神经网络
分类:Math
Let’s play a game:
Input1 | Input2 | Input3 | Output |
---|---|---|---|
0 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
1 | 0 | 1 | 1 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | ? |
当人类看到这种游戏的时候应该怎么思考?肯定是找相关性,结果与每一个元素的相关性。怎么用数学语言度量这种相关性,自然想到加权求和。如何寻找适当的权重得到“正确的”(注:这里的引号意指没有绝对正确的答案,只要依照现有的数据集,给出的权重能够符合所有的例子,则我们可以说找到了一个封闭集能够完整解释;当引入新的数据集时,若权重或者说规律无法满足,则需重新训练或者说重新找规律)答案,需要不断的试错(也就是所谓的用数据集训练机器),根据输出调整权重。
到此,就可以给出机器学习的训练过程了:
- 从训练集样本读取输入,根据权重进行调整,代入方程计算神经元的输出。
- 计算误差,也就是神经元的实际输出和训练样本的期望输出之差。
- 根据误差(大小和方向)调整权重。
- 重复1、2、3迭代10000次,进而得到“正确的”权重。
训练过程中的方程如何确定,emmm,不得不用到一些数学公式,霍金说多一个数学公式就会减少一半的读者,我尽量只减少1/2^3的读者:)
加权求和
加权总和公式很容易给出:
\[\sum_{i=1}^n {weight_i · input_i} = weight_1 · input_1 + weight_2 · input_2 + weight_3 · input_3\]正规化
目的是将输出限制在0和1之间,这里用一个叫做Sigmoid的函数,于是可以得到神经元的输出方程:
\[output = \frac{1}{ 1 + e^{ - \sum_{i=1}^n {weight_i · input_i} } }\]调整权重方程
训练过程中如何调整权重是关键,选取调整方程亦如此。方程应满足如下性质:
- 调整量与误差量成正比。这样可以加速收敛。
- 如果输出为0,则权重就不会被调整。因为不管权重为多少,对于0来说都没有意义。便于理解此时可以将权重看成自变量,将输出看成权重系数。
- 如果输出的绝对值很大,则表示该神经元很“自信”,确认自己得到的答案是正确的,认为“模棱两可”的可能性很小。
- 接3:如果神经元确信当前的权重是近乎正确的,那就不需要太大的调整。
鉴于3和4,恰好,Sigmoid曲线在绝对值较大处的梯度 $SigmoidCurveGradient(output) = output · (1 - output)$ 较小(求导即可得到),综上,就得出了误差加权导数方程:
\[adjustment = error · input · SigmoidCurveGradient(output)\]至此,我们就构建出了一个简单的神经网络,也是一个机器学习的过程。
以下是该算法的简单实现:
from numpy import exp, array, random, dot
training_set_inputs = array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
training_set_outputs = array([[0, 1, 1, 0]]).T
random.seed(1)
synaptic_weights = 2 * random.random((3, 1)) - 1
for iteration in range(10000):
output = 1 / (1 + exp(-dot(training_set_inputs, synaptic_weights)))
synaptic_weights += dot(training_set_inputs.T,
(training_set_outputs - output) * output * (1 - output))
print(1 / (1 + exp(-dot(array([1, 0, 1]), synaptic_weights))))
完整代码参见NeuralNetwork。
Note: Funny of machine learning is more than this.