简单三层网络的搭建

一:构造三层的神经网络

(一)初始化参数

使用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)
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值