跳转至

第14章 搭建深度神经网络框架⚓︎

14.0 深度神经网络框架设计⚓︎

14.0.1 功能/模式分析⚓︎

比较第12章中的三层神经网络的代码,我们可以看到大量的重复之处,比如前向计算中:

def forward3(X, dict_Param):
    ...
    # layer 1
    Z1 = np.dot(W1,X) + B1
    A1 = Sigmoid(Z1)
    # layer 2
    Z2 = np.dot(W2,A1) + B2
    A2 = Tanh(Z2)
    # layer 3
    Z3 = np.dot(W3,A2) + B3
    A3 = Softmax(Z3)
    ...    

1,2,3三层的模式完全一样:矩阵运算+激活/分类函数。

再看看反向传播:

def backward3(dict_Param,cache,X,Y):
    ...
    # layer 3
    dZ3= A3 - Y
    dW3 = np.dot(dZ3, A2.T)
    dB3 = np.sum(dZ3, axis=1, keepdims=True)
    # layer 2
    dZ2 = np.dot(W3.T, dZ3) * (1-A2*A2) # tanh
    dW2 = np.dot(dZ2, A1.T)
    dB2 = np.sum(dZ2, axis=1, keepdims=True)
    # layer 1
    dZ1 = np.dot(W2.T, dZ2) * A1 * (1-A1)   #sigmoid
    dW1 = np.dot(dZ1, X.T)
    dB1 = np.sum(dZ1, axis=1, keepdims=True)
    ...
每一层的模式也非常相近:计算本层的dZ,再根据dZ计算dWdB

因为三层网络比两层网络多了一层,所以会在初始化、前向、反向、更新参数等四个环节有所不同,但却是有规律的。再加上前面章节中,为了实现一些辅助功能,我们已经写了很多类。所以,现在可以动手搭建一个深度学习的迷你框架了。

14.0.2 抽象与设计⚓︎

图14-1是迷你框架的模块化设计,下面对各个模块做功能点上的解释。

图14-1 迷你框架设计

NeuralNet⚓︎

首先需要一个NeuralNet类,来包装基本的神经网络结构和功能:

  • Layers - 神经网络各层的容器,按添加顺序维护一个列表
  • Parameters - 基本参数,包括普通参数和超参
  • Loss Function - 提供计算损失函数值,存储历史记录并最后绘图的功能
  • LayerManagement() - 添加神经网络层
  • ForwardCalculation() - 调用各层的前向计算方法
  • BackPropagation() - 调用各层的反向传播方法
  • PreUpdateWeights() - 预更新各层的权重参数
  • UpdateWeights() - 更新各层的权重参数
  • Train() - 训练
  • SaveWeights() - 保存各层的权重参数
  • LoadWeights() - 加载各层的权重参数

Layer⚓︎

是一个抽象类,以及更加需要增加的实际类,包括:

  • Fully Connected Layer
  • Classification Layer
  • Activator Layer
  • Dropout Layer
  • Batch Norm Layer

将来还会包括:

  • Convolution Layer
  • Max Pool Layer

每个Layer都包括以下基本方法: - ForwardCalculation() - 调用本层的前向计算方法 - BackPropagation() - 调用本层的反向传播方法 - PreUpdateWeights() - 预更新本层的权重参数 - UpdateWeights() - 更新本层的权重参数 - SaveWeights() - 保存本层的权重参数 - LoadWeights() - 加载本层的权重参数

Activator Layer⚓︎

激活函数和分类函数:

  • Identity - 直传函数,即没有激活处理
  • Sigmoid
  • Tanh
  • Relu

Classification Layer⚓︎

分类函数,包括:

  • Sigmoid二分类
  • Softmax多分类

#### Parameters

基本神经网络运行参数:

  • 学习率
  • 最大epoch
  • batch size
  • 损失函数定义
  • 初始化方法
  • 优化器类型
  • 停止条件
  • 正则类型和条件

LossFunction⚓︎

损失函数及帮助方法:

  • 均方差函数
  • 交叉熵函数二分类
  • 交叉熵函数多分类
  • 记录损失函数
  • 显示损失函数历史记录
  • 获得最小函数值时的权重参数

Optimizer⚓︎

优化器:

  • SGD
  • Momentum
  • Nag
  • AdaGrad
  • AdaDelta
  • RMSProp
  • Adam

WeightsBias⚓︎

权重矩阵,仅供全连接层使用:

  • 初始化
  • Zero, Normal, MSRA (HE), Xavier
  • 保存初始化值
  • 加载初始化值
  • Pre_Update - 预更新
  • Update - 更新
  • Save - 保存训练结果值
  • Load - 加载训练结果值

DataReader⚓︎

样本数据读取器:

  • ReadData - 从文件中读取数据
  • NormalizeX - 归一化样本值
  • NormalizeY - 归一化标签值
  • GetBatchSamples - 获得批数据
  • ToOneHot - 标签值变成OneHot编码用于多分类
  • ToZeroOne - 标签值变成0/1编码用于二分类
  • Shuffle - 打乱样本顺序

从中派生出两个数据读取器:

  • MnistImageDataReader - 读取MNIST数据
  • CifarImageReader - 读取Cifar10数据