距离上一篇文章《SemiFlow 01 从一个例子开始》已有三个月。首先我为自己的拖延和狂妄道歉。在过去的三个月里由于课程和跨国行程原因,我中断了数次开发。SemiFlow的开发进度已远远超出我的预期。从今天开始,我尽量连续更新我的过去三个月的工作。
好消息是:SemiFlow 1.0已经发布了。目前支持使用MNIST 数据训练MLP、CNN分类网络。
本文介绍我对SemiFlow的设计与开发。这是一篇概要,介绍SemiFlow的组件及其关系,并尽可能详细地解释原因。
Layer is all you need.
在SemiFlow中,所有有数据流动的类都是抽象类Layer的子类。激活函数Activation、数据输入层InputLayer、损失函数Loss和包括Dense在内的其他常用层都继承自Layer, 都分别实现了ForwardPropagation、BackPropagation 和InitParams方法。在训练神经网络过程中,ForwardPropagation用来计算每一层的结果, BackPropagation 用来计算梯度。
- InputLayer 是用来接收用户输入数据的输入层。在用户定义网络结构时,它对用户是透明的。在编译时, model将会给第一层之前自动添加一个InputLayer, 由model管理。 这一层没有训练参数,但是它将检查用户输入数据的格式并把数据传递给第一个真正可训练的层。
- Activation 是激活函数。它继承自Layer,但目前不被model管理。它属于每个非Activation层。在调用SomeLayer.ForwardPropagation()时,每层计算出结果output_value后将调用Activation.ForwardPropagation(output_value)得到最终的结果。
- Loss 是损失函数层。 它继承自Layer并被model管理。网络在编译时,model会在最后一层输出层后自动添加一个Loss layer, 用来计算损失值与后向更新网络参数。
- Dense 是Fully connected layer。
- Conv2D 是2D卷积层。并且目前SemiFlow只支持channel last的输入数据。
- MaxPooling2D 是2D池化层。它的前一层只能是Conv2D或者InputLayer。
- Flatten 是典型的Flatten。它的后面一层可以是Dense。
Figure 1.
然后根据不同的Layer子类,我们为其添加不同的参数和方法以完成ForwardPropagation、BackPropagation的实现。
Figure 2.
Loss
基于Loss类,我们实现了MeanSquaredError、MeanAbsoluteError、BinaryCrossentropy、CategoricalCrossentropy和SoftmaxCategoricalCrossentropy。 SoftmaxCategoricalCrossentropy是一个优化过的Loss类。当网络输出层的激活函数是Softmax并且网络的损失函数是CategoricalCrossentropy时,我们可以以一种计算量更少的方式更新权值。
Figure 3
Activation
基于Activation类, 我们实现了Linear、Sigmoid、Relu、Tanh、Softplus 和Softmax。其中, Linear是默认的Activation。用户可以根据任务和需要,选择不同的激活函数。
Figure 4
Initializer
我们也设计了Initializer类,并实现Ones、Zeros、RandomNormal和RandomUniform子类,用来以不同的方式初始化参数。GlorotUniform Initializer也将会在近期实现。
Figure 5
Model
Model是用来存储网络结构、编译网络、控制训练网络、执行不同参数搜索算法的类。
我们实现了Sequential子类。在这Sequential模型中。所有网络层按照添加顺序依次排布。
Figure 6
Optimizer
Optimizer 是model的一个属性,用来控制网络的前向计算和后向传播更新参数。它决定了什么时候、以何种方式、用多少数据更新参数。
Figure 7
代码
代码已经发布在Github. 欢迎star和issue.
文章评论