神经网络基础篇: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 是世界上最流行的脚本语 ...
随机推荐
- 【WebGL系列-04】清除缓冲区并绘制图形
清除缓冲区并绘制图形 前文中已经准备好了webgl程序和绘制所用的数据,但是在绘制图像之前,还要对画布进行处理. 清除缓冲区 由于图像的绘制是一帧一帧绘制,每一帧针对当前的状态,计算屏幕上每个像素的颜 ...
- 阿里如何实现秒级百万TPS?搜索离线大数据平台架构解读
★ 淘宝搜索阶段 在2008-2012这个阶段,我们重点支持淘宝搜索的业务发展,随着淘宝商品量的不断增加,逐步引入Hadoop.Hbase等开源大数据计算和存储框架,实现了搜索离线系统的分布式化,有力 ...
- UG NX实现叉车运输货物功能遇见的问题
在前一段时间编写模拟叉车运输功能时遇到,货物无法跟随的问题(如下动图) 后面发现是速度太快的原因导致货物没有跟着动,类似于抽桌布的感觉 解决办法有两种:第一种解决办法很简单就是把速度降低到不超过 2 ...
- django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported.
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing a ...
- 【pandas小技巧】--缺失值的列
在实际应用中,数据集中经常会存在缺失值,也就是某些数据项的值并未填充或者填充不完整.缺失值的存在可能会对后续的数据分析和建模产生影响,因此需要进行处理. pandas提供了多种方法来处理缺失值,例如删 ...
- 转 致创业者:APP已死 服务永生
前几日,有位创业者和我讲他在带领团队做一个将爱踢球的人集中在一起的App,我告诉他你的创业方向错了.原因在于你的目的是要为爱踢球的人提供服务,而你现在却在竭尽全力的做App,你应该做的是设计你为爱踢球 ...
- 一次Python本地cache不当使用导致的内存泄露
背景 近期一个大版本上线后,Python编写的api主服务使用内存有较明显上升,服务重启后数小时就会触发机器的90%内存占用告警,分析后发现了本地cache不当使用导致的一个内存泄露问题,这里记录一下 ...
- mysql到底需不需要容器化?
前言:在容器化的时代,当然一切皆可容器化.在docker官网首页赫然有下面这几个大字.足以知道docker的优势.那么且问,mysql适合跑在docker中吗? 当然,这个问题有人说可以,也有人说不可 ...
- CodeForces 1388C Uncle Bogdan and Country Happiness
题意 给一棵\(n\)节点的树,每个节点有\(a[i]\)个人住,他们从\(1\)号节点回家,回家路上可能从开心的状态变成不开心的状态(但不可以由不开心变为开心),每个节点有个探测器,会探测经过该节点 ...
- 云上的甜蜜早安:腾讯云云函数助力PHP打造女友专属每日推送
用腾讯云的云函数做一个微信公众号早安,每天定时发送早安给你的女朋友! 1.首先我们登录腾讯云,在搜索栏搜索云函数,或直接用这个链接进入curl.qcloud.com/Td0IkpmD 2.进入云函数, ...