最近补了一下深度学习的基础知识,对全连接层中数据的前向传播和梯度的反向传播有了更深的认识,同时自己用Python实现了一个三层的全连接网络,并将结果可视化出来。
准备工作
全连接的神经网络也叫多层感知机(MLP),前后两层的任意两个神经元都相连,同层的神经元之间没有连接关系,通过如下线性组合后送入一个激活函数进行非线性运算。
$$
Zi = \sum_j W{i,~ j} x_j + b_i
$$
常见的激活函数有Sigmoid
、ReLU
、双曲正切等,本次试验要实现一个二分类的神经网络,因此采用Sigmoid
函数。
$$
Sigmoid=\frac {1}{1+e^{-z}}
$$Sigmoid
函数图像如下所示,它会把任意范围的数映射到0和1之间,我们可以把它的输出当作二分类的概率,当最后一层的输出大于0.5时我们认为它类别为1,小于0.5时我们认为类别为0。

本试验采用的损失函数(Loss Function)为最简单的二次损失函数,即:
$$
Loss(y,t)=\frac{1}{2}(y-t)^2
$$
其中t表示标签数据,y表示神经网络的输出。
实验数据
本次试验构造一个三层全连接神经网络,第一层为输入层,维度为2;最后一层为输出层,维度为1;隐藏层神经元为超参数,可自由设定。
训练样本共有96个,特征数据为浮点数,标签数据为0或者1,分别表示两类。
训练数据如下:
-0.1097 | 0.5517 | 1 |
---|---|---|
0.1097 | -0.5517 | 0 |
-0.2392 | 0.5774 | 1 |
0.2392 | -0.5774 | 0 |
… | … | … |
可视化如图:

测试数据和其相似,只是在坐标上有轻微变化。
实验分析
我简单的画了下前向传播和反向传播的流程,为方便起见这里令隐藏层神经元数目为4个,这个值对后续的代码没有影响。
此处x的每一行都表示一个样本,总的行数表示样本的个数。
代码实现
我们首先来定义全连接层:
|
|
注意这里反向传播时,对于参数b的偏导grad_b
,我们令它等于z的偏导grad_z
在第一维度上的求和。在每次前向传播时,我们都把x的值保留下来,用于反向传播。所有的梯度传播完成之后,再进行参数的更新。
然后我们定义损失函数:
|
|
接下来我们就可以开始搭建神经网络了:
|
|
我们让每10次训练打印一次训练准确率,最终训练完成后用测试数据进行测试,并打印出测试准确率。
下面我们把训练数据和测试数据输入进去开始训练:
|
|
我们首先定义隐藏层神经元为10个,训练迭代次数为5000次,结果如下:
|
|
可以看出从1800次迭代之后就已经达到了1的训练准确率,最终的测试数据准确率同样为1。
我们添加一个类Draw
来画出整个模型的收敛结果:
|
|
输出如下:

我们把隐藏层神经元改为30,得出的结果:

可以看出隐藏层神经元在30的情况下边界相对更加平滑,而且收敛速度也更快。
完整代码和训练数据可在我的GitHub下载。