在研究一个小型两层神经网络的例子时,我注意到了一些无法解释的结果。
假设我们有一个如下数据集及其对应的标签:
[0,1] -> [0][0,1] -> [0][1,0] -> [1][1,0] -> [1]
让我们创建一个小型两层神经网络,它将学习预测由两个数字组成的序列的输出,每个数字可以是0或1。我们将使用上述数据集来训练这个神经网络。
import numpy as np # 计算sigmoid非线性函数 def sigmoid(x): output = 1 / (1 + np.exp(-x)) return output # 将sigmoid函数的输出转换为其导数 def sigmoid_to_deriv(output): return output * (1 - output) def predict(inp, weigths): print inp, sigmoid(np.dot(inp, weigths)) # 输入数据集 X = np.array([ [0,1], [0,1], [1,0], [1,0]]) # 输出数据集 Y = np.array([[0,0,1,1]]).T np.random.seed(1) # 随机初始化权重,均值为0 weights0 = 2 * np.random.random((2,1)) - 1 for i in xrange(10000): # 前向传播 layer0 = X layer1 = sigmoid(np.dot(layer0, weights0)) # 计算误差 layer1_error = layer1 - Y # 梯度下降 # 计算当前x位置的斜率 layer1_delta = layer1_error * sigmoid_to_deriv(layer1) weights0_deriv = np.dot(layer0.T, layer1_delta) # 通过斜率的负值改变x(x = x - slope) weights0 -= weights0_deriv print 'INPUT PREDICTION' predict([0,1], weights0) predict([1,0], weights0) # 测试未知数据的预测 predict([1,1], weights0) predict([0,0], weights0)
在训练完这个神经网络后,我们对其进行测试。
INPUT PREDICTION[0, 1] [ 0.00881315][1, 0] [ 0.99990851][1, 1] [ 0.5][0, 0] [ 0.5]
好的,0,1
和1,0
的预测结果是我们预期的。0,0
和1,1
的预测结果也可以解释,我们的神经网络只是没有这些情况的训练数据,所以让我们将这些数据添加到我们的训练数据集中:
[0,1] -> [0][0,1] -> [0][1,0] -> [1][1,0] -> [1][0,0] -> [0][1,1] -> [1]
重新训练网络并再次测试它!
INPUT PREDICTION[0, 1] [ 0.00881315][1, 0] [ 0.99990851][1, 1] [ 0.9898148][0, 0] [ 0.5]
- 等等,为什么[0,0]仍然是0.5?
这意味着神经网络对0,0
仍然不确定,就像它对1,1
不确定直到我们训练它一样。
回答:
分类也是正确的。你需要理解网络能够分离测试集。
现在你需要使用一个阶跃函数来将数据分类为0
或1
。
在你的例子中,0.5
似乎是一个好的阈值
。
编辑:
你需要在代码中添加偏置项。
# 输入数据集X = np.array([ [0,0,1], [0,0,1], [0,1,0], [0,1,0]])# 随机初始化权重,均值为0weights0 = 2 * np.random.random((3,1)) - 1