引言

本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。

要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不适用外部完备的框架前提下,实现我们想要的模型。本系列文章的宗旨就是通过这样的过程,让大家切实掌握深度学习底层实现,而不是仅做一个调包侠。
本系列文章首发于微信公众号:JavaNLP

本文来理解下什么是广播,以及其他框架是如何实现各种乘法)的。

广播

在这之前,必须先弄懂广播机制。在NumPyPyTorch中都有广播机制。

当要进行运算(不仅仅是乘法)的两个向量的形状不同时,如果符合某种条件,小向量会被广播成大的向量,使得它们的维度一致。

当要进行广播时,会逐元素地比较它们的形状。如果两个向量ab的形状相同。那么像a*b就是对应元素相乘。

> a = np.array([1.0, 2.0, 3.0])
> b = np.array([2.0, 2.0, 2.0])
> a * b
array([2., 4., 6.])

当运算中的两个向量形状不同,但满足某些条件时,将触发广播机制。

> a = np.array([[ 0, 0, 0],[10,10,10],[20,20,20],[30,30,30]])
> b = np.array([1,2,3]) #  (3,) -> (1,3) -> (4,3)
> a + b
array([[ 1,  2,  3],[11, 12, 13],[21, 22, 23],[31, 32, 33]])

下图很好的图示了上面的计算过程:

这里b是一个元素个数为3的数组,把它从左边添加一个维度,变成(1×3)(1 \times 3)(1×3)的向量,然后在第1个维度上重复4次,变成了(4×3)(4 \times 3)(4×3)的矩阵,使得ab的维度一致,再进行对应元素相加的加法运算。

上面说的某些条件是,首先让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在维度左边加 1 补齐,然后比较对应维度值,需要满足:

  • 它们是相等的
  • 其他一个为1

如果不满足该条件,就无法进行广播。

理论总是枯燥的,需要通过实例来理解。

还是以上面的例子为例,

a # (4,3)
b = np.array([1,2,3]) #  (3,) -> (1,3) -> (4,3)

a的形状是(4×3)(4 \times 3)(4×3),b的形状是(3,)(3,)(3,),b需要向a看齐,首先在其维度左边加1,直到它们拥有相同的维度个数(即a.ndim == b.ndimTrue),因此这里变成(1,3)(1,3)(1,3);

比较它们的第一个维度值,ab分别是444和111,此时b在该维度上重复4次,向大佬看齐,b变成了(4×3)(4 \times 3)(4×3);

比较它们的第二个维度值,都是333,它们是相等的,啥都不做;

它们只有两个维度,比较完了。

然后这里再进行加法操作。

下面看些其他例子:

> a = np.arange(4) # (4,)
> b = np.ones(5) # (5,)
> a + b
ValueError: operands could not be broadcast together with shapes (4,) (5,)

是的,这不合理。它俩的维度值不一样,无法进行对应元素相加,也无法进行广播。

再来看一个相对复杂一点的例子:

> a = np.arange(4).reshape(4,1) # (4,1)
> b = np.ones(5) # (5,)
> (a + b).shape
(4, 5)
> a + b
array([[1., 1., 1., 1., 1.],[2., 2., 2., 2., 2.],[3., 3., 3., 3., 3.],[4., 4., 4., 4., 4.]])

乍看起来有点奇怪,我们来分析一下。

a的形状是(4×1)(4 \times 1)(4×1),b的形状是(5,)(5,)(5,),b需要向a看齐,首先在其维度左边加1,因此这里变成(1,5)(1,5)(1,5);

比较它们的第一个维度值,ab分别是444和111,此时b在该维度上重复4次,向大佬a看齐,b变成了(4×5)(4 \times 5)(4×5);

比较它们的第二个维度值,ab分别是111和555,嘿,此时b咸鱼翻身成为被仰望的对象了,ab看齐,a在该维度上重复5次,a变成了(4×5)(4 \times 5)(4×5)

它们只有两个维度,比较完了。

然后这里再进行加法操作。

我们通过手动广播来执行一遍上面的例子。

# 先来看下a和b长啥样
> a
array([[0],[1],[2],[3]])
> b
array([1., 1., 1., 1., 1.])> a_new = np.repeat(a, repeats=5, axis=1) # a需要在第二个维度上重复5次
> a_new # (4,5)
array([[0, 0, 0, 0, 0],[1, 1, 1, 1, 1],[2, 2, 2, 2, 2],[3, 3, 3, 3, 3]])

再看对b对转换。

> b_new = b[np.newaxis, :] # 现在左边插入一个维度,变成了(1,5)
> b_new
array([[1., 1., 1., 1., 1.]])
> b_new = np.repeat(b_new, repeats=4,axis=0) # 然后在第一个维度上重复4次,变成了(4,5)
> b_new
array([[1., 1., 1., 1., 1.],[1., 1., 1., 1., 1.],[1., 1., 1., 1., 1.],[1., 1., 1., 1., 1.]])

它们的维度一致了,现在可以执行按元素相加了。

> a_new + b_new
array([[1., 1., 1., 1., 1.],[2., 2., 2., 2., 2.],[3., 3., 3., 3., 3.],[4., 4., 4., 4., 4.]])
> (a_new + b_new ) == (a + b) # 验证一下
array([[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True]])

Numpy

Numpy里面提供了很多种进行乘法计算的方法,主要讨论的是numpy.dotnumpy.matmulnumpy.multiply

np.dot

numpy.dot(a,b)

两个数组的点乘

  • 如果ab都是一维(1-D)数组,计算它们的内积
  • 如果ab都是二维)(2-D)数组,那么计算的是矩阵积,此时推荐使用matmula @ b
  • 如果ab是标量(0-D),等同于multiply,推荐使用numpy.multiply(a,b)a * b
  • 如果a是一个N维(N-D)数组,b是一个一维数组,那么就是计算ab最后一个维度(轴)上的内积(按元素相乘再求和)
  • 如果a是一个N维数组,b是一个M维(M-D,M>=2)数组,那么就是a最后一个维度(轴)上和b倒数第二个维度上的内积(对应元素相乘再求和)
> np.dot(3, 4) # 两个标量,等同于a*b
12
> a = np.arange(3) # [0 1 2]
> b = np.arange(3,6) # [3 4 5]
> print(a,b)
[0 1 2] [3 4 5]
> print(np.dot(a,b)) # 0*3 + 1*4 + 2*5=14 两个一维数组,计算它们的内积
14
> a = np.arange(6).reshape(-1,2) # (3,2)
> b = np.arange(2).reshape(2,-1) # (2,1)
> print(a)
[[0 1][2 3][4 5]]
> print(b)
[[0][1]]
> print(np.dot(a,b)) # (3,2) x (2,1) -> (3,1) 两个二维数组,计算矩阵乘法
[[1][3][5]]

下面来看一下稍微复杂一点的第4种情况

> a = np.arange(1,7).reshape(-1,3) #(2,3) a是二维数组
[[1 2 3][4 5 6]]
> b = np.array([1,2,3]) # (3,)  b是一维数组
[1 2 3]
> c = np.dot(a,b) # 计算a和b最后一个轴上的内积之和
[14 32]

相当于是用a的最后一个轴,(2,3)3对应的那个轴去和b的最后一个轴,也是第一个轴(3)去计算内积,即

[1*1 + 2*2 + 3*3, 4*1 + 5*2 + 6*3] = [14,32]

最复杂的是最后一种情况,由于博主无法想象出超过三维的情况(如果你能想象出来,

从零实现深度学习框架——理解广播和常见的乘法相关推荐

  1. python学习框架图-从零搭建深度学习框架(二)用Python实现计算图和自动微分

    我们在上一篇文章<从零搭建深度学习框架(一)用NumPy实现GAN>中用Python+NumPy实现了一个简单的GAN模型,并大致设想了一下深度学习框架需要实现的主要功能.其中,不确定性最 ...

  2. 从零实现深度学习框架——GloVe从理论到实战

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导.

  3. 从零实现深度学习框架——Seq2Seq从理论到实战【实战】

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导.

  4. 从零实现深度学习框架——RNN从理论到实战【理论】

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导.

  5. 从零实现深度学习框架——深入浅出Word2vec(下)

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导. 要深入理解深度学 ...

  6. 从零实现深度学习框架——从共现矩阵到点互信息

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导.

  7. 从零实现深度学习框架——LSTM从理论到实战【理论】

    引言 本着"凡我不能创造的,我就不能理解"的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导.

  8. 支撑千万规模类别分类技术,百度飞桨定义工业级深度学习框架

    2016 年,AlphaGo 横空出世,人工智能时代到来.同年,百度开源自研的深度学习框架 PaddlePaddle(飞桨),成为中国首个开源深度学习框架. 然而,这波由深度学习推动的技术和产业浪潮, ...

  9. 大数据分析PyTorchx深度学习框架教程

    PyTorch是一个不断发展的深度学习框架,具有许多令人兴奋的附加功能.我们将回顾其基本元素,并逐步演示构建简单的深度神经网络(DNN)的示例. PyTorch的基础知识-简介 自从2017年初推出它 ...

  10. 深度学习框架-Backbone汇总

    Backbone--  Neck -- Head 1.Backbone:翻译为骨干网络的意思,既然说是主干网络,就代表其是网络的一部分,那么是哪部分呢?这个主干网络大多时候指的是提取特征的网络,其作用 ...

最新文章

  1. 老生常谈:文字常量区的那点事
  2. 港口物流系统设计与优化-SMU在线学习笔记
  3. Awk by Example--转载
  4. telnet命令发送邮件
  5. virtualenv之python虚拟环境
  6. PAT甲级 1003 Dijkstra的口诀干货
  7. ABP教程(四)- 开始一个简单的任务管理系统 - 实现UI端的增删改查
  8. go import用法
  9. ①读后感之《当我们谈论爱情时我们在谈论什么》┊(美)雷蒙德.卡佛
  10. 红外编解码模块YS-NEC使用
  11. 马克思在《数学手稿》中提出如下问题:有30个人(包括男人、女人和小孩)在一家饭店吃饭共花50先令,其中每个男人花3先令,每个女人花2先令,每个小孩花1先令,问男人、女人、小孩各有多少人
  12. 汕头示范新品种技术 国稻种芯·中国水稻节:广东水稻粒粒归仓
  13. 【高德地图API】如何转到高德坐标系?
  14. Diagnosing OSGi uses conflicts
  15. java获取唯一序列号,Android 获取本机唯一序列号 和可变UUID方法
  16. vue 项目node服务器部署流程
  17. python小球游戏代码
  18. 使用scrapy爬取qq音乐
  19. python格式化输出xml_将Scrapy的输出格式化为XML
  20. 基于同态加密的隐私计算技术在基因序列演化分析场景的应用

热门文章

  1. 导出所有DB2存储过程的四种方法
  2. Quartz的时间配置
  3. RESTful源码笔记之RESTful Framework的基本组件
  4. 《自控力》-自控力极限
  5. [转]详细解说:简单CSS3实现炫酷读者墙
  6. SQL中COUNT()函数介绍
  7. Centos 03 基础命令
  8. 【纪念】我的大学同学名单
  9. Linux虚拟机下mysql 5.7安装配置方法图文教程
  10. PHP GZ压缩与解压