Python 中的广播

这是一个不同食物(每100g)中不同营养成分的卡路里含量表格,表格为3行4列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。

那么,现在想要计算不同食物中不同营养成分中的卡路里百分比。

现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和56+1.2+1.8

= 59,然后用56/59 = 94.9%算出结果。

可以看出苹果中的卡路里大部分来自于碳水化合物,而牛肉则不同。

对于其他食物,计算方法类似。首先,按列求和,计算每种食物中(100g)三种营养成分总和,然后分别用不用营养成分的卡路里数量除以总和,计算百分比。

那么,能否不使用for循环完成这样的一个计算过程呢?

假设上图的表格是一个4行3列的矩阵\(A\),记为 \(A_{3\times 4}\),接下来要使用Pythonnumpy库完成这样的计算。打算使用两行代码完成,第一行代码对每一列进行求和,第二行代码分别计算每种食物每种营养成分的百分比。

jupyter notebook中输入如下代码,按shift+Enter运行,输出如下。

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

其中sum的参数axis=0表示求和运算按列执行,之后会详细解释。

接下来计算百分比,这条指令将 \(3\times 4\)的矩阵\(A\)除以一个\(1 \times 4\)的矩阵,得到了一个 \(3 \times 4\)的结果矩阵,这个结果矩阵就是要求的百分比含量。

下面再来解释一下A.sum(axis = 0)中的参数axisaxis用来指明将要进行的运算是沿着哪个轴执行,在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)的更多相关文章

  1. 【原创 深度学习与TensorFlow 动手实践系列 - 3】第三课:卷积神经网络 - 基础篇

    [原创 深度学习与TensorFlow 动手实践系列 - 3]第三课:卷积神经网络 - 基础篇 提纲: 1. 链式反向梯度传到 2. 卷积神经网络 - 卷积层 3. 卷积神经网络 - 功能层 4. 实 ...

  2. 吴恩达深度学习:python中的广播

    1.python中的广播: (1)广播是一种手段,可以让python代码执行得更快,我们来看看python实际如何执行. 下面矩阵列出了100克苹果.牛肉.鸡蛋和蛋白质中含有的碳水化合物.蛋白质和脂肪 ...

  3. 利用Python中的mock库对Python代码进行模拟测试

    这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下     ...

  4. python学习笔记(1)python中的注释和安装python

    注释 目标 注释的作用 单行注释 多行注释 01注释的作用 在程序中对代码的标注说明,增强代码的可读性 以 # 开头,# 右边的所有东西都被当做说明文字,而不是真正要执行的程序,只起到辅助说明作用 为 ...

  5. 【转】利用Python中的mock库对Python代码进行模拟测试

    出处 https://www.toptal.com/python/an-introduction-to-mocking-in-python http://www.oschina.net/transla ...

  6. 面向对象和面向过程,python中的类class,python中程序的入口——main方法,

    1.程序入口,让main显现出来: print(__name__)#__name___是模块中的隐藏字段,当前模块运行的函数名 if __name__ == __main__ __main__() # ...

  7. html/css基础篇——DOM中关于脱离文档流的几种情况分析

    所谓的文档流,指的是元素排版布局过程中,元素会自动从左往右,从上往下的流式排列.并最终窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素.脱离文档流即是元素打乱了这个排列,或是从排版中拿走. ...

  8. 自动化测试基础篇--Selenium中数据参数化之TXT

    摘自https://www.cnblogs.com/sanzangTst/p/7722594.html 一.搜索参数化 在TXT文件中保存需要搜索的内容: 测试代码: 1 #!/usr/bin/env ...

  9. 自动化测试基础篇--Selenium中JS处理浏览器弹窗

    摘自https://www.cnblogs.com/sanzangTst/p/7692454.html 浏览器弹窗: 现在大多数网站都会使用自定义弹窗,使用Selenium自带的方法暂时处理不了,这时 ...

  10. 自动化测试基础篇--Selenium中JS处理滚动条

    摘自https://www.cnblogs.com/sanzangTst/p/7692285.html 前言 什么是JS? JS就是JavaScript: JavaScript 是世界上最流行的脚本语 ...

随机推荐

  1. (数据科学学习手札153)基于martin的高性能矢量切片地图服务构建

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,在日常研发地图类应用的场景中, ...

  2. redis 使用 nologin 用户启动

    添加不可登录的redis用户 sudo useradd -M -s /sbin/nologin redis 为redis新建目录,并设置属性 mkdir -p /data/redis &&am ...

  3. 王道oj/problem18

    网址:略 思路:见注释:有bug:插入时1和2的结果正好相反,稍后编辑. 代码: #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#incl ...

  4. JavaWeb和MVC三层架构

    JavaWeb 概述 网站发布和部署一定要依托技术语言吗: 不一定,一个网站可以直接发布和部署,因为因为浏览器能够识别网页只需要两样东西,网络和静态页面,还有一个装在他们的容器,比如 nginx. 静 ...

  5. ES6之清楚明白的使用类(class)

    定义 类是构造函数.原型链的语法糖. 定义类有两种方式 class Student { } var Student = class { } 某些浏览器可能无法解析es6及以上的语法,这时候需要通过ba ...

  6. 使用$test$plusargs提高RTL验收速度

    0 前言 这段时间在整合一个小ip,因为要验证每个feature是否可行,需要用testbench + C语言的方式进行仿真验证,由于每种feature不仅要在C语言中修改寄存器配置,还要再testb ...

  7. [git]基于GitLab搭建本地Git服务

    0.准备 (如果选择docker安装)Docker 系统:CentOS 7 1.安装部署GitLab 1.1.使用docker安装中文社区版GitLab 在docker上发现一个中文版的gitlab, ...

  8. SpringBoot3进阶用法

    标签:切面.调度.邮件.监控: 一.简介 在上篇<SpringBoot3基础>中已经完成入门案例的开发和测试,在这篇内容中再来看看进阶功能的用法: 主要涉及如下几个功能点: 调度任务:在应 ...

  9. 【译】基于XAML的跨平台框架对比分析

    多年来,基于XAML的UI框架已经有了很大的发展.下面的图表是最好的说明.这些框架主要包含:支持跨平台应用的Avalonia UI, Uno Platform和 .NET MAUI.事实上,除了Ava ...

  10. vite 找不到依赖模块:[plugin:vite:dep-pre-bundle]

    问题描述: 运行项目时,出现[plugin:vite:dep-pre-bundle] 错误.这种问题一般为依赖的包未正常配置相关字段,导致vite无法找到包的入口. 遇到这种模块内.找不到引用模块的, ...