神经网络基础篇:向量化(Vectorization)
向量化
向量化是非常基础的去除代码中for循环的艺术,在深度学习安全领域、深度学习实践中,会经常发现自己训练大数据集,因为深度学习算法处理大数据集效果很棒,所以的代码运行速度非常重要,否则如果在大数据集上,代码可能花费很长时间去运行,将要等待非常长的时间去得到结果。所以在深度学习领域,运行向量化是一个关键的技巧,让举个栗子说明什么是向量化。
在逻辑回归中需要去计算\(z={{w}^{T}}x+b\),\(w\)、\(x\)都是列向量。如果有很多的特征那么就会有一个非常大的向量,所以\(w\in {{\mathbb{R}}^{{{n}_{x}}}}\) , \(x\in{{\mathbb{R}}^{{{n}_{x}}}}\),所以如果想使用非向量化方法去计算\({{w}^{T}}x\),需要用如下方式(python)
z=0
for i in range(n_x):
z += w[i]*x[i]
z += b
这是一个非向量化的实现,会发现这真的很慢,作为一个对比,向量化实现将会非常直接计算\({{w}^{T}}x\),代码如下:
z=np.dot(w,x)+b
这是向量化计算\({{w}^{T}}x\)的方法,将会发现这个非常快
让用一个小例子说明一下,在的将会写一些代码(以下是在Jupyter notebook上写的Python代码,)
import numpy as np #导入numpy库
a = np.array([1,2,3,4]) #创建一个数据a
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那么擅长吧。接下来,将看到向量化怎么能够加速的代码,经验法则是,无论什么时候,避免使用明确的for循环。
以下代码及运行结果截图:
向量化的更多例子(More Examples of Vectorization)
从上面例子中,知道了怎样通过numpy内置函数和避开显式的循环(loop)的方式进行向量化,从而有效提高代码速度。
经验提醒,当在写神经网络程序时,或者在写逻辑(logistic)回归,或者其他神经网络模型时,应该避免写循环(loop)语句。虽然有时写循环(loop)是不可避免的,但是可以使用比如numpy的内置函数或者其他办法去计算。当这样使用后,程序效率总是快于循环(loop)。
让看另外一个例子。如果想计算向量\(u=Av\),这时矩阵乘法定义为,矩阵乘法的定义就是:\(u_{i} =\sum_{j}^{}{A_{\text{ij}}v_{i}}\),这取决于怎么定义\(u_{i}\)值。同样使用非向量化实现,\(u=np.zeros(n,1)\), 并且通过两层循环\(for(i):for(j):\),得到\(u[i]=u[i]+A[i][j]*v[j]\) 。现在就有了\(i\) 和 \(j\) 的两层循环,这就是非向量化。向量化方式就可以用\(u=np.dot(A,v)\),右边这种向量化实现方式,消除了两层循环使得代码运行速度更快。
下面通过另一个例子继续了解向量化。如果已经有一个向量\(v\),并且想要对向量\(v\)的每个元素做指数操作,得到向量\(u\)等于\(e\)的\(v_1\),\(e\)的\(v_2\),一直到\(e\)的\(v_n\)次方。这里是非向量化的实现方式,首先初始化了向量\(u=np.zeros(n,1)\),并且通过循环依次计算每个元素。但事实证明可以通过python的numpy内置函数,帮助计算这样的单个函数。所以会引入import numpy as np
,执行 \(u=np.exp(v)\) 命令。注意到,在之前有循环的代码中,这里仅用了一行代码,向量\(v\)作为输入,\(u\)作为输出。已经知道为什么需要循环,并且通过右边代码实现,效率会明显的快于循环方式。
事实上,numpy库有很多向量函数。比如 u=np.log
是计算对数函数(\(log\))、 np.abs()
计算数据的绝对值、np.maximum(v, 0)
按元素计算\(v\)中每个元素和和0相比的最大值,v**2
代表获得元素 \(v\) 每个值的平方、 1/v
获取 \(v\) 中每个元素的倒数等等。所以当想写循环时候,检查numpy是否存在类似的内置函数,从而避免使用循环(loop)方式。
那么,将刚才所学到的内容,运用在逻辑回归的梯度下降上,看看是否能简化两个计算过程中的某一步。这是逻辑回归的求导代码,有两层循环。在这例子有\(n\)个特征值。如果有超过两个特征时,需要循环 \(dw_1\) 、\(dw_2\) 、\(dw_3\) 等等。所以 \(j\) 的实际值是1、2 和 \(n_x\),就是想要更新的值。所以想要消除第二循环,在这一行,这样就不用初始化 \(dw_1\) , \(dw_2\) 都等于0。去掉这些,而是定义 \(dw\) 为一个向量,设置 \(u=np.zeros(n(x),1)\)。定义了一个\(x\)行的一维向量,从而替代循环。仅仅使用了一个向量操作 \(dw=dw+x^{(i)}dz^{(i)}\) 。最后,得到 \(dw=dw/m\) 。现在通过将两层循环转成一层循环,仍然还有这个循环训练样本。
希望这个博客有给读者一点向量化感觉,减少一层循环使代码更快,但事实证明能做得更好。所以在下个博客,将进一步的讲解逻辑回归,将会看到更好的监督学习结果。在训练中不需要使用任何 for 循环,也可以写出代码去运行整个训练集。到此为止一切都好。
神经网络基础篇:向量化(Vectorization)的更多相关文章
- 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇
[原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...
- 基础篇|一文搞懂RNN(循环神经网络)
基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...
- 《量化投资:以MATLAB为工具》连载(2)基础篇-N分钟学会MATLAB(中)
http://www.matlabsky.com/thread-43937-1-1.html <量化投资:以MATLAB为工具>连载(3)基础篇-N分钟学会MATLAB(下) ...
- 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)
http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...
- (转)深度学习word2vec笔记之基础篇
深度学习word2vec笔记之基础篇 声明: 1)该博文是多位博主以及多位文档资料的主人所无私奉献的论文资料整理的.具体引用的资料请看参考文献.具体的版本声明也参考原文献 2)本文仅供学术交流,非商用 ...
- 深度学习word2vec笔记之基础篇
作者为falao_beiliu. 作者:杨超链接:http://www.zhihu.com/question/21661274/answer/19331979来源:知乎著作权归作者所有.商业转载请联系 ...
- Andrew Ng - 深度学习工程师 - Part 1. 神经网络和深度学习(Week 2. 神经网络基础)
=================第2周 神经网络基础=============== ===2.1 二分分类=== ===2.2 logistic 回归=== It turns out, whe ...
- C#多线程之基础篇3
在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 2000条你应知的WPF小姿势 基础篇<15-21>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...
随机推荐
- 超星读书下载的pdz文件如何转为pdf文件详细教程(亲测有效)
前言: 你还在为超星读书下载的pdz格式书籍而烦恼吗?还在为不知道怎么将pdz格式转为pdf格式而气愤吗?请看以下教程. 流程: 使用超星阅读器将pdz文件转换为.xps或.oxps文件 利用第三方软 ...
- mysql5.5自定义函数-计算并赋值
mysql自定义函数的写法 特别注意,将全部的定义现在最前面,然后再写其他语句,因为之前将定义变量和赋值混着写,死活报错.最后一个前同事高手"邢哥"解决. DELIMITER $$ ...
- 【短道速滑十一】标准的Gabor滤波器及Log_Gabor滤波器的实现、解析、速度优化及其和Halcon中gen_gabor的比较。
最近有朋友在研究Halcon中gen_gabor的函数,和我探讨,因为我之前也没有怎么去关注这个函数,因此,前前后后大概也折腾了有一个星期去模拟实现这个东西,虽然最终没有实现这个函数,但是也是有所收获 ...
- 生成CSR和自签名证书
CSR,全称Certificate Signing Request(证书签发请求),是一种包含了公钥和与主题(通常是实体的信息,如个人或组织)相关的其他信息的数据结构.CSR通常用于向证书颁发机构(C ...
- Ubuntu18.04环境下安装redis 6.2.0,配置文件的部分参数说明
环境是win11的Linux子系统Ubuntu-18.04,安装方式是源码安装,也可以用apt安装(见本文最后参考资料),用的用户是默认用户(所以一些关键命令要注意用sudo,不用会报错) 安装: j ...
- k8s Redis安装部署
一.文档简介 作者:lanjiaxuan 邮箱:lanheader@163.com 博客地址:https://www.cnblogs.com/lanheader/ 更新时间:2021-07-09 安装 ...
- 拿到开发板需要做的事情 -- 配置Python环境
1.查看系统时间 date -R 2.修改系统时间 windows上时间项目时间正常,Ubuntu16.04上时间错误 - 贾斯丁哔哔 - 博客园 (cnblogs.com) 3.安装pip3 sud ...
- 一文读懂强化学习:RL全面解析与Pytorch实战
在本篇文章中,我们全面而深入地探讨了强化学习(Reinforcement Learning)的基础概念.主流算法和实战步骤.从马尔可夫决策过程(MDP)到高级算法如PPO,文章旨在为读者提供一套全面的 ...
- Transformers 中原生支持的量化方案概述
本文旨在对 transformers 支持的各种量化方案及其优缺点作一个清晰的概述,以助于读者进行方案选择. 目前,量化模型有两个主要的用途: 在较小的设备上进行大模型推理 对量化模型进行适配器微调 ...
- 【NOI2014】 魔法森林---解题报告
传送门 题目大意 给定 \(n\) 个点和 \(m\) 条边.每条边包含起点终点和两个精灵的最低限制,求最少需要携带的精灵数量. 题目解析 直接套 LCT 板子 将所有边按照进行升序排序,从小到大将边 ...