【深度学习】3-3 神经网络的学习- 导数梯度

导数

导数就是表示某个瞬间的变化量,式子如下:
在这里插入图片描述

式子的左边,表示f(x)关于x的导数,即f(x)相对于x的变化程度。式子表示的导数的含义是,x的“微小变化”将导致函数f(x)的值在多大程度上发生变化其中,表示微小变化h无限趋近0
下面使用程序来实现上面的例子

def numerical_diff(f,x):
	h = 10e - 50
	return (f(x+h) - f(x))/h

这个函数有两个参数,即“函数f”和“传给函数f的参数x”
上面的函数乍一看没什么问题,但是实际上这段代码有两个需要改进的地方

  1. h使用了10e-50这个微小值。但是,这样反而产生了舍入误差(rounding error)。所谓舍人误差,是指因省略小数的精细部分的数值(比如小数点后第8位以后的数值)而造成最终的计算结果上的误差。如果用float32类型(32位的浮点数)来表示10e-50,就会变成0.0,无法正确表示出来。因此需要将微小值h改为。使用0.0001就可以得到正确的结果。
  2. 第二个要改进的地方与函数f的差分有关。上述实现中计算了函数f在x+h和x之间的差分,但这个计算有误差,因为“真的导数”对应函数在x处的斜率(称为切线),但上述实现中计算的导数对应的是(x+h)和x之间的斜率。这个差异出现是因为h不可能无限接近0。为了减少这个误差,可以以x为中心,计算它左右两边的差分,所以也称为中心差分。(x + h)和x之间的差分称前向差分

在这里插入图片描述

看下面是改进的代码:

def numerical_diff(f,x):
	h = 1e-4  #0.001
	return (f(x+h) - f(x-h))/ 2*h

利用微小的差分求导数的过程称为数值微分(numerical differentiation)
基于数学式的推导求导数的过程,称为“解析性求解”或者“解析性求导
解析性求导得到的导数是不含误差的“真的导数”。

偏导数
有多个变量的函数的导数称为偏导数
例如这个例子:
在这里插入图片描述

这个式子可以用Python来实现,如下所示

def function_2(x):
	return x[0]**2 + x[1]**2
	# 或者 return np.sum(x**2)

这里,假定想参数输入了一个NumPy数组,函数的内部实现比较简单,先计算 NumPy 数组中各个元素的平方,再求它们的和。下面是这个函数的图像:
在这里插入图片描述

求这个式子的导数,这里需要注意的是,这个式子有两个变量,所以有必要区分对哪个变量求导数。

求x0=3,x1=4时,关于x0的偏导数

>>>def function tmp1(x0):
... return x0*x0+4.0**2.0
...
>>> numerical_diff(function_tmp1, 3.0)

结果:600000000000378

求x0=3,x1=4时,关于x1的偏导数

>>>def function tmp1(x0):
... return 3.0**2.0+x1*x1
...
>>> numerical_diff(function_tmp2, 4.0)

结果:7.999999999999119

这里的结果和解析解的导数基本一致。
像这样,偏导数和单变量的导数一样,都是求某个地方的斜率
偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。

梯度

由全部变量的偏导数汇总而成的向量称为梯度(gradient)。
梯度可以像下面这样来实现

def numerical_gradient(f,x):
	h = 1e - 4
	grad = np.zeros_like(x)

	for idx in range(x.size):
		tmp_val = x[idx]
		# f(x+h)的计算
		x[idx] = tmp_val + h
		fxh1 = f(x)

		# f(x-h)的计算
		x[idx] = tmp_val - h
		fxh2 = f(x)

		grad[idx] = (fxh1 - fxh2) /(2*h)
		x[idx] = tmp_val # 还原值
	return grad

在该函数中,参数f为函数,x为NumPy数组
然后用这个方法来求点(3,4)、(0,2)、(3,0)处的梯度
可以得到:
点(3,4)处的梯度是(6,8),点(0.2)处的梯度是(0,4),点(3,0)处的梯度是(6,0)。
如果把函数的所有梯度(元素值为负梯度)都显示出来会发现梯度指向函数的“最低处”(最小值)。然而并不是任何时候梯度都会指向最低处,实际上,梯度会指向各点处的函数值降低的方向。更严格地讲,梯度指示的方是各点处的函数值减小最多的方向

梯度法
神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数,这里通过巧妙地使用梯度来寻找函数最小值(或者尽可能小的值)的方法就是梯度法。

这里需要注意的是,梯度表示的是各点处的函数值减小最多的方向。因此,无法保证梯度所指的方向就是函数的最小值或者真正应该前进的方向。实际上,在复杂的函数中,梯度指示的方向基本上都不是函数值最小处

函数的极小值、最小值以及被称为鞍点(saddle point)的地方,梯度为0。鞍点是从某个方向上看是极大值,从另一个方向上看则是极小值的点。虽然梯度法是要寻找梯度为0的地方,但是那个地方不一定就是最小值(也有可能是极小值或者鞍点)。(梯度为0的地方,不一定就是最小值)

此外,当函数很复杂且呈扁平状时,学习可能会进入一个(几乎)平坦的地区,陷入被称为“学习高原”的无法前进的停滞期。

虽然梯度的方向并不一定指向最小值,但沿着它的方向能够最大限度地减小函数的值。因此,在寻找函数的最小值(或者尽可能小的值)的位置的任务中,要以梯度的信息为线索,决定前进的方向
(要以梯度为学习的前进方向)
通过不断地沿梯度方向前进,逐渐减小函数值的过程就是梯度法

下面用数学式来表示梯度法,如下所示:
在这里插入图片描述
其中n表示更新量,在神经网络的学习中,称为学习率。学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数
学习率需要事先确定为某个值,比如0.01或0.001。一般而言,这个过大或过小,都无法抵达一个“好的位置”。在神经网络的学习中,一般会边改变学习率的值,一边确认学习是否正确进行了。
学习率过大的话,会发散成一个很大的值;反过来,学习率过小的话,基本上没怎么更新就结束了。
像学习率这样的参数称为超参数,超参数需要尝试多个值,以便找到一种可以使学习顺进行的设定。

下面用Python来实现梯度下降法。

def gradient_descent(f,init_x,lr=0.01,step_num=100):
	x=init_x
	for i in range(step_num):
		grad = numerical_gradient(f,x)
		x -= lr*grad
	return x

init_x是初始值,lr是学习率learnirate,step_num是梯度法的重复次数
使用这个函数可以求函数的极小值,顺利的话,还可以求函数的最小值。

神经网络的梯度
神经网络的梯度是指损失函数关于权重参数的梯度。
比如,有一个只有一个形状为2 x 3的权重 W的神经网络,损失函数用L表示。此时,梯度可以用请添加图片描述表示

用数学式表示的话,如下所
在这里插入图片描述

请添加图片描述的元素由各个元素关于W的偏导数构成。比如,第1行第1列的元素请添加图片描述表示当W11稍微变化时,损失函数L会发生多大变化。这里要注意的是形状要和W相同

下面,我们以一个简单的神经网络为例,来实现求梯度的代码。

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


class simpleNet:
    def __init__(self):
    	# 实例变量, 形状为2x3的权重参数
        self.W = np.random.randn(2,3) # 用高斯分布进行初始化

	# 用于预测
    def predict(self, x):
        return np.dot(x, self.W)

	# 求损失函数值,这里参数x接收输人数据,t接收正确解标签
    def loss(self, x, t):
        z = self.predict(x)
        y = softmax(z)
        loss = cross_entropy_error(y, t)

        return loss

x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])

net = simpleNet()

# Python中如果定义的是简单的函数,可以使用lambda表示法
# 对应的方法其实是
# def f(W):
#	return net.loss(x,t)
# 这里面参数W是一个伪参数,因为numerical_gradient会在内部执行f(x),为了与之兼容定义f(W)

f = lambda w: net.loss(x, t)

# 使用numerical_gradient求梯度
# net.W 权重参数
dW = numerical_gradient(f, net.W)

print(dW)

求出神经网络的梯度后,接下来只需根据梯度法,更新权重参数即可。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

了解一下EPC模式和它的优势

目录 什么是EPCEPC的优势有哪些?BT、BOT、EPC分别是什么模式?总结 什么是EPC EPC是Engineering(工程):代表设计、采购和施工总承包。Procurement(采购):代表采购和物资管理。Constru…

各牌浏览器设置地址栏显示完整URL

有时候,我们在浏览器的地址栏输入URL后,需要查看完整的URL路径,比如想看到是http协议还是https协议。 目前大多数浏览器都直接将协议头隐藏,需要复制出地址,或者点击地址栏才能看到,比较麻烦。 浏览器支持通…

Docker 部署 jar 项目

文章目录 1、上传jar包2、新建 Dockerfile 文件3、新建 deploy.sh 脚本(创建并运行)4、新建 upgrade.sh 脚本(更新) 1、上传jar包 2、新建 Dockerfile 文件 添加jar包及修改端口 # 基础镜像 FROM java:8 # 添加jar包 ADD servic…

【STM32】基于stm32的阿里云智能家居

摘 要 智能家居是一种通过物联网将家里的各种电器设备连接在一起,并由中心控制器统一管理的信息系统。系统的核心是各类家居信息的采集与处理。阿里云能够提供云端的数据存储和分析功能,可以作为智能家居中心控制器的重要平台。 本文主要研究了基于阿里云…

WPF 控件设置透明度的方法

方法一:通过 Opacity 属性设置背景色透明度。范围从0-1,0表示完全透明,看不见。 通过 Opacity 属性去改变控件透明度 会影响子控件的透明度,是因为Opacity属性是在UIElement 类(以及Brush基类)中定义,所有元素都具有该…

Unity VR 开发教程:Meta Quest 一体机开发 (二)混合现实 MR 透视 Passthrough 环境配置

文章目录 📕教程说明📕配置透视的串流调试功能📕第一步:设置 OVRManager📕第二步:添加 OVRPassthroughLayer 脚本📕第三步:在场景中添加虚拟物体📕第四步:删除…

系统架构设计师 5:软件工程

一、软件工程 1 软件过程模型 软件要经历从需求分析、软件设计、软件开发、运行维护,直至被淘汰这样的全过程,这个全过程称为软件的生命周期。 为了使软件生命周期中的各项任务能够有序地按照规程进行,需要一定的工作模型对各项任务给予规…

JavaScript进阶----《getter 和 setter 是什么》

前言: 这两个属性在学习前端的时候看到过,但是由于项目中没有用到过,所以一直没有细致的了解。今天 review 同事代码的时候,遇到了这个写法,看了半天也不知道如何处理。再不学习真的以后连别人的代码都不知道什么意思了…

spring Cloud使用Skywalking搭建笔记

skywalking支持dubbo,SpringCloud,SpringBoot集成,代码无侵入,通信方式采用GRPC,性能较好,实现方式是java探针,支持告警,支持JVM监控,支持全局调用统计等等,功…

uniapp 中 引入vant组件 和 vant 报错Unclosed bracket 的问题解决

在uniapp 中引入vant组件,遇到一个报错,所以在此记录一下完整过程 一、引入vant组件 方式一:前往 GitHub官网 Vant 下载压缩文件,获取下载中的dist 文件 方式二:通过npm install 方式引入 npm i vant/weapp -S --pr…

Android Studio 找不到 uploadArchives 入口

在4.2之前版本的 Android Studio 中想要module 打包arr,上传Maven 我们只需要 在对应module的build.gradle文件顶部添加 apply plugin: maven然后每一次修改记得要修改版本号,相同版本号提交失败,是不会覆盖的 defaultConfig {......versi…

2022年12月份青少年软件编程Python等级考试试卷六级真题(含答案)

一、单选题(共25题,共50分) 1.数据文件“abc.txt”中包含若干个英文单词,如图所示: 读取文件“abc.txt”中数据的Python程序段如下: file abc.txt word_b [] for word in open(file):if word[0:1] a and len(word)>4:wo…

工具系列之wireshark使用说明

简介 工具下载: https://www.wireshark.org/官方FAQ: https://www.wireshark.org/faq.html 过滤器设置 通常情况下,将.pcap 数据拖拽至 wireshark中即可打开。通过: 导航栏–》分析 --> 显示过滤器 即可找到对应的筛选器,筛…

优维低代码实践:数据加工/转化详解

优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 优维…

自然语言处理(概念)

1、 RNN模型简介 1.2传统RNN模型 2、LSTM模型 3、GRU模型 5、注意力机制 6、人名分类器 7 、BERT 8、Transformer 的结构是什么样子的? 各个子模块有什么作用? 8.1 Encoder模块 8.2 Decoder模块 8.3 Transformer 结构中的Decoder端具体输入是什么&#…

期末复习【网络安全】

期末复习【网络安全】 前言推荐期末复习重点第1章 引言1.1 计算机安全概念 21.2 OSI安全体系结构 61.3 安全攻击 71.3.1 被动攻击1.3.2 主动攻击 第2章 对称加密和消息机密性2.1 对称加密原理 232.1.3 Feistel密码结构 25 2.2 对称分组加密算法 272.2.1 数据加密标准2.2.2 三重…

【强化学习】常用算法之一 “Q-learning”

作者主页:爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

如何看待低级爬虫与高级爬虫?

爬虫之所以分为高级和低级,主要是基于其功能、复杂性和灵活性的差异。根据我总结大概有下面几点原因: 功能和复杂性:高级爬虫通常提供更多功能和扩展性,包括处理复杂页面结构、模拟用户操作、解析和清洗数据等。它们解决了开发者…

Spring基础知识(四)

目录 1.Spring包含的模块主要有什么 2.Core Container的作用 3.Data Access/Integration模块的作用 4.AOP模块的作用 5.Spring Web模块的作用 6.Test模块的作用 7.如何将一个类声明为Bean 8.Component和Bean的区别 9.能够注入Bean的注解有什么 10.Resource注解 1.Spr…

《微服务实战》 第三十二章 微服务链路跟踪-sleuth zipkin

系列文章目录 第三十二章 微服务链路跟踪-sleuth zipkin 第三十章 分布式事务框架seata TCC模式 第二十九章 分布式事务框架seata AT模式 第十二章 Spring Cloud Alibaba Sentinel 第十一章 Spring Cloud Alibaba nacos配置中心 第十章 SpringCloud Alibaba 之 Nacos discover…