一:构造三层的神经网络
(一)初始化参数
使用sigmoid激活函数。x为输入数据,大小(5*3),设定y为输出标签,尺寸为5*1
三层结构的神经网络,隐藏层只有中间一层,设定第一层为L0,隐藏层(中间层)为L1,输出层为L
定义L0输入层的大小为5X3,输入层与隐藏层的连接为权重参数W0,W0的大小为3X4,隐藏层的大小为5X4(因为这里是一个矩阵运算,5行3列的矩阵乘以3行4列的矩阵得到5行4列的矩阵),隐藏层与输出层的连接为权重参数W1,大小为4X1,输出层的大小为5X1,也就是5个数据的预测标签。
网络结构:L0->W0->sigmoid->L1->W1->sigmoid->L2
(二)前向传播
前向传播就是从L0的X输入数据开始
L0 = x:
L1 = sigmoid(w0,x)
L2 = sigmoid(W1,L1)
(三) 反向传播
反向传播就是不断的优化每两个层的链接权重参数W,通过计算出各个样本对误差的影响程度。
L2是输出层,输出的预测标签,要与给定标签y进行比较,L2_error就是L2与y的误差,误差应该越小越好。
L2_error = y - L2
反向传播将误差L2_error首先从L2传到sigmoid函数,计算sigmoid函数的反求导操作,并且乘以L2_error操作,因为L2_error决定了反向传播的必要性。
L2_error很小,说明预测结果与y匹配的很好,反向传播没有必要;
L2_error很大,说明预测结果与y匹配的不好,需要用L2_error来决定反向传播的力度。
L2_delta = L2_error X 反向求导sigmoid
L2_delta:前面样本对误差的影响程度,之后就是按照这种步骤,不断的前传。
(四) 更新W参数
反向传播首先应该更新W1参数,因为L2是通过W1*L1得到的 那么要求出W1对L2有多大的影响,就对W1求导 得到L1,并乘以上一层传下来的L2_delta L2_delta求的是前面的样本对误差有多大的影响。 W1 += L1...T.dot(L2_delta); 同理: 对于W0,也是通过求导与乘以上层传下来的误差影响值 w0 += L0.T.dot(l1_delta) 最终W0,W1不断更新,使得误差值越来越小。
import numpy as np
def sigmoid(x, deriv=False):
"""激活函数与反求导"""
if(deriv==True):
return x*(1-x)
return 1 / (1 + np.exp(-x))
x = np.array([
[0,0,1],
[0,1,1],
[1,0,1],
[1,0,1],
[1,0,1]
])
#print(x.shape) 5 x 3
y = np.array([
[0],[1],[0],[1],[0]
])
#print(y.shape) 5 x 1
#随机数种子
np.random.seed(1)
#随机生成W参数
w0 = 2 * np.random.random((3,4)) -1
w1 = 2 * np.random.random((4,1)) -1
#print(w0.shape) 3 x 4
#print(w1.shape) 4 x 1
for i in range(600000):
#求出三个层的数据
l0 = x
l1 = sigmoid(np.dot(l0, w0))
l2 = sigmoid(np.dot(l1, w1))
#l2层误差
l2_error = y - l2
#每隔10000次输出误差
if i % 10000 == 0:
print("Error" + str(np.mean(np.abs(l2_error))))
#反向传播
l2_delta = l2_error * sigmoid(l2, deriv=True)
l1_error = l2_delta.dot(w1.T)
l1_delta = l1_error * sigmoid(l1, deriv=True)
#更新w 参数
w1 += l1.T.dot(l2_delta)
w0 += l0.T.dot(l1_delta)
def sigmoid(x, deriv=False):
"""激活函数与反向求导"""
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
#指定输入和label值
x = np.array([
[0,0,1],
[0,1,1],
[1,0,1],
[1,0,1],
[1,0,1]
])
print(x.shape)
#一共有五个数据,每个数据有三个特征
#数据网络是有监督的算法
y=np.array([[0],
[1],
[1],
[0],
[0]]
)
print(y.shape)
np.random.seed(1)
w0=2*np.random.random((3,4))-1 #变成-1-1的区间上
#(3,4)随机构造一个矩阵,该矩阵是3行4列的,3为三层,4表示L层有多少神经元
w1=2*np.random.random((4,1))-1
print(w0)
#数据网络的构造及迭代的计算
for j in range(5):
#反向传播
l0 = x
l1 = sigmoid(np.dot(l0,w0))
l2 = sigmoid(np.dot(l1,w1))
l2_error = y - 12
#print (l2_error.shape)
if (j%10000) == 0:
print('Error'+str(np.mean(np.abs(l2_error))))
#首先1/2(y-L2)^2算均方误差当作目标函数
#l2表示真实值和预测值之间的差距,L2是权重项
#L2_delta:表示L1对L2的贡献,每个样本错了多少
l2_delta = l2_error*sigmoid(l2,deriv=True)
#L2error相当于反向传播值
#对应元素相乘
print (l2_delta.shape)
l1_error = l2_delta.dot(w1.T)
l1_delta = l1_error * sigmoid(l1,deriv=True)
w1 += l1.T.dot(l2_delta)
w0 += l0.T.dot(l1_delta)