ANN之手写数字识别
MNIST数据集请查看上一篇博文:
本文在数据存储形式上与上一篇博文区别为,将target从单一的数字转化为了一个10*1的矩阵,或者说是一个10维向量,对应的target的维度值为1,其它均为0。
简介
ANN是人工神经网络的简称。如果你对比ANN简单的线性回归、逻辑回归和梯度下降法没有认识,推荐先学习一下再学习ANN。
ANN与回归的不同之处在于,它有网络结构,大概如下:
而对于回归,我们可以简单地理解为,只有输入层到输出层。而ANN有一个或多个隐藏层,隐藏层的每个节点称作神经元,每层之间依赖于一个权重系数矩阵。设计神经网络的主要工作在于设计隐藏层的结构和权重系数矩阵。
对于每层之间的传播过程,可以总结为如下:
in=WiX+b i n = W i X + b
out=activation(in) o u t = a c t i v a t i o n ( i n )
Wi W i 表示系数矩阵的第 i i 行,由 in i n 在该层的位置决定。
1 1 是偏置项。
是激活函数。
该层的每一个节点的 out o u t 构成该层的输出 X X 。
权重系数矩阵
初始化
权重初始化一般采用Xavier权重初始化和MSRA Filler两种方式,如果激活函数为sigmod或者tanh,使用前者;如果激活函数为relu,则使用后者。
两种初始化方式的具体和区别,推荐博文:https://www.cnblogs.com/makefile/p/init-weight.html?utm_source=itdadao&utm_medium=referral
代码实现
#neurons是神经网络的结构表示,是一个数组,元素为每层的节点数,例如[784,40,10]。
#输出parameter是一个字典,键为Wi,值为系数矩阵。
def initialize_parameters(neurons):
inputneurons=neurons[0]
hideneurons=neurons[1:len(neurons)-1]
outputneurons=neurons[-1]
hidelayers=len(hideneurons)
parameter={}
np.random.seed(2);
#input->hide
W0=np.random.uniform(low=-np.sqrt(6)/np.sqrt(inputneurons+1+hideneurons[0]), high=np.sqrt(6)/np.sqrt(inputneurons+1+hideneurons[0]),size=(hideneurons[0],inputneurons+1))
parameter["W0"]=W0
#hide->hide
for l in range(0,hidelayers-1):
Wl=np.random.uniform(low=-np.sqrt(6)/np.sqrt(hideneurons[l]+1+hideneurons[l+1]), high=np.sqrt(6)/np.sqrt(hideneurons[l]+1+hideneurons[l+1]),size=(hideneurons[l+1],hideneurons[l]+1))
parameter["W"+str(l+1)]=Wl
#hide->output
Wo=np.random.uniform(low=-np.sqrt(6)/np.sqrt(hideneurons[hidelayers-1]+1+outputneurons), high=np.sqrt(6)/np.sqrt(hideneurons[hidelayers-1]+1+outputneurons),size=(outputneurons,hideneurons[hidelayers-1]+1))
parameter["W"+str(hidelayers)]=Wo
return parameter
偏置项
如果我们只看一维的
, w w 是斜率,
是截距。
如果 b=0 b = 0 ,则图像经过原点,但并不是所有的数据都是关于原点线性可分的,如下图。因此需要一个偏置项来移动分割面。
而这里的 b b 可以看做
, b b 则可以作为系数矩阵的一列,作为可训练的系数。
激活函数
激活函数常用的有sigmod、tanh和relu。