MelonTeam 移动终端前沿技术的探索者

跬步神经网络2-C++简单实现

2017-08-11
yanjun

导语 不考虑性能,用c++简单实现NN网络,通过训练预测 XOR、AND、OR

目录
跬步神经网络1-基本模型解析
跬步神经网络2-C++简单实现
跬步神经网络3-MNIST手写库初步识别


跬步1 了解了bp神经网络的原理,这次动手实践。

代码在这里: https://git.coding.net/yj_3000/SimpleNN.git
                      xcode工程,需要设置一下开发者账号
                      windows是vs2012的工程

**代码大致结构:
**主要包括3个类,Session、Layer 和 Unit。
Session 代表一套NN网络,可以配置激活函数、损失函数、数据填充方法等
Layer 代表网络中的一层,包含一个或者多个Unit
Unit 代表神经元,实现了  UpdateO(更新输出值)    UpdateE(更新Error)
                                          UpdateB(更新Bias)        UpdateW(更新权重)

简单训练方法:
1. 设置 input 所有 unit的 输出值 和 output 所有 unit 的目标值
2. 正向依次调用所有 unit 的 updateO
3. 反向依次调用所有 unit 的 updateE updateB updateW
4. 重复 epochs 次

目前实现了3种激活函数: logistic、tanh、relu

测试1 - (LogicFitting::run) :
1. 建立 2,2,1的网络,随机填充
2. 使用相同的网络、相同的参数(lr=0.013),设置不同的激活函数,开始训练 XOR
3. 退出条件
         1)训练次数达到上限
         2)预测结果与目标值的距离小于 0.01
结果如下图,
1) lr=0.013时, relu 表现最好

2)lr=0.3时, relu训练次数以内,没有达到要求

3)lr=0.9时, relu和tanh训练次数以内,都没有达到要求

测试2 - (LogicFitting::run1) :
1. 使用相同的网络, 调整 lr,看结果,
    relu 在 lr > 0.33 之后就再也没有成功过,
    尝试设置 lr = 0.31 ,然后多次随机填充网络,都会失败,无法成功
    relu 太容易 die 了
    这也引出另外一个问题,如何动态调整 lr

下一步打算使用 mnist 上的手写数字数据库,做识别手写数字的联系,
如果训练性能跟不上,尝试把一般的网络优化方式都实现,看看效果

这里借一张图:
https://www.youtube.com/watch?v=yKKNr- QKz2Q&index=3&list=PLJV_el3uVTsPy9oCRY30oBPNLCo89yu49

蓝色线,表示 lr 太小,导致梯度下降很慢,有生之年系列
红色刚刚好
绿色比较尴尬,出现循环,
        栗子(y=xx  y’=2x   想通过梯度下降求极小值, lr=1   x初始值是1,x1=1-1y’(1)=-1)
        x会一直在 -1 和 1之间摇摆
黄色是lr设置太大,直接越过最低点


说一说

目录