章二习题(NumPy基础、广播和向量化)

numpy常用函数

  • mat( ): 将数组转化为矩阵
  • np.I 操作符: 实现了矩阵求逆的运算
  • np.log:是计算对数函数
  • np.abss:是计算数据的绝对值
  • np.max imum:计算元素 y 中的最大值,你也可以 np.max imum(v,0)

1. np.exp()

  • 使用np.exp()
    1
    2
    3
    4
    5
    import numpy as np

    # example of np.exp
    x = np.array([1, 2, 3])
    print(np.exp(x)) # result is (exp(1), exp(2), exp(3))
1
[2.71828183  7.3890561  20.08553692]
  • 实现sigmoid函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import numpy as np 

    def sigmoid(x):
    """
    Arguments:
    x -- A scalar or numpy array of any size
    # x-- 任何大小的标量或numpy数组
    Return:
    s -- sigmoid(x)
    """

    s = 1 / (1 + np.exp(-x))

    return s
1
2
x = np.array([1, 2, 3])
sigmoid(x)
  • Sigmoid梯度
  • 计算梯度已使用反向传播优化损失函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mport numpy as np 

def sigmoid(x):
"""
计算sigmoid函数相对于其输入x的梯度(斜率或导数)
可以将sigmoid函数的输出存储到变量中,然后使用它来计算渐变

Arguments:
x -- A scalar or numpy array of any size
# x-- 任何大小的标量或numpy数组

Return:
ds -- 你的计算渐变
"""

s = 1 / (1 + np.exp(-x))
ds = s * (1 - s)

return ds

2.X.shape和X.reshape

  • X.shape:用于获取矩阵/向量X的形状(维度)
  • X.reshape:用于将X重塑为其他维度

3.标准化处理

  • 实现normalizeRows()来规范矩阵的行。将这个函数应用到输入矩阵x之后,x的每一行应该是单位长度的向量(意思是长度1)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 分级功能: normalizeRows

    def normalizeRows(x):
    """
    实现对矩阵x的每一行进行归一化的函数(具有单位长度)

    Argument:
    x -- A numpy matrix of shape (n, m)

    Returns:
    x -- The normalized (by row) numpy matrix. You are allowed to modify x.
    x -- 标准化(按行)numpy矩阵,可以修改x
    """

    # 计算 x_norm 作为 x的规范2. 使用 np.linalg.norm(..., ord = 2, axis = ..., keepdims = True)
    x_norm = np.linalg.norm(x, axis = 1, keepdims = True)

    # Divide x by its norm.
    # 将x除以其规范
    x = x / x_norm

    return x
1
2
3
4
x = np.array([
[0, 3, 4],
[1, 6, 4]])
print("normalizeRows(x) = " + str(normalizeRows(x)))
1
2
normalizeRows(x) = [[ 0.          0.6         0.8       ]
[ 0.13736056 0.82416338 0.54944226]]

4.广播和softmax函数

  • 使用numpy实现softmax函数:归一类函数,对两个或多个类进行分类时使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def softmax(x):
"""计算输入x的每一行softmax
row vector 行矢量
matrices 形状
Your code should work for a row vector and also for matrices of shape (n, m).

Argument:
x -- A numpy matrix of shape (n,m)

Returns:
s -- A numpy matrix equal to the softmax of x, of shape (n,m)
返回等于x的softmax的numpy矩阵,形状(n,m)
"""

# element-wise 元素
# Apply exp() element-wise to x. Use np.exp(...).
x_exp = np.exp(x)

# Create a vector x_sum that sums each row of x_exp. 对x_exp的每一行求和
# Use np.sum(..., axis = 1, keepdims = True).
x_sum = np.sum(x_exp, axis = 1, keepdims = True)

# dividing 除以
# Compute softmax(x) by dividing x_exp by x_sum. It should automatically use numpy broadcasting. 自动使用numpy广播
s = x_exp / x_sum

return s
1
2
3
4
x = np.array([
[9, 2, 5, 0, 0],
[7, 5, 0, 0 ,0]])
print("softmax(x) = " + str(softmax(x)))
  • np.exp(x)适用于任何np.array x,并将指数函数应用于每个坐标
  • sigmoid函数及其渐变
  • image2vector常用于深度学习
  • np.reshape被广泛使用。在将来,你会发现保持矩阵/向量的维度直接将消除大量的错误。
  • numpy具有高效的内置功能
  • 广播是非常有用的

5.向量化(Vectorization)

  1. 在深度学习中,您处理非常大的数据集。因此,非计算最优函数可能会成为算法中的一个巨大瓶颈,并可能导致需要长时间运行的模型。为了确保你的代码在计算上是高效的,你将使用向量化。
  2. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    import time

    x1 = [9, 2, 5, 0, 0, 7, 5, 0, 0, 0, 9, 2, 5, 0, 0]
    x2 = [9, 2, 2, 9, 0, 9, 2, 5, 0, 0, 9, 2, 5, 0, 0]
    # DOT PRODUCT 矢量积
    ### CLASSIC DOT PRODUCT OF VECTORS IMPLEMENTATION ###
    tic = time.process_time()
    dot = 0
    for i in range(len(x1)):
    dot+= x1[i]*x2[i]
    toc = time.process_time()
    print ("dot = " + str(dot) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

    ### CLASSIC OUTER PRODUCT IMPLEMENTATION ###
    tic = time.process_time()
    outer = np.zeros((len(x1),len(x2))) # we create a len(x1)*len(x2) matrix with only zeros
    for i in range(len(x1)):
    for j in range(len(x2)):
    outer[i,j] = x1[i]*x2[j]
    toc = time.process_time()
    print ("outer = " + str(outer) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

    ### CLASSIC ELEMENTWISE IMPLEMENTATION ###
    tic = time.process_time()
    mul = np.zeros(len(x1))
    for i in range(len(x1)):
    mul[i] = x1[i]*x2[i]
    toc = time.process_time()
    print ("elementwise multiplication = " + str(mul) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

    ### CLASSIC GENERAL DOT PRODUCT IMPLEMENTATION ###
    W = np.random.rand(3,len(x1)) # Random 3*len(x1) numpy array
    tic = time.process_time()
    gdot = np.zeros(W.shape[0])
    for i in range(W.shape[0]):
    for j in range(len(x1)):
    gdot[i] += W[i,j]*x1[j]
    toc = time.process_time()
    print ("gdot = " + str(gdot) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
x1 = [9, 2, 5, 0, 0, 7, 5, 0, 0, 0, 9, 2, 5, 0, 0]
x2 = [9, 2, 2, 9, 0, 9, 2, 5, 0, 0, 9, 2, 5, 0, 0]

### VECTORIZED DOT PRODUCT OF VECTORS ###
tic = time.process_time()
dot = np.dot(x1,x2)
toc = time.process_time()
print ("dot = " + str(dot) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

### VECTORIZED OUTER PRODUCT ###
tic = time.process_time()
outer = np.outer(x1,x2)
toc = time.process_time()
print ("outer = " + str(outer) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

### VECTORIZED ELEMENTWISE MULTIPLICATION ###
tic = time.process_time()
mul = np.multiply(x1,x2)
toc = time.process_time()
print ("elementwise multiplication = " + str(mul) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")

### VECTORIZED GENERAL DOT PRODUCT ###
tic = time.process_time()
dot = np.dot(W,x1)
toc = time.process_time()
print ("gdot = " + str(dot) + "\n ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  1. 实现L1和L2的损失函数
  • 实现L1损失函数的numpy向量化版本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def L1(yhat, y):
    """
    Arguments:
    predicted labels 预测标签
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)

    Returns:
    defined above 上面定义
    loss -- the value of the L1 loss function defined above
    """

    loss = np.sum(np.abs(y - yhat))

    return loss
1
2
3
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])
print("L1 = " + str(L1(yhat,y)))
1
L1 = 1.1
  • 实现L2损失函数的numpy向量化版本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def L2(yhat, y):
    """
    Arguments:
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)

    Returns:
    loss -- the value of the L2 loss function defined above
    """

    loss = np.dot((y - yhat),(y - yhat).T)

    return loss
1
2
3
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])
print("L2 = " + str(L2(yhat,y)))
1
L2 = 0.43
  • 矢量化在深度学习中非常重要。它提供了计算效率和清晰度。
  • 你已经检查了L1和L2的损失。
  • 您熟悉np.sum,np.dot,np.multiply,np.maximum等许多numpy函数。