BP神经网络的实现详解

本文详细介绍了如何从头实现BP神经网络,包括网络结构、矩阵运算、前馈传导、反向传播算法以及训练过程。代码基于C++11和Eigen3库,通过随机生成的数据进行演示,展示了神经网络的学习能力。
摘要由CSDN通过智能技术生成

本文主要详解BP神经网络编程实现,旨在一步一步解析BP神经网络细节,希望能形象明了的阐述BP神经网络,实现原理源自于斯坦福UFLDL教程,原理公式推导不再赘述,但会有些说明,本文程序由C++11实现,矩阵计算基于Eigen3(不熟悉的可以去网上搜索Eigen的使用方法,本文不做叙述),那么我们开始吧!
为了给算法列一个提纲,首先截一个UFLDL教程上关于BP算法的步骤,做个引导:
这里写图片描述
下面是神经网络一次批量迭代的过程:
这里写图片描述
为了形象的表明这里的参数含义,请看下图列举了一个[4, 4, 1]的神经网络结构(字和图很矬,请见谅,另外图中只绘制了单个样本下的情况,届时代码里会体现向量化的方式,神经网络的输入就是很多样本列向量组成的矩阵,而不是这里的单列向量了):
这里写图片描述
那么为了实现这个[4, 4, 1]的神经网络,我们需要在代码里定义来描述这个结构,下面是神经网络类的定义:

class NeuralNetwork
{
public:
    NeuralNetwork(std::vector<int> _architecture
                    , const Eigen::MatrixXd _train_dataX
                    , const Eigen::MatrixXd _train_LabelY
                    , double _learning_rate = 0.5
                    , int _mini_batch_size = 30
                    , int _iteration_size = 1000
                    , double _lambda = 0.0);
    // 执行训练操作 
    void train();
    // 求解单个样本输出
    Eigen::MatrixXd predict(const Eigen::MatrixXd &_input);
    // 评估模型, 默认label为one_hot编码
    double evaluate(const Eigen::MatrixXd &_test_dataX, const Eigen::MatrixXd &_test_dataY, bool one_hot = true);
private:
    // _z为上层输出线性组合值:[z1, z2, z3, ...], 例如z1为一个样本的计算值
    Eigen::MatrixXd sigmoid(const Eigen::MatrixXd &_z);
    // 激励函数梯度计算,_a为激励函数输出值
    Eigen::MatrixXd sigmoid_grad(const Eigen::MatrixXd &_a);
    // 损失函数实现
    double loss(const Eigen::MatrixXd &pre_y, const Eigen::MatrixXd &ori_y, int m);
    // 前向传播, _x为样本矩阵[x1, x2, x3,...], 例如x1为一个样本
    Eigen::MatrixXd feedforword(const Eigen::MatrixXd &_x);
    // 反向传播, _x为训练样本,_y为样本与输出
    void backforward(const Eigen::MatrixXd &_x, const Eigen::MatrixXd &_y);
    // 得到列向量的最大值行号
    int argmax(const Eigen::MatrixXd &_y);
    // 返回将列向量_bias复制_m列的矩阵
    Eigen::MatrixXd replicate(const Eigen::MatrixXd &_bias, int _m);

private:
    std::vector<int> architecture;                  // 神经网络的结构(4, 4, 1) 表示有一个input layer(4个神经元, 和输入数据的维度一致), 
                                                    //一个hidden layer(4个神经元), 一个output layer(1个神经元)

    const Eigen::MatrixXd train_dataX;                  // 训练数据(n, m) 表示有m个训练样本, 每个样本是n维向量
    const Eigen::MatrixXd train_dataY;                  // 训练数据label
    std::vector<Eigen::MatrixXd> train_weights;     // 训练权重
    std::vector<Eigen::MatrixXd> train_weights_grad;// 权重梯度
    std::vector<Eigen::MatrixXd> train_bias;        // 训练偏置
    std::vector<Eigen::MatrixXd> train_bias_grad;   // 偏置梯度
    std::vector<Eigen::MatrixXd> feedforword_a;     // 前向传播得到的激活值的中间输出
    std::vector<Eigen::MatrixXd> error_term;        // 残差
    std::vector<Eigen::MatrixXd> predict_a;         // 预测中间值, 用于单个样本的预测输出

    double learning_rate;                           // 反向传播学习率
    double lambda;                                  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值