最近在学习机器学习有关神经网络的部分,其中有两份很好的参考资料,链接如下:
Neural Networks and Deep Learning
前者是关于神经网络和深度学习的一份简单的入门资料,后者是关于神经网络的一系列文章。
前者涉及到神经网络基本概念及其公式的介绍, 搭配手写数字识别的算法,对初学者非常友好。
不过我建议在阅读之前,先看一下更适合入门的视频,链接如下:
这篇文章我打算在作者已有python2算法的基础上,对其进行python3的转换,同时做出自己的理解,算是加深印象。
神经网络基本结构
1 | 复制代码class Network(object): |
如上,sizes举例如下,[2, 3, 1]。表示该神经网络有3层,分别为输入层,隐藏层和输出层。
对于该数据集来说,每张图片为28 * 28像素,共计784个像素,输出为10个神经元,取其中最大值作为预测数字。
因此 net = Network([784, 30, 10])
表示该神经网络有3层,输入层有784个神经元,输出层有10个神经元。
数据加载
1 | 复制代码def load_data(): |
从文件中读取该数据集进行处理。
1 | 复制代码def load_data_wrapper(): |
经过以上两步处理,training_data包含数据50000组数据,每组数据包含向量分别如下:
前者是784个像素点的灰度值,后者包含10个值,对应该图片的正确分类值。
1 | 复制代码//表示分类为5. |
利用如下方法可以将矩阵转为图片查看:
1 | 复制代码 c = tr_d[0][0] |
以上,数据准备完毕。
基本的概念,比如sigmoid激活函数,随机梯度下降,前向传播算法和反向传播算法,代码中会有实现,有疑问可以参考上述资料。
随机梯度下降
1 | 复制代码 def SGD(self, training_data, epochs, mini_batch_size, eta, test_data=None): |
参数的解释如上。
对于每一次迭代,首先打乱数据集,根据随机梯度下降给定的最小batch数据集,将训练数据分开进行。对于每一个batch数据集,用学习速率进行更新。如果有测试集,则评估算法的准确性。评估算法如下:
1 | 复制代码 def evaluate(self, test_data): |
对于测试数据集,feedforward函数根据随机梯度下降中更新得到的biases, weights计算10个值的预测输出。np.argmax()函数得到10个值中的最大值,即使预测的输出值。
判断是否相等并统计,看共计多少个预测准确。
如上,让我们忽略update_mini_batch()
函数
1 | 复制代码if __name__ == '__main__': |
初始化神经网络,建立3层,输入层784个神经元,隐藏层30个神经元,输出层10个神经元。
利用随机梯度下降,迭代30次,随机下降的数据集为10个,学习速率为3.0。针对测试集的结果如下:
1 | 复制代码Epoch 0: 9080 / 10000 |
可以看到随着训练次数的增加,模型的准确率在不断提高。
随机梯度下降更新biases和weights
1 | 复制代码 def update_mini_batch(self, mini_batch, eta): |
首先初始化与biases和weights相同大小的矩阵。
对于每一个nimi_batch的x(像素矩阵, 784), y(预测矩阵, 10),利用反向传播算法计算
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
得到每一次的梯度,相加得到mini_batch的梯度,进行权重和偏置项更新。
反向传播算法
1 | 复制代码 def backprop(self, x, y): |
上面就是最重要也就是最复杂的反向传播算法。该算法mini_bitch中的向量为参数,
首先也是初始化与biases和weights相同大小的矩阵,并存储所有的激活值。
1 | 复制代码 for b, w in zip(self.biases, self.weights): |
上述函数对biases和weights进行运算,通过sigmoid函数得到激活值。
接着求出最后一层的参数。
1 | 复制代码 for l in range(2, self.num_layers): |
该函数从倒数第二层开始,迭代分别求出每一层梯度值,返回更新梯度。
至此算法的全部代码完成。
完整代码请查看:
总结:
- python3
- 神经网络入门
- 随机梯度下降
- 反向传播算法
todo:
利用这个思想去看kaggle上的手写数字识别的题目。
本文转载自: 掘金