深度学习-神经网络的数学基础

1.标量(0D 张量)

仅包含一个数字的张量叫作 标量 scalar ,也叫标量张量、零维张量、 0D 张量)。在 Numpy
中,一个 float32 float64 的数字就是一个标量张量(或标量数组)。

2.向量

数字组成的数组叫作 向量 vector )或一维张量( 1D 张量)。一维张量只有一个轴。下面是
一个 Numpy 向量。
x=np.array([12,3,6,14,7])

3.矩阵(2D 张量)

向量组成的数组叫作 矩阵 matrix )或二维张量( 2D 张量)。矩阵有 2 个轴(通常叫作
)。你可以将矩阵直观地理解为数字组成的矩形网格。下面是一个 Numpy 矩阵。
 x = np.array([[5, 78, 2, 34, 0],
 [6, 79, 3, 35, 1],
 [7, 80, 4, 36, 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]]])
将多个 3D 张量组合成一个数组,可以创建一个 4D 张量,以此类推。深度学习处理的一般
0D 4D 的张量,但处理视频数据时可能会遇到 5D 张量。

5.关键属性

张量是由以下三个关键属性来定义的。
轴的个数(阶) 例如, 3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy Python 库中
也叫张量的 ndim
形状: 这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩
阵示例的形状为 (3, 5) 3D 张量示例的形状为 (3, 3, 5) 。向量的形状只包含一个
元素,比如 (5,) ,而标量的形状为空,即 ()
  数据类型 (在 Python 库中通常叫作 dtype )。这是张量中所包含数据的类型,例如,张
量的类型可以是 float32 uint8 float64 等。在极少数情况下,你可能会遇到字符
char )张量。注意, Numpy (以及大多数其他库)中不存在字符串张量,因为张量存
储在预先分配的连续内存段中,而字符串的长度是可变的,无法用这种方式存储。

6.张量运算

6.1逐元素运算
relu 运算和加法都是 逐元素 element-wise )的运算,即该运算独立地应用于张量中的每
个元素,也就是说,这些运算非常适合大规模并行实现。下列代码是对逐元素 relu 运算的简单实现。
def naive_relu(x):
     assert len(x.shape) == 2 
     x = x.copy() 
     for i in range(x.shape[0]):
         for j in range(x.shape[1]):
              x[i, j] = max(x[i, j], 0)
     return x
对于加法采用同样的实现方法。
def naive_add(x, y): 
     assert len(x.shape) == 2 
     assert x.shape == y.shape
     x = x.copy() 
     for i in range(x.shape[0]):
         for j in range(x.shape[1]):
             x[i, j] += y[i, j]
     return x

6.2广播

广播包含 以下两步。
(1) 向较小的张量添加轴(叫作 广播轴 ),使其 ndim 与较大的张量相同。
(2) 将较小的张量沿着新轴重复,使其形状与较大的张量相同。
来看一个具体的例子。假设 X 的形状是 (32, 10) y 的形状是 (10,) 。首先,我们给 y
添加空的第一个轴,这样 y 的形状变为 (1, 10) 。然后,我们将 y 沿着新轴重复 32 次,这样
得到的张量 Y 的形状为 (32, 10) ,并且 Y[i, :] == y for i in range(0, 32) 。现在,
我们可以将 X Y 相加,因为它们的形状相同。
 def naive_add_matrix_and_vector(x, y):
     assert len(x.shape) == 2 
     assert len(y.shape) == 1 
     assert x.shape[1] == y.shape[0]
     x = x.copy() 
     for i in range(x.shape[0]):
         for j in range(x.shape[1]):
         x[i, j] += y[j]
     return x
6.3张量点积
点积运算,也叫 张量积 tensor product ,不要与逐元素的乘积弄混),是最常见也最有用的
张量运算。与逐元素的运算不同,它将输入张量的元素合并在一起。
从数学的角度来看,点积运算做了什么?我们首先看一下两个向量 x y 的点积。其计算
过程如下:
 def naive_vector_dot(x, y):
     assert len(x.shape) == 1 
     assert len(y.shape) == 1
     assert x.shape[0] == y.shape[0]
     z = 0
     for i in range(x.shape[0]):
          z += x[i] * y[i]
     return z
注意,两个向量之间的点积是一个标量,而且只有元素个数相同的向量之间才能做点积。

6.4张量变形

张量变形是指改变张量的行和列,以得到想要的形状。变形后的张量的元素总个数与初始
张量相同。简单的例子可以帮助我们理解张量变形。
import numpy as np
x = np.array([[ 0,1],
          [ 2,3],
          [ 4,5]])
print(x.shape)
x = x.reshape((6, 1))
print(x)

深度学习-神经网络的数学基础_第1张图片

6.5张量运算的导数(梯度)

梯度 gradient )是张量运算的导数。它是导数这一概念向多元函数导数的推广。多元函数
是以张量作为输入的函数。
随机梯度下降

 给定一个可微函数,理论上可以用解析法找到它的最小值:函数的最小值是导数为 0 的点, 因此你只需找到所有导数为 0 的点,然后计算函数在其中哪个点具有最小值。

将这一方法应用于神经网络,就是用解析法求出最小损失函数对应的所有权重值。

由于处理的是一个可微函数,你可以计算出它的梯度,从而有效地实
现第四步。沿着梯度的反方向更新权重,损失每次都会变小一点。
(1) 抽取训练样本 x 和对应目标 y 组成的数据批量。
(2) x 上运行网络,得到预测值 y_pred
(3) 计算网络在这批数据上的损失,用于衡量 y_pred y 之间的距离。
(4) 计算损失相对于网络参数的梯度[一次 反向传播 backward pass )]。
(5) 将参数沿着梯度的反方向移动一点,比如 W -= step * gradient ,从而使这批数据
上的损失减小一点。
刚刚描述的方法叫作 小批量随机梯度下降 mini-batch stochastic gradient descent
又称为小批量 SGD )。
深度学习-神经网络的数学基础_第2张图片

 

6.6链式求导:反向传播算法

在前面的算法中,我们假设函数是可微的,因此可以明确计算其导数。在实践中,神经网
络函数包含许多连接在一起的张量运算,每个运算都有简单的、已知的导数。例如,下面这个
网络 f 包含 3 个张量运算 a b c ,还有 3 个权重矩阵 W1 W2 W3
f(W1, W2, W3) = a(W1, b(W2, c(W3)))
根据微积分的知识,这种函数链可以利用下面这个恒等式进行求导,它称为 链式法则 chain
rule ): (f(g(x)))' = f'(g(x)) * g'(x) 。将链式法则应用于神经网络梯度值的计算,得
到的算法叫作 反向传播 backpropagation ,有时也叫 反式微分 reverse-mode differentiation )。反
向传播从最终损失值开始,从最顶层反向作用至最底层,利用链式法则计算每个参数对损失值
的贡献大小。

你可能感兴趣的:(python)