【深度学习】日常笔记7

news2024/11/24 8:28:52

可以通过在⽹络中加⼊⼀个或多个隐藏层来克服线性模型的限制,使其能处理更普遍的函数关系类型。要做到这⼀点,最简单的⽅法是将许多全连接层堆叠在⼀起。每⼀层都输出到上⾯的层,直到⽣成最后的输出。

上面红框的公式其实换个角度是没错的。实际上,XW和b都是矩阵,所以它们符合矩阵加法规则。具体来说,假设X是一个n×d的矩阵,W是一个d×h的矩阵,b是一个1×h的行向量,那么XW是一个n×h的矩阵,b也可以被扩展为一个n×h的矩阵,使得在矩阵加法时可以直接与XW相加。这种扩展b的方法叫做广播(broadcasting),在深度学习中经常用到。

举个例子,假设X是一个2×3的矩阵:

X = [[1, 2, 3],

     [4, 5, 6]]

W是一个3×2的矩阵:

W = [[0.1, 0.2],

     [0.3, 0.4],

     [0.5, 0.6]]

b是一个1×2的行向量:

b = [0.5, 0.7]

那么XW的结果是一个2×2的矩阵:

XW = [[3.2, 4.3],

      [9.8, 12.9]]

现在我们需要把b扩展成一个2×2的矩阵,才能将其与XW相加。具体来说,我们需要让b在第一维(即行)上重复2次,在第二维(即列)上不变。这可以使用NumPy库中的np.newaxis和np.repeat函数实现:

import numpy as np

b = b[np.newaxis, :]  # b变为1x2的矩阵

b = np.repeat(b, 2, axis=0)  # 在第一维上重复2次,变为2x2的矩阵

现在b是一个2×2的矩阵:

b = [[0.5, 0.7],

     [0.5, 0.7]]

最后,我们将XW和b相加,得到:

XW + b = [[3.7, 5.0],

          [10.3, 13.6]]

这就是广播的过程。在深度学习中,如果两个矩阵不满足加法规则,那么就可以利用广播来扩展其中一个矩阵,使得它们可以相加。

如果仿射函数本来就是类似XW+b的话,无论多少层这样的仿射函数的符合叠加都是等价于直接的一层线性仿射函数,这样并没有为模型引入新的表示能力。

多层感知机(Multilayer Perceptron,MLP)的结构可以看作是数学中的复合函数。每个隐藏层都可以看作是输入经过仿射变换(线性函数)和激活函数组合而成的函数,而输出层又是对隐藏层输出进行类似的组合。

在多层感知机中,输入信号经过第一层隐藏层的仿射变换和激活函数得到隐藏层的输出,然后该输出又作为下一层隐藏层的输入,以此类推直到最后一个隐藏层。最后一个隐藏层的输出再经过仿射变换和激活函数得到最终的输出结果。

这种堆叠隐藏层的方式使得多层感知机能够逐渐提取输入数据的抽象特征,从而增强模型的表达能力。类似于复合函数,每一层隐藏单元的输出都会作为下一层隐藏单元的输入,通过多层的组合运算,模型能够学习更加复杂和高级的表示。

因此,可以将多层感知机视为一个复合函数,其中每一层隐藏层都相当于复合函数中的一个函数,整个模型的参数通过梯度下降等方法来优化,以使得模型能够捕捉到输入数据中的有效模式和关系。

单隐层网络确实可以理论上表示和学习任何函数,这被称为"万能逼近定理"。然而,在实际应用中,使用更深的网络(多个隐藏层)通常更具优势。

虽然单隐层网络有能力表示任意函数,但它可能需要大量的神经元才能实现复杂函数的逼近。而使用更深的网络结构,可以以更高效的方式逼近复杂函数。多层网络并不一定需要比单层网络使用更少的神经元。

事实上,在某些情况下,多层网络可能需要更多的神经元来处理复杂的函数逼近任务。深层网络之所以能够更好地逼近复杂函数,是因为它可以通过多个非线性变换来建立更高级别的表征和抽象。然而,每个隐藏层都需要足够数量的神经元来有效地表示和处理数据。在实践中,神经网络的层数和每层神经元的数量通常是根据问题的复杂性和规模进行调整的。对于简单的问题,单隐层网络可能足够,而对于更复杂的问题,需要更深的网络结构,并且可能需要更多的神经元来确保网络的表达能力。

因此,并不能简单地说多层网络就比单层网络使用更少的神经元,而是要根据具体问题和任务的需求来确定合适的网络结构和参数设置。深层网络可以通过一系列非线性变换来提取多层次的抽象特征,从而更好地捕捉数据的复杂性。

此外,深层网络还具有梯度传播更容易、参数共享和重复模式的利用等优点,这些都有助于提高网络的训练效率和性能。

在实践中,通常会选择使用更深的网络来解决复杂问题,而不是仅限于单隐层网络。

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活,它们将输⼊信号 转换为输出的可微运算。⼤多数激活函数都是⾮线性的。

ReLU的优点:它求导表现得特别好:要么让参数消失,要么让参数通过。这使得优化表现得更好,并且ReLU减轻了困扰以往神经络的梯度消失问题。

报错RuntimeError: grad can be implicitly created only for scalar outputs

这个报错是因为 torch.relu(x) 返回的 y 是一个张量,而不是一个标量。在使用 backward() 方法计算梯度时,该方法只适用于标量输出。

解决方法是将 y 转换为标量,可以使用聚合操作(如求和、平均值等)来实现。例如,可以使用 torch.sum() 对 y 进行求和操作,然后再调用 backward() 方法。

接着我发现下面的z.backward()y.backward(torch.ones_like(x))其实效果是等价的。

%matplotlib inline

import torch

import matplotlib.pyplot as plt

from d2l import torch as d2l

x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)

y = torch.relu(x)

d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize=(5, 2.5))

z = torch.sum(y)

z.backward()  # 效果等价于y.backward(torch.ones_like(x))

d2l.plot(x.detach(), x.grad, 'x', 'grad of relu', figsize=(5, 2.5))

为什么会等价呢?

对于 y.backward(torch.ones_like(x)) 这种写法。

实际上,torch.ones_like(x) 返回的是一个与张量 x 具有相同形状的张量,其中所有元素的值都为 1。在反向传播过程中,torch.ones_like(x) 会被作为梯度权重使用。

具体来说,当调用 y.backward(torch.ones_like(x)) 时,PyTorch会计算关于 y 的梯度,并将这些梯度累积到 x 上。torch.ones_like(x) 的作用是为每个与 x 对应的梯度指定一个权重值,这个权重值是1。通过将这些相等的权重值传递给 backward(),PyTorch 将这些权重与梯度相乘并进行累积计算,从而得到最终的梯度值。

在调用 z.backward() 时,PyTorch会自动计算关于 z 的梯度,并将这些梯度通过计算图向后传播并累积到所有涉及到的叶子节点上,也就是 x。

因此,z.backward() 和 y.backward(torch.ones_like(x)) 的效果是一致的,它们都会计算出关于 x 的梯度。

当调用 z.backward() 时,PyTorch会自动计算关于变量 z 的梯度,并将这些梯度向后传播到所有涉及到的变量(包括向量)上。反向传播就是为了计算每个变量对最终输出的影响程度。

在这种情况下,我们有一个向量 x 和一个向量 y,其中 y 是通过对 x 进行一些操作得到的,这里是使用修正线性单元函数。现在我们想知道对于每个 x 中的元素,它们对最终输出 y 中的对应元素的影响有多大。

通过调用 z.backward(),我们可以得到关于 z 的梯度,并且这些梯度会根据链式法则自动传播回 x。这意味着我们可以获得 ∂z/∂x,即对于 x 中的每个元素,它们对 z 中的对应元素的影响程度。由于 z 是通过对 y 中的元素求和得到的,所以 ∂z/∂x 等于 ∂y/∂x。

嗯…感觉越解释越有点乱,最好还是自己动手跑跑看()

Sigmoid函数是一种常用的激活函数,通常用于二分类问题,将输入的实数映射到一个范围在0到1之间的概率值。它的输出只针对单个输入进行转换。

Softmax函数则是一种多分类问题的激活函数,它将一组实数作为输入,并将它们转换为概率值,使得所有输出的概率之和等于1。Softmax函数适用于具有多个类别的分类问题,可以将每个类别的概率分布表示出来。

当Softmax函数应用于二分类问题时,它会输出两个类别的概率分布,其和为1。而Sigmoid函数会将输入映射到一个范围在0到1之间的单一概率值,表示某个样本属于正例的概率。

因此,Softmax函数在二分类问题中并不能直接得到与Sigmoid函数相同的输出结果。如果只关注两个类别中的一个,可以使用Softmax函数的一个输出值作为正例的概率,并用1减去该值得到负例的概率。

常用激活函数↓

ReLu函数:

函数图像如下:

ReLu函数的导数图像如下,注意在x=0时,ReLu极限不存在,这里默认使用左侧的导数0:

sigmoid函数:

sigmoid函数图像如下:

sigmoid函数的导数图像如下:

tanh函数:

tanh函数图像如下:

tanh函数的导数图像如下,注意在x=0时,ReLu极限不存在,这里默认使用左侧的导数0:

p137习题:

1. 计算pReLU激活函数的导数。

答:

首先pReLU(Parametric ReLU)是一种带参数的修正线性单元激活函数,它的公式如下:

pReLU(x) = max(0, x) + α min(0, x).

其中,α为一个可学习的参数。

现在来计算pReLU函数的导数:

当x > 0时,pReLU(x) = x,此时导数为1。

当x < 0时,pReLU(x) = αx,此时导数为α。

当x = 0时,pReLU(x) = max(0, x)

当x > 0时,pReLU(x) = x

当x < 0时,pReLU(x) = αx

我们可以计算一下在x=0附近的极限:

lim(x->0+) (pReLU(x) - pReLU(0)) / x, lim(x->0+) (x - 0) / x = 1

lim(x->0-) (pReLU(x) - pReLU(0)) / x, lim(x->0-) (αx - 0) / x = α

那α为1就说明在0处可导了

综上所述,pReLU函数的导数可以表示为:

pReLU'(x) = 1, if x > 0

pReLU'(x) = α, if x < 0

x=0的话,看α的情况,如果为1则可导,不为1则不可导

在实际应用中,通常会对导数进行近似处理,比如取左导数或右导数来代替。

2. 证明⼀个仅使⽤ReLU(或pReLU)的多层感知机构造了⼀个连续的分段线性函数。

答:

连续的分段线性函数是指在定义域上具有多个线性段的函数,且在每个线性段上都是连续的。

下面是对于ReLU函数的证明,pReLU函数的证明过程类似。

首先,我们知道ReLU函数定义为:

ReLU(x) = max(0, x)

ReLU函数有以下性质:

对于x < 0,ReLU(x) = 0,该部分的函数图像为一条水平直线;

对于x > 0,ReLU(x) = x,该部分的函数图像为一条斜率为1且通过原点的直线;

在x=0处,ReLU(0) = 0,即函数图像在原点取值为0。

现在考虑一个多层感知机,每一层都只采用ReLU激活函数。假设这个多层感知机有L层,每一层的输出作为下一层的输入,最后一层输出为f(x)。

由于ReLU函数的性质,我们可以得出结论:

在每一层的节点中,所有输入小于0的神经元将激活为零,相当于去掉了那些非零斜率的部分,并保持输出为零;

所有输入大于等于0的神经元将保留其输出值,并传递给下一层。

因此,整个多层感知机实际上是将输入空间划分为一系列超平面的组合。每个ReLU激活函数在相应的超平面上决定输出值。

由于每一层都使用ReLU激活函数,整个多层感知机构成了一系列连续的分段线性函数,其特点是在不同的区域内具有线性性质,通过阈值划分输出值。

所以,一个仅使用ReLU(或pReLU)的多层感知机可以构造一个连续的分段线性函数。

请注意,以上证明是基于ReLU函数的情况,对于pReLU函数也可以进行类似的证明,只是在x < 0部分的线性函数会有斜率α而不是零。

ps:超平面是高维空间中的一个概念。在二维空间中,可以将超平面理解为一条无限延伸的直线。在三维空间中,超平面即是一个二维平面。更一般地,在n维空间中,超平面是一个n-1维的子空间,它将整个空间分割成两个互补的部分。超平面在机器学习和模式识别领域中经常被使用,特别是在分类问题中。通过训练数据,我们可以找到一个超平面,将不同类别的数据样本分隔开。在高维空间中,这个超平面变成了一个用于划分不同类别的决策边界。

另解:

假设我们有一个两层的多层感知机,每一层只有一个神经元。对于输入x,我们的网络可以表示为:

y = f(w2 * f(w1 * x + b1) + b2)

其中,f是ReLU(或pReLU)函数,w1和w2是权重,b1和b2是偏置。

我们可以将其展开为:

h1 = w1 * x + b1

h2 = f(h1)

y = w2 * h2 + b2

这里,h1是第一层的线性变换输出,h2是激活函数ReLU(或pReLU)作用后的输出,y是最终的输出。

现在我们来观察这个网络的行为。ReLU(或pReLU)函数的性质是:如果输入大于0,则保持输入不变,如果输入小于等于0,则将输入变为0。

根据这一性质,我们可以得出以下结论:

当h1 > 0时,h2 = f(h1) = h1 (ReLU函数保持输入不变)

当h1 ≤ 0时,h2 = f(h1) = 0 (ReLU函数将输入变为0)

因此,在不同的区间上,我们可以看到h2与h1线性相关,

在连接处并没有保持严格的连续性。

在每个线性段上,ReLU(或pReLU)函数会将输入划分为两个区域:当输入大于零时,输出与输入成比例;当输入小于等于零时,输出为零。

具体来说,在第一层的线性变换中,h1 = w1 * x + b1,表示输入与权重的线性组合。这样的线性变换将输入空间划分为两个区域:一部分是使h1大于零的输入值,一部分是使h1小于等于零的输入值。

然后,对h1应用ReLU(或pReLU)函数,我们得到h2。在连接处,从小于等于零的区域过渡到大于零的区域时,h2会从零逐渐增加,因此在连接处并不是严格的连续性。但是,在每个线性段内部,都是连续的,也就是说,对于每个线性段,输出在该段上是连续的。

最终,我们还需要对h2进行第二个线性变换,得到输出y。这个线性变换可以写作y = w2 * h2 + b2。这个公式代表了h2与最终输出y之间的线性关系。所以,整个网络可以看作是通过一系列线性变换和ReLU(或pReLU)操作的组合来构建一个连续的分段线性函数。每个线性段内部都是连续的,但在连接处并不是严格的连续性。

总体而言,我们的输出y是由h2通过一个线性变换加上偏置得到的。因此,我们可以得出结论:一个仅使用ReLU(或pReLU)的两层多层感知机构造了一个连续的分段线性函数。

3. 证明tanh(x) + 1 = 2 sigmoid(2x)

tanh(x) = (1-exp(-2x)) /(1+exp(-2x))

sigmoid(x) = 1 / (1 + exp(-x))

答:

首先,我们计算左边的表达式 tanh(x) + 1:

tanh(x) + 1 = (1 - exp(-2x)) / (1 + exp(-2x)) + 1

= (1 - exp(-2x) + 1 + exp(-2x))/(1 + exp(-2x))

= 2 / (1 + exp(-2x))

接下来,我们计算右边的表达式 2 sigmoid(2x):

2 sigmoid(2x) = 2 * (1 / (1 + exp(-2x)))

= 2 / (1 + exp(-2x))

结果显而易见了。

4. 假设我们有⼀个⾮线性单元,将它⼀次应⽤于⼀个⼩批量的数据。这会导致什么样的问题?

答:应用一个非线性单元一次于一个小批量的数据可能会导致以下问题:

维度不匹配:如果小批量中的数据在维度上不一致,即特征数量不同,那么应用非线性单元可能会导致维度不匹配的错误。

梯度失踪或爆炸:非线性函数在某些区域可能具有非常小的梯度,这可以导致梯度消失的问题。相反,非线性函数在某些情况下也可能具有非常大的梯度,导致梯度爆炸的问题。这会影响反向传播算法的稳定性和收敛速度。

过拟合:如果非线性单元具有足够的模型参数,它可能会过度拟合训练数据,导致模型在新样本上的泛化能力下降。

运算量增加:非线性单元通常比线性单元计算量更大,因为它们涉及到复杂的数学运算,如指数、对数等。对于大规模的数据集和复杂的神经网络结构,这可能会导致计算资源需求增加。

要解决这些问题,可以采取一些措施,如使用合适的激活函数、初始化权重参数、正则化技术、批量归一化等,以提高模型的性能和稳定性。

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

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

相关文章

总结911

目标规划&#xff1a; 月目标&#xff1a;6月&#xff08;线性代数强化9讲&#xff0c;考研核心词过三遍&#xff09; 周目标&#xff1a;线性代数强化5讲&#xff0c;英语背3篇文章并回诵&#xff0c;检测 每日规划 今日已做 1.回诵之前文章 2.每日长难句&#xff0c;句句…

Redis五种数据结构底层编码结构

String String是Redis中最常见的数据存储类型&#xff1a; 其基本编码方式是RAW&#xff0c;基于简单动态字符串&#xff08;SDS&#xff09;实现&#xff0c;存储上限为512mb。如果存储的SDS长度小于44字节&#xff0c;则会采用EMBSTR编码&#xff0c;此时object head与SDS是…

Mysql(Linux数据库或者在Navicate中)

Mysql数据库组成 服务端:主要存储数据,并接收用户发过来的SQL语句,并执行结果返回给客户端 客户端:下发用户要执行的sql语句,并显示服务器返回的执行结果 命令行数据库连接方式 mysql -h 数据库 IP -P 端口号 -u 数据库登录用户名 -p 数据库登录密码 -h不加表示为本机,-P不…

编译原理一:编译器工作流

文章目录 1. 编译器工作流1.1. 解析&#xff08;Parsing&#xff09;1.2. 遍历&#xff08;Traversal&#xff09;1.3 转换(Transformation)1.4 代码生成(Code Generation) 1. 编译器工作流 编译器是将一种语言转化为另一种语言的程序。在编译器工作流中&#xff0c;通常可以分…

git上传云效codeup

为了标识身份&#xff0c;建议先完成 Git 全局设置 git config --global user.name "xxx" git config --global user.email "xxxxxxqq.com" 1.删除本地 .git文件夹 2.云效上 添加库-新建代码库 3.在 git bash 里 按照 建好的代码库 下方的 命令行指引-…

chatgpt赋能python:Python编译成二进制文件:优化代码执行效率

Python编译成二进制文件&#xff1a;优化代码执行效率 介绍 随着Python编程的不断普及&#xff0c;越来越多的开发者选择Python作为开发工具。然而&#xff0c;Python解释器需要读取并解释源代码&#xff0c;这种解释方式在执行效率上存在瓶颈。为了提高执行效率&#xff0c;…

io.netty学习(十三)Netty 解码器

目录 前言 编解码概述 编解码器概述 Netty 内嵌的编码器 解码器 ByteToMessageDecoder 抽象类 ReplayingDecoder 抽象类 MessageToMessageDecoder 抽象类 总结 前言 编码和解码&#xff1a;数据从一种特定协议格式到另一种格式的转换。 处理编码和解码的程序通常被称…

【VulnHub系列】BrokenGallery

因为是从PDF转换过来偶尔可能会出现内容缺少&#xff0c;可以看原版PDF&#xff1a;有道云笔记 实验信息 Broken&#xff1a;192.168.10.111 Kali&#xff1a;192.168.10.106 实验过程 sudo arp-scan --interface eth0 192.168.10.1/24 然后对靶机进行端口探测 nmap -sT -…

定积分的应用—所围图形的面积、绕轴旋转所围成立体的体积、旋转曲面的面积、弧长

本篇本章&#xff0c;将从几个简单的例子带大家分析总结定积分的应用中常用的方法和思想&#xff0c;一起学习进入定积分的世界&#x1f61c;&#x1f61c; 一、求所围图形的面积 1.求由抛物线 y x 2 与 y 2 − x 2 所 围 图 形 的 面 积 yx^2与y2-x^2所围图形的面积 yx2与y2…

Windows下Android studio 搭建 android NDK 搭建 OLLVM 踩坑记录

1. 编译 ollvm-9.0.1 下载源码进行编译 https://github.com/heroims/obfuscator/tree/llvm-9.0.1 编译 这里有坑要注意 不能使用最新的 mingw 8.0.1 编译会报错 报错内容如下: PS D:\OLLVM\obfuscator-llvm-9.0.1\build> cmake -G "MinGW Makefiles" -DCMA…

浏览器 HTTPS 协议的相关知识点有哪些?

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言HTTPS协议的概念HT…

腾讯云私有云平台运维面试

文章目录 概述JD 岗位描述一面二面三面HR面 概述 根据会议将面试问题进行总结&#xff0c;很多问题感觉当时没回答好&#xff0c;这是为啥呢&#xff1f;应该还是不熟练吧&#xff0c;或者不善于表达。将次经历分享出来&#xff0c;大家多练练。 JD 岗位描述 私有云平台运维…

io.netty学习(十四)Netty 编码器

目录 前言 MessageToByteEncoder 抽象类 MessageToMessageEncoder 抽象类 总结 前言 上一篇我们讲解了解码器的相关知识&#xff0c;其中也提到了编码器的定义。 编码器就是用来把出站&#xff08;针对本身来讲&#xff0c;发送都是出站&#xff0c;接收都是入站&#xf…

TIA博途_字符转换为字符串以及截取字符串有效字符的具体方法示例

TIA博途_字符转换为字符串以及截取字符串有效字符的具体方法示例 情景再现: 在做某些通信相关的项目时,可能会遇到通信接收到的字符串是以字节的形式传送过来的字符,此时就需要我们对接收到的这些字符进行处理,从而获取我们实际需要的字符或字符串。 如下图所示,打开博途…

一文了解什么是Dubbo

Dubbo学习 Dubbo应用架构的演变RPC&#xff08;远程过程调用&#xff09;RPC介绍RPC组件RPC调用 Apache Dubbo概述Dubbo简介Dubbo的架构 服务注册中心ZookeeperZookeeper介绍运行zookeeper Dubbo的快速开发Dubbo管理控制台治理中心 Dubbo Dubbo是一个分布式服务框架&#xff0…

基于Servlet+JDBC实现的基础博客系统>>系列3 -- Servlet后端服务器搭建

目录 前言 1. 前期准备 2. Model层 2.1 数据库的设计 2.2 数据库表对应的实体类实现 User类 Blog类 2.3 JDBC 工具类实现 2.4 UserDao 的实现 2.5 BlogDao 的实现 3. Controller 层实现 3.1 博客列表页 3.1.1 约定前后端交互接口 3.1.2 编写后端代码 3.1.3 编写…

【Shell1】shell语法,ssh/build/scp/upgrade,环境变量

文章目录 1.shell语法&#xff1a;shell是用C语言编写的程序&#xff0c;是用户使用Linux的桥梁&#xff0c;硬件>内核(os)>shell>文件系统1.1 变量&#xff1a;readonly定义只读变量&#xff0c;unset删除变量1.2 函数&#xff1a;shell脚本传递的参数中包含空格&…

聊天GPT如何运作?| 景联文科技

什么是聊天 GPT&#xff1f; Chat GPT 被定义为一种生成语言模型。在实践中&#xff0c;它被理解为经过训练和设计以进行自然对话的人工智能聊天。 聊天 GPT 的用途是什么&#xff1f; 1.借助 GPT&#xff0c;您可以生成各种风格、主题和语言的连贯且写得很好的文本。此外&a…

【比赛writeup】2023省赛-Reverse-Re2

2023省赛-Reverse-Re2 一、概要 1、标题&#xff1a;Re2 2、关键字&#xff1a;换表BASE64 3、比赛&#xff1a;2023省赛 4、工具&#xff1a;IDAx64、python 二、开始 1、题目分析 逆向的题目&#xff0c;找到关键字符串&#xff0c;找到关键函数&#xff0c;分析函数逻辑…