文章目录
一、BP神经网络简介及算法实现
1.向前传播阶段
1)隐藏层神经元输入
本实验以单隐藏层的神经网络为例,隐藏层神经元的输入为 n e t i = x 1 w 1 i + x 2 w 2 i + ⋯ + x n w n i net_i=x_1 w_{1i}+x_2 w_{2i}+⋯+x_n w_{ni} neti=x1w1i+x2w2i+⋯+xnwni其中n对应输入数据的特征数,为加快收敛速度,本实验中给每一个神经元增加一个偏移量来加快收敛速度。涉及到的代码如下:
def hidden_in(feature, w0, b0):
m = np.shape(feature)[0]
hidden_in = feature * w0
for i in range(m):
hidden_in[i, ] += b0
return hidden_in
2)隐藏层神经元输出
隐藏层神经元的输入经过激活函数f即可得到神经元的输出o=f(net),常见激活函数包括sigmoid、ReLU、Leaky_ReLU和tanh等,其表达式如下,相关代码位于activation.py中。
3)输出层神经元
在向前传播阶段,输出层神经元的输入和输出与隐藏层同理,不再重复。
2.向后传播阶段
1)输出层权的调整
代码示意如下:
delta_output = -np.multiply((label - output_out), act_derivate(output_in, mode=activate))
w1 = w1 - alpha * (hidden_output.T * delta_output)
2)隐藏层权的调整
代码示意如下:
delta_hidden = np.multiply((delta_output * w1.T), act_derivate(hidden_input, mode=activate))
w0 = w0 - alpha * (feature.T * delta_hidden)
3.误差测度(cost function)
向后传播算法的目的是希望缩小实际计算输出的O与理想输出(标签)Y的差距,所以整个过程需要按极小化误差的方式调整权矩阵。网络关于第p个样本的误差测度 E p = 1 2 ∑ j = 1 m ( y p j − o p j ) 2 E_p=\frac{1}{2}∑_{j=1}^{m}(y_{pj}-o_{pj} )^2 Ep=21j=1∑m(ypj−opj)2由此可得网络关于整个样本集的误差测度为: E = ∑ p E p E=∑_pE_p E=p∑Ep
二、随机生成数据集
为了便于分析不同输入向量维度、分类类别数对于BP算法应用于分类问题的影响,本实验选择借助sklearn库中的make_classification函数随机生成数据并按照8:2的比例划分训练集和测试集写入相应的txt文档中。
关键代码如下:
X1, Y1 = make_classification(n_samples=num, n_features=nfeatute, n_redundant=0, n_clusters_per_class=1, n_classes=nclass)
当特征数目为2或3时,可将数据可视化,图1、2为示例:
当特征数大于3时,同样地将数据写入txt文档,图3为特征数为4的3分类数据集示例。
※初始化说明
由于本实验使用两级BP神经网络,所以共包含两个权重矩阵W0(输入-隐藏层)和W1(隐藏层-输出),借助random.rand随机对W0、W1及相应的偏置进行初始化。具体代码如下所示:
w0 = np.mat(np.random.rand(n, n_hidden))
w0 = w0 * (8.0 * sqrt(6) / sqrt(n + n_hidden)) - \
np.mat(np.ones((n, n_hidden))) * (4.0 * sqrt(6) / sqrt(n + n_hidden))
b0 = np.mat(np.random.rand(1, n_hidden))
b0 = b0 * (8.0 * sqrt(6) / sqrt(n + n_hidden)) - \
np.mat(np.ones((1, n_hidden))) * (4.0 * sqrt(6) / sqrt(n + n_hidden))
w1 = np.mat(np.random.rand(n_hidden, n_output))
w1 = w1 * (8.0 * sqrt(6) / sqrt(n_hidden + n_output)) - \
np.mat(np.ones((n_hidden, n_output))) * \
(4.0 * sqrt(6) / sqrt(n_hidden + n_output))
b1 = np.mat(np.random.rand(1, n_output))
b1 = b1 * (8.0 * sqrt(6) / sqrt(n_hidden + n_output)) - \
np.mat(np.ones((1, n_output))) * (4.0 * sqrt(6) / sqrt(n_hidden + n_output))
- 可根据情况设置多组对照实验,例如1)不同输入向量(特征)/输出向量(类别)维度的对比实验;2)不同隐藏层神经元个数的对比实验;不同激活函数的对比实验;不同学习率的对比实验等。