探秘TensorFlow 和 NumPy 的 Broadcasting 机制
作者:文哥的学习日记 发布时间:2023-07-22 06:09:50
在使用Tensorflow的过程中,我们经常遇到数组形状不同的情况,但有时候发现二者还能进行加减乘除的运算,在这背后,其实是Tensorflow的broadcast即广播机制帮了大忙。而Tensorflow中的广播机制其实是效仿的numpy中的广播机制。本篇,我们就来一同研究下numpy和Tensorflow中的广播机制。
1、numpy广播原理
1.1 数组和标量计算时的广播
标量和数组合并时就会发生简单的广播,标量会和数组中的每一个元素进行计算。
举个例子:
arr = np.arange(5)
arr * 4
得到的输出为:
array([ 0, 4, 8, 12, 16])
这个是很好理解的,我们重点来研究数组之间的广播
1.2 数组之间计算时的广播
用书中的话来介绍广播的规则:两个数组之间广播的规则:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相等或其中一方的长度为1,则认为他们是广播兼容的,广播会在缺失和(或)长度为1的维度上进行。
上面的规则挺拗口的,我们举几个例子吧:
二维的情况
假设有一个二维数组,我们想要减去它在0轴和1轴的均值,这时的广播是什么样的呢。
我们先来看减去0轴均值的情况:
arr = np.arange(12).reshape(4,3)
arr-arr.mean(0)
输出的结果为:
array([[-4.5, -4.5, -4.5],
[-1.5, -1.5, -1.5],
[ 1.5, 1.5, 1.5],
[ 4.5, 4.5, 4.5]])
0轴的平均值为[4.5,5.5,6.5],形状为(3,),而原数组形状为(4,3),在进行广播时,从后往前比较两个数组的形状,首先是3=3,满足条件而继续比较,这时候发现其中一个数组的形状数组遍历完成,因此会在缺失轴即0轴上进行广播。
可以理解成将均值数组在0轴上复制4份,变成形状(4,3)的数组,再与原数组进行计算。
书中的图形象的表示了这个过程(数据不一样请忽略):
我们再来看一下减去1轴平均值的情况,即每行都减去该行的平均值:
arr - arr.mean(1)
此时报错了:
我们再来念叨一遍我们的广播规则,均值数组的形状为(4,),而原数组形状为(4,3),按照比较规则,4 != 3,因此不符合广播的条件,因此报错。
正确的做法是什么呢,因为原数组在0轴上的形状为4,我们的均值数组必须要先有一个值能够跟3比较同时满足我们的广播规则,这个值不用多想,就是1。因此我们需要先将均值数组变成(4,1)的形状,再去进行运算:
arr-arr.mean(1).reshape((4,1))
得到正确的结果:
array([[-1., 0., 1.],
[-1., 0., 1.],
[-1., 0., 1.],
[-1., 0., 1.]])
三维的情况
理解了二维的情况,我们也就能很快的理解三维数组的情况。
首先看下图:
根据广播原则分析:arr1的shape为(3,4,2),arr2的shape为(4,2),它们的后缘轴长度都为(4,2),所以可以在0轴进行广播。因此,arr2在0轴上复制三份,shape变为(3,4,2),再进行计算。
不只是0轴,1轴和2轴也都可以进行广播。但形状必须满足一定的条件。举个例子来说,我们arr1的shape为(8,5,3),想要在0轴上广播的话,arr2的shape是(1,5,3)或者(5,3),想要在1轴上进行广播的话,arr2的shape是(8,1,3),想要在2轴上广播的话,arr2的shape必须是(8,5,1)。
我们来写几个例子吧:
arr2 = np.arange(24).reshape((2,3,4))
arr3_0 = np.arange(12).reshape((3,4))
print("0轴广播")
print(arr2 - arr3_0)
arr3_1 = np.arange(8).reshape((2,1,4))
print("1轴广播")
print(arr2 - arr3_1)
arr3_2 = np.arange(6).reshape((2,3,1))
print("2轴广播")
print(arr2 - arr3_2)
输出为:
0轴广播
[[[ 0 0 0 0]
[ 0 0 0 0]
[ 0 0 0 0]][[12 12 12 12]
[12 12 12 12]
[12 12 12 12]]]
1轴广播
[[[ 0 0 0 0]
[ 4 4 4 4]
[ 8 8 8 8]][[ 8 8 8 8]
[12 12 12 12]
[16 16 16 16]]]
2轴广播
[[[ 0 1 2 3]
[ 3 4 5 6]
[ 6 7 8 9]][[ 9 10 11 12]
[12 13 14 15]
[15 16
17 18]]]
如果我们想在两个轴上进行广播,那arr2的shape要满足什么条件呢?
arr1.shape | 广播轴 | arr2.shape |
---|---|---|
(8,5,3) | 0,1 | (3,),(1,3),(1,1,3) |
(8,5,3) | 0,2 | (5,1),(1,5,1) |
(8,5,3) | 1,2 | (8,1,1) |
具体的例子就不给出啦,嘻嘻。
2、Tensorflow 广播举例
Tensorflow中的广播机制和numpy是一样的,因此我们给出一些简单的举例:
二维的情况
sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3),0,0.1))
b = tf.Variable(tf.random_normal((2,1),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)
输出为:
array([[-0.1419442 , 0.14135399, 0.22752595],
[ 0.1382471 , 0.28228047, 0.13102233]], dtype=float32)
三维的情况
sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3,4),0,0.1))
b = tf.Variable(tf.random_normal((2,1,4),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)
输出为:
array([[[-0.0154749 , -0.02047186, -0.01022427, -0.08932371],
[-0.12693939, -0.08069084, -0.15459496, 0.09405404],
[ 0.09730847, 0.06936138, 0.04050628, 0.15374713]],[[-0.02691782, -0.26384184, 0.05825682, -0.07617196],
[-0.02653179, -0.01997554, -0.06522765, 0.03028341],
[-0.07577246, 0.03199019, 0.0321 , -0.12571403]]], dtype=float32)
错误示例
sess = tf.Session()
a = tf.Variable(tf.random_normal((2,3,4),0,0.1))
b = tf.Variable(tf.random_normal((2,4),0,0.1))
c = a - b
sess.run(tf.global_variables_initializer())
sess.run(c)
输出为:
ValueError: Dimensions must be equal, but are 3 and 2 for 'sub_2' (op: 'Sub') with input shapes: [2,3,4], [2,4].
来源:https://www.jianshu.com/p/550c90dfffa0
猜你喜欢
- 行高的概念看上去很简单——文字行的高度,其实,行高所涉及到的基础知识,对于今后理解其它属性也很重要。大片密密麻麻的文字往往会让人觉得乏味,因
- 简介在SQL SERVER中,数据库在硬盘上的存储方式和普通文件在Windows中的存储方式没有什么不同,仅仅是几个文件而已.SQL SER
- 偶写的几个ASP字符串处理函数,用于文章分页的小玩意函数名:StrLen作 用:取得字符串长度(汉字为2)参 
- 工作时需要取得MySQL中一个表的字段是否存在于是就使用Describe命令来判断mysql_connect(localhost, root
- 随着现在宽屏显示器的流行,Flash的全屏模式下,越来越需要考虑到普屏显示器与宽屏显示器的差别。Flash全屏模式有以下特点:窗口最大化,且
- MySQL 是完全网络化的跨平台关系型数据库系统,同时是具有客户机/服务器体系结构的分布式数据库管理系统。MySQL 是完全网络化
- 网上有这样一道题目:一个字符串String=“adadfdfseffserfefsefseetsdg”,找出里面出现次数最多的字母和出现的次
- 前些日子在SmashingMagazine看到一篇关于CSS3新技术不错的文章,它详细介绍了CSS3的新特性和它的使用方法,它包括:浏览器专
- 以前跟同事开玩笑时说过,我们遇到的用户在访谈测试过程中的表现基本上就三种类型,发泄型,赞美型和实话实说型。发泄型用户通常是在产品的使用过程中
- 常用Mysql查询语句记录一、授权1.授权本地用户对所有数据库具有所有权限> grant all privileges on
- 适用环境: PHP5.2.x / mysql 5.0.xclass Mysql { priva
- 1. document.form.item 问题 (1)现有问题:现有代码中存在许多 document.formName.item(&quo
- 但是Class这个东西,如果用得比较少,充其量只是一个大模块的包装方式. 只有大规模地用它来开发,才能显出它对项目管理的优越性来. 所谓的意
- 无论安装何版本的mysql,在管理工具的服务中启动mysql服务时都会在中途报错。内容为:在 本地计算机 无法启动mysql服务 错误106
- 不同的数字之间使用 空格“ ”,“$”,"*"等隔开,支持带小数点的字符串NumArray=str2num(LineSt
- 经常会看到这种弹出层背景变暗的效果,感觉手痒于是自己写了一个基于jquery的弹出层类。我习惯先写好结构和样式,然后再写js交互效果。结构定
- 装饰器模式(Decorator Pattern)是什么装饰器模式是一种结构型模式,它允许你在运行时为一个对象动态地添加新的行为,而不影响其原
- <!--#include file="conn/conn.asp"--> <% set Newslis
- 为了降低用户注册难度,国际站的主注册表单一直在改进。主注册三月至今发生了两次较大的变化,现在对表单调整的地方分解如下:1. 两步
- 仿windows选项卡或叫做tabpan以及tabpage,现在还有最新的进展譬如仿淘宝网导航菜单效果皆属于此类:运行代码框<scri