Linear Algebra for Deep Learning
深度学习(Deep Learning)是机器学习的一个子领域,涉及的算法模仿大脑的功能和结构,称为人工神经网络。
线性代数(linear algebra)是有关连续值的数学。许多计算机科学家在此方面经验不足(传统上计算机科学更偏重离散数学)。想要理解和使用许多机器学习算法,特别是深度学习算法,对线性代数的良好理解是不可或缺的。
为什么要学习数学?
线性代数、概率论和微积分是用来表达机器学习的“语言”。学习这些内容将有助于深入理解底层的算法机制,也有助于开发新的算法。
当被限制在足够小的尺度上,深度学习背后的一切都是数学。所以在开始深度学习之前,了解基本的线性代数是非常重要的。
深度学习背后的核心数据结构是标量(Scalar)、向量(Vector)、矩阵(Matrix)、张量(Tensor)。在编程中,让我们使用这些数据结构求解基本的线性代数问题。
标量(Scalars)
标量是一个数字,或者说,是一个0阶张量。符号表示是一个属于实数集的标量。
深度学习中有着不同的数字集合。表示正整数集。表示整数集,包括正整数,负整数和零。表示有理数集,可以表达两个整数之比的数。
在Python中有几个内置的标量类型:int、float、complex、bytes、Unicode。Numpy又增加了二十多种新的标量类型。有关数据类型的更多信息,请参阅文档。
在Python中定义标量和一些运算: 下面的代码片段展示了对标量的几个运算操作。
# In-Built Scalars
a =
5
b =
7.5
print(type(a))
print(type(b))
print(a + b)
print(a - b)
print(a * b)
print(a / b)
输出结果:
<
class
'int'
>
<
class
'float'
>
12.5
-
2.5
37.5
0.6666666666666666
下面的代码片段用来检查给定的变量是否是标量。
import
numpy
as
np
# Is Scalar Function
def
isscalar(num):
if
isinstance(num
,
generic):
return True
else
:
return False
print(np.isscalar(
3.1
))
print(np.isscalar([
3.1
]))
print(np.isscalar(
False
))
输出结果:
True
False
True
向量(Vectors)
向量是由单个数字组成的有序数组,或者说,1阶张量。向量是向量空间这一对象的组成部分。一个向量空间可以看作是一个特定长度(或维度)的所有可能向量的集合。三维实数向量空间()常用于表示现实世界中的三维空间。为了明确地识别向量的分量(component),向量的第个标量元素被记为。
在深度学习中,向量通常表示特征向量,其原始分量定义了特定特征的相关性。这些元素可以是二维图像中一组像素的强度的相关性或者是金融工具截面的历史价格值。
在Python中定义向量和一些运算:
import
numpy
as
np
# 声明向量
x = [
1
,
2
,
3
]
y = [
4
,
5
,
6
]
print(type(x))
# +并不表示向量的加法,而是列表的连接:
print(x + y)
# 需要使用Numpy进行向量加法:
z = np.add(x
,
y)
print(z)
print(type(z))
# 向量的叉积(cross product):两个向量的叉积向量,
大小等于以这两个向量为邻边的平行四边形面积,方向与这两个向量所在平面垂直
mul = np.cross(x
,
y)
print(mul)
输出结果:
<
class
'list'
>
[
1
,
2
,
3
,
4
,
5
,
6
]
[
5 7 9
]
<
class
'numpy.ndarray'
>
[-
3 6
-
3
]
矩阵(Matrices)
矩阵是由数字组成的矩形数组,或者说,2阶张量。如果和为正整数,即 ,那么一个的矩阵包含个数字,行列。 一个的矩阵可表示成:
有时可简写为:
在Python中,我们使用numpy库创建n维数组,也就是矩阵。我们将列表传入matrix方法,以定义矩阵。
>>>
import
numpy
as
np
>>> x = np.matrix([[
1
,
2
]
,
[
2
,
3
]])
>>> x
matrix([[
1
,
2
]
,
[
2
,
3
]])
>>> a = x.mean(
0
)
>>> a
matrix([[
1.5
,
2.5
]])
>>>
# Finding the mean with 1 with the matrix x.
>>> z = x.mean(
1
)
>>> z
matrix([[
1.5
]
,
[
2.5
]])
>>> z.shape
(
2
,
1
)
>>> y = x - z
matrix([[-
0.5
,
0.5
]
,
[-
0.5
,
0.5
]])
>>>
print
(
type
(z))
<
class
'numpy.matrixlib.defmatrix.matrix'
>
在Python中定义矩阵和一些运算:
矩阵加法
矩阵可以与标量、向量和其他矩阵相加。每个操作都有一个精确的定义。这些技术在机器学习和深度学习中经常被使用,所以你需要熟悉它们。
# Matrix Addition
import
numpy
as
np
x = np.matrix([[
1
,
2
]
,
[
4
,
3
]])
sum = x.sum()
print
(sum)
# Output: 10
矩阵-矩阵相加
C = A + B(矩阵A和矩阵B应该具有相等的行数和列数)
两个矩阵的相对应的元素分别相加,如果矩阵的形状不相同,则会抛出一个错误,说明不能相加。
# Matrix-Matrix Addition
import
numpy
as
np
x = np.matrix([[
1
,
2
]
,
[
4
,
3
]])
y = np.matrix([[
3
,
4
]
,
[
3
,
10
]])
print
(x.shape)
# (2, 2)
print
(y.shape)
# (2, 2)
m_sum = np.add(x
,
y)
print
(m_sum)
print
(m_sum.shape)
"""
Output :
[[ 4 6]
[ 7 13]]
(2, 2)
"""
矩阵-标量相加
将给定的标量与给定矩阵中的所有元素相加。
# Matrix-Scalar Addition
import
numpy
as
np
x = np.matrix([[
1
,
2
]
,
[
4
,
3
]])
s_sum = x +
1
print
(s_sum)
"""
Output:
[[2 3]
[5 4]]
"""
矩阵-标量相乘
将给定的标量与给定矩阵中的所有元素相乘。
# Matrix Scalar Multiplication
import
numpy
as
np
x = np.matrix([[
1
,
2
]
,
[
4
,
3
]])
s_mul = x *
3
print
(s_mul)
"""
[[ 3 6]
[12 9]]
"""
矩阵-矩阵相乘
矩阵A(m行n列)与矩阵B(n行p列)得到矩阵C(m行p列),如下图所示:
# Matrix Multiplication
import
numpy
as
np
a = [[
1
,
0
]
,
[
0
,
1
]]
b = [
1
,
2
]
np.matmul(a
,
b)
# Output: array([1, 2])
complex_mul = np.matmul([
2j
,
3j
]
,
[
2j
,
3j
])
print
(complex_mul)
# Output: (-13+0j)
矩阵转置
矩阵转置交换原矩阵的行和列(行变为列,列变为行)。通过转置,可以将行向量转换为列向量,反之亦然:
# Matrix Transpose
import
numpy
as
np
a = np.array([[
1
,
2
]
,
[
3
,
4
]])
print
(a)
"""
[[1 2]
[3 4]]
"""
a.transpose()
print
(a)
"""
array([[1, 3],
[2, 4]])
"""
张量(Tensors)
比标量、向量、矩阵更通用的概念是张量。在物理科学和机器学习中,有时需要使用超过二阶的张量(如前文中所说,标量、向量、矩阵分别可以视为0、1、2阶张量。)
一般来说,我们使用像tensorflow或PyTorch这样的Python库来声明张量。
在PyTorch中定义一个简单的张量:
import
torch
a = torch.Tensor([
26
])
print(type(a))
# <class 'torch.FloatTensor'>
print(a.shape)
# torch.Size([1])
# Creates a Random Torch Variable of size 5x3.
t = torch.Tensor(
5
,
3
)
print(t)
"""
0.0000e+00 0.0000e+00 0.0000e+00
0.0000e+00 7.0065e-45 1.1614e-41
0.0000e+00 2.2369e+08 0.0000e+00
0.0000e+00 0.0000e+00 0.0000e+00
nan nan -1.4469e+35
[torch.FloatTensor of size 5x3]
"""
print(t.shape)
# torch.Size([5, 3])
Python中对张量的一些算术运算:
import
torch
# Creating Tensors
p = torch.Tensor(
4
,
4
)
q = torch.Tensor(
4
,
4
)
ones = torch.ones(
4
,
4
)
print(p
,
q
,
ones)
"""
Output:
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00
1.6009e-19 4.4721e+21 6.2625e+22 4.7428e+30
3.1921e-09 8.0221e+17 5.1019e-08 8.1121e+17
8.1631e-07 8.2022e+17 1.1703e-19 1.5637e-01
[torch.FloatTensor of size 4x4]
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00
1.8217e-44 1.1614e-41 0.0000e+00 2.2369e+08
0.0000e+00 0.0000e+00 2.0376e-40 2.0376e-40
nan nan -5.3105e+37 nan
[torch.FloatTensor of size 4x4]
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
[torch.FloatTensor of size 4x4]
"""
print(
"Addition:{}"
.format(p + q))
print(
"Subtraction:{}"
.format(p - ones))
print(
"Multiplication:{}"
.format(p * ones))
print(
"Division:{}"
.format(q / ones))
"""
Addition:
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00
1.6009e-19 4.4721e+21 6.2625e+22 4.7428e+30
3.1921e-09 8.0221e+17 5.1019e-08 8.1121e+17
nan nan -5.3105e+37 nan
[torch.FloatTensor of size 4x4]
Subtraction:
-1.0000e+00 -1.0000e+00 -1.0000e+00 -1.0000e+00
-1.0000e+00 4.4721e+21 6.2625e+22 4.7428e+30
-1.0000e+00 8.0221e+17 -1.0000e+00 8.1121e+17
-1.0000e+00 8.2022e+17 -1.0000e+00 -8.4363e-01
[torch.FloatTensor of size 4x4]
Multiplication:
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00
1.6009e-19 4.4721e+21 6.2625e+22 4.7428e+30
3.1921e-09 8.0221e+17 5.1019e-08 8.1121e+17
8.1631e-07 8.2022e+17 1.1703e-19 1.5637e-01
[torch.FloatTensor of size 4x4]
Division:
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00
1.8217e-44 1.1614e-41 0.0000e+00 2.2369e+08
0.0000e+00 0.0000e+00 2.0376e-40 2.0376e-40
nan nan -5.3105e+37 nan
[torch.FloatTensor of size 4x4]
"""
有关张量和PyTorch的更多文档,请查阅文档。
原文发布时间为:2018-06-26
本文作者:Vihar Kurama
本文来自云栖社区合作伙伴“专知”,了解相关信息可以关注“专知”。