神经网络的编程基础2

Neural Networks and Deep Learning(week 2_python 编程练习-2)

吴恩达深度学习课程第二周编程练习——python的numpy基础-2

  • 本文主要讲python基础编程numpy基础的第二部分,即向量化与非向量化的差别及如何使用numpy进行向量化。
  • 第一部分见上一篇,点击链接查看。

Python Basics with Numpy-2

2.向量化

在深度学习中需要处理规格很大的数据集。因此,一个不是最佳的可计算函数会成为算法的致命瓶颈,而且可能导致计算运行结果需要花费数年。为了确保代码计算更有效率,需要使用向量化。首先,试着区分以下例子中dot/outer/elementwise运算结果的不同。

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运算 ###
tic = time.process_time()
dot = 0
### 此处表示基本的dot点乘运算即两向量相应位置的元素相乘再相加。
### 最后的结果为一个实数。
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")

### 基本的outer运算 ###
tic = time.process_time()
### 此处表示基本的outer运算,即我们熟知的矩阵/向量乘法运算。
### 假设len(x1)=m,len(x2)=n,x1表示行向量,x2表示列向量。即(m,1)(1,n)维的向量相乘,结果为(m,n)维的矩阵。
### (m,n)维矩阵中元素x_ij = x1(i,1)*x2(1,j)
outer = np.zeros((len(x1), len(x2))) # 创建一个len(x1)*len(x2)维的零矩阵。
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")

### 基本的elementwise运算 ###
tic = time.process_time()
### 与dot运算类似,均是对应位置元素相乘,x1_i * x2_i, 但是不用相加,而是各位置元素相乘得到的值组成一个新向量。

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")
### 基本的总体dot运算 ###
W = np.random.rand(3,len(x1)) # 随机 3*len(x1) 维的numpy array
tic = time.process_time()
### W是随机矩阵,类型为numpy array。此例gdot(1,3)维的向量,gdot中的第i个值,为随机生成的W中第i行向量与x1作dot(点乘运算,即基本向量dot运算)得到的值。

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")
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运算 ###
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")

### 向量化后的outer运算 ###
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")

### 向量化后的elementwise运算 ###
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")

### 向量化后的general dot运算 ###
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")

你可能注意到了,向量化后的代码更简洁,运算速度也更快。对更大的矩阵/向量来说,运算速度差异会更大。

注意:np.dot()表示矩阵-矩阵或矩阵-向量乘法,与np.multiply()*运算符不同。

关于np.dot,np.outer,np.multiply的区别可以看此链接。

2.1 计算L1,L2损失函数

Exercise 7 – L1

计算向量化后的L1损失函数,函数abs(x)会被用到。

注意:

  • 损失函数用于评估模型的性能。损失越大,预测值%5Chat%7By%7D与实际值y的差异越大。在深度学习中,可以使用梯度下降等优化算法,或者可以继续修改模型以最小化成本。
  • L1 损失的定义如下:

L_1%28%5Chat%7By%7D%2C%20y%29%20%3D%20%5Csum_%7Bi%3D0%7D%5E%7Bm-1%7D%7Cy%5E%7B%28i%29%7D%20-%20%5Chat%7By%7D%5E%7B%28i%29%7D%7C

# FUNCTION:计算L1 loss

def L1(yhat, y):
    """
    参数:
    	yhat -- m维向量(预测值标签)
    	y -- m维向量 (真实值标签)
    
    返回:
    loss -- 上面定义的L1函数的值
    """
    loss = np.sum(abs(y-yhat))
    return loss
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])
print("L1 = " + str(L1(yhat, y)))  

正确的输出应该是:L1 = 1.1

Exercise 8 – L2

计算向量化后的L2损失函数。有许多种计算L2损失的方法,不过推荐使用np.dot()

如果x%20%3D%20%5Bx_1%2C%20x_2%2C%20...%2C%20x_n%5D,则np.dot(x,x)=%5Csum_%7Bj%3D0%7D%5En%20x_j%5E%7B2%7D

  • L2损失的定义如下:

L_2%28%5Chat%7By%7D%2Cy%29%20%3D%20%5Csum_%7Bi%3D0%7D%5E%7Bm-1%7D%28y%5E%7B%28i%29%7D%20-%20%5Chat%7By%7D%5E%7B%28i%29%7D%29%5E2

# FUNCTION:计算L2 loss

def L2(yhat, y):
    """
    参数:
    	yhat -- m维向量(预测值标签)
    	y -- m维向量 (真实值标签)
    
    返回:
    loss -- 上面定义的L2函数的值
    """
    
    loss = np.sum(np.dot(y-yhat,y-yhat))
       
    return loss
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])

print("L2 = " + str(L2(yhat, y)))

正确的输出应该是:L2 = 0.43
总结:
在深度学习中,尽量避免使用for、while循环,而是将向量化后的数据作为输入。这样可以最大程度地加快运算速度,并且能大大简化我们的模型。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年3月18日 下午3:57
下一篇 2022年3月18日 下午4:12

相关推荐