文章目录
- 一、线性代数
- 1. 标量
- 2. 向量及其运算
- 3. 矩阵及其运算
- 4. 范数
- 二、微积分
- 1. 导数
- 2. 偏导数
- 3. 梯度
- 三、信息论
- 1. 熵
- 2. KL 散度
- 3. 交叉熵
一、线性代数
深度学习背后的核心有标量、向量、矩阵和张量这 4 种数据结构,可以通过使用这些数据结构,以编程的方式解决基本的线性代数问题
1. 标量
代码语言:javascript复制x = 6.0
print(type(x)) <class 'float'>
y = 6
print(type(y)) <class 'int'>
2. 向量及其运算
一个向量表示一组有序排列,并可以通过索引获取其中对应位置的数值。一般情况下,我们会使用 numpy 对向量进行表示和运算。numpy 是 Python 的一个扩展程序库,能够很好地支持数组、向量、矩阵的运算。官网地址为:https://numpy.org/
标量是一个数字,所以标量在跟向量进行加减乘除运算时,实际上与向量中的每一个数字都同步进行了计算,代码如下:
代码语言:javascript复制# 向量和标量的运算
import numpy as np
s1 = np.array([1, 2, 3, 4])
print(s1 * 2) # [2 4 6 8]
s2 = s1 6
print(s2) # [ 7 8 9 10]
向量之间的加减操作是各自对应位置的加减操作。因为 Python 中列表相加实现的是两个列表拼接,所以向量的计算不能使用列表,要使用 numpy 的 ndarray 进行加减运算
给定如下图的两个向量,经过加运算之后,得到如下结果:
代码语言:javascript复制import numpy as np
s1 = [1, 2, 3]
s2 = [4, 5, 6]
print(s1 s2) # [1, 2, 3, 4, 5, 6]
# -----------------------------
print(np.add(s1, s2)) # [5 7 9]
print(np.array(s1) np.array(s2)) # [5 7 9]
print(type(np.add(s1, s2))) # <class 'numpy.ndarray'>
向量之间的乘法操作:点乘(内积)、叉乘(外积)和对应项相乘
- 向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。给定两个向量:a=[a1, a2…an] 和 b=[b1,b2…bn],则 a 和 b 的点乘计算方式为 a·b = a1b1 a2b2 … anbn。向量的点乘要求两个向量的长度一致。
- 向量的叉乘,也叫向量的外积、向量积。叉乘的运算结果是一个向量而不是一个标量。
- 对应项相乘,顾名思义,就是两个向量对应的位置相乘,得到的结果还是原来的形状。给定两个向量:a=[a1, a2…an] 和 b=[b1,b2…bn],则 a 和 b 的对应项相乘计算方式为:a*b = [a1b1,a2b2 … anbn]。
点乘、叉乘及对应项相乘的代码如下所示:
代码语言:javascript复制import numpy as np
s1 = [1, 2, 3]
s2 = [4, 5, 6]
# 点乘 result:32
print(np.inner(s1, s2))
# ------------------------
print(np.outer(s1, s2))
'''叉乘 result
[[ 4 5 6]
[ 8 10 12]
[12 15 18]]'''
# ------------------------
print(np.multiply(s1,s2))
# 对应项相乘 result:array([ 4 10 18])
3. 矩阵及其运算
矩阵一般是一个 m 行 n 列的矩形阵列,一般的表达方式如下图所示:
矩阵中每个元素都有 m 和 n 两个下标,分别代表行和列的位置,所以矩阵也可以通过索引直接定位元素的值。
矩阵的加减法操作跟向量类似,也是对应位置进行相加减。如图所示,红色和绿色的框分别代表了不同位置数字的计算过程:
代码如下所示:
代码语言:javascript复制import numpy as np
m1 = np.mat([[1, 2], [3, 4]])
print(m1)
print('------------------------')
m2 = np.mat([[5, 6], [7, 8]])
print(m2)
print('------------------------')
print(m1 m2)
print(type(m1 m2))
矩阵的乘运算也有两种形式:
- 第一种是两个形状一样的矩阵的对应位置分别相乘
- 第二种是矩阵乘法。设 a 为 m 行 p 列的矩阵,b 为 p 行 n 列的矩阵,相乘的结果为一个 m 行 n 列的新矩阵,其中第 i 行第 j 列(1≤i≤m,1≤j≤n)的元素为:
可以看出:每个新的元素都是由一个行向量和一个列向量做点乘之后生成的
代码语言:javascript复制import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(a)
print('------------')
print(b)
print('------------')
print(a*b) # 对应相乘
print('------------')
print(a.dot(b)) # 矩阵乘法 每个新的元素都是由一个行向量和一个列向量做点乘之后生成
4. 范数
范数是一种距离的表示,或者说向量的长度。常见的范数有: L0 范数、L1 范数和 L2 范数
- L0 范数指这个向量中非 0 元素的个数。我们可以通过 L0 范数减少非 0 元素的个数,从而减少参与决策的特征,减少参数。这样一来,自然模型就运算得更快,模型的体积也更小了。
- L1 范数指的是向量中所有元素的绝对值之和,它是一种距离的表示(曼哈顿距离),也被称为稀疏规则算子,公式如下:
L0 范数和 L1 范数都能实现权值稀疏。但 L1 范数是 L0 范数的最优凸近似,它比 L0 范数有着更好的优化求解的特性,所以被更广泛地使用。
为什么要实现权值稀疏呢?
在设计模型的过程中,我们有时会使用到大量的特征(例如在推荐系统中,特征维度都是上亿的),每个特征都会从不同的角度体现问题的不同信息。这些特征经过某些方式的组合、变换、映射之后,会按照不同的权重得到最终的结果。
但有时候,有一部分特征对于最后结果的贡献非常小,甚至近乎零,这些用处不大的特征,我们希望能够将其舍弃,以更方便模型做出决策。这就是权值稀疏的意义。
- 除了 L0、L1,还有一个更为常用的范数 L2,也有叫它 “岭回归” 和 “权值衰减” 的。我们首先来看它的定义:L2 范数是向量中所有元素的平方和的平方根。其公式如下:
L2 也代表一种距离,即欧式距离,L0 和 L1 可以起到权值稀疏的作用,L2 也有它的作用,那就是防止过拟合。
L2 是如何解决过拟合的呢?
- 参数值小的模型一般会比较简单,它能适应不同的数据集,也能在一定程度上避免过拟合。举一个简单的例子,y=10x1 1000x2。x2 取值 1 和 3,最终会导致 y 差了 2000。x2 稍微一变,结果就差别很大了。更进一步,x1 的权重就低了很多,x1 的变化对 y 的结果影响小,模型的适应性就很差了。所以,我们可以得出一个结论:越小的参数,模型就越简单,越简单的模型,就越不容易过拟合。
- L2 实际上就是让向量中所有元素的平方和再开方。那么,如果我们要避免模型过拟合,就要使 L2 最小,这意味着向量中的每一个元素的平方都要尽量小,且接近于 0。和 L0 和 L1 不一样,L2 不会让元素等于 0。
- 由此,L1 和 L2 范数的区别就很显然了。L1 会趋向于产生少量的特征,而其他的特征都是 0,用于特征选择和稀疏;L2 会选择更多的特征,但这些特征都会接近于 0,用于减少过拟合。
二、微积分
微积分是现代数学的核心基础知识,深度学习中会用到的知识点,分别是导数、偏导数和梯度
1. 导数
- 导数,也叫作导函数值。假定我们现在手头有一个函数 F(x) = 2x。当 x=1 的时候,函数值 F(x)=F(2)=2*1。然后我们给 x 增加一个非常小的变化(增量)Δx,那么F(x Δx)=2(x Δx),这意味着函数的结果也有了一个增量,记为Δy。
- 当函数值增量 Δy 与变量增量 Δx 的比值在 Δx 趋近于 0 时,如果极限 a 存在,我们就称 a 为函数 F(x)在 x 处的导数。
这里有两个需要注意的地方,第一个是 Δx 一定要趋近于 0,第二个是极限 a 要存在。F(x)=2x 作图如下:
一个函数在某一点的导数描述了这个函数在这一点附近的变化率,导数一般记为:
不光函数有导数,导数也有导数。代表函数在 x 处斜率(导数)的变化率我们称之为二阶导数。由此类推,还有高阶导数等
2. 偏导数
在实际应用中,很多函数都有多个变量。为了方便分析不同变量与函数的关系,为单个变量求导是很有必要的。这个时候,我们需要让其他变量不变,只有某一个变量发生变化,这种情况下的求导我们称之为 “偏导数”。公式如下:
导数就是函数在某个点上的斜率。如果我们把坐标系从二维变成三维,甚至更多维时,偏导数就好理解了:它实际上是函数在不同方向(坐标轴)上的变化率。
假定我们有一个函数 z = f(x,y),我们想要求这个函数在 x 方向的导数,只需要将 y 固定,在 x 上增加一个小的增量Δx;同样的,如果要求 y 方向的导数,则需要固定 x,y 上增加一个增量Δy,例如:
分别表示函数在 x 轴方向和 y 轴方向上的导数
3. 梯度
在机器学习中,梯度是一个出现频率极高的词语,模型的设计、训练、优化等过程中,梯度都是一个核心概念。函数的所有偏导数构成的向量就叫作梯度。我们用 ∇f 表示,公式化的形式为:
注意:梯度是一个向量。同时,梯度向量的方向即为函数值增长最快的方向。
三、信息论
1. 熵
熵,也称信息熵。假定我们有一枚标准的硬币,每次投掷,得到正面和反面的概率都是 1/2,不确定性非常大。假如我们在硬币上做点手脚,在正面加点重量,那么每次投掷的概率就发生了变化,正面朝上的概率就比原来大了,比如此时变成了 2/3,这种正反面的不确定性就减少了。
对于每一个事件(情况)的发生,都有一个信息量的度量,它的公式为:
其中 P(x) 是 x 发生的概率
2. KL 散度
KL 散度,也称为相对熵,它衡量了两个分布之间的差异,它的公式如下:
上面的 p(xi) 为真实事件的概率分布,q(xi) 为理论拟合出来的该事件的概率分布。因此该公式字面上的含义就是真实事件的信息熵,同理论拟合的事件的信息量与真实事件的概率的乘积的差的累加。
- 真实事件的信息熵就是 p(xi) log p(xi),理论拟合的事件的信息量就是 log q(xi),真实事件的概率就是 p(xi)。
- 在模型优化、数据分析和统计等场合下,我们就可以使用 KL 散度衡量我们选择的近似分布与数据原分布有多大差异。当拟合事件和真实事件一致的时候 KL 散度就成了 0,不一样的时候就大于 0。
3. 交叉熵
交叉熵也衡量了两个分布之间的差异,但是与 KL 散度的区别在于,交叉熵代表用拟合分布来表示实际分布的困难程度,其公式如下:
三种度量方式的公式放在一起看,可以发现其中的关联,如下所示:
作者:叶庭云 CSDN:https://yetingyun.blog.csdn.net/ 本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。 觉得文章对你有帮助、让你有所收获的话,期待你的点赞呀,不足之处,也可以在评论区多多指正。