博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TensorFlow2.0(二):数学运算
阅读量:5272 次
发布时间:2019-06-14

本文共 3708 字,大约阅读时间需要 12 分钟。

1 基本运算:加(+)、减(-)、点乘(*)、除(/)、地板除法(//)、取余(%)

基本运算中所有实例都以下面的张量a、b为例进行:

>>> a = tf.random.uniform([2, 3], minval=1, maxval=6,dtype=tf.int32)>>> b = tf.random.uniform([2, 3], minval=1, maxval=6,dtype=tf.int32)>>> a
>>> b

(1)加(+)

>>> tf.add(a,b)
>>> a + b

(2)减(-)

>>> tf.subtract(a,b)
>>> a - b

(3)乘法(*)

>>> tf.multiply(a,b)
>>> a * b

(4)除法(/)

>>> tf.divide(a,b)
>>> a/b

(5)地板除法(//)

>>> tf.floor_div(a,b)
>>> a//b

(6)取余(%)

>>> tf.mod(b,a)
>>> b % a

可以看出,对于基本运算加(+)、减(-)、点乘(*)、除(/)、地板除法(//)、取余(%),都是对应元素进行运算。

2 指数运算、开方、对数运算

(1)对数运算

TensorFlow提供tf.math.log()方法来求对数,当然,求的是以自然常数$e$为底的对数:

>>> e = 2.71828183>>> a = tf.constant([e, e*e, e*e*e])>>> tf.math.log(a)
>>> c = tf.fill([2,2],1.)>>> tf.math.log(c)

注意:TensorFlow中没有提供函数实现以其他数值为底的对数运算,例如$lo{g_2}8$, $lg100$。不过,我们可以通过其他方式来求取,记得下面这个高中时学过的公式吗:

$$lo{g_a}b = \frac{

{lo{g_c}b}}{
{lo{g_c}a}}$$

所以有:

>>> f = tf.constant([[1., 9.], [16., 100.]])>>> g = tf.constant([[2., 3.], [2., 10.]])>>> tf.math.log(f) / tf.math.log(g)

(2)指数运算

>>> g = tf.constant([[2, 3], [2, 10]])>>> tf.pow(g, 2)

也可以直接通过运算符来完成:

>>> g ** 2

(3)开方

>>> f = tf.constant([[1., 9.], [16., 100.]])>>> tf.sqrt(f)

自然常数$e$的指数运算:

>>> d = tf.constant([[1.,2.],[3.,4.]])>>> tf.exp(d)

注意:对数运算函数log()与指数运算函数在不同的模块中。

在我看来,上面提到的指数运算与对数运算不在通知模块以及没有提供以其他自然数为底的对数运算,应该应该是TensorFlow中的遗留问题,希望能够在正式版中得到修正。

3 矩阵相乘

注意,矩阵相乘与上面的矩阵点乘可不一样,这里的矩阵相乘是线性代数中的矩阵乘法,通过TensorFlow提供的matmul()方法实现:

>>> import tensorflow as tf>>> import numpy as np>>> a = tf.constant(np.arange(6),shape=(2,3))>>> b = tf.constant(np.arange(6),shape=(3,2))>>> a
>>> b
>>> tf.matmul(a,b)

矩阵相乘也可以通过符号来操作进行,用“@”表示:

>>> a@b

这里的张量a和b都是二维的,但在实际应用中,数据往往高于二维,这时候怎么应算呢?

>>> a = tf.constant(np.arange(12),shape=(2,2,3))>>> b = tf.constant(np.arange(12),shape=(2,3,2))>>> a
>>> b
>>> a@b

可以看到,当高于二维的张量进行矩阵相乘时,最终的实现还是二维矩阵相乘,只不过分成了多个二维矩阵,四维张量也是一样的:

>>> a = tf.constant(np.arange(24),shape=(2,2,2,3))>>> b = tf.constant(np.arange(24),shape=(2,2,3,2))>>> a@b

4 Broadcasting机制

上面的所有实例中所用到的张量都是在维度数和形状相同情况下进行,那么,当两个张量维度数或者形状不一样时能不能进行运算呢?

>>> a = tf.constant([1,2,3])>>> b = tf.constant(np.arange(12),shape=(2,2,3))>>> b
>>> a+b
>>> a*b

可以看到,一个一维的张量与一个三维张量进行运算是完全没有问题的,从运算结果上可以看出,相当于是三维张量中的每一行数据与张量a进行运算,为什么可以这样运输呢?这就得益于TensorFlow中的Broadcasting机制。

Broadcasting机制解除了只能维度数和形状相同的张量才能进行运算的限制,当两个数组进行算术运算时,TensorFlow的Broadcasting机制首先对维度较低的张量形状数组填充1,从后向前,逐元素比较两个数组的形状,当逐个比较的元素值(注意,这个元素值是指描述张量形状数组的值,不是张量的值)满足以下条件时,认为满足 Broadcasting 的条件:

(1)相等

(2)其中一个张量形状数组元素值为1。

当不满足时进行运算则会抛出 ValueError: frames are not aligne 异常。算术运算的结果的形状的每一元素,是两个数组形状逐元素比较时的最大值。

回到上面张量a与b相乘的例子,a的形状是(3,),b的形状是(2, 2, 3),在Broadcasting机制工作时,首先比较维度数,因为a的维度为1,小于b的维度3,所以填充1,a的形状就变成了(1,1,3),然后从最后端的形状数组元素依次往前比较,先是就是3与3比,结果是相等,接着1与2相比,因为其中一个为1,所以a的形状变成了(1,2,3),继续1与2比较,因为其中一个为1,所以a的形状变成了(2,2,3),a中的数据每一行都填充a原来的数据,也就是[1,2,3],然后在与b进行运算。

当然,在TensorFlow的Broadcasting机制运行过程中,上述操作只是理论的,并不会真正的将a的形状变成(2,2,3,),更不会将每一行填充[1,2,3],只是虚拟进行操作,真正计算时,依旧是使用原来的张量a。这么做的好处是运算效率更高,也更节省内存。

再举一些例子加深理解:

A (2d array): 5 x 4B (1d array): 1Result (2d array): 5 x 4 A (2d array): 5 x 4B (1d array): 4Result (2d array): 5 x 4 A (3d array): 15 x 3 x 5B (3d array): 15 x 1 x 5Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5B (2d array): 3 x 5Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5B (2d array): 3 x 1Result (3d array): 15 x 3 x 5

一些反例(不满足 Broadcasting 规则 ):

A (1d array): 3B (1d array): 4  A (2d array): 2 x 1B (3d array): 8 x 4 x 3

参考

转载于:https://www.cnblogs.com/chenhuabin/p/11594239.html

你可能感兴趣的文章
数据库01 /Mysql初识以及基本命令操作
查看>>
数据库02 /MySQL基础数据类型以及多表之间建立联系
查看>>
Python并发编程04/多线程
查看>>
CF461B Appleman and Tree
查看>>
CF219D Choosing Capital for Treeland
查看>>
杂七杂八的小笔记本
查看>>
51Nod1353 树
查看>>
CF1215E Marbles
查看>>
BZOJ2339 HNOI2011卡农(动态规划+组合数学)
查看>>
octave基本操作
查看>>
axure学习点
查看>>
WPF文本框只允许输入数字[转]
查看>>
dom4j 通用解析器,解析成List<Map<String,Object>>
查看>>
第一个项目--用bootstrap实现美工设计的首页
查看>>
使用XML传递数据
查看>>
TYVJ.1864.[Poetize I]守卫者的挑战(概率DP)
查看>>
0925 韩顺平java视频
查看>>
iOS-程序启动原理和UIApplication
查看>>
mysql 8.0 zip包安装
查看>>
awk 统计
查看>>