《Neural Networks and Deep Learning》读书笔记:最简单的识别MNIST的神经网络程序(1)
来源:互联网 发布:淘宝一休老银匠怎么样 编辑:程序博客网 时间:2024/06/05 11:42
转载请注明出处:https://www.codelast.com/
《Neural Networks and Deep Learning》一书的中文译名是《神经网络与深度学习》,书如其名,不需要解释也知道它是讲什么的,这是本入门级的好书。
在第一章中,作者展示了如何编写一个简单的、用于识别MNIST数据的Python神经网络程序。对于武林高手来说,看懂程序不会有任何困难,但对于我这样的Python渣则有很多困惑。所以我对做了一些笔记,希望同时也可以帮助有需要的人。
『1』原文及程序
在这里,先把中译版部分贴上来,以方便后面的笔记记录(这只是一部分):
在给出一个完整的清单之前,让我解释一下神经网络代码的核心特征,如下。核心是一个Network类,我们用来表示一个神经网络。这是我们用来初始化一个Network对象的代码:
class Network(object):def __init__(self, sizes):self.num_layers = len(sizes)self.sizes = sizesself.biases = [np.random.randn(y, 1) for y in sizes[1:]]self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
net = Network([2, 3, 1])
『2』程序解读
正如上面的代码示例,创建一个Network对象的时候,传入的是一个list,例如 [2, 3, 1],list中有几个元素就表示神经网络有几层,从list中的第一个元素开始,每一个元素依次表示第1层、每2层、……第n层的神经元的数量。
这个不难理解,比较难理解的是 bias(偏差)以及 weight(权重)的表示方式。
文章来源:http://www.codelast.com/
我们先来看 bias(偏差):
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
首先需要明确的是,中括号表明了 biases 是一个list,中括号里的内容是对这个list进行赋值的代码,它采用了一个for循环的方式来赋值,例如下面的代码:
a = [i for i in range(3)]print(a)
会输出结果:
[0, 1, 2]
所以,np.random.randn(y, 1) for y in sizes[1:] 这部分代码表达的就是—— list中的每一个元素都是 np.random.randn(y, 1) 这个表达式的计算结果,而这个表达式是含有变量 y 的,y 必须要有实际的值才能计算,所以用一个for循环来给 y 赋值,y 能取的所有值就是对 sizes[1:] 这个list进行遍历得到的。前面已经说过了,sizes本身是一个list,而sizes[1:] 表示的是取这个 list 从第2个元素开始的子集,给个例子:
a = [5, 6, 8]print(a[1:])
会输出:
[6, 8]
所以,在我们前面用 net = Network([2, 3, 1]) 这样的代码来创建了一个对象之后,sizes[1:] 的内容其实就是 [3, 1],所以 y 的取值就是 3 和 1,所以 biases 这个list的第一个元素就是 np.random.randn(3, 1),第二个元素就是 np.random.randn(1, 1)。
文章来源:http://www.codelast.com/
我觉得经过这样解释,biases 在结构上看来是什么东西已经比较清楚了吧?
那么话说回来,我们虽然知道了 np.random.randn(3, 1) 是 biases 的第一个元素,但 np.random.randn() 又是什么鬼?
且听我道来:
np 是这个Python程序 import 进来的Numpy库的缩写:
import numpy as np
randn() 是Numpy这个库中,用于生成标准正态分布数据的一个函数。其实 randn(3, 1) 生成的是一个3x1的随机矩阵,我们可以在Python命令行中直接试验一下:
import numpy as npnp.random.randn(3, 1)
输出结果如下:
array([[ 1.33160979],[ 0.66314905],[ 0.27303603]])
可见,它输出的是一个3行,1列的随机数矩阵——你看这输出多体贴,为了表明“3行1列”,它没有把数字都排在一行,而是特意放在了3行里。
好了,现在我们已经彻底了解了 biases 的结构,那么再来看看,为什么它的第一个元素是3x1的矩阵,第二个元素是1x1的矩阵呢?
这跟要创建的神经网络层的结构有关。
文章来源:http://www.codelast.com/
如作者书中所说,“假设第一层神经元是一个输入层,并对这些神经元不设置任何偏差,因为偏差仅在之后的层中使用”,所以 biases 只有两个元素,而不是3个。但知道了这一点并不能解决我们心中的疑惑:为什么 biases[0] 是一个 3x1 的矩阵,biases[1] 是一个 1x1 的矩阵呢?
这就跟weight(权重)有关了,所以,我们不妨先来看看代码中,weight是如何定义的:
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
这个冗长的实现需要“细细品味”。
首先,中括号表明 weights 是一个list,中括号里的代码对这个list的每一个元素进行赋值,list中的每一个元素都是一个 np.random.randn(y, x) ——这个东西我们刚才在解释 biases 的时候已经说过了,它是一个y行x列的随机数矩阵。那么y和x的具体值又是什么呢?它们是由for循环定义的:
for x, y in zip(sizes[:-1], sizes[1:])
首先要注意,这里是按 x, y 的顺序来赋值的,而不是 y, x,这和 np.random.randn(y, x) 中的顺序相反。
其中,zip()是Python的一个内建函数,它接受一系列可迭代的对象(例如,在这里是两个list)作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list。
为了形象地说明zip()的作用,我们来看看这句简单的代码:
zip([3, 4], [5, 9])
它的输出是:
[(3, 5), (4, 9)]
可见,zip() 分别取出 [3, 4] 以及 [5, 9] 这两个 list 的第一个、第二个元素,然后合成了两个 tuple:(3, 5) 和 (4, 9),然后再把这两个tuple组成一个list:[(3, 5), (4, 9)]。所以,假设我们有如下代码:
for x, y in zip([3, 4], [5, 9])
那么 x, y 的取值就有两组了:3, 5 和 4, 9。
有了这样直观的对比,我们已经可以理解 for x, y in zip(sizes[:-1], sizes[1:]) 是什么含义了。其实 sizes 就是一个含有3个元素的list:[2, 3, 1],因此 sizes[:-1] 就是去掉最后一个元素的子list,即 [2, 3];而 sizes[1:] 就是去掉第一个元素的子list,即 [3, 1]。
所以现在真相大白:x, y 的取值有两组,一组是 2, 3,另一组是 3, 1。
再回去看 weights 的赋值代码,于是可以秒懂:weights 的第一个元素 weights[0] 是一个 3x2 的随机数矩阵,weights 的第二个元素 weights[1] 是一个 1x3 的随机数矩阵。
文章来源:http://www.codelast.com/
现在总结一下:
biases[0]:3x1 的矩阵
biases[1]:1x1 的矩阵
weights[0]:3x2 的矩阵
weights[1]:1x3 的矩阵
虽然我们已经精确分析出了那段代码的含义,但有人可能还是要问:为什么创建的bias和weight是这些维度的?
为了能帮助理解,我们画出这个神经网络的结构(第一层有2个神经元,第二层有3个神经元,最后一层有1个神经元):
文章来源:http://www.codelast.com/
从图上我们可以一眼看出,第一层的输入向量(也就是
我们知道,除了输出层(output)之外,每一层的输入
来看看:
第一层→第二层的
第二层→第三层的
通过以上不厌其烦的分析,相信任何人都能搞明白那仅有不到10行的代码是如何巧妙地定义了一个神经网络,搞定!
- 《Neural Networks and Deep Learning》读书笔记:最简单的识别MNIST的神经网络程序(1)
- 《Neural Networks and Deep Learning》读书笔记:最简单的识别MNIST的神经网络程序(2)
- neural-networks-and-deep-learning mnist-loader
- Neural Networks and Deep Learning学习笔记ch3 - 改进神经网络的学习方法
- deep learning 卷积神经网络的实现(Convolution Neural Networks)
- deep learning 卷积神经网络的实现(Convolution Neural Networks)
- deep learning 卷积神经网络的实现(Convolution Neural Networks)
- 《neural networks and deep learning》——使用神经网络识别手写数字
- Neural Networks and Deep Learning之中文翻译-第一章 用神经网络识别手写数字
- Neural Networks and Deep Learning的学习建议
- Neural Networks And Deep Learning(1)
- COURSE 1 Neural Networks and Deep Learning
- Neural Networks and Deep Learning学习笔记ch1 - 神经网络
- Neural Networks and Deep Learning 神经网络和深度学习book
- Neural Networks and Deep Learning 神经网络和深度学习
- Neural Networks and Deep Learning
- Neural Networks and Deep Learning
- Neural networks and Deep Learning
- 为什么梯度下降是有效的?
- Activity相关知识回顾
- 一款能帮助程序员发现问题的软件
- VOC2007数据集图片画框
- java--TCP
- 《Neural Networks and Deep Learning》读书笔记:最简单的识别MNIST的神经网络程序(1)
- 关于彩票
- Java NIO1:浅谈I/O模型
- 1
- 大型网站技术架构演化之路
- 1
- SDUT-2711-->电子时钟中的运算符重载
- 222
- pageoffice在网站上部署