前面讲的都是前向传播,已知输入层数据,计算出输出层结果。如果我们已知输出层结果是否可以反向推理出图片的像素值呢。在前面的神经网络基础上面进行修改。
1.训练
训练神经网络和前面讲的一样。
2.定义反向查询函数
1.>定义反向激活函数。利用logit函数
self.inverse_activation_function = lambda x: spc.logit(x)
2.>利用已知结果得到激活之前的输出值,在通过矩阵点乘得到激活之后的隐藏层的值,在通过反向激活函数得到激活之前的隐藏层值,在通过矩阵点乘得到输入值。逻辑和前向传播逻辑相反。
final_output = np.array(target_list, ndmin=2).T
final_input = self.inverse_activation_function(final_output)
hidden_output = np.dot(self.who.T, final_input)
hidden_output -= np.min(hidden_output)
hidden_output /= np.max(hidden_output)
hidden_output *= 0.98
hidden_output += 0.01
hidden_input = self.inverse_activation_function(hidden_output)
inputs = np.dot(self.wih.T, hidden_input)
inputs -= np.min(inputs)
inputs /= np.max(inputs)
inputs *= 0.98
inputs += 0.01
中间有调整点乘之后的矩阵值大小,使其在0.01到1.0之间
3.测试
定义已知结果。输出层为10个节点,默认值为0.01。当已知输入节点为0时,输出层的第1个节点的输出值为0.99
for i in range(10):
target = np.zeros(10) + 0.01
target[i] = 0.99
inputs = mnist.backquery(target)
用图形化显示得到的输入层节点的值
plt.imshow(inputs.reshape(28, 28), cmap='Greys', interpolation='None')
plt.show()
上面的图形化显示的值不太清晰,所以我们可以在用前向传播测试下得到的输入值。
mnist.train2(inputs, target)
final = mnist.query2(inputs)
label = np.argmax(final)
if label == i:
print("i is:", i, "success")
else:
print("i is:", i, "label is:", label, "fail")
输出结果显示如下:
可以看到成功率大概在70%
上面代码的地址为:https://github.com/pythonAndAI/nerve-net/blob/master/com/test/otherExercises/backquery.py