实验步骤
初始化网络架构
网络层数,每层神经元数,连接神经元的突触权重,每个神经元的偏置
构造bp算法函数
- 对于一个输入数据,前向计算每层的输出值,保存未激活的输出和激活过的输出值,这里用的激活函数是sigmoid
- 根据最后一层的输出值计算出相应的δ,再依次反向计算对应层的δ。
- 根据得到的δ,可以得到每层的Δw和Δb。
- 更新网络中w , b
遍历训练集中的每个训练样本,每个样本通过bp算法所得到的Δw和Δb各自累加,最后通过
w − s u m ( Δ w ) ∗ η / l e n ( t r a i n i n g s e t ) w - sum(Δw)*η/len(training_set) w−sum(Δw)∗η/len(trainingset) 计算出更新后的w和b。 - 使用SGD(随机梯度下降)来优化网络,减少模型损失
将训练集分成若干个小的训练集,每个训练集使用更新函数来更新网络中的w,b的值。设置一个迭代次数值epochs,每次迭代首先打乱训练集,将上述过程重复epochs次。 - 预测程序运行结果
对于每次迭代得到的w和b的值,使用测试集中的每个数据前向计算输出,得到预测正确的数据数。依次输出每次迭代后的预测正确数。
数据集描述
这里的数据集使用的是MINST数据集,是由Yann提供的手写数字数据集文件,这个数据集主要包含了50000个的训练数据和10000个的测试数据。每个数据导入成(x,y)的元组,x是28*28的图片,这里是784维的向量,y是对应的数字标签。
测试结果
由于数据集的输入是784维,输出是10维的数据,所以选择的网络架构为【784 30 10】.学习率η为3.0,迭代次数为30.输出的10维向量每一位对应着该数字的得分,哪一维的得分最高即该数据的预测结果。每次迭代后将更新后的网络计算测试集的数据,统计预测正确的个数。实验结果如下图所示:
从该实验结果可以看出,尽管正确率在某些迭代次数中小有下跌,这是因为在某些迭代过程中初始点选择导致的。但是总体上的趋势随着迭代次数的增加,手写数字预测的正确率逐渐提高。
源代码
神经网络部分代码
import numpy as np
import mnist_loader
class Network:
def __init__(self, size):
# 网络的架构:层数 每层的神经元
self.num_layers = len(size)
self.size = size
# 除第一层外神经元的偏置和连接神经元突触的权值
self.biases = [np.random.randn(n, 1) for n in size[1:]] # 偏置
self.weights = [np.random.randn(m, n) for n, m in zip(size[: -1]