小白也能看懂的深度学习5

2.11 向量化

这篇文章我们来讲向量化,这需要你有一定的python知识,不然听了缺少实践也不好。当然你一定是能够听懂的。

向量化是非常基础的去除代码中 for 循环的艺术,在深度学习安全领域、深度学习实践
中,你会经常发现自己训练大数据集,因为深度学习算法处理大数据集效果很棒,所以你的
代码运行速度非常重要,否则如果在大数据集上,你的代码可能花费很长时间去运行,你将
要等待非常长的时间去得到结果。

那么为什么用向量化的效率会高呢?

向量化是利用NumPy等库提供的高效数组操作来替代显式的循环。NumPy等库的底层实现是用C语言编写的,因此在处理数组操作时非常高效。

import numpy as np #导入 numpy 库 
a = np.array([1,2,3,4]) #创建一个数据 
print(a) 
# [1 2 3 4] 
import time #导入时间库 
a = np.random.rand(1000000) 
b = np.random.rand(1000000) #通过 round 随机得到两个一百万维度的数组 
tic = time.time() #现在测量一下当前时间
#向量化的版本 
c = np.dot(a,b) 
toc = time.time() 
print(“Vectorized version:” + str(1000*(toc-tic)) +”ms”) #打印一下向量
化的版本的时间
#继续增加非向量化的版本 
c = 0 
tic = time.time() 
for i in range(1000000): 
 c += a[i]*b[i] 
toc = time.time() 
print(c) 
print(“For loop:” + str(1000*(toc-tic)) + “ms”)#打印 for 循环的版本的时
间

这里我们来具体感受一下,向量化到底有什么魅力。

在两个方法中,向量化和非向量化计算了相同的值,如你所见,向量化版本花费了 1.5 毫秒,非向量化版本的 for 循环花费了大约几乎 500 毫秒,非向量化版本多花费了 300 倍时 间。所以在这个例子中,仅仅是向量化你的代码,就会运行 300 倍快。这意味着如果向量化方法需要花费一分钟去运行的数据,for 循环将会花费 5 个小时去运行。

一句话总结,以上都是再说和 for 循环相比,向量化可以快速得到结果。 
你可能听过很多类似如下的话,“大规模的深度学习使用了 GPU 或者图像处理单元实
现”,但是我做的所有的案例都是在 jupyter notebook 上面实现,这里只有 CPU,CPU 和 GPU
都有并行化的指令,他们有时候会叫做 SIMD 指令,这个代表了一个单独指令多维数据。这
个的基础意义是,如果你使用了 built-in 函数,像 np.function 或者并不要求你实现循环的。

它可以让 python 的充分利用并行化计算,这是事实在 GPU 和 CPU 上面计算,GPU 更加擅长 SIMD 计算,但是 CPU 事实上也不是太差,可能没有 GPU 那么擅长吧。

2.13 向量化逻辑回归

我们已经讨论过向量化是如何显著加速你的代码,在这里我们将讨论如何实现逻辑回归的向量化计算。

这样就能处理整个数据集,甚至不会用一个明确的 for 循环就能实现对于整个数据集梯度下降算法的优化,并且当我们后面谈到神经网络时同样也不会用到一个明确的 for 循环。

可以想象,这项技术是多么伟大。

从这幅图中也不难见得我们的意图,本质上,我们就是将一连串的数据变成了一些行向量和列向量,再通过矩阵化的乘法,从而对一组数据进行计算训练,比显性的for循环快速很多。但是在这边,我们先了解一下广播和前向传播。

广播

在深度学习中,广播(Broadcasting)是一种强大的技术,它允许不同形状的数组进行算术运算。广播机制使得在处理张量(多维数组)时更加灵活和高效。这种机制在许多深度学习框架中都有实现,如NumPy、TensorFlow和PyTorch。

广播的核心思想是自动扩展较小的数组,使其与较大的数组具有相同的形状,从而可以进行逐元素操作。具体规则如下:

维度对齐:如果两个数组的维度不同,较短的数组会在其形状前面添加1,直到两个数组的维度相同。
尺寸匹配:对于每个维度,如果两个数组的尺寸相同或其中一个为1,则可以进行广播。如果某个维度的尺寸不匹配且都不为1,则无法进行广播。

看起来很难理解,但其实你就理解为向量的加减,只不过拥有限制,同类人才能加减。也就是说,要么0向量那一定可以进行广播,要么长度相同来叠加,才能广播。

import numpy as np

# 一维数组与标量
a = np.array([1, 2, 3])
b = 2
result = a + b  # 结果是 [3, 4, 5]

# 二维数组与一维数组
A = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([1, 0, -1])
result = A + b  # 结果是 [[2, 2, 2], [5, 5, 5]]

# 三维数组与二维数组
A = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
B = np.array([[1, 2], [3, 4]])
result = A + B  # 结果是 [[[2, 4], [6, 8]], [[6, 8], [10, 12]]]

这里放一下具体实现,可能代码会更容易理解。

前向传播

前向传播(Forward Propagation)是深度学习中神经网络的核心过程之一。它是指从输入层开始,通过每一层的计算,最终得到输出层的结果。前向传播是训练和推理过程中必不可少的步骤。

也就是说,我们从第一节课的房价预测开始,就已经一直在使用这个前向传播了。他里面包括输入层、隐层和输出层。

下面是一个使用Python和NumPy实现的简单全连接神经网络的前向传播过程:看不懂就跳过,但是要大致理解思路

import numpy as np

# 定义激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 定义输入数据
x = np.array([0.1, 0.2, 0.3])

# 初始化权重和偏置
W1 = np.random.randn(4, 3)  # 4个隐藏单元,3个输入特征
b1 = np.random.randn(4, 1)
W2 = np.random.randn(2, 4)  # 2个隐藏单元,4个输入特征
b2 = np.random.randn(2, 1)
W3 = np.random.randn(1, 2)  # 1个输出单元,2个输入特征
b3 = np.random.randn(1, 1)

# 前向传播
z1 = np.dot(W1, x) + b1
h1 = sigmoid(z1)

z2 = np.dot(W2, h1) + b2
h2 = sigmoid(z2)

z3 = np.dot(W3, h2) + b3
y = sigmoid(z3)

print("Output:", y)

好了,感谢阅读,我们下篇文章见!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值