如果你对神经网络还不太了解,又想了解这篇文章,希望你能先看
机器学习(1)--神经网络初探
在那篇代码中,对神经网络基本原理讲的更细致一些,
在这篇文章里,对于weights和biases的设置,我采用了另一种方法,先简单说一下
1、在那篇中,biases是在每层神经元(除去最后一层)基础上再加一个补充的一个神经元当BIASES,但这不能算是相对准确的biases
假如在一个[10 5 2] 那么,weights就是[[11,6],[6,2]]的结构,
同时输入的10个神经元是以一维数组形式存在同时加上b后,即[0,1,2,3,4,5,6,7,8,9,b]
在使用矩阵乘法时,即np.dot时,就是
先注:后面的(...) 是指每个矩阵的shape
x(11,) * w(11,6) = (6,) 得到第二层
(6,) * (6,2) = (2,) 得到最后的输出层,输出层是一维数组
请注意:那里矩阵乘法的顺序是np.dot(x,w),同时np.dot后没有加b,b已经算在了神经元里了
2、在本篇中,biases而是对应除第一层外的所有神经元,也是以二维数组形式存在,
假如在一个[10 5 2]这样的三层神经网络中, weights就是[[5,10],[2,5]],b 就是[[5,1],[2,1]]
注意这里weights每个元素的顺序是导的,这写是和那篇文章主要的不同处,
根本原因是那篇文章的 输入量是一维数组,即(10,)
而这篇文章的输入量是二维数组,是(10,1)即[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]],注意后面没b
所以在使用矩阵乘法时,即np.dot时,就是
w(5,10) * x(10,1)+ b(5,1)=(5,1) 得到第二层
(2,5) * (5,1)+b(2,1) = (2,1) 得到最后输出层,输出层也是二维数组
请注意,这里矩阵乘法的顺序是np.dot(w,x)
3、 激活函数使用不同,关于激活函数,可参考
机器学习09--神经网络的激活函数(Activation Function)及python代码实现
因为对weights和biases设置的差异,导致算法的微小差异,但神经网络的基本流程还是一样的
1、读取数据,调整数据格式以适配算法,设置基本参数
2、建立初始化的weights和biases
3、正向计算(从1层至N层):通过训练集随机抽取一定数量,计算出最后结果,
4、反向计算(从N层至1层):和正确结果进行比较,梯度下降调整weights和biases
5、循环第3步
6、正向计算测试集:计算出结果
7、和正确结果比较,统计出正确率
一些补充说明
1、关于上述第2点,建立初始化的weights和biases,这里我用了固定值做为初始化,
因为在这个例子中是手写数字,输入的单条记录为784元素,数据量比较大,
初始化在使用随机分布时,计算差异有差异
因此第一轮初始值使用固定值(这样实测后是极不合理的做法),所第二轮开始时,我会先调整为随机值
最后选择固定初始化的值,我选了0.1,至于为什么和学习率也就是梯度下降有关,这里不在详述,可以参考我别的文章
tensorflow实例(6)--机器学习中学习率的实验
机器学习(7)--梯度下降法(GradientDescent)的简单实现
2、关于后面的代码,共有三段,其实都是一个内容,只是我做了一些调整
2.1 我尽量不使用大段的函数,让代码以顺序流的方式向下走,这样诸位在测试时比较简单点不会跳来跳去的找变量什么
为了让诸位如果想自己尝试写代码时,能看数据结果和我写的是否相同,使得有些地方设计并不是太合理,如
2.1.1 如前面提到的第一轮使用固定值做初始值
2.1.2 会加入一些辅助代码段,我会说明哪些是测试代码段,具体用处,主便诸位如果想自己尝试写代码时能看数据,
但这样代码变得有些凌乱
2.1.3 只提取了十分之一数据,这样测度调试会快点,但相应的准确率不是那么高,在这里最终正确率只能到83%左右,如果 有全数据,可以到93%左右
2.2 就是2.1中的代码去除了大段备注、测试代码段及以些相对没用的print语句后的结果
2.3 将其中一些过程提取成函数形式,
关于使用的数据集,可参考
机器学习(1)--神经网络初探
在那篇代码中,对神经网络基本原理讲的更细致一些,
在这篇文章里,对于weights和biases的设置,我采用了另一种方法,先简单说一下
1、在那篇中,biases是在每层神经元(除去最后一层)基础上再加一个补充的一个神经元当BIASES,但这不能算是相对准确的biases
假如在一个[10 5 2] 那么,weights就是[[11,6],[6,2]]的结构,
同时输入的10个神经元是以一维数组形式存在同时加上b后,即[0,1,2,3,4,5,6,7,8,9,b]
在使用矩阵乘法时,即np.dot时,就是
先注:后面的(...) 是指每个矩阵的shape
x(11,) * w(11,6) = (6,) 得到第二层
(6,) * (6,2) = (2,) 得到最后的输出层,输出层是一维数组
请注意:那里矩阵乘法的顺序是np.dot(x,w),同时np.dot后没有加b,b已经算在了神经元里了
2、在本篇中,biases而是对应除第一层外的所有神经元,也是以二维数组形式存在,
假如在一个[10 5 2]这样的三层神经网络中, weights就是[[5,10],[2,5]],b 就是[[5,1],[2,1]]
注意这里weights每个元素的顺序是导的,这写是和那篇文章主要的不同处,
根本原因是那篇文章的 输入量是一维数组,即(10,)
而这篇文章的输入量是二维数组,是(10,1)即[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]],注意后面没b
所以在使用矩阵乘法时,即np.dot时,就是
w(5,10) * x(10,1)+ b(5,1)=(5,1) 得到第二层
(2,5) * (5,1)+b(2,1) = (2,1) 得到最后输出层,输出层也是二维数组
请注意,这里矩阵乘法的顺序是np.dot(w,x)
3、 激活函数使用不同,关于激活函数,可参考
机器学习09--神经网络的激活函数(Activation Function)及python代码实现
因为对weights和biases设置的差异,导致算法的微小差异,但神经网络的基本流程还是一样的
1、读取数据,调整数据格式以适配算法,设置基本参数
2、建立初始化的weights和biases
3、正向计算(从1层至N层):通过训练集随机抽取一定数量,计算出最后结果,
4、反向计算(从N层至1层):和正确结果进行比较,梯度下降调整weights和biases
5、循环第3步
6、正向计算测试集:计算出结果
7、和正确结果比较,统计出正确率
一些补充说明
1、关于上述第2点,建立初始化的weights和biases,这里我用了固定值做为初始化,
因为在这个例子中是手写数字,输入的单条记录为784元素,数据量比较大,
初始化在使用随机分布时,计算差异有差异
因此第一轮初始值使用固定值(这样实测后是极不合理的做法),所第二轮开始时,我会先调整为随机值
最后选择固定初始化的值,我选了0.1,至于为什么和学习率也就是梯度下降有关,这里不在详述,可以参考我别的文章
tensorflow实例(6)--机器学习中学习率的实验
机器学习(7)--梯度下降法(GradientDescent)的简单实现
2、关于后面的代码,共有三段,其实都是一个内容,只是我做了一些调整
2.1 我尽量不使用大段的函数,让代码以顺序流的方式向下走,这样诸位在测试时比较简单点不会跳来跳去的找变量什么
为了让诸位如果想自己尝试写代码时,能看数据结果和我写的是否相同,使得有些地方设计并不是太合理,如
2.1.1 如前面提到的第一轮使用固定值做初始值
2.1.2 会加入一些辅助代码段,我会说明哪些是测试代码段,具体用处,主便诸位如果想自己尝试写代码时能看数据,
但这样代码变得有些凌乱
2.1.3 只提取了十分之一数据,这样测度调试会快点,但相应的准确率不是那么高,在这里最终正确率只能到83%左右,如果 有全数据,可以到93%左右
2.2 就是2.1中的代码去除了大段备注、测试代码段及以些相对没用的print语句后的结果
2.3 将其中一些过程提取成函数形式,
关于使用的数据集,可参考
机器学习(10.1)--手写数字识别的不同算法比较(1)--mnist数据集不同版本解析及平均灰度实践
代码段一:
# -*- coding:utf-8 -*-
import pickle
import gzip
import numpy as np
import random
#激活函数
def sigmoid(z):
return 1.0 / (1.0 + np.exp(-z))
de