当前位置:   article > 正文

【动手学深度学习】 2预备知识_y.sum().backward()

y.sum().backward()

李沫《动手学习深度学习》课程学习

需要预备的知识原因重点
线性代数处理表格数据矩阵运算
微积分决定以何种方式调整参数

损失函数(loss function)—— 衡量“模型有多糟糕”这个问题的分数

梯度(gradient)—— 连结一个多元函数对其所有变量的偏导数,简单理解就是求导

概率在不确定的情况下进行严格的推断

目录

2.1. 数据操作——张量

2.1.1. 入门

2.1.2. 运算符

2.1.3. 广播机制

 2.1.4. 索引和切片

2.1.5. 节省内存

2.1.6. 转换为其他Python对象

2.1.8. 练习

2.2. 数据预处理

2.3. 线性代数

2.3.1. 标量

2.3.2. 向量

2.3.3. 矩阵

2.3.4. 降维

2.3.4.1. 非降维求和——轴数不变

 2.3.5. 练习​编辑

2.4. 微积分

2.5. 自动微分

2.6. 概率


2.1. 数据操作——张量

一个名词——张量(tensor),指n维数组,其中具有一个轴的张量对应数学上的向量(vector); 具有两个轴的张量对应数学上的矩阵(matrix)

多维张量的几何理解 - 简书 (jianshu.com)

张量的几何理解

2.1.1. 入门

库名:torch

pytorch中基本的数值计算、张量创建
函数名作用例子例子意义结果
arange()创建行向量torch.arange(12)创建了一个包含以0开始的前12个整数的行向量
tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
zeros()设置张量所有元素均为0torch.zeros(2,3,4)创建一个形状为(2,3,4)的张量,其中所有元素都设置为0

ones()设置张量所有元素均为1torch.ones(2,3,4)创建一个形状为(2,3,4)的张量,其中所有元素都设置为1
randn()随机初始化张量中参数的值torch.randn(3,4)形状为(3,4)的张量。 其中的每个元素都从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样。
tensor()提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值。 在这里,最外层的列表对应于轴0,内层的列表对应于轴1。torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])指定张量
张量属性,设x=tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
函数名作用例子结果
shape访问张量(沿每个轴的长度)的形状x.shape
torch.Size([12])
size()访问张量(沿每个轴的长度)的形状x.size()
torch.Size([12])
numel()张量中元素的总数x.numel()
12
reshape()改变一个张量的形状而不改变元素数量和元素值x.reshape(3,4)

 
3维张量的张量属性实例
注:len()函数二维张量时结果与numel()函数相同,三维就不同了

2.1.2. 运算符

——按元素(elementwise)运算

对于任意具有相同形状的张量, 常见的标准算术运算符(+-*/**)都可以被升级为按元素运算。 我们可以在同一形状的任意两个张量上调用按元素操作。

运算函数(部分不用再导入包)
程序中运算函数意义
+
-
*
/
**
torch.exp(input)

x.sum()

x指一个张量

对张量中的所有元素进行求和,会产生一个单元素张量

torch.cat(tensons,dim=0/1)

例如:torch.cat((x,y),dim=0),torch.cat((x,y),dim=1)

x,y均为(3,4)的张量

张量连结(concatenate)

dim指张量连接的维度

torch.cat 张量连结补充

名词解释:把给定张量端对端地叠起来形成一个更大的张量。 

torch.cat 张量连结例子

 上面的例子分别演示了当沿行(轴-0,形状的第一个元素) 和按列(轴-1,形状的第二个元素)连结两个矩阵时,会发生什么情况。 可以看到,第一个输出张量的轴-0长度(6)是两个输入张量轴-0长度的总和(3+3); 第二个输出张量的轴-1长度(8)是两个输入张量轴-1长度的总和(4+4)

2.1.3. 广播机制

——形状不同的张量通过调用 广播机制(broadcasting mechanism)来执行按元素操作。

广播机制工作方式:复制元素拓展数组,使两个张量具有相同的形状。

拓展方法:在大多数情况下,我们将沿着数组中长度为1的轴进行广播。

例子:ab分别是3×1和1×2矩阵,如果让它们相加,它们的形状不匹配。 我们将两个矩阵广播为一个更大的3×2矩阵,如下所示:矩阵a将复制列, 矩阵b将复制行,然后再按元素相加。

广播机制实例

 2.1.4. 索引和切片

 ——第一个元素的索引是0,最后一个元素索引是-1

索引、切片例子,X是一个tensor
例子意义
X[-1]选择最后一个元素
X[1:3]选择第二个和第三个元素
X[0:2,:]访问第1行和第2行,其中“:”代表沿轴1(列)的所有元素。

2.1.5. 节省内存

低层逻辑:运行一些操作可能会导致为新结果分配内存,机器学习运算量巨大,会导致内存不断被更新占用。

现实意义:节省内存,更重要的是防止需要引用最新值时由于一些问题还是指向了旧值地址,导致错误。

方法:切片表示法,例Y[:] = <expression>

  1. Z = torch.zeros_like(Y)
  2. print('id(Z):', id(Z))
  3. Z[:] = X + Y
  4. print('id(Z):', id(Z))
  5. output:
  6. id(Z): 140316199714544
  7. id(Z): 140316199714544

2.1.6. 转换为其他Python对象

numpy转torch

  1. A = X.numpy()
  2. B = torch.tensor(A)
  3. type(A), type(B)
  4. output:
  5. (numpy.ndarray, torch.Tensor)

torch张量转标量——item函数或Python的内置函数

  1. a = torch.tensor([3.5])
  2. a # tensor([3.5000])
  3. a.item() # 3.5
  4. float(a) # 3.5
  5. int(a) # 3

2.1.8. 练习

  1. 运行本节中的代码。将本节中的条件语句X == Y更改为X < YX > Y,然后看看你可以得到什么样的张量。

    x<y:判断每一个元素是否满足 x<y 的要求,满足为 True,不满足为False ,张量形状为(3,4);x>y:判断每一个元素是否满足 x>y 的要求,满足为 True,不满足为False ,张量形状为(3,4).

  2. 用其他形状(例如三维张量)替换广播机制中按元素操作的两个张量。结果是否与预期相同

是相同的,但要注意两个问题:

(1) 第3个维度必须相同,否则相加报错

 (2)3维tensor元素与几何图之间的对应方法

2.2. 数据预处理

——运用pandas库

注:数据预处理是深度学习中很重要的一部分,pandas库是一个很常用且强大的库,本书中该部分并不是重点,内容较少,在此不总结,会再写一篇文章具体总结pandas库的一些详细用法,并跑几个例程。

2.3. 线性代数

2.3.1. 标量

——包含一个数值的叫标量(scalar)

1、实例

标量实例

2、数学知识

标量的一些数学知识

2.3.2. 向量

—— 一维张量,将标量从零阶推广到一阶

1、实例

向量实例

2、数学知识 

向量的一些数学知识1
向量的一些数学知识2
注:点乘、叉乘的区别可以看这 数学基础 —— 向量运算:点乘和叉乘 - 哔哩哔哩 (bilibili.com)

注:点乘和点积(dot product)是一个东西,给定两个向量相同位置的按元素乘积的和。

2.3.3. 矩阵

—— 二维张量,将向量从一阶推广到二阶

1、实例

矩阵实例

 2、矩阵基础知识 

特殊矩阵,设有一矩阵A
代码含义数学解释
A.T矩阵的转置

交换矩阵的行和列

A==A.T结果均为True对称矩阵Aij = Aji 
反对称矩阵Aij = -Aji 
正交矩阵

AAT=E(E为单位矩阵,AT表示“矩阵A的转置矩阵”)或ATA=E

什么是正交矩阵-百度经验 (baidu.com)

置换矩阵

A 是方阵,A 的每一行和每一列都有且仅有一个1,其余均为0

【2.7】P矩阵:置换矩阵 - 知乎 (zhihu.com)

方阵矩阵的行数与列数相等

补充知识:特征向量与特征值特征值与特征向量 (baidu.com)

 3、数学知识 

矩阵的一些数学知识1

Hadamard积:两个矩阵的按元素乘法

矩阵的一些数学知识2

矩阵乘法会对空间进行扭曲,公式不好理解,视频清楚:矩阵乘法的动画演示_哔哩哔哩_bilibili

矩阵的一些数学知识2
矩阵的一些数学知识3
注:这部分现阶段理解有点困难,先理解向量的概念吧 向量的【范数】:模长的推广,柯西不等式_哔哩哔哩_bilibili
矩阵的【范数】:也是一种长度_哔哩哔哩_bilibili

范数其实可以理解为一种长度,常见L1、L2范数 

在深度学习中,我们经常试图解决优化问题: 最大化分配给观测数据的概率; 最小化预测和真实观测之间的距离。 用向量表示物品(如单词、产品或新闻文章),以便最小化相似项目之间的距离,最大化不同项目之间的距离。 目标,或许是深度学习算法最重要的组成部分(除了数据),通常被表达为范数。

4、代码中的函数

运算函数
函数意义 
A+BA、B张量加法
A * BA、B张量的Hadamard积
torch.dot(x,y)x,y向量点积
torch.sum(x*y)执行按元素乘法,然后进行求和来表示两个向量的点积
torch.mv(A,x)矩阵A和向量x的矩阵-向量积,注意,A的列维数(沿轴1的长度)必须与x的维数(其长度)相同。
torch.mm(A,B)矩阵A和矩阵B乘法
torch.norm(u)u张量的L2范数(Frobenius范数)
torch.abs(u).sum()u张量的L1范数,将绝对值函数和按元素求和组合起来。

2.3.4. 降维

方法:

1、求和

直接求和——沿所有的轴降低张量的维度,变为一个标量,向量、矩阵均适用

 指定张量沿哪一个轴来求和:

 2、求平均

直接求平均:

 指定轴:

2.3.4.1. 非降维求和——轴数不变

1、cumsum函数不会沿任何轴降低输入张量的维度。

 2、由于sum_A在对每行进行求和后仍保持两个轴,我们可以通过广播将A除以sum_A。

 2.3.5. 练习

 

 

 

 

 

2.4. 微积分

  • 微分和积分是微积分的两个分支,前者可以应用于深度学习中的优化问题。

  • 导数可以被解释为函数相对于其变量的瞬时变化率,它也是函数曲线的切线的斜率。

  • 标量关于列向量的导数是一个行向量。

  • 列向量关于标量的导数是一个列向量。

  • 向量关于向量的导数结果是一个矩阵。

  • 梯度是一个向量,指向值最大的方向,其分量是多变量函数相对于其所有变量的偏导数。

  • 链式法则使我们能够微分复合函数。

不同情况下求导形状的变化

2.5. 自动微分

深度学习框架通过自动计算导数,即自动微分(automatic differentiation)来加快求导。 实际中,根据我们设计的模型,系统会构建一个计算图(computational graph),来跟踪计算是哪些数据通过哪些操作组合起来产生输出。 自动微分使系统能够随后反向传播(方向累积)梯度。 这里,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。

计算图(链式法则过程)

1、backward()反向传播函数和grad函数计算梯度

最基础例子:对函数y=2x⊤x(y等于标量2乘列向量x点积列向量x)关于列向量x求导(按照规则求导后结果为y=4x)

  1. import torch
  2. x = torch.arange(4.0)
  3. x
  4. x.requires_grad_(True) # 等价于x=torch.arange(4.0,requires_grad=True),梯度存的位置
  5. x.grad # 默认值为None
  6. y = 2 * torch.dot(x, x) # y为标量
  7. y
  8. y.backward() # 通过调用反向传播函数来自动计算y关于x每个分量的梯度
  9. x.grad # 打印梯度

 在默认情况下,pytorch会累积梯度,单运用同一个变量进行运算,需要清除之前的值,运用下面这行代码

x.grad.zero_()

2、非标量变量的反向传播

y不是标量时,机器学习中通常单独计算批量中每个样本的偏导数之和,如下代码所示。

  1. # 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
  2. # 在我们的例子中,我们只想求偏导数的和,所以传递一个1的梯度是合适的
  3. x.grad.zero_()
  4. y = x * x
  5. # 等价于y.backward(torch.ones(len(x)))
  6. y.sum().backward()
  7. x.grad

3、运用detach()函数使在系统中函数类型转为常数类型

例子:计算z=u*x关于x的偏导数,同时将u作为常数处理, 而不是z=x*x*x关于x的偏导数。

  1. x.grad.zero_()
  2. y = x * x
  3. u = y.detach()
  4. z = u * x
  5. z.sum().backward()
  6. x.grad == u
  7. output:tensor([True, True, True, True])
  8. ##由于记录了y的计算结果,可以随后在y上调用反向传播, 得到y=x*x关于的x的导数,即2*x。
  9. x.grad.zero_()
  10. y.sum().backward()
  11. x.grad == 2 * x
  12. output:tensor([True, True, True, True])

4、通过Python控制流(例如,条件、循环或任意函数调用),仍然可以计算得到的变量的梯度。

例子:在下面的代码中,while循环的迭代次数和if语句的结果都取决于输入a的值。

  1. def f(a):
  2. b = a * 2
  3. while b.norm() < 1000:
  4. b = b * 2
  5. if b.sum() > 0:
  6. c = b
  7. else:
  8. c = 100 * b
  9. return c
  10. #计算梯度
  11. a = torch.randn(size=(), requires_grad=True)
  12. d = f(a)
  13. d.backward()
  14. a.grad == d / a
  15. output:tensor(True)

小结:深度学习框架可以自动计算导数,首先将梯度附加到想要对其计算偏导数的变量上。然后记录目标值的计算,执行它的反向传播函数,并访问得到的梯度。

2.6. 概率

  • 我们可以从概率分布中采样。

  • 我们可以使用联合分布、条件分布、Bayes定理、边缘化和独立性假设来分析多个随机变量。

  • 期望和方差为概率分布的关键特征的概括提供了实用的度量形式。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/832103
推荐阅读
相关标签
  

闽ICP备14008679号