Update programming model (#425)

This commit is contained in:
Cheng Lai
2023-03-09 16:21:00 +08:00
committed by GitHub
parent f80e6559b0
commit 3d7c502c68
6 changed files with 81 additions and 41 deletions

View File

@@ -1,13 +1,13 @@
## 定义深度神经网络
在上一节我们使用MindSpore构建了一个多层感知机的网络结构随着深度神经网络的飞速发展各种深度神经网络结构层出不穷但是不管结构如何复杂神经网络层数量如何增加构建深度神经网络结构始终遵循最基本的规则1.承载计算的节点2.可变化的节点权重节点权重可训练3.允许数据流动的节点连接。因此在机器学习编程库中神经网络是以层为核心,它提供了各类神经网络层基本组件;将神经网络层组件按照网络结构进行堆叠、连接就能构造出神经网络模型。
在上一节我们使用MindSpore构建了一个多层感知机的网络结构随着深度神经网络的飞速发展各种深度神经网络结构层出不穷但是不管结构如何复杂神经网络层数量如何增加构建深度神经网络结构始终遵循最基本的元素1.承载计算的节点2.可变化的节点权重节点权重可训练3.允许数据流动的节点连接。因此在机器学习编程库中深度神经网络是以层为核心,它提供了各类深度神经网络层基本组件;将神经网络层组件按照网络结构进行堆叠、连接就能构造出神经网络模型。
### 以层为核心定义神经网络
神经网络层包含构建机器学习网络结构的基本组件,如计算机视觉领域常用到卷积(Convolution)、池化(Pooling)、全连接(Fully Connected);自然语言处理常用到循环神经网络(Recurrent Neural NetworkRNN)为了加速训练防止过拟合通常用到批标准化BatchNorm、Dropout等。
**全连接**是将当前层每个节点都和上一层节点一一连接,本质上是特征空间的线性变换;可以将数据从高维映射到低维,也能从低维映射到高维度。
:numref:`fc_layer`展示了全连接的过程对输入的n个数据变换到另一个大小为m的特征空间再从大小为m的特征空间变换到大小为p的特征空间可见全连接层的参数量巨大两次变换所需的参数大小为$n \times m$和$m \times p$。
:numref:`fc_layer`展示了全连接的过程对输入的n个数据变换到大小为m的特征空间再从大小为m的特征空间变换到大小为p的特征空间可见全连接层的参数量巨大两次变换所需的参数大小为$n \times m$和$m \times p$。
![全连接层](../img/ch02/fc_layer_1.svg)
:width:`800px`
@@ -56,7 +56,7 @@
:width:`800px`
:label:`nn_network`
有了上述基础知识,我们对卷积神经网络所需组件接口和模型构建使用伪代码描述如下:
有了上述基础知识,对卷积神经网络模型构建过程使用伪代码描述如下:
```python
# 构建卷积神经网络的组件接口定义:
全连接层接口fully_connected(input, weights)
@@ -94,26 +94,15 @@ Transformer又是BERT模型架构的重要组成。随着深度神经网络的
### 神经网络层的实现原理
3.3.1中使用伪代码定义了一些卷积神经网络接口和模型构建过程,整个构建过程需要创建训练变量和构建连接过程
随着网络层数的增加手动管理训练变量是一个繁琐的过程因此2.3.1中描述的接口在机器学习库中属于低级API。
机器学习编程库大都提供了更高级用户友好的API它将神经网络层抽象成一个基类所有的神经网络层实现都继承基类调用低级API。
如MindSpore提供的mindspore.nn.Cell、mindspore.nn.Conv2d、mindspore.dataset
PyTorch提供的torch.nn.Module、torch.nn.Conv2d、torch.utils.data.Dataset。
2.3.1中使用伪代码定义了一些卷积神经网络接口和模型构建过程,整个构建过程需要创建训练变量和构建连接过程。随着网络层数的增加手动管理训练变量是一个繁琐的过程因此2.3.1中描述的接口在机器学习库中属于低级API。机器学习编程库大都提供了更高级用户友好的API它将神经网络层抽象出一个基类所有的神经网络层都继承基类来实现如MindSpore提供的mindspore.nn.CellPyTorch提供的torch.nn.Module。基于基类他们都提供了高阶API如MindSpore 提供的mindspore.nn.Conv2d、mindspore.nn.MaxPool2d、mindspore.datasetPyTorch提供的torch.nn.Conv2d、torch.nn.MaxPool2d、torch.utils.data.Dataset。
:numref:`model_build`描述了神经网络构建过程中的基本细节。
神经网络层需要的功能有该层的训练参数(变量,包括初始化方法和训练状态)以及计算过程;
神经网络模型需要的功能是对神经网络层管理和神经网络层参数的管理。
在机器学习编程库中承担此功能有MindSpore的Cell、PyTorch的Module。
Cell和Module是模型抽象方法也是所有网络的基类。
现有模型抽象方案有两种。
一种是抽象出两个方法分别为Layer负责单个神经网络层的参数构建和前向计算Model负责对神经网络层进行连接组合和神经网络层参数管理
另一种是将Layer和Model抽象成一个方法该方法既能表示单层神经网络层也能表示包含多个神经网络层堆叠的模型Cell和Module就是这样实现的。
:numref:`model_build`描述了神经网络构建过程中的基本细节。基类需要初始化训练参数、管理参数状态以及定义计算过程神经网络模型需要实现对神经网络层和神经网络层参数管理的功能。在机器学习编程库中承担此功能有MindSpore的Cell、PyTorch的Module。Cell和Module是模型抽象方法也是所有网络的基类。现有模型抽象方案有两种一种是抽象出两个方法分别为Layer负责单个神经网络层的参数构建和前向计算Model负责对神经网络层进行连接组合和神经网络层参数管理另一种是将Layer和Model抽象成一个方法该方法既能表示单层神经网络层也能表示包含多个神经网络层堆叠的模型Cell和Module就是这样实现的。
![神经网络模型构建细节](../img/ch02/model_build.svg)
:width:`800px`
:label:`model_build`
:numref:`cell_abs`展示了设计神经网络层抽象方法的通用表示。通常在构造器会选择使用Python中collections模块的OrderedDict来初始化神经网络层和神经网络层参数的存储它的输出是一个有序的相比与Dict更适合深度学习这种模型堆叠的模式。参数和神经网络层的管理是在\_\_setattr\_\_中实现的当检测到属性是属于神经网络层及神经网络层参数时就记录起来。神经网络模型比较重要的是计算连接过程可以在\_\_call\_\_里重载实现神经网络层时在这里定义计算过程。训练参数的返回接口是为了给优化器传所有训练参数。神经网络层返回为了遍历各层神经网络得到各个神经网络层的参数。这里只列出了一些重要的方法,在自定义方法中,通常需要实现参数插入删除方法、神经网络层插入删除、神经网络模型信息
:numref:`cell_abs`展示了设计神经网络层抽象方法的通用表示。通常在构造器会选择使用Python中collections模块的OrderedDict来初始化神经网络层和神经网络层参数的存储它的输出是一个有序的相比与Dict更适合深度学习这种模型堆叠的模式。参数和神经网络层的管理是在\_\_setattr\_\_中实现的当检测到属性是属于神经网络层及神经网络层参数时就记录起来。神经网络模型比较重要的是计算连接过程可以在\_\_call\_\_里重载实现神经网络层时在这里定义计算过程。训练参数的返回接口给优化器传所有训练参数,这些参数是基类遍历了所有网络层后得到的。这里只列出了一些重要的方法,在自定义方法中,通常需要实现参数插入删除、神经网络层插入删除、神经网络模型信息返回等方法
![神经网络基类抽象方法](../img/ch02/cell_abstract.svg)
:width:`800px`
@@ -123,7 +112,7 @@ Cell和Module是模型抽象方法也是所有网络的基类。
### 自定义神经网络层
2.3.1中使用伪代码定义机器学习库中低级API有了实现的神经网络基类抽象方法那么就可以设计更高层次的接口解决手动管理参数的繁琐。假设已经有了神经网络模型抽象方法Cell构建Conv2D将继承Cell并重构\_\_init\_\_和\_\_call\_\_方法在\_\_init\_\_里初始化训练参数和输入参数在\_\_call\_\_里调用低级API实现计算逻辑。同样使用伪代码接口描述自定义卷积层的过程。
2.3.1中使用伪代码定义机器学习库中低级API有了实现的神经网络基类抽象方法那么就可以设计更高层次的接口解决手动管理参数的繁琐。假设已经有了神经网络模型抽象方法Cell构建Conv2D将继承Cell并重构\_\_init\_\_和\_\_call\_\_方法在\_\_init\_\_里初始化训练参数和输入参数在\_\_call\_\_里调用低级API实现计算逻辑。同样使用伪代码描述自定义卷积层的过程。
```python
# 接口定义:
@@ -153,7 +142,7 @@ conv = Conv2D(in_channel=10, out_channel=20, filter_size=3, stride=2, padding=0)
output = conv(input)
```
执行过程为,在初始化Conv2D时\_\_setattr\_\_会判断属性属于Cell把神经网络层Conv2D记录到self.\_cellsfilters属于parameter把参数记录到self.\_params。查看神经网络层参数使用conv.parameters_and_names查看神经网络层列表使用conv.cells_and_names执行操作使用conv(input)。
执行过程中,初始化Conv2D时\_\_setattr\_\_会判断属性属于Cell把神经网络层Conv2D记录到self.\_cells属于parameter的filters记录到self.\_params。查看神经网络层参数使用conv.parameters_and_names查看神经网络层列表使用conv.cells_and_names执行操作使用conv(input)。
### 自定义神经网络模型
@@ -191,4 +180,4 @@ class CNN(Cell):
net = CNN()
```
上述卷积模型进行实例化,其执行将从\_\_init\_\_开始第一个是Conv2DConv2D也是Cell的子类会进入到Conv2D的\_\_init\_\_此时会将第一个Conv2D的卷积参数收集到self.\_params之后回到Conv2D将第一个Conv2D收集到self.\_cells第二个的组件是MaxPool2D因为其没有训练参数因此将MaxPool2D收集到self.\_cells依次类推分别收集第二个卷积参数和卷积层,三个全连接层的参数和全连接层。实例化之后可以调用net.parameters_and_names来返回训练参数调用net.cells_and_names查看神经网络层列表。
上述卷积模型进行实例化,其执行将从\_\_init\_\_开始第一个是Conv2DConv2D也是Cell的子类会进入到Conv2D的\_\_init\_\_此时会将第一个Conv2D的卷积参数收集到self.\_params之后回到Conv2D将第一个Conv2D收集到self.\_cells第二个的组件是MaxPool2D因为其没有训练参数因此将MaxPool2D收集到self.\_cells依次类推分别收集第二个卷积层的参数和层信息以及三个全连接层的参数和层信息。实例化之后可以调用net.parameters_and_names来返回训练参数调用net.cells_and_names查看神经网络层列表。