基于随机梯度下降法的手写数字识别、epoch是什么、python实现

基于随机梯度下降法的手写数字识别、epoch是什么、python实现

    • 一、普通的随机梯度下降法的手写数字识别
      • 1.1 学习流程
      • 1.2 二层神经网络类
      • 1.3 使用MNIST数据集进行学习
      • 注:关于什么是epoch
    • 二、基于误差反向传播算法求梯度的手写数字识别
      • 2.1 学习流程
      • 2.2 实现与结果分析

一、普通的随机梯度下降法的手写数字识别

1.1 学习流程

1.从训练数据中随机选择一部分数据

2.计算损失函数关于各个权重参数的梯度

这里面用数值微分方法求梯度

3.将权重参数沿梯度方向进行微小的更新

4.重复前三个步骤

1.2 二层神经网络类

params:保存神经网络参数的字典型变量

grads:保存梯度的字典型变量

def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):

input_size:输入层神经元个数

hidden_size:隐藏层神经元个数

output_size:输出层神经元个数

def predict(self, x):

进行识别,x:图像数据

 def loss(self, x, t):

求损失函数,x:图像数据;t:正确解标签

def accuracy(self, x, t):

计算识别精度

 def numerical_gradient(self, x, t):

计算权重参数梯度

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
from common.functions import *
from common.gradient import numerical_gradientclass 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)def predict(self, x):W1, W2 = self.params['W1'], self.params['W2']b1, b2 = self.params['b1'], self.params['b2']a1 = np.dot(x, W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2y = softmax(a2)return y# x:输入数据, t:监督数据def loss(self, x, t):y = self.predict(x)return cross_entropy_error(y, t)def accuracy(self, x, t):y = self.predict(x)y = np.argmax(y, axis=1)t = np.argmax(t, axis=1)accuracy = np.sum(y == t) / float(x.shape[0])return accuracy# x:输入数据, t:监督数据def numerical_gradient(self, x, t):loss_W = lambda W: self.loss(x, t)grads = {}grads['W1'] = numerical_gradient(loss_W, self.params['W1'])grads['b1'] = numerical_gradient(loss_W, self.params['b1'])grads['W2'] = numerical_gradient(loss_W, self.params['W2'])grads['b2'] = numerical_gradient(loss_W, self.params['b2'])return grads
    def numerical_gradient(f, x):h = 1e-4 # 0.0001grad = np.zeros_like(x)it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])while not it.finished:idx = it.multi_indextmp_val = x[idx]x[idx] = float(tmp_val) + hfxh1 = f(x) # f(x+h)x[idx] = tmp_val - h fxh2 = f(x) # f(x-h)grad[idx] = (fxh1 - fxh2) / (2*h)x[idx] = tmp_val # 还原值it.iternext()   return grad

1.3 使用MNIST数据集进行学习

这里面用的是数值微分方法求梯度,速度超级慢。

iters_num是梯度法的更新次数。

batch_size = 100,说明每次从60000个训练数据中随机取出100个数据。

对这100个数据求梯度,然后用梯度下降法更新参数,更新iters_num次。

最后可以画出来一个损失函数的图,的确是下降的。

注:关于什么是epoch

什么是epoch,我们在代码里可以很清楚理解。

先来一段源码分析:

这个代码中,可看出,epochs是len(train_acc_list)。

x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.xlabel("epochs")

我们看train_acc_list,它其实是在进行if i % iter_per_epoch == 0判断后,才添加的。

也就是说,每经过一个epoch,就对所有训练数据和测试数据计算识别精度。

那么就可以知道了,epoch的作用就是不那么频繁的记录识别精度,毕竟,只要从大方向上大致把握识别精度即可。

train_acc_list = []
test_acc_list = []
#平均每个epoch的重复次数
iter_per_epoch = max(train_size / batch_size, 1)if i % iter_per_epoch == 0:train_acc = network.accuracy(x_train, t_train)test_acc = network.accuracy(x_test, t_test)train_acc_list.append(train_acc)test_acc_list.append(test_acc)print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))

那现在就知道epoch是什么了吧,其实它就是:网络里面经过多少次数据学习之后再求整体的网络精度。

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet# 读入数据
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)iters_num = 10000  # 适当设定循环的次数
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1train_loss_list = []
train_acc_list = []
test_acc_list = []
#平均每个epoch的重复次数
iter_per_epoch = max(train_size / batch_size, 1)for i in range(iters_num):batch_mask = np.random.choice(train_size, batch_size)x_batch = x_train[batch_mask]t_batch = t_train[batch_mask]# 计算梯度grad = network.numerical_gradient(x_batch, t_batch)#grad = network.gradient(x_batch, t_batch)# 更新参数for key in ('W1', 'b1', 'W2', 'b2'):network.params[key] -= learning_rate * grad[key]loss = network.loss(x_batch, t_batch)train_loss_list.append(loss)#计算每个epoch的识别精度if i % iter_per_epoch == 0:train_acc = network.accuracy(x_train, t_train)test_acc = network.accuracy(x_test, t_test)train_acc_list.append(train_acc)test_acc_list.append(test_acc)print("train acc, test acc | " + str(train_acc) + ", " + str(test_acc))# 绘制图形
'''
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()'''
x = np.arange(len(train_loss_list))
plt.plot(x, train_loss_list, label='train lost')
plt.xlabel("iteration")
plt.ylabel("loss")
plt.ylim(0, 3)
plt.show()

二、基于误差反向传播算法求梯度的手写数字识别

2.1 学习流程

1.从训练数据中随机选择一部分数据

2.计算损失函数关于各个权重参数的梯度

这里面用误差反向传播算法求梯度

3.将权重参数沿梯度方向进行微小的更新

4.重复前三个步骤

2.2 实现与结果分析

和第一个类似,只不过改动了求梯度的函数

    def gradient(self, x, t):W1, W2 = self.params['W1'], self.params['W2']b1, b2 = self.params['b1'], self.params['b2']grads = {}batch_num = x.shape[0]# forwarda1 = np.dot(x, W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2y = softmax(a2)# backwarddy = (y - t) / batch_numgrads['W2'] = np.dot(z1.T, dy)grads['b2'] = np.sum(dy, axis=0)da1 = np.dot(dy, W2.T)dz1 = sigmoid_grad(a1) * da1grads['W1'] = np.dot(x.T, dz1)grads['b1'] = np.sum(dz1, axis=0)return grads

然后调用的时候调用下面这句话

grad = network.gradient(x_batch, t_batch)

最终结果:

下面这个图是随着网络对训练数据和测试数据训练次数的增加,网络识别精度的变化。

在这里插入图片描述

下面这个图表示,朝着梯度下将方向走10000次过程中,loss逐渐减小。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于卷积神经网络的手写数字识别、python实现

一、CNN网络结构与构建 参数: 输入数据的维数,通道,高,长 input_dim(1, 28, 28)卷积层的超参数,filter_num:滤波器数量,filter_size:滤波器大小,stride:步幅…

基于深度学习的手写数字识别、python实现

基于深度学习的手写数字识别、python实现一、what is 深度学习二、加深层可以减少网络的参数数量三、深度学习的手写数字识别一、what is 深度学习 深度学习是加深了层的深度神经网络。 二、加深层可以减少网络的参数数量 加深层的网络可以用更少参数获得与没有加深层同等水…

二极管的结构、特性、参数、稳压管的特性和参数

二极管的结构、特性、参数、稳压管的特性和参数本文介绍的定义一、半导体类型二、PN结的结构与单向导电性三、二极管的伏安特性四、二极管的参数五、稳压管本文介绍的定义 本文介绍的定义:半导体、本征半导体、空穴、载流子、杂质半导体、N型半导体、P型半导体、PN…

双极结型三极管的结构、特性曲线、参数、lceda仿真

双极结型三极管的结构、特性、参数本文介绍的定义一、三极管结构二、三极管特性曲线三、三极管参数本文介绍的定义 硅平面管、锗合金管、发射区、基区,集电区、发射极、基极、集电极、发射结、集电结、发射、发射极电流、复合和扩散、基极电流、收集、集电极电流、…

结型场效应管的结构、特性、参数

结型场效应管的结构、特性、参数本文介绍的定义一、N沟道结型场效应管结构二、N沟道结型场效应管特性曲线本文介绍的定义 场效应管、结型场效应管、N沟道结型场效应管的结构、耗尽层、栅极、源极、漏极、N沟道结型场效应管、夹断电压、预夹断、输出特性、可变电阻区、恒流区、…

绝缘栅型场效应管的结构、特性、参数

绝缘栅型场效应管的结构、特性、参数本文介绍的定义一、N沟道增强型MOS场效应管结构二、N沟道增强型MOS场效应管特性曲线三、N沟道耗尽型MOS场效应管结构和特性曲线本文介绍的定义 绝缘栅型场效应管、N沟道增强型MOS场效应管、耗尽型场效应管、增强型场效应管、反型层、开启电…

放大电路、单管共发射极放大电路结构、工作原理、lceda仿真

放大电路、单管共发射极放大电路结构、工作原理本文介绍的定义一、放大电路基本概念二、单管共发射极放大电路本文介绍的定义 放大、实现放大作用、放大电路技术指标测量、电压放大倍数、电流放大倍数、相量表示、最大输出幅度、峰峰值、非线性失真系数、输入电阻、输出电阻、…

放大电路分析方法、图解法分析放大电路、lceda仿真

放大电路分析方法、图解法分析放大电路一、本文介绍的定义二、放大电路分析方法三、图解法一、本文介绍的定义 放大电路分析、图解法、微变等效电路法、静态分析、动态分析、直流通路、交流通路、单管共射放大电路的直流和交流通路、静态工作点、图解法分析静态、直流负载线、…

通过共现矩阵和余弦相似度实现机器对单词的认知、python实现

通过共现矩阵和余弦相似度实现机器对单词的认知、python实现本文介绍的定义:一、语料库预处理二、单词的分布式表示三、单词的相似度四、相似单词排序本文介绍的定义: 语料库、计数方法的目的、语料库预处理、单词的分布式表示、分布式假设、上下文、窗…

使用PPMI改进共现矩阵

使用PPMI改进共现矩阵 共现矩阵的元素表示两个单词同时出现的次数,这里的次数并不具备好的性质,举个例子,有短语叫the car,因为the是个常用词,如果以两个单词同时出现的次数为衡量相关性的标准,与drive 相…

基于SVD的降维优化

基于SVD的降维优化 向量降维:尽量保留数据“重要信息”的基础上减少向量维度。可以发现重要的轴(数据分布广的轴),将二维数据 表示为一维数据,用新轴上的投影值来表示各个数据点的值,示意图如下。 稀疏矩阵…

微变等效电路法分析放大电路

微变等效电路法分析放大电路本文介绍的定义一、简化的h参数微变等效电路1.静态工作点计算2.微变等效电路法估算电压放大倍数二、微变等效电路法应用本文介绍的定义 微变等效电路法、h参数微变等效电路、单管共射放大电路的微变等效电路、Rbe近似估算、微变等效电路法应用。 一…

分压式静态工作点稳定电路

分压式静态工作点稳定电路本文介绍的定义:一、静态工作点稳定问题二、分压式静态工作点稳定电路本文介绍的定义: 静态工作点稳定问题、温度对三极管参数的影响、分压式静态工作点稳定电路、电流负反馈式工作点稳定电路、旁路电容、静态分析、动态分析。…

双极型三极管共集电极、共基极放大电路

双极型三极管共集电极、共基极放大电路本文介绍的定义共集电极放大电路共基极放大电路本文介绍的定义 双极型三极管放大电路的接法、共集电极放大电路、射极跟随器、带负载能力、共基极放大电路、改善频率响应。 共集电极放大电路 接法:根据输入信号与输出信号公…

stm32使用DAP下载程序

jym认为,会下载程序等于学会stm32,hahaha。 首先点这个魔术棒 接下来进行下面的设置: 配置Debug选项 配置Utilities选项 配置Degug-setting选项 选择目标板,flash大小由板子芯片型号决定,勾选reset and run&#xff…

stm32 NVIC EXTI

stm32 NVIC EXTINVICEXTI原理图main.cexti.hexti.cstm32f10x_it.cNVIC NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。配置中断的时候我们一般只用 ISER、ICER 和 IP 这三个寄存器&#…

stm32 HSE HSI

stm32 HSE HSI时钟树main.cclkconfig.hclkconfig.c时钟树 HSE_SetSysClock和HSI_SetSysClock这两个函数就是根据上面这个时钟树编写的。 main.c 这个实验是通过HSE或者HSI配置系统时钟,结果就是,用HSE比HSI灯闪的快点,因为代码设置的是使用…

stm32 SysTick

SysTick是系统定时器,属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候&am…

stm32 USART

介绍的定义 串行通信、并行通信、全双工、半双工、单工、同步、异步、比特率、码元、波特率、TTL、RS232、DB9接口、DTE、DCE、协议层、USART、UART、CH340G芯片、USB。 通信基础 根据数据传送的方式,通讯可分为串行通讯与并行通讯。 串行通信:同一时…

robot 用AP连PC

1.启动机器人 2.PC找到机器人的热点,连接 3.看机器人分配的电脑ip 4.打开putty软件,下图里面是机器人的ip。然后点击open 。 5.输入机器人用户名和密码,现在已经登陆进去了。 6.输入ifconfig查看网络状况