深度学习笔记:使用随机梯度下降法识别mnist数据集

news2024/9/24 4:15:50

深度学习算法实现流程:
1 从训练数据中随机选出一部分数据,称为mini-batch。我们的目标为减小mini-batch损失函数的值

2 计算损失函数关于权重的梯度。梯度方向即为损失函数值减小最快的方向

3 将权重沿梯度下降方向更新

4 重复以上步骤,在另外选取的一种mini-batch中更新权重

该方法由于使用随机的mini-batch数据,被称为随机梯度下降法(stochastic gradient descent SGD)

示例:

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
from common.functions import *
from common.gradient import numerical_gradient


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)

    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) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = 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

1

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)

初始化网络权重和偏置。权重初始值为0.1 * 随机正态。偏置初始值0

2

    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) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = softmax(a2)
        
        return y

得到网络输出。我们使用sigmoid函数作为第一层激活函数,softmax作为输出层激活函数计算结果

3

    def loss(self, x, t):
        y = self.predict(x)
        
        return cross_entropy_error(y, t)

使用交叉熵计算总损失

4

	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

计算神经网络预测准确率:预测正确次数除以输入样本量
注:
np.argmax() 得到数组中最大值,我们用此函数得到网络预测的数值和one-hot标签值

5

    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

计算数值梯度。计算损失函数关于各个参数的偏导,得到损失函数关于神经网络参数的梯度

基于该神经网络的mini-batch训练

这里我们使用mnist手写数字集作为训练对象。

# 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=100, output_size=10)

iters_num = 100  # 适当设定循环的次数
train_size = x_train.shape[0]
batch_size = 10000
learning_rate = 0.5

train_loss_list = []
train_acc_list = []
test_acc_list = []

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)
    
    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()

1

network = TwoLayerNet(input_size=784, hidden_size=100, output_size=10)

创建神经网络。输入神经元数784为 28 X 28 图片展开。隐藏层神经元数量100,输出层数10,代表判断的数字结果0-9

2

iters_num = 100  # 适当设定循环的次数
train_size = x_train.shape[0]
batch_size = 10000
learning_rate = 0.5

超参数:迭代次数,训练集样本量,每次选取的mini-batch样本量,学习率

3

batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]

初始化训练数据及标签

4

    # 计算梯度
    #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]

计算梯度并更新参数

5

	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检测神经网络关于训练数据和关于测试数据的预测精准度。如果两个数据差距不大说明网络的泛化能力较强。在这里我们每当处理了和train_size相等的batch数量就进行一次检测

结果:
learning_rate = 0.5, hidden_size = 100, batch_size = 10000

train acc, test acc | 0.11236666666666667, 0.1135
train acc, test acc | 0.11236666666666667, 0.1135
train acc, test acc | 0.2014, 0.2007
train acc, test acc | 0.2825, 0.2805
train acc, test acc | 0.2062, 0.2052
train acc, test acc | 0.38693333333333335, 0.3913
train acc, test acc | 0.34846666666666665, 0.3494
train acc, test acc | 0.43978333333333336, 0.4341
train acc, test acc | 0.5131166666666667, 0.5132
train acc, test acc | 0.6023166666666666, 0.606
train acc, test acc | 0.6332666666666666, 0.6387
train acc, test acc | 0.6871833333333334, 0.6881
train acc, test acc | 0.68835, 0.6933
train acc, test acc | 0.7204666666666667, 0.7224
train acc, test acc | 0.7432166666666666, 0.7444
train acc, test acc | 0.7611333333333333, 0.768
train acc, test acc | 0.7908833333333334, 0.7933
在这里插入图片描述
这里我们看到神经网络预测准确度在不断上升,说明模型训练成功。train acc和test acc两条线基本上重合,说明模型具有很强泛化能力,没有出现过拟合

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

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

相关文章

【自动驾驶汽车技术 | 车载雷达系统】

本文编辑:调皮哥的小助理 1、摘要 自动驾驶汽车传感器系统一般包括4种雷达:激光雷达(Lidar)、毫米波雷达(mmWave Radar)、超声波雷达(Ultrasonic Radar)和红外雷达(Infrared Radar)。目前激光雷达和毫米波雷达是基本和必要的车载传感器设备,…

I.MX6ULL内核开发8:linux设备驱动模型

目录 一、为什么需要设备驱动模型 二、sysfs概述 驱动模型一 驱动模型二 kobject kset kobj_type 一、为什么需要设备驱动模型 早期内核(2.4之前)没有统一的设备驱动模型,但是照样可以使用(之前的led字符设备驱动&#xff…

2023-2-12刷题情况

字母板上的路径 题目描述 我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。 在本题里,字母板为board [“abcde”, “fghij”, “klmno”, “pqrst”, “uvwxy”, “z”],如下所示。 我们可以按下面的指令规则行动…

合宙Air103|fbd数据库| fskv - 替代fdb库|LuatOS-SOC接口|官方demo|学习(16):类redis的fbd数据库及fskv库

基础资料 基于Air103开发板:🚗 Air103 - LuatOS 文档 上手:开发上手 - LuatOS 文档 探讨重点 对官方社区库接口类redis的fbd数据库及fskv库的调用及示例进行复现及分析,了解两库的基本原理及操作方法。 软件及工具版本 Luat…

肝了几天的Git入门教程,收获满满

1.简介 谈及版本控制系统,或许大多数程序员最开始接触的都是SVN(Subversion),它是一个集中式的版本控制系统,使用的时候需要提供一台的服务器来进行部署,所有的更新与同步操作都需要与这台服务器进行交互&…

windows/linux下Qt可执行程序打包,linux桌面双击运行程序sh脚本

1、windows下Qt打包 windows下Qt的可执行文件打包简单的来说就是利用Qt自带依赖的打包工具windeployqt进行打包,该工具存在Qt安装目录下,执行命令为:windeployqt name.exe 打包依赖文件可参考如下链接中1-7步,后面的步骤是打包依…

156、【动态规划】AcWing ——3. 完全背包问题:二维数组+一维滚动数组(C++版本)

题目描述 原题链接:3. 完全背包问题 解题思路 完全背包相对于01背包来说,对同一个物品可以选择多次。而01背包对同一个物品只能选择一次。 递推公式上的区别:01背包是dp[i][j] max(dp[i - 1][j], dp[i - 1][j - v[i]] w[i]),…

14. 最长公共前缀

14. 最长公共前缀 一、题目描述: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”] 输出:“fl” 示例 2: …

在线支付系列【23】支付宝支付接入指南

有道无术,术尚可求,有术无道,止于术。 文章目录前言接入指南1. 创建应用2. 绑定应用3. 配置密钥4. 上线应用5. 开通产品沙箱环境开发前准备(沙箱环境)1. 获取参数、秘钥、证书2. 下载支付宝客户端3. 案例演示前言 在之…

一个自动配置 opengrok 多项目的脚本

前段时间在服务器上配置 opengrok 阅读代码,项目有很多个,一个一个手动配置比较繁琐。 我从搭建 tomcat 和 opengrok,到配置和索引完 5 个 Android 项目,用了差不多一整天。 要是再让我手动配置几个项目,估计真要崩溃…

学习Request和Response这一篇就够啦~

Request(请求) : Request:获取请求数据 Response:设置响应数据 Request继承体系: 使用request对象,查阅JavaEE API文档的HttpServeltRequest接口 Tomcat需要解析请求数据,封装为request对象,并且创建requ…

知识图谱嵌入技术研究综述

作者 张天成 1 , * 田 雪 1 , * 孙相会 1 , * 于明鹤 2 , * 孙艳红 1 , * 于 戈 摘要 知识图谱 是一种用图模型来描述知识和建模事物之间的关联关系的技术。 知识图谱嵌入 作为一种被广泛采用的知识表示方法。 主要思想是将知识图谱中的实体和关系嵌入到连续的向量空间中…

Ansible---playbook剧本

目录 引言:什么是playbook? 一、Playbook 1.1、playbook中的核心元素 1.2、playbook中的基础组件 1.3、playbook格式说明 1.4、实例:httpd服务剧本 二、playbook中的模块 2.1、Templates 模块 2.2、tags 模块 2.3、Roles 模块 引言&…

关于链表中插入结点的操作……

服了,好久没敲链表了,这都忘了 newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur-…

科技常识就像雨衣,要常备哦

科技常识就像雨衣,平常不准备,遇雨成落汤鸡 昨日晨跑遇雨,随身带轻便雨塑料雨衣 趣讲大白话:晴天挖水渠 *********** 信息科技是现代科技的【火车头】 往前看:要关注趋势 往后看:要了解行业历史 在当下&…

数据结构 | 栈与队列

🔥Go for it!🔥 📝个人主页:按键难防 📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 📖系列专栏:数据结构与算法 &#x1f52…

使用C#编写k8s CRD Controller

本文项目地址:k8s-crd - Repos (azure.com)CRDCRD指的是Custom Resource Definition。开发者更多的关注k8s对于容器的编排与调度,这也是k8s最初惊艳开发者的地方。而k8s最具价值的地方是它提供了一套标准化、跨厂商的 API、结构和语义。k8s将它拥有的一切…

【测试开发】web 自动化测试实战 --- MuiscServerTest

目录界面测试功能测试1. 登录注册模块功能测试2. 音乐列表页自动化测试3. 喜欢音乐列表页自动化测试4. 上传音乐模块自动化测试5. 以上所有测试用例集成测试套件项目测试亮点web 自动化测试实战就通过测试自己的 onlinemusicserver 音乐服务器项目进行测试,通过 sel…

冰冰学习笔记:多线程

欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位…

基于TimeQuest时序优化原理和方法

💡 回顾基于RTL逻辑时序优化的基本思路,在关键路径中插入寄存器来优化时序 分析最坏路径 通过前面对TimeQuest软件的理解,基本上可以找到关键路径,此文章主要对关键路径时序进行优化,使设计达到时序要求,以…