《Python深度学习·神经网络的数学基础》学习记录

466 阅读7分钟

一、 本章学习目标

学习神经网络的一些数学基础,主要是线性代数的一些基本知识。当然首先要明确的是,神经网络所涉及到的数学知识远不只是本章所介绍的这一些。神经网络涉及到线性代数、概率与信息论、数值计算等方面的数学基础知识。后续将在《Deep Learning》 一书的阅读笔记中详细介绍,在这边先只介绍最基础的线性代数。

二、神经网络的数据表示

1. 标量:

仅包含一个数字的张量叫做标量(也叫标量张量、零维张量、0D张量)。在Numpy中,一个float32或float64的数字就是一个标量。可以使用ndim属性来查看一个Numpy张量的轴的个数。标量张量有0个轴。张量轴的个数也叫阶。下面是一个Numpy标量。

>>> import numpy as np
>>> x = np.array(12)
>>> x
array(12)
>>> x.ndim
0   

2. 向量(1D张量):

数字组成的数组叫做向量,或一维张量(1D张量)。当然,数学上的严格定义要比这个严谨很多,要求是一列有序排列的数字,这里只以编程上的思维来做一个直观的定义。一维张量只有一个轴。下面是Numpy向量。

>>> x = np. array([ 12, 3, 6, 14, 7]) 
>>> x 
array([ 12, 3, 6, 14, 7]) 
>>> x. ndim 
1

3. 矩阵(2D张量):

向量组成的数组叫做矩阵或者二维张量(2D张量)。矩阵有两个轴,分别叫做行和列。下面是Numpy矩阵。

>>> x = np. array([[ 5, 78, 2, 34, 0],
                   [6, 79, 3, 35, 1], 
                   [7, 80, 4, 36, 2]]) 
>>> x. ndim 
2

4. 3D张量与更高维张量:

一般的,一个数组中的元素分布在若干维度坐标的规则网络中,我们称之为张量。标量、向量、矩阵都属于张量。将多个矩阵组合成一个新的数组,可以得到一个3D张量。下面是一个Numpy的3D张量。

>>> x = np. array([[[ 5, 78, 2, 34, 0], 
                    [6, 79, 3, 35, 1], 
                    [7, 80, 4, 36, 2]], 
                   [[5, 78, 2, 34, 0], 
                    [6, 79, 3, 35, 1], 
                    [7, 80, 4, 36, 2]], 
                   [[5, 78, 2, 34, 0], 
                    [6, 79, 3, 35, 1], 
                    [7, 80, 4, 36, 2]]]) 
>>> x. ndim 3

将多个3D张量组合成一个数组,可以创建一个4D张量,以此类推。深度学习处理的一般是0D到4D的张量,但处理视频数据时可能会遇到5D张量。

三、张量的关键属性

  1. 轴的个数(阶)。3D张量有3个轴,矩阵有2个轴。在Numpy中表示为ndim
  2. 形状。一个整数元组,表示张量沿每个轴的元素个数。如上述矩阵的形状为(3,5)3行5列,上述3D张量的形状表示为(3,3,5),上诉向量形状表示为(5,),而标量的形状为空表示为(),Numpy中形状存在shape属性中。
  3. 数据类型。在Numpy中用dtype表示。可取值为float32、uint8、float64等。注意,Numpy中不存在字符串张量,因为张量存储在预先分配的连续内存段中,而字符串长度是可变的,无法用这种方式存储。

四、现实世界中的数据张量

  1. 向量数据: 2D张量,形状为(samples,features) samples:样本,features:特征数据 下同。例如:人口统计数据集,其中包括每个人的年龄、邮编、收入。每个人包含3个值的向量,而整个数据集包含100000个人。因此可以存储在形状为(100000,3)的2D张量中。

  2. 时间序列数据或序列数据: 3D张量,形状为(samples,timesteps,features) timesteps:每个样本包含的时间长度。当时间或者序列顺序对数据很重要的时候,应该将数据存储在带有时间轴的3D张量中。 image.png

  3. 图像: 4D张量,形状为(samples,height,width,channels)或者(samples,channels,height,width) height:图像高度,width:图像宽度,channels:通道数量 image.png

  4. 视频: 5D张量,形状为(samples,frames,height,width,channels)或者(samples,frames,channels,height,width) frames:每个样本所包含的帧数。视频的每一帧是一张彩色图像。可以保存在形状为(height,width,channels)的3D张量中,没一个视频样本一般都是由很多帧图像组成,可以存在一个形状为(frame,height,width,channels)的4D张量中,所有样本构成的集合就可以用形状为(samples,frame,height,width,channels)的5D张量进行存储。

五、矩阵和张量的运算

1. 逐个元素计算:

单独地将运算作用在每个元素上。比如对两个张量中对应的元素单独做加法运算或者乘法运算。Numpy的乘法和加法支持逐个元素计算

>>> import numpy as np
>>> x = np.array([[1,2,3],
                 [4,5,6]])

>>> y = x * 2         # x的每个元素乘以2
>>> y
array([[2,3,6],
       [8,10,12]])

>>> z = x + y         # x和y对应元素相加
>>> z
array([[3,5,9],
       [12,15,18]])

>>> m = x * y         # x和y对应元素相乘
>>> m
array([[2,6,18],
       [32,50,72]])

2. 广播:

上述例子中参与运算的两个张量的形状是相同的。但是并不是只有形状相同的张量才可以做上述运算。我们试着将一个矩阵和一个向量做加法和乘法运算看看输出结果。

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> y = np.array([1, 2, 3])
>>> z = x + y
>>> z
array([[2 4 6],
       [5 7 9]])
>>> m = x * y
>>> m
array([[ 1  4  9],
       [ 4 10 18]])

可以发现运算过程是先对y向量进行扩张变为矩阵,扩张后的矩阵的每一行元素和原向量的元素保持一致,再使用扩张后的矩阵和x矩阵进行逐元素运算,这个过程就叫做张量的广播。

3. 矩阵转置:

我们先来看看矩阵转置在numpy中的运算结果。

>>> x = np.array([[1, 2, 3],
                  [4, 5, 6]])
>>> y = x.T  # x的转置
>>> y
array([[1, 4],
       [2, 5],
       [3, 6]])

数学上我们将矩阵X的转置表示为XX^\top,由上述的输出结果我们可以得到转置的定义公式为:

(X)i,j=Xj,i(X^\top)_i,_j = X_j,_i

即:沿着对角线将x轴的元素和y轴的元素进行镜像对调得到。

4. 张量点积。

点积运算是张量运算中最常见的运算,在numpy和kera中都是用标准的dot运算来实现点积。我们先来看看两个向量之间的运算规则。

>>> x = np.array([1, 2, 3])
>>> y = np.array([1, 2, 3])
>>> z = x.dot(y)
>>> z
14          # z = x0*y0 + x1*y1 + x2*y2

向量的点积运算是对向量所有元素的乘积做求和运算,结果是一个标量。

z=iXiYiz = \sum_i X_i Y_i

接下来我们扩展,再来看看矩阵的点积运算。

>>> x = np.array([[1, 2],
                  [1, 2]])
                  
>>> y = np.array([[3, 4],
                  [5, 6]])
>>> z = x.dot(y)
>>> z
array([[13, 16],
       [13, 16]])

可见,矩阵的点积结果是一个矩阵(z)。矩阵z的每个元素是由x的行和y的列的积求和得到,这个满足向量的计算公式 将上述公式推广到矩阵运算中:

Zi,j=kXi,kYk,jZ_i,_j = \sum_k X_i,_k Y_k,_j

可以通过如下图对点积运算做一个进一步的理解

image.png

根据上述公式我们可以得出一些结论和推理公式:

  • X矩阵的列数必须和矩阵Y的行数相等
  • 如果X的形状是m x n Y的形状是n x p,那么通过点积得到的Z形状就是m x p
  • 矩阵的点积运算满足分配律:A(B+C)=AB+ACA(B+C)=AB+AC
  • 矩阵的点积运算满足结合律:A(BC)=(AB)CA(BC)=(AB)C
  • 矩阵的点积运算并不满足交换律
  • 矩阵乘积的转置有着简单的形式:(AB)=BA(AB)^\top=B^\top A^\top

以上结论都可以通过上述公式推导得到,这里就不作具体的推理和证明了。当然要明确的一个问题是:线性代数的知识远不止这里列出来的这些。这里只是列出了在深度学习中最经常用到的一小部分知识,后续有遇到再进行扩展学习吧。

六、资料引用

  • 《Deep Learning with Python》
  • 《Deep Learning》