神经网络基础篇:Python 中的广播(Broadcasting in Python)
Python 中的广播

这是一个不同食物(每100g)中不同营养成分的卡路里含量表格,表格为3行4列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。
那么,现在想要计算不同食物中不同营养成分中的卡路里百分比。
现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和56+1.2+1.8
= 59,然后用56/59 = 94.9%算出结果。
可以看出苹果中的卡路里大部分来自于碳水化合物,而牛肉则不同。
对于其他食物,计算方法类似。首先,按列求和,计算每种食物中(100g)三种营养成分总和,然后分别用不用营养成分的卡路里数量除以总和,计算百分比。
那么,能否不使用for循环完成这样的一个计算过程呢?
假设上图的表格是一个4行3列的矩阵\(A\),记为 \(A_{3\times 4}\),接下来要使用Python的numpy库完成这样的计算。打算使用两行代码完成,第一行代码对每一列进行求和,第二行代码分别计算每种食物每种营养成分的百分比。
在jupyter notebook中输入如下代码,按shift+Enter运行,输出如下。

下面使用如下代码计算每列的和,可以看到输出是每种食物(100g)的卡路里总和。

其中sum的参数axis=0表示求和运算按列执行,之后会详细解释。
接下来计算百分比,这条指令将 \(3\times 4\)的矩阵\(A\)除以一个\(1 \times 4\)的矩阵,得到了一个 \(3 \times 4\)的结果矩阵,这个结果矩阵就是要求的百分比含量。

下面再来解释一下A.sum(axis = 0)中的参数axis。axis用来指明将要进行的运算是沿着哪个轴执行,在numpy中,0轴是垂直的,也就是列,而1轴是水平的,也就是行。
而第二个A/cal.reshape(1,4)指令则调用了numpy中的广播机制。这里使用 \(3 \times 4\)的矩阵\(A\)除以 \(1 \times 4\)的矩阵\(cal\)。技术上来讲,其实并不需要再将矩阵\(cal\) reshape(重塑)成 \(1 \times 4\),因为矩阵\(cal\)本身已经是 \(1 \times 4\)了。但是当写代码时不确定矩阵维度的时候,通常会对矩阵进行重塑来确保得到想要的列向量或行向量。重塑操作reshape是一个常量时间的操作,时间复杂度是\(O(1)\),它的调用代价极低。
那么一个 \(3 \times 4\) 的矩阵是怎么和 \(1 \times 4\)的矩阵做除法的呢?让来看一些更多的广播的例子。

在numpy中,当一个 \(4 \times 1\)的列向量与一个常数做加法时,实际上会将常数扩展为一个 \(4 \times 1\)的列向量,然后两者做逐元素加法。结果就是右边的这个向量。这种广播机制对于行向量和列向量均可以使用。
再看下一个例子。

用一个 \(2 \times 3\)的矩阵和一个 \(1 \times 3\) 的矩阵相加,其泛化形式是 \(m \times n\) 的矩阵和 \(1 \times n\)的矩阵相加。在执行加法操作时,其实是将 \(1 \times n\) 的矩阵复制成为 \(m \times n\) 的矩阵,然后两者做逐元素加法得到结果。针对这个具体例子,相当于在矩阵的第一列加100,第二列加200,第三列加300。这就是在前面的计算卡路里百分比的广播机制,只不过这里是除法操作(广播机制与执行的运算种类无关)。
下面是最后一个例子

这里相当于是一个 \(m \times n\) 的矩阵加上一个 \(m \times 1\) 的矩阵。在进行运算时,会先将 \(m \times 1\) 矩阵水平复制 \(n\) 次,变成一个 \(m \times n\) 的矩阵,然后再执行逐元素加法。
广播机制的一般原则如下:

这里先说一下本人对numpy广播机制的理解。
首先是numpy广播机制
如果两个数组的后缘维度的轴长度相符或其中一方的轴长度为1,则认为它们是广播兼容的。广播会在缺失维度和轴长度为1的维度上进行。
后缘维度的轴长度:A.shape[-1] 即矩阵维度元组中的最后一个位置的值
对于博客中卡路里计算的例子,矩阵 \(A_{3,4}\) 后缘维度的轴长度是4,而矩阵 \(cal_{1,4}\) 的后缘维度也是4,则他们满足后缘维度轴长度相符,可以进行广播。广播会在轴长度为1的维度进行,轴长度为1的维度对应axis=0,即垂直方向,矩阵 \(\text{cal}_{1,4}\) 沿axis=0(垂直方向)复制成为 \(\text{cal_temp}_{3,4}\) ,之后两者进行逐元素除法运算。
现在解释上图中的例子
矩阵 \(A_{m,n}\) 和矩阵 \(B_{1,n}\) 进行四则运算,后缘维度轴长度相符,可以广播,广播沿着轴长度为1的轴进行,即 \(B_{1,n}\) 广播成为 \({B_{m,n}}'\) ,之后做逐元素四则运算。
矩阵 \(A_{m,n}\) 和矩阵 \(B_{m,1}\) 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为1,可以广播,广播沿着轴长度为1的轴进行,即 \(B_{m,1}\) 广播成为 \({B_{m,n}}'\) ,之后做逐元素四则运算。
矩阵 \(A_{m,1}\) 和常数$ R$ 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为1,可以广播,广播沿着缺失维度和轴长度为1的轴进行,缺失维度就是axis=0,轴长度为1的轴是axis=1,即\(R\)广播成为 \({B_{m,1}}'\) ,之后做逐元素四则运算。
最后,对于Matlab/Octave 有类似功能的函数bsxfun。
总结一下broadcasting,可以看看下面的图:

神经网络基础篇:Python 中的广播(Broadcasting in Python)的更多相关文章
- 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇
[原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...
- 吴恩达深度学习:python中的广播
1.python中的广播: (1)广播是一种手段,可以让python代码执行得更快,我们来看看python实际如何执行. 下面矩阵列出了100克苹果.牛肉.鸡蛋和蛋白质中含有的碳水化合物.蛋白质和脂肪 ...
- 利用Python中的mock库对Python代码进行模拟测试
这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下 ...
- python学习笔记(1)python中的注释和安装python
注释 目标 注释的作用 单行注释 多行注释 01注释的作用 在程序中对代码的标注说明,增强代码的可读性 以 # 开头,# 右边的所有东西都被当做说明文字,而不是真正要执行的程序,只起到辅助说明作用 为 ...
- 【转】利用Python中的mock库对Python代码进行模拟测试
出处 https://www.toptal.com/python/an-introduction-to-mocking-in-python http://www.oschina.net/transla ...
- 面向对象和面向过程,python中的类class,python中程序的入口——main方法,
1.程序入口,让main显现出来: print(__name__)#__name___是模块中的隐藏字段,当前模块运行的函数名 if __name__ == __main__ __main__() # ...
- html/css基础篇——DOM中关于脱离文档流的几种情况分析
所谓的文档流,指的是元素排版布局过程中,元素会自动从左往右,从上往下的流式排列.并最终窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素.脱离文档流即是元素打乱了这个排列,或是从排版中拿走. ...
- 自动化测试基础篇--Selenium中数据参数化之TXT
摘自https://www.cnblogs.com/sanzangTst/p/7722594.html 一.搜索参数化 在TXT文件中保存需要搜索的内容: 测试代码: 1 #!/usr/bin/env ...
- 自动化测试基础篇--Selenium中JS处理浏览器弹窗
摘自https://www.cnblogs.com/sanzangTst/p/7692454.html 浏览器弹窗: 现在大多数网站都会使用自定义弹窗,使用Selenium自带的方法暂时处理不了,这时 ...
- 自动化测试基础篇--Selenium中JS处理滚动条
摘自https://www.cnblogs.com/sanzangTst/p/7692285.html 前言 什么是JS? JS就是JavaScript: JavaScript 是世界上最流行的脚本语 ...
随机推荐
- Oracle批量处理SQL
批量更新且更新字段数字需要递增 示例: DECLARE n int; -- 定义变量 BEGIN n:=1000010; --为n 赋值 FOR i IN (SELECT AGENCY.ID FROM ...
- PostgreSQL 9.6 文档: 数据类型
章 8. 数据类型 目录 8.1. 数字类型 8.1.1. 整数类型 8.1.2. 任意精度数字 8.1.3. 浮点类型 8.1.4. 序数类型 8.2. 货币类型 8.3. 字符类型 8.4. 二进 ...
- React: husky > pre-push hook failed (add --no-verify to bypass)
解决方案 提交commit和推送代码时都加上--no-verify参数,然他跳过检查 提交 推送
- Bootstrap使用方法
中文文档:https://www.bootcss.com/ 使用方式: 1.选择对应的文档: 2.网站会自动跳转,一般选择Bootstrap3中文文档: 3.点击入门,下拉找到基础模板,复制代码到 ...
- Django 组织json格式
@api_view(['GET', 'POST']) def api_test(request): classes = Classes.objects.all() # classes_data = C ...
- spring-mvc系列:简介和基本使用
目录 一.简介 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.基本使用 1.开发环境 2.创建maven工程 3.配置web.xml 4.创建SpringMVC的配 ...
- 洛谷 P1336 最佳课题选择 题解
P1336 最佳课题选择 题解 状态:考虑\(f_{i,j}\)表示前\(i\)种论文里面,一共写了\(j\)篇,的最少花费时间. 转移策略:我们一次考虑每一种论文写多少篇.假设写\(k\)篇,\(k ...
- [故障处理]nfs导致系统负载异常
目录 情况 排查 原因 解决 情况 某台虚拟机服务器系统负载极高,但是cpu.内存.IO都正常.home目录下无法使用ls,也无法使用 df -h. 排查 top看cpu和内存,正常. iotop看i ...
- 开源.NetCore通用工具库Xmtool使用连载 - HTTP请求篇
[Github源码] <上一篇> 介绍了Xmtool工具库中的XML操作类库,今天我们继续为大家介绍其中的HTTP请求类库. 在现如今的软件需求场景中,HTTP网络请求几乎是开发过程中必然 ...
- C#是否应该限制链式重载的设计模式?
1.代码的可阅读性 一眼看懂是什么意思,并且能看出生成的SQL是什么样的 var list = db.Queryable<Student>() .GroupBy(it => it.N ...