上一篇(深度学习从入门到夺门而出——Keras实践(一):初识keras与人工神经网络)讲解了使用keras的风格和神经网络的一点基础认知,这一篇来到了无论如何也绕不过去的数学部分。在一切开始变得有些无趣之前,先让我们来做一点好玩的事情。下面是一段人工神经网络通过学习已经标注好正负和奇偶性的1万个随机整数建立模型来判断一个整数的正负和奇偶性的代码(目前阶段还不需要每一行都能看懂)。在1百万个随机整数的测试数据集上判断的正确率可以达到100%。
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
def create_label(datas):
label = np.zeros((len(datas), 2))
for index in range(0, len(label)):
label[index][0] = datas[index][0]
label[index][1] = datas[index][31]
return label
# 创建训练及测试数据
train_data_size = 10000
train_datas = np.random.randint(2, size=(train_data_size, 32))
test_data_size = 1000000
test_datas = np.random.randint(2, size=(train_data_size, 32))
train_labels = create_label(train_datas)
test_labels = create_label(test_datas)
# 创建神经网络
network = Sequential()
network.add(Dense(8, activation='sigmoid', input_shape=(32,)))
network.add(Dense(2, activation='sigmoid'))
network.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
network.fit(train_datas, train_labels, epochs=25, batch_size=128)
# 测试准确性
test_loss, test_acc = network.evaluate(test_datas, test_labels)
print('test_acc:', test_acc)
train_datas是训练数据集,里面是1万个随机最高位是符号位的32位整数的2进制数组。如:
1=00000000000000000000000000000001—>[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
2=00000000000000000000000000000010—>[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]
3=00000000000000000000000000000011—>[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]
-1=10000000000000000000000000000001—>[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
train_labels是训练数据的标签集,存放着train_datas中每条数据的正负和奇偶性,每条数据是一个长度为2的数组,如[0,1],前一位的0表示正数,1表示负数;后一位的0表示偶数,1表示奇数。考虑到一个整数是正还是负数只与这个数组的第一位有关;是奇数还是偶数只与数组的最后一位有关,我们有:
train_labels[n][0] = train_datas[n][0]
train_label[n][1] = train_datas[n][31]
同样得可以得到测试用的数据集test_datas和测试的标签集test_labels。
参照上一篇中的神经网络结构,在这里搭建了如下结构的人工神经网络:
输入层接收一个用数组存放的2进制32位整数,经过隐藏层后,在输出层输出一个能够表示这个整数的正负和奇偶性的长度为2的数组。
对于我们来说,想要达成准备的判断效果,只需要将这个32位的数组的第一位和最后一位组装成一个新的数组即可,其它的30位数字对于结果的判定没有任何意义。设输入的数组为X=[x1,x2,x3...x32],输出的数组为Y=[y1,y2],若将Y看做关于X的函数,则有y1=f(X)=x1,y2=g(X)=x32:
为了与上面的图做对比,方便理解,我们暂时忘记隐藏层的存在,只考虑输入和输出层。如下图所示,我们的代码没有这么机智,在完成训练前,32位的每一位都会被它认为是有意义的 ,每一位都可能是很重要决策因素。对于这个神经网络来说,训练过程就是在求解f(X)=?,y2=g(X)=?
这里假设了这两个函数都是线性函数,即:
训练的过程就是在求解K、W、b1、b2的过程。对于这个问题来说,如果我们训练出了: