C++实现神经网络
神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。
y = f ( ∑ i ω i x i − θ ) y = f(\sum_i \omega_i x_i - \theta) y=f(i∑ωixi−θ)
感知机油两层神经元组成,权重 ω i ( i = 1 , 2 , . . . , n ) \omega_i(i = 1,2,...,n) ωi(i=1,2,...,n)以及阈值 θ \theta θ可通过学习得到,阈值 θ \theta θ可看作是一个固定输入为-1.0得节点所对应得连接权重是 ω n + 1 \omega_{n+1} ωn+1,这样权重和阈值得学习就可统一为权重得学习。权重调整为
ω i = ω i + Δ ω i Δ ω i = η ( y − y ^ ) x i \omega_i= \omega_i + \Delta\omega_i \\ \Delta\omega_i = \eta(y-\widehat{y})x_i ωi=ωi+ΔωiΔωi=η(y−y )xi
η ∈ ( 0 , 1 ) \eta \in (0,1) η∈(0,1)称为学习率
感知机只有输出层神经元进行激活函数处理,即只拥有一层功能神经元。(解决线性可分问题)
要解决非线性可分问题,要使用多层功能得神经元。
给定训练集 D = ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) , x i ∈ R d , y i ∈ R l D=\bm{{(x_1,y_1),(x_2,y_2),...,(x_m,y_m)}, x_i \in \mathbb{R}^d, y_i \in \mathbb{R}^l} D=(x1,y1),(x2,y2),...,(xm,ym),xi∈Rd,yi∈Rl,即输入由 d d d个属性描述,输出 l l l维实值向量
假设隐层和输出层都是用Sigmod函数。
θ j \theta_j θj:输出层第j 个神经元的阀值
γ h \gamma_h γh:隐层第h 个神经元的阔值
v i h v_{ih} vih:输入层第t 个神经元与隐居第h 个神经元之间的连接权
ω h j \omega_{hj} ωhj:,隐层第h 个神经元与输出层第j 个神经元之间的连接权
BP算法推导过程
S i g m o d Sigmod Sigmod函数性质: f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f^{'}(x) = f(x)(1-f(x)) f′(x)=f(x)(1−f(x))
令
g i = − ∂ E k ∂ y ^ j k . ∂ y ^ j k ∂ β j = − ( y ^ j k − y j k ) f ′ ( β i − θ j ) = y ^ j k ( 1 − y ^ j k ) ( y ^ j k − y j k ) g_i = -\frac{\partial{E_k}}{\partial{\widehat{y}_j^k}} .\frac{\partial{\widehat{y}_j^k}}{\partial{\beta_j}} \\ = -(\widehat{y}_j^k - y_j^k)f^{'}(\beta_i - \theta_j) \\ = \widehat{y}_j^k(1-\widehat{y}_j^k)(\widehat{y}_j^k - y_j^k) gi=−∂y jk∂Ek.∂βj∂y jk=−(y jk−yjk)f′(βi−θj)=y jk(1−y jk)(y jk−yjk)
得出
Δ ω h j = η g j b h \Delta\omega_{hj} = \eta g_jb_h Δωhj=ηgjbh
类似得出
θ j = − η g j v i h = η e h x i γ h = − η e h \theta_j = -\eta g_j \\ v_{ih}= \eta e_hx_i \\ \gamma_h = -\eta e_h θj=−ηgjvih=ηehxiγh=−ηeh
其中 e h = b h ( 1 − b h ) ∑ j = 1 l ω h j g j e_h = b_h(1-b_h)\sum_{j=1}^l\omega_{hj} g_j eh=bh(1−bh)∑j=1lωhjgj
BP算法得目标是要最小化训练集D上得累计误差
E = 1 m ∑ k = 1 m E k E = \frac{1}{m}\sum_{k=1}^{m}E_k E=m1k=1∑mEk
缓解过拟合策略
BP神经网络经常遭遇过拟合。
有两种策略常用来缓解BP网络得过拟合:
ω i \omega_i ωi表示连接权和阈值, λ ∈ ( 0 , 1 ) \lambda\in(0, 1) λ∈(0,1)用于对经验误差与网络复杂度这两项进行折中,常通过交叉验证法来估计。
如图,如果误差函数仅有一个局部极小值,则这个就是全局最小,如果有多个局部极小值,则不能保证找到得解是全局最小。
解决方法:
此外, 遗传算法(genetic algorithms) [Goldberg, 1989] 也常用来训练神经网络以更好地逼近全局最小. 需注意的是?上述用于跳出局部极小的技术大多是启发式,理论七尚缺乏保障.
典型得深度学习模型就是很深层得神经网络。
增加隐层得数目。
但多隐层神经网络难以直接用经典BP算法训练,因为误差在对隐层逆传播时,往往会“发散”而不能收敛到稳定状态。