深度学习入门5——为什么神经网络可以学习?

在理解神经网络的可学习性之前,需要先从数学中的导数、数值微分、偏导数、梯度等概念入手,从而理解为什么神经网络具备学习能力。

1.数值微分的定义

先从导数出发理解什么是梯度。某一点的导数直观理解就是在该点的切线的斜率。在数学中导数表示某个瞬时的变化量,如下公式表示:

\frac{\mathrm{d}f(x)}{\mathrm{d}x}=\lim\limits_{h\to0}\frac{f(x+h)-f(x)}{h}\\

上述利用微小的差分求导数的过程称为数值微分(numerical differentiation),公式(1)表示的是前向差分(f(x+h)-f(x)),因为h无法无限趋近于0,所以存在误差(如下图所示)。为了减小这种数值微分误差,可以用中心差分(f(x+h)-f(x-h))减小误差。

2.数值微分的例子

以下面这个二次函数为例,对其数在x = 5和x = 10处进行求导。

y=0.01x^{2}+0.1x\\

import numpy as np
import matplotlib.pylab as pltdef numerical_diff(f, x):h = 1e-4 # 0.0001return (f(x+h) - f(x-h)) / (2*h)  # 中心差分def function_1(x):return 0.01*x**2 + 0.1*x def tangent_line(f, x):d = numerical_diff(f, x)print(d)  # 0.1999999999990898  0.2999999999986347y = f(x) - d*xreturn lambda t: d*t + y#该函数首先调用numerical_diff函数来计算函数f在点x处的导数d,然后根据切线的方程 y = ax + b 中的斜率和截距来计算切线的斜率d和截距y。最后返回一个匿名函数,该函数接受一个参数 t,并返回切线上在 t 处的函数值。
x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")tf1 = tangent_line(function_1, 5)  # x=5处的切线方程
tf2 = tangent_line(function_1, 10)  #  x=10处的切方程
y1 = tf1(x)
y2 = tf2(x)plt.plot(x, y)
plt.plot(x, y1)
plt.plot(x, y2)
plt.show()

3.偏导数和梯度

下式表示的是包含两个变量的函数,可以看为计算平面内点的坐标的平方和函数:

f(x_{1},x_{2})=x_{1}^{2}+x_{2}^{2}\\

求某个变量的偏导数时,需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值才能求解。下面是该函数(由全部变量的偏导数汇总而成的向量)梯度(gradient)的可视化。

4.梯度法

机器学习的主要任务是在学习时寻找最优参数,而神经网络也必须在学习时找到最优的参数(权重和偏置)。上面介绍的函数其梯度指向的是函数最小值的方向,但是在复杂函数也就是一般的情况下,梯度下降的方向不一定是指向函数最小值,因为还可能存在鞍点(极小值、局部极值)。一般来说,损失函数很复杂,参数空间庞大,不知道它在何处能取得最小值,因此可以利用梯度求最小值。梯度法中,函数的取值从当前位置沿着梯度方向前进一定距离,然后在新的地方重新求梯度,再沿着新梯度方向前进,如此反复,不断地沿梯度方向前进。通过不断地沿梯度方向前进,逐渐减小函数值的过程就是梯度法。其中寻找最小值的梯度法称为梯度下降法,寻找最大值的梯度法称为梯度上升法。一般情况下,在神经网络中主要指的是梯度下降法,要最小化损失函数,最终得到最小值处对应的神经网络的权重和偏置,此时神经网络就被训练好了

def gradient_descent(f, init_x, lr=0.01, step_num=100):x = init_xfor i in range(step_num):grad = numerical_gradient(f, x)x -= lr * gradreturn xdef function_2(x):return x[0]**2 + x[1]**2init_x = np.array([-3.0, 4.0])
gradient_descent(function_2, init_x=init_x, lr=0.1, step_num=100)  # 得到损失函数最小值对应的坐标点(0, 0),array([ -6.11110793e-10, 8.14814391e-10])

f是要进行最优化的函数,,init_x是初始值,lr是学习率learning rate,step_num是梯度法的重复次数。在上面的例子中,学习率设置为0.1。学习率设置的过大或过小对于损失函数的收敛都不利,因此选取合适的学习率也是神经网络超参数的一个重要部分。与神经网络的权重和偏置不同,学习率需要人为设定。如何理解学习率过大过小对损失函数收敛的影响呢?现在我们将损失函数想象成一口大铁锅,锅底的位置就是损失函数达到最小值的地方。当学习率设置的过小时,此时可以看成是放了一只小蚂蚁在锅的外边缘,步子很小,它需要走很多步才能走到底部,耗时长且效率慢,而且有可能陷入“局部最优”。而学习率过大则可以想象成是跳蚤,它每次向前运动的幅度很大,仅略小于锅的尺寸,它会在锅的侧壁来回弹跳,而到达不了锅底。

5.神经网络的梯度

神经网络在学习的过程中也要进行梯度的计算。以一个只有一个形状为2 × 3的权重W的神经网络为例,它的损失函数用L表示,那么梯度

\frac{\partial L}{\partial W}\\

可表示为如下:

\begin{gathered} \boldsymbol{W} \left.=\left(\begin{array}{ccc}w_{11}&w_{12}&w_{13}\\w_{21}&w_{22}&w_{23}\end{array}\right.\right) \\ \begin{aligned}\frac{\partial L}{\partial\boldsymbol{W}}\end{aligned} \left.=\left(\begin{array}{ccc}\frac{\partial L}{\partial w_{11}}&\frac{\partial L}{\partial w_{12}}&\frac{\partial L}{\partial w_{13}}\\\frac{\partial L}{\partial w_{21}}&\frac{\partial L}{\partial w_{22}}&\frac{\partial L}{\partial w_{23}}\end{array}\right.\right)  \end{gathered} \\

求梯度代码实现:

import sys, os
import numpy as npdef 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_sizedef 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 gradclass simpleNet:def __init__(self):self.W = np.random.randn(2,3)def predict(self, x):return np.dot(x, self.W)def loss(self, x, t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y, t)return lossx = np.array([0.6, 0.9])
t = np.array([0, 0, 1])net = simpleNet()f = lambda w: net.loss(x, t)
dW = numerical_gradient(f, net.W)print(dW)

结果:

6.神经网络学习的实现流程

完整实现参见《深度学习入门:基于python的理论与实现》第四章第五节的内容。以上是神经网路学习的所有基本概念,包括“mini-batch”、“梯度”、“梯度下降法”等概念。神经网络的学习过程为:

前提:训练数据是均匀的,即是被shuffle(打乱)过的。其次神经网络已经存在较为合适的权重和偏置。

step1:按照mini-batch的方法从训练数据中随机选出一部分数据进行训练。

step2:计算各个权重参数的梯度,梯度表示函数值减小最多的方向。

step3:将权重参数沿梯度方向进行微小更新(lr,学习率)。

step4:重复 step1、step2、step3。

上面使用的数据时从原始数据中随机选择的mini-batch数据,所以又称之为随机梯度下降法(stochastic gradient descent),即对随机选择的数据进行的梯度下降法。在很多深度学习框架中,其一般由一个名为SGD的函数进行实现。为了保证所有的训练数据都被使用,一般做法是事先将所有训练数据随机打乱,然后按指定的批次大小按序生成mini-batch。这样每个mini-batch均有一个索引号,然后用索引号可以遍历所有的mini-batch。遍历一次所有数据,就称为一个epoch

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

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

相关文章

c#一个udp代码

不使用socket进行 unity下的 private Thread connectThread;private UdpClient udpClient;public Queue LogQueue new Queue();public static UDPManager Instance{get;private set;}private void Awake(){Instance this;}private void Start(){udpClient new UdpClient();…

dolphinscheduler独立集群部署文档(海豚调度)

一、下载解压 服务器内下载(华为云镜像站网址): wget https://mirrors.huaweicloud.com/apache/dolphinscheduler/3.2.0/apache-dolphinscheduler-3.2.0-bin.tar.gz解压:tar -xvf apache-dolphinscheduler-3.2.0-bin.tar.gz 改名…

05-对混合app应用中的元素进行定位

本文介绍对于混合app应用中的元素如何进行定位。 一、app的类型 1)Native App(原生应用) 原生应用是指利用Android、IOS平台官方的开发语言、开发类库、工具等进行开发的app应用,在应用性能和交互体验上应该是最好的。 通俗点来…

Win10录屏,3种方法,快速搞定

在数字化时代,录屏功能已经成为了我们日常生活和工作中不可或缺的一部分。无论是为了制作教学视频,还是为了记录游戏的高光时刻,还是为了保存开会内容,录屏功能都能为我们提供极大的便利。Win10操作系统作为微软推出的经典之作&am…

在k8s中部署Elasticsearch高可用集群详细教程

🐇明明跟你说过:个人主页 🏅个人专栏:《洞察之眼:ELK监控与可视化》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Elasticsearch简介 2、为什么在k8s中部署elasti…

Redis 6.0新特性详解

Redis 6.0新特性主要有3个:多线程、Client Side Cache、Acls。下面详细说明一下。 1.多线程 redis 6.0 提供了多线程的支持,redis 6 以前的版本,严格来说也是多线程,只不过执行用户命令的请求时单线程模型,还有一些线…

鸿蒙HarmonyOS实战:状态管理和传值

状态管理 State State是一个装饰器,是用来存放数据的,比较好理解 由State的数据来进行状态驱动视图更新 代码很简单 State count: number 0; 需要注意的是State初始化的数据必须赋值 这里我们讨论简单用法,至于复杂的用法可以到项目中介绍…

python通过COM接口调用CANoe工具实现相关操作以及使用API接口跑CAPL的自动化脚本

使用Python来操作CANoe(一个用于汽车总线系统设计、分析、仿真和测试的强大工具),你可以借助win32com库来实现。这涉及到使用COM接口来控制CANoe。以下是一个示例,演示了如何使用Python通过win32com库来操作CANoe。 一、前提条件…

RAG 流程及论文串烧

文档切片 文档切片的五个层次 https://medium.com/anuragmishra_27746/five-levels-of-chunking-strategies-in-rag-notes-from-gregs-video-7b735895694d#b123 Basic RAG 与 Advanced RAG https://pub.towardsai.net/advanced-rag-techniques-an-illustrated-overview-04d…

TTS前端原理学习 chatgpt生成答案

第一篇文章学习 小绿鲸阅读器 通篇使用chatgpt生成答案 文章: https://arxiv.org/pdf/2012.15404 1. 文章概述 本文提出了一种基于Distilled BERT模型的统一普通话文本到语音前端模块。该模型通过预训练的中文BERT作为文本编码器,并采用多任务学习技术…

在数据分析中,对缺失值解决方案的分析

1. 删除缺失值 使用dropna函数来删除空值,具体用法如下 # 函数用法 df.dropna( axis0, howany, inplaceTrue, subset[列名,...], thresh10 ) ​ df.drop() # 按列删除 dropna函数参数解释 axis0 可选参数 ,默认为0按行删 0, or inde…

Python学习笔记14:进阶篇(三)。类的终结篇,类的导入和模块的导入。

前言 这篇文章属于类知识的最后一篇,带一点点其他知识,学习内容来自于Python crash course。 关注我私信发送Python crash course,分享一份中文版PDF。 类的导入 在学习的时候,包括之前,我都是在一个文件中把所有代…

免费域名第二弹:手把手教你获取个性化免费域名并托管至Cloudflare

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 免费申请域名的方法 📒📝 注册账号📝 创建免费域名📝 将域名添加到 Cloudflare⚓️ 相关链接 ⚓️📖 介绍 📖 在如今的数字时代,拥有一个个性化的域名已经成为越来越多人的需求。无论是建立个人博客、项目展示,还…

基于springboot的人口老龄化社区服务与管理平台源码数据库

随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了人口老龄化社区服务与管理平台的开发全过程。通过分析人口老龄化社区服务与管理平台方面的不足,创建了一个计算机管理人口老龄化社区服务与管理平台的方案…

鸿蒙开发通信与连接:【@ohos.connectedTag (有源标签)】

有源标签 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import connectedTag from ohos.connectedTag;connectedTag.init init(): boolean 初始化有源标签芯片。 需要权限&#…

python-docx 遍历文档

python-docx 遍历文档 遍历段落和表格(顶级)获取段落中的图片参考资料 遍历段落和表格(顶级) 只有业务场景中需要严格按照word文档中段落和表格的顺序遍历时才使用这个方案。 否则直接遍历下面这几个更方便: 段落&…

前端开发之浏览器安全

浏览器安全涉及多方面的威胁与防护,其中XSS(跨站脚本攻击)与CSRF(跨站请求伪造)是最常见的两类安全问题,而中间人攻击与网络劫持也是不容忽视的安全隐患。下面是对这些安全问题的深入分析与防护策略的总结。…

常用损失函数详解:广泛使用的优化约束方法

各类常用损失函数详解:广泛使用的优化约束方法 今天介绍下损失函数,先介绍下我常用的方法SmoothedL1,它是一个平滑的L1 penalty函数,用于处理约束violation。 标准的L1 penalty函数定义为: L 1 ( x ) { 0 , if x ≤ 0 x , if x > 0 …

MySQL经典面试题:谈一谈你对事务的理解

文章目录 📑事务事务的基本概念回滚开启事务的sql语句 事务的基本特性总结一下涉及到的三个问题 ☁️结语 📑事务 事务的基本概念 事务是用来解决一类特定场景的问题的,在有些场景中,完成某个操作,需要多个sql配合完…

解决header加了固定定位以后,原来页面的锚点链接位置不准确的问题

在网页设计中&#xff0c;当头部&#xff08;header&#xff09;使用了固定定位&#xff08;CSS中的position: fixed;&#xff09;&#xff0c;它将脱离文档流并且固定在视口的顶部或指定位置。这可能导致页面上的锚点链接&#xff08;使用<a href"#id">形式&a…