手动实现——单样本bp算法

本周学习计划

  • 周一 SVM
  • 周二 BP算法,基本框架理解
  • 周三 随机梯度下降,adam优化算法,TensorFlow
  • 周四 卷积神经网络,TensorFlow
  • 周五 卷积神经网络,TensorFlow
  • 下周 时间序列的深度学习模型 LSTM

BP神经网络(基于单个样本)

算法基本流程:

  • 首先给出w和b的值
  • 向前选择:计算并且保留每一层输出值,直到最后一层的输出值y
  • 向后传播:对于每一个w和b,计算偏导(具体计算时,先算枢纽变量偏导,再计算各参数偏导)
  • 迭代更新:梯度下降原理迭代更新w和b
## 将代码块运行结果全部输出,而不是只输出最后的,适用于全文
from IPython.core.interactiveshell import InteractiveShell 
InteractiveShell.ast_node_interactivity = "all"    

单样本梯度下降源码

## 加载绝对路径的本地图片
#from IPython.display import Image
#Image(filename = '/Users/mac/Desktop/快乐研一/python/机器学习/bp算法/2.jpeg', width=400, height=400)
import numpy as np

# 首先给出w和b的初始值,w为6维,b为3维
w = np.arange(0,1,0.18)
b = np.arange(3)

# 给出单个样本数据的增广向量,假设两个变量取值为5和10,y的取值为0.9
x = (5, 10, 0.5)

# 定义sigmoid函数及其导函数
def sigmoid(z):          # sigmoid函数
    return 1/(1+np.exp(-z))

def sigmoid_der(z):    # sigmoid导函数
    return sigmoid(z)*(1-sigmoid(z))   
  
################################
### 第一次向前选择,计算各层输出值 ###

# 第一层两个神经元wTx+b:
a1 = w[0]*x[0] + w[1]*x[1]+b[0]
a2 = w[2]*x[0] + w[3]*x[1]+b[1]

# 激活函数z=sigmoid(a)
z1 = sigmoid(a1)
z2 = sigmoid(a2)

# 第二层一个神经元 wTz+b:
z3 = sigmoid(w[4]*z1 + w[5]*z2+b[2])

# 计算误差平方
e2 = np.square(z3-x[2])

##################################
### 第一次向后传播,各系数按梯度调整 ###

learning_rate = 0.5   # 学习率设为0.5

# 从第二层的系数开始更新:
w[4] = w[4] - learning_rate * (z3 - x[2]) * z1
w[5] = w[5] - learning_rate * (z3 - x[2]) * z2
b[2] = b[2] - learning_rate * (z3 - x[2])

# 再更新第一层的系数:
w[0] = w[0] - learning_rate * (z3-x[2])* w[4] * sigmoid_der(a1) * x[0]
w[1] = w[1] - learning_rate * (z3-x[2])* w[4] * sigmoid_der(a1) * x[1]
w[2] = w[2]- learning_rate * (z3-x[2])* w[5] * sigmoid_der(a2) * x[0]
w[3] = w[3] - learning_rate * (z3-x[2])* w[5] * sigmoid_der(a2) * x[1]
b[0] = b[0] - learning_rate * (z3 - x[2]) * w[4] * sigmoid_der(a1)
b[1] = b[1] - learning_rate * (z3 - x[2]) * w[5] * sigmoid_der(a2)

# 返回值
print('第一次迭代后:\n第一层权重w:{},b:{}\n第二层权重w:{},b:{}\n预测值{}'.format(w[0:4],b[0:2],w[4:6],b[2],z3))
第一次迭代后:
第一层权重w:[-0.07425249  0.03149502  0.35978514  0.53957028],b:[0 0]
第二层权重w:[0.51782656 0.6644722 ],b:1
预测值0.9711849782403342
#################################
### 下面整理成为一个循环,定义函数  ###

def mybp(w, b, x, learning_rate):   # 分别为w和b的初始值、输入数据的增广向量、学习率
   
     # 1.向前选择
    a1 = w[0]*x[0] + w[1]*x[1]+b[0]
    a2 = w[2]*x[0] + w[3]*x[1]+b[1]
    z1 = sigmoid(a1)
    z2 = sigmoid(a2)
    z3 = sigmoid(w[4]*z1 + w[5]*z2+b[2])
    e2 = np.square(z3-x[2])
    
    # 2.向后传播迭代
    w[4] = w[4] - learning_rate * (z3 - x[2]) * z1
    w[5] = w[5] - learning_rate * (z3 - x[2]) * z2
    b[2] = b[2] - learning_rate * (z3 - x[2])
    w[0] = w[0] - learning_rate * (z3-x[2])* w[4] * sigmoid_der(a1) * x[0]
    w[1] = w[1] - learning_rate * (z3-x[2])* w[4] * sigmoid_der(a1) * x[1]
    w[2] = w[2]- learning_rate * (z3-x[2])* w[5] * sigmoid_der(a2) * x[0]
    w[3] = w[3] - learning_rate * (z3-x[2])* w[5] * sigmoid_der(a2) * x[1]
    b[0] = b[0] - learning_rate * (z3 - x[2]) * w[4] * sigmoid_der(a1)
    b[1] = b[1] - learning_rate * (z3 - x[2]) * w[5] * sigmoid_der(a2)
    
    # 输出y预测值、迭代后的系数w和b、误差平方
    return z3,w,b,e2
w = np.arange(0,1,0.18)
b = np.arange(3)
x = (5, 11, 0.5)

# 循环迭代
for i in range(66):  # 迭代次数
    y_pred,w,b,e2 = mybp(w, b, x, 0.3)
    print('第{}次迭代,预测值为({}),迭代后第一层w:{},迭代后第二层w:{}'.format(i, np.round(y_pred,8),np.round(w[0:4],4),np.round(w[4:6],4)))
第0次迭代,预测值为(0.97159866),迭代后第一层w:[-0.0449  0.0812  0.3599  0.5398],迭代后第二层w:[0.5957 0.7585]
第1次迭代,预测值为(0.89585902),迭代后第一层w:[-0.1137 -0.0702  0.3597  0.5394],迭代后第二层w:[0.5172 0.6398]
第2次迭代,预测值为(0.67848608),迭代后第一层w:[-0.136  -0.1192  0.3597  0.5393],迭代后第二层w:[0.5061 0.5863]
第3次迭代,预测值为(0.6563031),迭代后第一层w:[-0.1484 -0.1465  0.3596  0.5392],迭代后第二层w:[0.5004 0.5394]
第4次迭代,预测值为(0.64167738),迭代后第一层w:[-0.1568 -0.1649  0.3596  0.5391],迭代后第二层w:[0.4967 0.497 ]
第5次迭代,预测值为(0.62975449),迭代后第一层w:[-0.163  -0.1785  0.3595  0.539 ],迭代后第二层w:[0.494  0.4581]
第6次迭代,预测值为(0.61933944),迭代后第一层w:[-0.1678 -0.1892  0.3595  0.5389],迭代后第二层w:[0.4919 0.4223]
第7次迭代,预测值为(0.60998463),迭代后第一层w:[-0.1717 -0.1978  0.3595  0.5388],迭代后第二层w:[0.4903 0.3893]
第8次迭代,预测值为(0.60147204),迭代后第一层w:[-0.175  -0.205   0.3595  0.5388],迭代后第二层w:[0.4889 0.3589]
第9次迭代,预测值为(0.59367392),迭代后第一层w:[-0.1777 -0.211   0.3594  0.5388],迭代后第二层w:[0.4877 0.3308]
第10次迭代,预测值为(0.58650416),迭代后第一层w:[-0.1801 -0.2162  0.3594  0.5387],迭代后第二层w:[0.4867 0.3048]
第11次迭代,预测值为(0.57989849),迭代后第一层w:[-0.1821 -0.2207  0.3594  0.5387],迭代后第二层w:[0.4858 0.2809]
第12次迭代,预测值为(0.57380521),迭代后第一层w:[-0.1839 -0.2246  0.3594  0.5387],迭代后第二层w:[0.4851 0.2587]
第13次迭代,预测值为(0.56818064),迭代后第一层w:[-0.1855 -0.2281  0.3594  0.5386],迭代后第二层w:[0.4844 0.2383]
第14次迭代,预测值为(0.56298663),迭代后第一层w:[-0.1869 -0.2311  0.3594  0.5386],迭代后第二层w:[0.4838 0.2194]
第15次迭代,预测值为(0.55818912),迭代后第一层w:[-0.1881 -0.2338  0.3594  0.5386],迭代后第二层w:[0.4833 0.202 ]
第16次迭代,预测值为(0.55375728),迭代后第一层w:[-0.1892 -0.2362  0.3594  0.5386],迭代后第二层w:[0.4828 0.1858]
第17次迭代,预测值为(0.54966302),迭代后第一层w:[-0.1902 -0.2384  0.3593  0.5386],迭代后第二层w:[0.4824 0.1709]
第18次迭代,预测值为(0.54588051),迭代后第一层w:[-0.191  -0.2403  0.3593  0.5386],迭代后第二层w:[0.482  0.1572]
第19次迭代,预测值为(0.54238604),迭代后第一层w:[-0.1918 -0.242   0.3593  0.5385],迭代后第二层w:[0.4817 0.1445]
第20次迭代,预测值为(0.53915768),迭代后第一层w:[-0.1926 -0.2436  0.3593  0.5385],迭代后第二层w:[0.4814 0.1327]
第21次迭代,预测值为(0.53617521),迭代后第一层w:[-0.1932 -0.2451  0.3593  0.5385],迭代后第二层w:[0.4811 0.1219]
第22次迭代,预测值为(0.53341996),迭代后第一层w:[-0.1938 -0.2463  0.3593  0.5385],迭代后第二层w:[0.4808 0.1119]
第23次迭代,预测值为(0.53087463),迭代后第一层w:[-0.1943 -0.2475  0.3593  0.5385],迭代后第二层w:[0.4806 0.1026]
第24次迭代,预测值为(0.52852327),迭代后第一层w:[-0.1948 -0.2486  0.3593  0.5385],迭代后第二层w:[0.4804 0.0941]
第25次迭代,预测值为(0.52635111),迭代后第一层w:[-0.1953 -0.2496  0.3593  0.5385],迭代后第二层w:[0.4802 0.0861]
第26次迭代,预测值为(0.52434451),迭代后第一层w:[-0.1957 -0.2505  0.3593  0.5385],迭代后第二层w:[0.48   0.0788]
第27次迭代,预测值为(0.52249085),迭代后第一层w:[-0.196  -0.2513  0.3593  0.5385],迭代后第二层w:[0.4799 0.0721]
第28次迭代,预测值为(0.52077847),迭代后第一层w:[-0.1964 -0.252   0.3593  0.5385],迭代后第二层w:[0.4797 0.0659]
第29次迭代,预测值为(0.5191966),迭代后第一层w:[-0.1967 -0.2527  0.3593  0.5385],迭代后第二层w:[0.4796 0.0601]
第30次迭代,预测值为(0.5177353),迭代后第一层w:[-0.197  -0.2533  0.3593  0.5385],迭代后第二层w:[0.4795 0.0548]
第31次迭代,预测值为(0.51638536),迭代后第一层w:[-0.1972 -0.2539  0.3593  0.5385],迭代后第二层w:[0.4794 0.0499]
第32次迭代,预测值为(0.51513828),迭代后第一层w:[-0.1975 -0.2544  0.3593  0.5385],迭代后第二层w:[0.4793 0.0453]
第33次迭代,预测值为(0.51398623),迭代后第一层w:[-0.1977 -0.2549  0.3593  0.5385],迭代后第二层w:[0.4792 0.0412]
第34次迭代,预测值为(0.51292195),迭代后第一层w:[-0.1979 -0.2553  0.3593  0.5385],迭代后第二层w:[0.4791 0.0373]
第35次迭代,预测值为(0.51193874),迭代后第一层w:[-0.1981 -0.2557  0.3593  0.5385],迭代后第二层w:[0.479  0.0337]
第36次迭代,预测值为(0.51103042),迭代后第一层w:[-0.1982 -0.2561  0.3593  0.5385],迭代后第二层w:[0.4789 0.0304]
第37次迭代,预测值为(0.51019128),迭代后第一层w:[-0.1984 -0.2564  0.3593  0.5385],迭代后第二层w:[0.4789 0.0273]
第38次迭代,预测值为(0.50941603),迭代后第一层w:[-0.1985 -0.2568  0.3593  0.5385],迭代后第二层w:[0.4788 0.0245]
第39次迭代,预测值为(0.50869982),迭代后第一层w:[-0.1987 -0.2571  0.3593  0.5385],迭代后第二层w:[0.4788 0.0219]
第40次迭代,预测值为(0.50803813),迭代后第一层w:[-0.1988 -0.2573  0.3593  0.5385],迭代后第二层w:[0.4787 0.0195]
第41次迭代,预测值为(0.50742681),迭代后第一层w:[-0.1989 -0.2576  0.3593  0.5385],迭代后第二层w:[0.4787 0.0173]
第42次迭代,预测值为(0.50686202),迭代后第一层w:[-0.199  -0.2578  0.3593  0.5385],迭代后第二层w:[0.4786 0.0152]
第43次迭代,预测值为(0.50634022),迭代后第一层w:[-0.1991 -0.258   0.3593  0.5385],迭代后第二层w:[0.4786 0.0133]
第44次迭代,预测值为(0.50585812),迭代后第一层w:[-0.1992 -0.2582  0.3593  0.5385],迭代后第二层w:[0.4785 0.0115]
第45次迭代,预测值为(0.50541271),迭代后第一层w:[-0.1993 -0.2584  0.3593  0.5385],迭代后第二层w:[0.4785 0.0099]
第46次迭代,预测值为(0.50500118),迭代后第一层w:[-0.1993 -0.2585  0.3593  0.5385],迭代后第二层w:[0.4785 0.0084]
第47次迭代,预测值为(0.50462096),迭代后第一层w:[-0.1994 -0.2587  0.3593  0.5385],迭代后第二层w:[0.4784 0.007 ]
第48次迭代,预测值为(0.50426967),迭代后第一层w:[-0.1995 -0.2588  0.3593  0.5385],迭代后第二层w:[0.4784 0.0058]
第49次迭代,预测值为(0.50394509),迭代后第一层w:[-0.1995 -0.2589  0.3593  0.5385],迭代后第二层w:[0.4784 0.0046]
第50次迭代,预测值为(0.5036452),迭代后第一层w:[-0.1996 -0.2591  0.3593  0.5385],迭代后第二层w:[0.4784 0.0035]
第51次迭代,预测值为(0.50336812),迭代后第一层w:[-0.1996 -0.2592  0.3593  0.5385],迭代后第二层w:[0.4783 0.0025]
第52次迭代,预测值为(0.50311211),迭代后第一层w:[-0.1997 -0.2593  0.3593  0.5385],迭代后第二层w:[0.4783 0.0015]
第53次迭代,预测值为(0.50287557),迭代后第一层w:[-0.1997 -0.2594  0.3593  0.5385],迭代后第二层w:[0.4783 0.0007]
第54次迭代,预测值为(0.50265701),迭代后第一层w:[-0.1997 -0.2594  0.3593  0.5385],迭代后第二层w:[ 4.783e-01 -1.000e-04]
第55次迭代,预测值为(0.50245507),迭代后第一层w:[-0.1998 -0.2595  0.3593  0.5385],迭代后第二层w:[ 0.4783 -0.0009]
第56次迭代,预测值为(0.50226848),迭代后第一层w:[-0.1998 -0.2596  0.3593  0.5385],迭代后第二层w:[ 0.4783 -0.0015]
第57次迭代,预测值为(0.50209608),迭代后第一层w:[-0.1998 -0.2597  0.3593  0.5385],迭代后第二层w:[ 0.4783 -0.0022]
第58次迭代,预测值为(0.50193678),迭代后第一层w:[-0.1999 -0.2597  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0027]
第59次迭代,预测值为(0.50178959),迭代后第一层w:[-0.1999 -0.2598  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0033]
第60次迭代,预测值为(0.5016536),迭代后第一层w:[-0.1999 -0.2598  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0038]
第61次迭代,预测值为(0.50152794),迭代后第一层w:[-0.1999 -0.2599  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0042]
第62次迭代,预测值为(0.50141183),迭代后第一层w:[-0.2    -0.2599  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0047]
第63次迭代,预测值为(0.50130454),迭代后第一层w:[-0.2    -0.26    0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0051]
第64次迭代,预测值为(0.50120541),迭代后第一层w:[-0.2    -0.26    0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0054]
第65次迭代,预测值为(0.50111381),迭代后第一层w:[-0.2    -0.2601  0.3593  0.5385],迭代后第二层w:[ 0.4782 -0.0057]

更复杂的神经网络

## 加载绝对路径的本地图片
#from IPython.display import Image
#Image(filename = '/Users/mac/Desktop/快乐研一/python/机器学习/bp算法/1.jpeg', width=50, height=50)

随机梯度下降法

  • 把样本分组,每组50-200个样本,每组叫做一个BATCH
  • 每次输入一个BATCH,用它们的梯度平均值来调整参数
  • 把所有BATCH遍历也就是把样本遍历一次,叫做一个EPOCH
  • 做多次EPOCH,每次打乱样本顺序再划分BATCH,以增加BATCH内样本随机性

经验

出现以下情况请注意

  1. 当在训练集上目标函数的平均值增大时:

    • 模型不够复杂以至于不能完全拟合
    • 已经训练的很好了
  2. CV 训练集 验证集 测试集

  3. 调整学习率:

    • 如果目标函数变化太小——α太小
    • 如果刚开始目标函数就增加——α太大

正则项

即加入L1或者L2正则(回忆下岭回归和lasso的特点),避免过拟合

归一化(标准化)

最好做归一化!!!

xmeanstd\frac{x-mean}{std}

参数初始化

梯度消失现象

  1. 由于初始值w和b是人为选定的,如果一开始wTx+b的绝对值很大,根据sigmoid函数图像会发现梯度将会趋近于0,经过后向传播所有梯度都会接近0.——导致训练缓慢

  2. 一种有效的解决方案是,初始化时从区间(1d,1d)(-\frac{1}{\sqrt{d}}, \frac{1}{\sqrt{d}})均匀取值,d是参数所在层的神经元个数。使得WTX+B尽量靠近0.

  3. BATCH normalization,我们希望每一层输出值都在0附近,从而避免梯度消失线性,因此对每一层做基于均值和方差的标准化/归一化。

梯度相关两大问题

  • “梯度分类不平衡”,由于每个分量的梯度绝对值有大有小,优化路径变成z型,速度下降。
  • “梯度方向随机性” 引入momentum概念,考虑这次梯度和上次梯度的加权求和,降低搜索路径的随机性。
  • Adam算法(进一步学习)

TensorFlow

import tensorflow as tf
print('加载成功!')
加载成功!