以上就是处理MNIST数据集的神经网络的实现,现在我们来关输入数据和权重参数的“形状”,输出刚才神经网络的各层的权重的形状:
通过上面的结果可以看到 多维数组的对应维度的元素个数是否一致。此外,我们可以确认最终的结果是输出元素个数为10的1维数组。
输入一个由784个元素(原本是一个28*28的二维数组)构成的一维数组后,输出一个有10个元素的一维数组。这是只输入一张图像数据时的处理流程。
这里复习一下Numpy 的shape的概念,参考 https://www.runoob.com/numpy/numpy-matrix.html
现在我们来考虑打包输入多张图像的情形,比如,我们想用predict() 函数一次性打包处理100张图像。为此,我们可以把X 的形状改为100*784,(100行,784列),将100张图像打包作为输入数据。用图展示如下:
3-27 批处理中数据形状的变化
predict 函数如下所示:
def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
return y如图3-27,输入数据为100*784, 输出数据的形状为100*10, 表示输入的100张图片的结果被一次性输出了。比如x[0] 对应的(输入矩阵第一行所有列)保存了第一张图片,y[0](输出矩阵第一行所有列)中保存了推理结果。
这种打包式的输入数据称为批(batch)。批有捆的意思,图像就如同纸币一样扎成一捆。
在神经网络的运算中,当数据传送称为瓶颈时,批处理可以减轻数据总线的负荷(严格的讲,相对于数据读入,可以将更多的时间用在计算上)。也就是说,批处理一次性大批量计算大型数组要比分开逐步计算各个小型数组速度更快。
下面我们进行批处理的代码实现,这里用粗体显示与之前的实现的不同之处。
x,t = get_data()
network = init_network()
batch_size = 100
accuracy_cnt = 0
for i in range(0,len(x),batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network,x_batch)
p = np.argmax(y_batch,axis=1)
accuracy_cnt + = np.sum(p == t[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
批处理执行效果
这里逐个解释下代码:
range(start,end, step) 指定三个证书,生成一个列表。每一个元素的下一个元素会增加step指定的值:
list(range(0,10))
在range() 函数生成列表的基础上通过 x[i,i+batch_size] 从输入数据中抽出批数据。
x[i:i+batch_n] 会去除从第i个到第i+batch_n 个之间的数值。本例中像x[0:100], x[100:200]... 这样,从头开始以100为单位将数据抽取为批数据。
然后,通过argmax()函数,可以获取最大元素的索引。
这里需要注意的是,我们指定了参数axis=1 ,这指定了按照行来读取数据。
矩阵的第0维是列方向,第1维是行方向。
最后,我们以批为单位比较分类的结果和实际的答案(这里实际的答案指的是标注数据,即测试集的结果标签数据)。
两个list 取 == ,输出的值为一个list ,list 中每个值时一个bool 值(真或者假)。np.sum(list) 会计算list 里面真值的数量。
至此,基于批处理的代码实现就介绍完了。
小结:
本章介绍了神经网络的前向传播,神经网络中使用的激活函数用的是平滑的sigmoid 函数,而感知机中使用的是信号急剧变化的阶跃函数。
看到page 79 页,第三章结束。明天从第四章往下看。
| 留言与评论(共有 0 条评论) “” |