误差反向传播法实现手写数字识别(纯numpy实现)
前面一篇博客中我们讲解了仅仅使用numpy实现了数值微分法的梯度下降完成手写数字识别,使用数值微分的计算量会非常大,因此耗时也非常久。在这里我们使用另外一种快速计算梯度的方式-误差反向传播法。
代码如下:
from audioop import reverse
import numpy as np
from collections import OrderedDict
from dataset.mnist import load_mnist
import matplotlib.pylab as plt'''
OrderedDict:有序字典,有序指的是它可以记住向字典里添加元素的顺序
'''def softmax(x):if x.ndim == 2:x = x.Tx = x - np.max(x, axis=0)y = np.exp(x) / np.sum(np.exp(x), axis=0)return y.T x = x - np.max(x) # 溢出对策return np.exp(x) / np.sum(np.exp(x))def cross_entropy_error(y, t):if y.ndim == 1:t = t.reshape(1, t.size)y = y.reshape(1, y.size)# 监督数据是one-hot-vector的情况下,转换为正确解标签的索引if t.size == y.size:t = t.argmax(axis=1)batch_size = y.shape[0]return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size#relu层的实现
class Relu:def __init__(self):self.mask=Nonedef forward(self,x):#前向传播小于或等于0的变为0#大于0的原封不动self.mask=(x<=0)out=x.copy()out[self.mask]=0return outdef backward(self,dout):#反向传播小于或等于0的变为0#大于0的乘以导数1也就是原封不动dout[self.mask]=0dx=doutreturn dx#Sigmoid层的实现
class Sigmoid:def __init__(self):self.out=Nonedef forward(self,x):out=1/(1+np.exp(-x))self.out=outreturn outdef backward(self,dout):dx=dout*self.out*(1.0-self.out)return dx#Affine层的实现
class Affine:def __init__(self,W,b):self.W=Wself.b=bself.x=Noneself.dW=Noneself.db=Nonedef forward(self,x):self.x=xout=np.dot(x,self.W)+self.breturn outdef backward(self,dout):dx=np.dot(dout,self.W.T)self.dW=np.dot(self.x.T,dout)self.db=np.sum(dout,axis=0)return dx#Softmax-with-Loss层的实现
class SoftmaxWithLoss:def __init__(self):self.loss=Noneself.y=Noneself.t=Nonedef forward(self,x,t):self.t=tself.y=softmax(x)self.loss=cross_entropy_error(self.y,self.t)return self.lossdef backward(self,dout=1):batch_size=self.t.shape[0]dx=(self.y-self.t)/batch_sizereturn dx#两层网络结构
class TwoLayerNet:def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):#初始化权重self.params={}self.params['W1']=weight_init_std*np.random.randn(input_size,hidden_size)self.params['b1']=np.zeros(hidden_size)self.params['W2']=weight_init_std*np.random.randn(hidden_size,output_size)self.params['b2']=np.zeros(output_size)#生成层self.layers=OrderedDict()self.layers['Affine1']=Affine(self.params['W1'],self.params['b1'])self.layers['Relu1']=Relu()self.layers['Affine2']=Affine(self.params['W2'],self.params['b2'])self.LastLayer=SoftmaxWithLoss()def predict(self,x):for layer in self.layers.values():x=layer.forward(x)return x#损失函数def loss(self,x,t):y=self.predict(x)return self.LastLayer.forward(y,t)#计算梯度def gradient(self,x,t):#前向传播self.loss(x,t)#反向传播 #反向传播必须从最后一层往回调用backward函数dout=1dout=self.LastLayer.backward(dout)layers=list(self.layers.values())layers.reverse()for layer in layers:dout=layer.backward(dout)#反向传播完后各个层的权重和偏置的梯度也就生成grads={}grads['W1']=self.layers['Affine1'].dWgrads['b1']=self.layers['Affine1'].dbgrads['W2']=self.layers['Affine2'].dWgrads['b2']=self.layers['Affine2'].dbreturn grads#计算准确率def accuracy(self,x,t):y=self.predict(x)y=np.argmax(y,axis=1)if t.ndim !=1:t=np.argmax(t,axis=1)accuracy=np.sum(y==t)/float(x.shape[0])return accuracyif __name__=='__main__':(x_train,t_train),(x_test,t_test)=load_mnist(normalize=True,one_hot_label=True)net=TwoLayerNet(input_size=784,hidden_size=50,output_size=10)train_loss_list=[]#超参数iter_nums=10000train_size=x_train.shape[0]batch_size=100learning_rate=0.1#记录准确率train_acc_list=[]test_acc_list=[]#平均每个epoch的重复次数iter_per_epoch=max(train_size/batch_size,1)for i in range(iter_nums):#小批量数据batch_mask=np.random.choice(train_size,batch_size)x_batch=x_train[batch_mask]t_batch=t_train[batch_mask]#计算梯度#误差反向传播法 计算很快grad=net.gradient(x_batch,t_batch)#更新参数 权重W和偏重bfor key in ['W1','b1','W2','b2']:net.params[key]-=learning_rate*grad[key]#记录学习过程loss=net.loss(x_batch,t_batch)print('训练次数:'+str(i)+' loss:'+str(loss))train_loss_list.append(loss)#计算每个epoch的识别精度if i%iter_per_epoch==0:#测试在所有训练数据和测试数据上的准确率train_acc=net.accuracy(x_train,t_train)test_acc=net.accuracy(x_test,t_test)train_acc_list.append(train_acc)test_acc_list.append(test_acc)print('train acc:'+str(train_acc)+' test acc:'+str(test_acc))print(train_acc_list)print(test_acc_list)# 绘制图形markers = {'train': 'o', 'test': 's'}x = np.arange(len(train_acc_list))plt.plot(x, train_acc_list, label='train acc')plt.plot(x, test_acc_list, label='test acc', linestyle='--')plt.xlabel("epochs")plt.ylabel("accuracy")plt.ylim(0, 1.0)plt.legend(loc='lower right')plt.show()
训练过程的图片
最终训练的结果计算识别率
误差反向传播法实现手写数字识别(纯numpy实现)相关推荐
- 【FPGA教程案例100】深度学习1——基于CNN卷积神经网络的手写数字识别纯Verilog实现,使用mnist手写数字数据库
FPGA教程目录 MATLAB教程目录 ---------------------------------------- 目录 1.软件版本 2.CNN卷积神经网络的原理 2.1 mnist手写数字数 ...
- linux手写数字识别opencv,opencv实现KNN手写数字的识别
人工智能是当下很热门的话题,手写识别是一个典型的应用.为了进一步了解这个领域,我阅读了大量的论文,并借助opencv完成了对28x28的数字图片(预处理后的二值图像)的识别任务. 预处理一张图片: 首 ...
- 朴素贝叶斯分类器_MINST手写数字识别
朴素贝叶斯分类器_MINST手写数字识别 import numpy as np import pandas as pd from sklearn.preprocessing import Binari ...
- 误差反向传播法(二)【神经网络以层的方式实现】
我们来看激活函数层的实现,对于激活函数,大家初学神经网络的时候就经常听到,准确来说是在接触感知机的时候熟悉的,它是进入神经网络大门的钥匙,是现代神经网络快速发展的源头. ReLU层(Rectified ...
- 深度学习——误差反向传播法
前言 通过数值微分的方法计算了神经网络中损失函数关于权重参数的梯度,虽然容易实现,但缺点是比较费时间,本章节将使用一种高效的计算权重参数梯度的方法--误差方向传播法 本文将通过①数学式.②计算图,这两 ...
- 深度学习入门-误差反向传播法(人工神经网络实现mnist数据集识别)
文章目录 误差反向传播法 5.1 链式法则与计算图 5.2 计算图代码实践 5.3激活函数层的实现 5.4 简单矩阵求导 5.5 Affine 层的实现 5.6 softmax-with-loss层计 ...
- 深度学习之学习笔记(九)—— 误差反向传播法
误差反向传播法() 对神经网络模型而言,梯度下降法需要计算损失函数对参数的偏导数,如果用链式法则对每个参数逐一求偏导,这是一个非常艰巨的任务!这是因为: 模型参数非常多--现在的神经网络中经常会有上亿 ...
- 深度学习入门-基于python的理论与实现(五)误差反向传播法
目录 回顾 1 计算图 1.1局部计算 1.2 计算图的优点是什么 1.3 反向传播的导数是怎么求? 1.3.1加法节点的反向传播 1.3.2 乘法节点的反向传播 1.3.3 购买苹果的反向传播 1. ...
- 误差反向传播法小练习(鱼书)
下载鱼书: hi,这是我用百度网盘分享的内容~复制这段内容打开「百度网盘」APP即可获取 链接:https://pan.baidu.com/s/1RKigRDqzmh4GAK1WEnA3gQ 提取 ...
最新文章
- java jdk 8u111_8u111-jdk-alpine在java开发中的NullPointerException错误解决方案
- 高糊图片可以做什么?
- 监听iPhone的通话状态之---CoreTelephony.framework
- Java实现多线程的两种方式
- GridView空记录时显示Header和Footer
- 子线程中更新UI线程的三个方法
- x264里的2pass指的是什么意思? x264源代码分析2.encode()
- 在10000以内判断一个整数,它加上100和加上268后都是一个完全平方数 3 提问:请问该数是多少?...
- [Swift]LeetCode1043. 分隔数组以得到最大和 | Partition Array for Maximum Sum
- python从入门到放弃pdf下载-《Python3从入门到放弃》视频教程
- 常用大数据核心技术有哪些?
- 使用three.js创建粒子火焰效果
- 报错PyTorch is not compiled with NCCL support
- 综合电商高保真移动端Axure原型模板
- GTK构件 tree_view
- Java编程之四大名著
- 2013年多益网络校园招聘笔试题
- 【书籍】——机器学习与深度学习
- 独立性权重指标怎么计算?
- DELL IDRAC
热门文章
- html自动拨打电话,javascript之网页点击直接拨打电话和发送短信
- 面试官常问的设计模式及常用框架中设计模式的使用(一)
- 亚马逊广告CPC优化技巧 投放就有效
- 数据库原理:了解范式(1NF、2NF、3NF、BCNF),做例题快速弄懂
- Ubuntu18.04之微信中文乱码解决(五十八)
- 看脸的时代,AI医美为什么没有成为风口?
- O2O、B2B、C2C(通俗讲解)
- 计算机学院姚茜,2019年东南大学计算机科学与工程学院硕士研究生拟录取名单公示...
- Mysql- --DQl语句(select数据查询语言,多表查询,View试图)linux常用(重点)
- BruteXSS:XSS暴力破解神器