参考文章:
https://www.zybuluo.com/hanbingtao/note/476663
https://www.zybuluo.com/hanbingtao/note/448086
# -*- coding: utf-8 -*-
import numpy as np
def sigmoid(x):#激活函数
return 1/(1+np.exp(-x))
input1 = np.array([[0.35],[0.9],[0.58],[0.78]]) #输入数据 4x1
w1 = np.random.rand(3,4)#第一层权重参数 3x4
w2 = np.random.rand(2,3)#第二层权重参数 2x3
real = np.array([[0.5],[0.7]])#标签
for s in range(100):
output1 = sigmoid(np.dot(w1,input1))#第一层输出 3x1
output2 = sigmoid(np.dot(w2,output1))#第二层输出,也即是最终输出 2x1
cost = np.square(real-output2)/2#误差 2x1
delta2=output2*(1-output2)*(real-output2) #2x1
delta1=output1*(1-output1)*w2.T.dot(delta2) #3x1
w2 = w2 + delta2.dot(output1.T) #2x3
w1 = w1 + delta1.dot(input1.T) #3x4
print(output1)
print(output2)
print(cost)
代码剖析
def sigmoid(x):#激活函数
return 1/(1+np.exp(-x))
定义激活sigmoid激活函数的定义:
output1 = sigmoid(np.dot(w1,input1))#第一层输出 3x1
output2 = sigmoid(np.dot(w2,output1))#第二层输出,也即是最终输出 2x1
第一层输出和第二层输出
第一层输出的计算方式是:
样本数据 左乘 权重
$vec{a}=f(Wcenterdotvec{x})qquad $
第二层类似,只不过替换为第一层的输出左乘权重
cost = np.square(real-output2)/2#误差 2x1
计算误差:$e=frac{1}{2}(y-ar{y})^2$
误差主要是用来衡量模型效果的
delta2=output2*(1-output2)*(real-output2) #2x1
delta1=output1*(1-output1)*w2.T.dot(delta2) #3x1
计算误差项:
误差项 主要是用来更新权重使用的
-
对于输出层节点:
$delta_i=y_i(1-y_i)(t_i-y_i)qquad$
其中,$delta_i$是节点$i$的误差项,$y_i$是节点$i$的输出值,$t_i$是样本对应于节点$i$的目标值 -
对于隐藏层节点:
$delta_i=a_i(1-a_i)sum_{kin{outputs}}w_{ki}delta_kqquad$
其中,$a_i$是节点的输出值,$w_{ki}$是节点$i$到它的下一层节点$k$的连接的权重,$delta_k$是节点$i$的下一层节点$k$的误差项。例如,对于隐藏层节点4来说,计算方法如下:
$delta_4=a_4(1-a_4)(w_{84}delta_8+w_{94}delta_9)$
w2 = w2 + delta2.dot(output1.T) #2x3
w1 = w1 + delta1.dot(input1.T) #3x4
最后,更新每个连接上的权值:
$w_{ji}gets w_{ji}+etadelta_jx_{ji}qquad$
其中,$w_{ji}$是节点$i$到节点$j$的权重,$eta$是一个成为学习速率的常数,$delta_i$是节点$i$的误差项,$x_{ji}$是节点$i$传递给节点$j$的输入。例如,$w_{84}$权重的更新方法如下:
$w_{84}gets w_{84}+etadelta_8 a_4$