如何从头设计一个神经网络库

本系列教程分为两部分

  • 1 设计一个神经网络库的基本架构设计
  • 2 每个组建的具体实现细节

1 神经网络库的基本架构设计

为了项目代码的可扩展性,我们选取面向对象的编码方式。我们设计的基本架构主要包括几个主要模块

  • 1.神经网络基本组件(NeuralNetwork):主要用于支持神经网络运行的完整流程,其中包括添加网络层,训练网络模型,预测等主要方法。
  • 2 .层组件(Layers):主要实现神经网络不同组件层:比如说全连接层(Dense),卷积网络层(RNN),卷积层(Conv2D),批正则化层(BN),池化层(PoolingLayer),Dropout层,**函数层(Activation)。层组件主要由层的前向传播,反向传播两个过程组成。
  • 3.**函数组件。主要实现神经网络中不同**函数:比如说SigmoidRelu。**函数组件主要有函数的定义以及函数一阶导的定义组成。
  • 4 损失函数组件。主要实现神经网络中的不同的损失函数:比如说对于回归问题的平方损失函数,对于分类问题的交叉熵损失函数。损失函数组件主要由函数定义以及函数一阶导定义组成
  • 5 优化器组件。主要实现神经网络中不同的优化方法:比如说随机梯度下降法,动量梯度下降法,以及Adam等等。优化器组件主要有更新参数方法组成。

图形化的解释
如何从头设计一个神经网络库

2 每个组建的具体实现细节

1.神经网络基本组件

主要用于支持神经网络运行的完整流程,其中包括添加网络层,训练网络模型,预测等主要方法。

2.层组件

(1)Dense
前向传播:WX+b

反向传播:

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来),
  2. 然后通过链式求导法则,W=δZW X=δZX
  3. 更新参数权重,并且回传X

(2)RNN
如何从头设计一个神经网络库
前向传播:
for t from 1 to T

  1. sint=XtUT+st1WT
  2. st=Activation(sint)
  3. ot=stVT

反向传播:

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来),形状是(batch_size,timesteps,input_dim)
  2. 对于每个步长t从1到T,首先计算垂直方向的梯度 V=V+δtTotV, sint=δtTotststsint Xt=sintsintXt。然后再计算时间维度的梯度:从t到0,计算U=U+δtTsintU W=W+δtTsintW
  3. 更新参数U,W,V,并且回传梯度X

(3)Conv2D
前向传播:

  1. 将原始的图片矩阵X(batch_size,channels,image_width,image_height)整理为(batch_size * out_height * out_width,filter_height*filter_width*channels)。将卷积核矩阵W(n_filters,channels,filter_height,filter_width)
    整理为(n_filters,filter_height*filter_width*channels)。这一步可以理解为卷积操作的准备工作。
  2. 进行卷积操作,即WXT,然后整理一下形状接着往下传

反向传播:

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来),形状是(batch_size,n_filters,out_height,out_width)
  2. W=δztW X=δztX
  3. 更新参数W,并且回传X(需要整理形状为(batch_size,channels,image_width,image_height))

(3)PoolingLayer
前向传播:

  1. 将原始的图片矩阵X(batch_size,channels,image_width,image_height)整理为(batch_size*channels * out_height * out_width,pool_shape[0]*pool_shape[1])。
  2. 然后计算池化区域的统计量,比如MaxAverage。然后传入下一层。

反向传播:

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来),形状是(batch_size,n_filters,out_height,out_width)
  2. δ的所有子矩阵矩阵大小还原成池化之前的大小,然后如果是MAX,则把δ的所有子矩阵的各个池化局域的值放在之前做前向传播算法得到最大值的位置。如果是Average,则把δ的所有子矩阵的各个池化局域的值取平均后放在还原后的子矩阵位置。这个过程一般叫做upsample

(4)Dropout

前向传播

  1. 随机以概率p选取部分神经单元置0,并且记录索引。往下传播

反向传播

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来)
  2. 然后乘以索引。往前传播

(5)Activation
前向传播:

  1. 将输入传入**函数,把输出往传输

后向传播:

  1. 首先接收损失函数对于该层输出的导数δ(可以作为参数传进来)
  2. δσ(.),然后接着往下传输。
3 **函数组件

**函数的实现以及一阶导的实现

4 损失函数组件

损失函数的实现以及一阶导的实现

5 优化器组件

优化器更新梯度函数的实现