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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yc1203968305/article/details/80272893

本系列教程分为两部分

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

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

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

  • 1.神经网络基本组件( N e u r a l N e t w o r k ):主要用于支持神经网络运行的完整流程,其中包括添加网络层,训练网络模型,预测等主要方法。
  • 2 .层组件( L a y e r s ):主要实现神经网络不同组件层:比如说全连接层( D e n s e ),卷积网络层( R N N ),卷积层( C o n v 2 D ),批正则化层( B N ),池化层( P o o l i n g L a y e r ), D r o p o u t 层,激活函数层( A c t i v a t i o n )。层组件主要由层的前向传播,反向传播两个过程组成。
  • 3.激活函数组件。主要实现神经网络中不同激活函数:比如说 S i g m o i d R e l u 。激活函数组件主要有函数的定义以及函数一阶导的定义组成。
  • 4 损失函数组件。主要实现神经网络中的不同的损失函数:比如说对于回归问题的平方损失函数,对于分类问题的交叉熵损失函数。损失函数组件主要由函数定义以及函数一阶导定义组成
  • 5 优化器组件。主要实现神经网络中不同的优化方法:比如说随机梯度下降法,动量梯度下降法,以及 A d a m 等等。优化器组件主要有更新参数方法组成。

图形化的解释
这里写图片描述

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

1.神经网络基本组件

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

2.层组件

(1) D e n s e
前向传播: W X + b

反向传播:

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

(2) R N N
这里写图片描述
前向传播:
for  t  from  1  to  T

  1. s i n t = X t U T + s t 1 W T
  2. s t = A c t i v a t i o n ( s i n t )
  3. o t = s t V T

反向传播:

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

(3) C o n v 2 D
前向传播:

  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. 进行卷积操作,即 W X T ,然后整理一下形状接着往下传

反向传播:

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

(3) P o o l i n g L a y e r
前向传播:

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

反向传播:

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

(4) D r o p o u t

前向传播

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

反向传播

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

(5) A c t i v a t i o n
前向传播:

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

后向传播:

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

激活函数的实现以及一阶导的实现

4 损失函数组件

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

5 优化器组件

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

猜你喜欢

转载自blog.csdn.net/yc1203968305/article/details/80272893