TensorFlow2.0(2):数学运算

简介: TensorFlow2.0(2):数学运算

1 基本运算:(+、-、*、/、//、%)


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


import tensorflow as tfa = 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


<tf.Tensor: id=3, shape=(2, 3), dtype=int32, numpy=
array([[1, 4, 5],
       [5, 1, 4]])>


b


<tf.Tensor: id=7, shape=(2, 3), dtype=int32, numpy=
array([[1, 3, 5],
       [3, 5, 2]])>


(1)加(+)


tf.add(a,b)  # 通过add方法执行加操作


<tf.Tensor: id=12, shape=(2, 3), dtype=int32, numpy=
array([[ 2,  7, 10],
       [ 8,  6,  6]])>


a + b  # 也可以通过操作符进行


<tf.Tensor: id=16, shape=(2, 3), dtype=int32, numpy=
array([[ 2,  7, 10],
       [ 8,  6,  6]])>


(2)减(-)


tf.subtract(a,b)


<tf.Tensor: id=18, shape=(2, 3), dtype=int32, numpy=
array([[ 0,  1,  0],
       [ 2, -4,  2]])>


a - b


<tf.Tensor: id=20, shape=(2, 3), dtype=int32, numpy=
array([[ 0,  1,  0],
       [ 2, -4,  2]])>


(3)乘法(*)


tf.multiply(a,b)


<tf.Tensor: id=22, shape=(2, 3), dtype=int32, numpy=
array([[ 1, 12, 25],
       [15,  5,  8]])>


a * b


<tf.Tensor: id=24, shape=(2, 3), dtype=int32, numpy=
array([[ 1, 12, 25],
       [15,  5,  8]])>


(4)除法(/)


tf.divide(a,b)


<tf.Tensor: id=28, shape=(2, 3), dtype=float64, numpy=
array([[1.        , 1.33333333, 1.        ],
       [1.66666667, 0.2       , 2.        ]])>


a/b


<tf.Tensor: id=32, shape=(2, 3), dtype=float64, numpy=
array([[1.        , 1.33333333, 1.        ],
       [1.66666667, 0.2       , 2.        ]])>


(5)地板除法(//)


tf.floor_div(a,b)


<tf.Tensor: id=34, shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 0, 2]])>


a // b


<tf.Tensor: id=38, shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 0, 2]])>


(6)取余(%)


tf.mod(b,a)


<tf.Tensor: id=115, shape=(2, 2, 3), dtype=int32, numpy=
array([[[0, 1, 2],
        [0, 0, 2]],
       [[0, 1, 2],
        [0, 0, 2]]])>


b % a


<tf.Tensor: id=117, shape=(2, 2, 3), dtype=int32, numpy=
array([[[0, 1, 2],
        [0, 0, 2]],
       [[0, 1, 2],
        [0, 0, 2]]])>


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


2 指数、开方、对数


(1)对数运算


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


e = 2.71828183a = tf
.constant([e, e*e, e*e*e])tf.math.log(a)


<tf.Tensor: id=41, shape=(3,), dtype=float32, numpy=array([0.99999994, 2.        , 3.        ], dtype=float32)>


c = tf.fill([2,2],1.)
tf.math.log(c)


<tf.Tensor: id=46, shape=(2, 2), dtype=float32, numpy=
array([[0., 0.],
       [0., 0.]], dtype=float32)>


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


所以有:


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


tf.math.log(f) / tf.math.log(g)


<tf.Tensor: id=52, shape=(2, 2), dtype=float32, numpy=
array([[0., 2.],
       [4., 2.]], dtype=float32)>


(2)指数运算


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


tf.pow(g, 2)


<tf.Tensor: id=66, shape=(2, 2), dtype=int32, numpy=
array([[  4,   9],
       [  4, 100]])>


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


g ** 2


<tf.Tensor: id=59, shape=(2, 2), dtype=int32, numpy=
array([[  4,   9],
       [  4, 100]])>


(3)开方


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


tf.sqrt(f)


<tf.Tensor: id=69, shape=(2, 2), dtype=float32, numpy=
array([[ 1.,  3.],
       [ 4., 10.]], dtype=float32)>


自然常数的指数运算:


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


tf.exp(d)


<tf.Tensor: id=72, shape=(2, 2), dtype=float32, numpy=
array([[ 2.7182817,  7.389056 ],
       [20.085537 , 54.598152 ]], dtype=float32)>


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


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


3 矩阵相乘



import numpy as npa = tf.constant(np.arange(6)
shape=(2,3))b = tf.constant(np.arange(6),
shape=(3,2))


a


<tf.Tensor: id=76, shape=(2, 3), dtype=int32, numpy=
array([[0, 1, 2],
       [3, 4, 5]])>


b


<tf.Tensor: id=79, shape=(3, 2), dtype=int32, numpy=
array([[0, 1],
       [2, 3],
       [4, 5]])>



tf.matmul(a,b)


<tf.Tensor: id=82, shape=(2, 2), dtype=int32, numpy=
array([[10, 13],
       [28, 40]])>


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


a @ b


<tf.Tensor: id=86, shape=(2, 2), dtype=int32, numpy=
array([[10, 13],
       [28, 40]])>


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

呢?


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


a


<tf.Tensor: id=90, shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 0,  1,  2],
        [ 3,  4,  5]],
       [[ 6,  7,  8],
        [ 9, 10, 11]]])>


b


<tf.Tensor: id=93, shape=(2, 3, 2), dtype=int32, numpy=
array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],
       [[ 6,  7],
        [ 8,  9],
        [10, 11]]])>


a @ b


<tf.Tensor: id=96, shape=(2, 2, 2), dtype=int32, numpy=
array([[[ 10,  13],
        [ 28,  40]],
       [[172, 193],
        [244, 274]]])>


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


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


a @ b


<tf.Tensor: id=104, shape=(2, 2, 2, 2), dtype=int32, numpy=
array([[[[  10,   13],
         [  28,   40]],
        [[ 172,  193],
         [ 244,  274]]],
       [[[ 550,  589],
         [ 676,  724]],
        [[1144, 1201],
         [1324, 1390]]]])>


4 Broadcasting机制


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


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



b


<tf.Tensor: id=109, shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 0,  1,  2],
        [ 3,  4,  5]],
       [[ 6,  7,  8],
        [ 9, 10, 11]]])>


a + b


<tf.Tensor: id=111, shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 1,  3,  5],
        [ 4,  6,  8]],
       [[ 7,  9, 11],
        [10, 12, 14]]])>


a * b


<tf.Tensor: id=113, shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 0,  2,  6],
        [ 3,  8, 15]],
       [[ 6, 14, 24],
        [ 9, 20, 33]]])>


可以看到,一个一维的张量与一个三维张量进行运算是完全没有问题的,从运算结果上可以看出,相当于是三维张量中的每一行数据与张量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 4
  • [ ] B:(1d array): 1
  • [ ] Result:(2d array): 5 x 4

  • [ ] A:(2d array): 5 x 4
  • [ ] B:(1d array): 4
  • [ ] Result:(2d array): 5 x 4

  • [ ] A:(3d array): 15 x 3 x 5
  • [ ] B:(3d array): 15 x 1 x 5
  • [ ] Result:(3d array): 15 x 3 x 5

  • [ ] A:(3d array): 15 x 3 x 5
  • [ ] B:(2d array): 3 x 5
  • [ ] Result:(3d array): 15 x 3 x 5

  • [ ] A:(3d array): 15 x 3 x 5
  • [ ] B:(2d array): 3 x 1
  • [ ] Result:(3d array): 15 x 3 x 5

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

  • [ ] A (1d array): 3
  • [ ] B (1d array): 4

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

5 范数

范数是泛函分析中的概念,指的是一种更宽泛的长度(距离)概念,只要满足非负、自反、三角不等式就可以称之为距离。向量的范数可以使用下面公式进行计算:


当时分别叫做1范数,2范数。除此以外,还有无穷范数:


import tensorflow as tf


a = tf.constant([[1.,2.],[1.,2.]])


tf.norm(a, ord=1)  # 1范数


<tf.Tensor: id=4, shape=(), dtype=float32, numpy=6.0>


tf.norm(a, ord=2)  # 2范数


<tf.Tensor: id=10, shape=(), dtype=float32, numpy=3.1622777>


tf.norm(a)  # ord不指定时,默认是2


<tf.Tensor: id=16, shape=(), dtype=float32, numpy=3.1622777>


我们也可以全手动地实现范数:


tf.sqrt(tf.reduce_sum(tf.square(a)))


<tf.Tensor: id=21, shape=(), dtype=float32, numpy=3.1622777>


指定维度求范数:


tf.norm(a, ord=2, axis=0)


<tf.Tensor: id=27, shape=(2,), dtype=float32, numpy=array([1.4142135, 2.828427 ], dtype=float32)>


tf.norm(a, ord=2, axis=1)


<tf.Tensor: id=33, shape=(2,), dtype=float32, numpy=array([2.236068, 2.236068], dtype=float32)>


相关文章
|
TensorFlow 算法框架/工具 Python
把python函数转化为 tensorflow 函数 加速运算
把python函数转化为 tensorflow 函数 加速运算
42 1
|
TensorFlow 算法框架/工具 索引
《30天吃掉那只 TensorFlow2.0》 4-2 张量的数学运算
《30天吃掉那只 TensorFlow2.0》 4-2 张量的数学运算
《30天吃掉那只 TensorFlow2.0》 4-2 张量的数学运算
|
机器学习/深度学习 算法 TensorFlow
学习笔记 | 深度学习开发—TensorFlow实践(基本运算)
学习笔记 | 深度学习开发—TensorFlow实践(基本运算)
学习笔记 | 深度学习开发—TensorFlow实践(基本运算)
|
存储 数据可视化 TensorFlow
斯坦福tensorflow教程(二) tensorflow相关运算(一)
斯坦福tensorflow教程(二) tensorflow相关运算(一)
180 0
斯坦福tensorflow教程(二) tensorflow相关运算(一)
|
存储 Shell TensorFlow
斯坦福tensorflow教程(二) tensorflow相关运算(二)
斯坦福tensorflow教程(二) tensorflow相关运算(二)
138 0
|
机器学习/深度学习 TensorFlow 算法框架/工具
Tensorflow快餐教程(2) - 标量运算
Tensorflow标量计算
4196 0
|
3天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
92 55
|
21天前
|
机器学习/深度学习 数据采集 数据可视化
TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤
本文介绍了 TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤,包括数据准备、模型定义、损失函数与优化器选择、模型训练与评估、模型保存与部署,并展示了构建全连接神经网络的具体示例。此外,还探讨了 TensorFlow 的高级特性,如自动微分、模型可视化和分布式训练,以及其在未来的发展前景。
47 5
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
77 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
1月前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
77 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型