BP神经网络识别手写字-学习笔记

原理

  • 前馈神经网络:一种最简单的神经网络,各神经元分层排列。每个神经元只与前一层的神经元相连。接收前一层的输出,并输出给下一层.各层间没有反馈。
  • BP神经网络:是一种按照误差逆向传播算法训练的多层前馈神经网络。
  • 卷积神经网络:包含卷积计算且具有深度结构的前馈神经网络。
    多了一个反馈
    BP网络的标准学习算法-学习过程 推导过程看这个!
    正向传播
    输入样本-----输入层------各隐层--------输出层
    判断是否转入反向传播阶段
    若输入层的实际输出(h(x))与期望的输出(y)不符。
    误差反传
    误差以某种形式在各层表示-----修正各层单元的权值(delta_w)
    最终结果
    网络输出的误差减少到了可以接受的程度(或 进行到预先设定的学习次数为止)

修正各单元的权值delta_w怎么推出来的我觉得不用完全了解,但是一定要知道公式。
Delta学习规则—代价函数,损失函数,就是误差 可以用梯度下降法来最小化E的值,也就是用梯度下降法来最小化求E时用到的W权值(就是对E进行求导)
就是导数的负数乘上学习率(学习率比较难选择,太大会有震荡,也可能会有最初值的不同而导致有局部最小值—多选择几次初值,多训练几次就好)

激活函数:
sigmoid(比较简单,但是最差),ReLu(最好!)
Tahn,softsign
激活函数,就是在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端)使用ReLu最好 ,非线性,分类界限是直线。(因为权值还要乘上激活函数的导数,relu 的导数为1也就是说他的梯度为1,权值不会到0,不会产生梯度消失或梯度爆炸)
计算规则:(包括delta_w)
在这里插入图片描述
公式使用举例:

 		L1 =sigmod(np.dot(x,V)) #矩阵乘法 x*V得到信号层的输出  1*64  * 64*100 == 1*100
        L2 = sigmod(np.dot(L1,W))#矩阵乘法 L1*W得到输出层的输出  1*100 * 100*10 == 1*10
        L2_delta = (y[i] - L2) * dsigmod(L2)
        L1_delta = L2_delta.dot(W.T) * dsigmod(L1)

全部代码:

import numpy as np
from sklearn.datasets import load_digits  # sklearn里自带的手写数字图片
from sklearn.preprocessing import LabelBinarizer  # 对标签数据做处理
from sklearn.model_selection import train_test_split  # 对训练集和测试集做区分
# from sklearn.metrics import classification_report.confusion_matris #对结果做评估
import matplotlib.pyplot as plt

# 载入数据
digits = load_digits()
# print(digits.images.shape) #(1797, 8, 8) 有1797张图片,每张8*8
# #显示图片
# plt.imshow(digits.images[0],cmap='gray')#显示digits数据集中第0张图片,显示灰度图
# plt.show()
# plt.imshow(digits.images[23],cmap='gray')
# plt.show()

X = digits.data  # 读入数据,函数的使用看官方文档
y = digits.target  # 读入标签
# print(X.shape)
# print(X[:3])
print(y.shape)
print(y)

# 首先定义神经网络的权值矩阵--要先知道权值要几个(输入层有多少个神经元
# 输入每幅图有8*8个像素 所以要64个神经元 隐藏层无所谓 可大可小
# 输出层有10个数字 所以定义10和神经元,表示0-9
# 一共两个权值矩阵

# 先定义输入层到隐藏层之间的权值矩阵64(输入层-100(隐藏层
V = np.random.random((64, 200)) * 2 - 1  # random表示生成随机数 64行 100列,从-1到1之间
# 定义隐藏层到输出层
W = np.random.random((200, 10)) * 2 - 1

# 数据切分 都分为测试集和训练集
# 默认1/4的数据为测试集,3/4为训练集,
X_train, X_test, y_train, y_test = train_test_split(X, y)

#做标签二值化:0:100000000 3:0001000000
lables_train = LabelBinarizer().fit_transform(y_train)


##定义激活函数:sigmod
def sigmod(x):
    return 1/(1+np.exp(-x))
 #激活函数的导数
def dsigmod(x):
    return x*(1-x)

def predict(x):
    L1 = sigmod(np.dot(L1 , W)) # 矩阵乘法 L1*W得到输出层的输出
    return L2
#训练模型
def train(X,y,steps,lr):
    global V,W
    for n in range(steps+1):
        #随机选取一个数据
        i = np.random.randint(X.shape[0])#从训练集里随机抽取一个数据,数据大小为0-X.shape[0]
        x = X[i]#选一个数据
        x = np.atleast_2d(x)#变成二维,方便后面做矩阵乘法,1*64
        #BP算法公式:(先了解算法原理
        L1 =sigmod(np.dot(x,V)) #矩阵乘法 x*V得到信号层的输出  1*64  * 64*100 == 1*100
        L2 = sigmod(np.dot(L1,W))#矩阵乘法 L1*W得到输出层的输出  1*100 * 100*10 == 1*10
        L2_delta = (y[i] - L2) * dsigmod(L2)
        L1_delta = L2_delta.dot(W.T) * dsigmod(L1)
        W += lr * L1.T.dot(L2_delta)#更新权值
        V += lr * x.T.dot(L1_delta)

        #每训练1000次 看一下准确率
        if n % 1000 ==0:
            output = predict(X_test)
            predictions= np.argmax(output,axis=1)#获取最大值的位置(二值化后的位置)其实就是在得到标签的值
            acc = np.mean(np.equal(predictions, y_test))#对比测试集的标签和真实标签
            print('steps ',n,'accurancy ',acc)

train(X_train,lables_train,100000,0.11)

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值