tensorflow2.0张量的结构操作分析和总结

回忆一下,我们python语言中,变量的类型有哪些?有多少种数据结构?变量类型有整型,字符串,浮点型,bool等等,数据结构有列表,元组,字典等。

那么

在tensorflow2.0框架当中,有哪些变量类型呢?有哪些数据结构呢?

答案是

在tensorflow2.0中,只存在一种数据结构,这种数据结构英文名叫tensor,中文名叫张量。

有些人就会问了,如果是只存在一种数据结构,那谁来表示字典,元组,列表这些东西呢?

答案是

不需要,tensorflow2.0在进行数据运算的时候,只用到张量这种数据结构就行了。因为张量的数据结构方便计算和使用。如果非要用到字典的操作,完全可以交给python语言来实现。

张量可以存储很多很多信息,得力于它多变的数据结构,因为如何有需要,它的维度可以无限扩张。对于一维张量,数据结构类似于我们的一维列表,对于二维张良,数据结构类似于我们列表里面嵌套着列表,对于三维张量,数据结构类似于我们列表里面嵌套着的列表的元素还是列表。

然后,重点是

这些列表的元素的数据类型可以是python中所有的数据类型,只是为了方便运算,一般元素的数据类型就是整型或者浮点型或者布尔型而已,千万别以为它不可以是别的类型哦。

好的,说了那么多张量,那我们该如何创建张量呢?你明白张量的本质之后,你就会明白,张量的值,当然是可以在创建的时候就初始化了,也可以创建之后不初始化,只指定元素的类型和张量的数据结构,到时候我们想用的时候直接按照指定的元素类型和数据结构shape给它传递值就行。

然后创建的张量初始化之后,这些值能不能被改变,如果能被改变,我们称这种张量为可变张量,简称变量,如果不可以改变,我们称这种张量为不变张量,简称常量。不变张量和可变张量的创建不一样,其实就是两个不同函数而已。

import tensorflow as tf

# 创建不变张量
a = tf.constant(value=2, dtype=tf.float32, shape=(2, 3), name='Const1')
"""
参数解析:
tf.Tensor(
[[2. 2. 2.]
 [2. 2. 2.]], shape=(2, 3), dtype=float32)
 如果对参数shape进行了指定,那么结果就是元素是value的一个张量
"""

b = tf.constant(value=5)
"""
如果不指定dtype和shape,那么结果tensor就由value值来确定它的dtype和shape
tf.Tensor(5, shape=(), dtype=int32), 
shape=(),表示没有维度
shape=(6,),表示维度只有一个维度,在这个维度上面有6个元素,shape的值是一个元组,元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当做运算符使用
shape=(28, 28, 3),表示有三个维度,在第一个维度上面有28个元素,在第二个维度上面有28个元素,在第三个维度上面有3个元素,
"""
print(a)
print(b)
# 明白了constant函数的使用,其它创建不变张量的方法我都不想使用,没必要,知道这个方法,我就可以创建出自己想要的一切数据了

另外一个方面也是常用的一个方面,就是创建随机分布数据,见代码分析

import tensorflow as tf

# 均匀分布随机
a = tf.random.uniform(shape=(5, 3), minval=0, maxval=1, dtype=tf.float32, name='a1')
"""
创建均匀分布数据,什么是均匀分布可参见:https://baike.baidu.com/item/%E5%9D%87%E5%8C%80%E5%88%86%E5%B8%83/954451?fr=aladdin
"""
print(a)
b = tf.random.normal(shape=(5, 3), mean=0.0, stddev=1.0, dtype=tf.float32, seed=1.0, name='b')
"""
创建标准正太分布数据, mean=0.0, stddev=1.0,默认就是标准正太分布
https://baike.baidu.com/item/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83/829892?fr=aladdin
"""
print(b)

c = tf.random.truncated_normal((5, 5), mean=0.0, stddev=1.0, dtype=tf.float32, name="c")
"""
创建标准正太分布数据, mean=0.0, stddev=1.0,并采取2sigma原则
对于sigma原则可参见:https://zhidao.baidu.com/question/1994458617275793107.html
"""

print(c)

现在开始解释如何创建可变张量,看代码注释,看代码注释,看代码注释,

import tensorflow as tf

a = tf.Variable(initial_value=tf.random.truncated_normal(shape=(2,)))
"""
该函数必须指定初始化值,初始化值就是前面所描述的不变张量,也可以是数值,也可以是数组
<tf.Variable 'Variable:0' shape=(2,) dtype=float32, numpy=array([-0.00675302, -1.3904084 ], dtype=float32)>
"""
print(a)

#############################*我是分割线###########################
接下来介绍张量的切片操作,其实张量最具有艺术感的行为就是切片行为了。你可以把所有完整的数据保存在一个张量里面,然后在使用的时候只是取出一点点所需的东西即可,这种本质赋予了张量强大的功能。

如何对张量进行切片操作呢?我们先来看一种极端情形,就是我只需要切一个元素出来,这种我们称之为索引,当我们不只是需要一个元素的时候,我们称之为切片。

索引是怎么一回事呢?看以下代码分析

import tensorflow as tf

a = tf.Variable(initial_value=tf.random.truncated_normal(shape=(3, 3, 3), seed=1.0))
"""
<tf.Variable 'Variable:0' shape=(3, 3, 3) dtype=float32, numpy=
array([[[-0.8113182 ,  1.4845988 ,  0.06532937],
        [ 0.0992484 ,  0.6396971 ,  1.6108712 ],
        [ 0.16353562, -1.5157056 ,  1.3587774 ]],

       [[ 0.5417414 , -0.86009884, -0.0040246 ],
        [ 0.55171245, -0.13107552, -0.04481387],
        [ 0.6709832 , -0.20888524,  0.00542188]],

       [[ 0.31266254,  0.5998527 , -0.36332107],
        [-0.07205155, -0.5527937 ,  0.10289733],
        [-0.67590594,  0.2866583 ,  0.3215887 ]]], dtype=float32)>
"""
# 索引取出一个数据
b = a[0, 0, 0]  # tf.Tensor(-0.8113182, shape=(), dtype=float32)取出第一个数据
c = a[0, 0, 1]  # tf.Tensor(1.4845988, shape=(), dtype=float32)取出第二个数据
d = a[0, 0, 2]  # tf.Tensor(0.06532937, shape=(), dtype=float32)取出第三个数据

# 如果这样子一个一个取数据,太慢了,能不能一次性全部取出来呢?上面一个一个叫索引,我们现在使用切片的方式。索引是用下标并且使用逗号隔开
e = a[0, 0, 0:3]  # tf.Tensor([-0.8113182   1.4845988   0.06532937], shape=(3,), dtype=float32)

# 切片操作通过:来实现,表示选择多个索引下标,0:3表示选择0、1、2索引下标,忽略索引# # 下标表示选择该维度下面的全部元素,不建议使用省略号来表示多个冒号,这种表示方法很不明确
print(e)

#############################*我是分割线###########################
接下来分析一些维度变换,看代码注释分析,看代码注释分析,看代码注释分析,

import tensorflow as tf

a = tf.Variable(initial_value=tf.random.truncated_normal(shape=(3, 3, 3), seed=1.0))
b = tf.reshape(tensor=a, shape=(27,))
"""
各种维度变换学习这一钟就够了,可以实现增加一个维度和减少一个维度的工作,也可以改变维度
b = tf.Tensor(
[-0.8113182   1.4845988   0.06532937  0.0992484   0.6396971   1.6108712
  0.16353562 -1.5157056   1.3587774   0.5417414  -0.86009884 -0.0040246
  0.55171245 -0.13107552 -0.04481387  0.6709832  -0.20888524  0.00542188
  0.31266254  0.5998527  -0.36332107 -0.07205155 -0.5527937   0.10289733
 -0.67590594  0.2866583   0.3215887 ], shape=(27,), dtype=float32)
"""
# 增加一个维度
c = tf.reshape(b, (27, 1))
"""
c = tf.Tensor(
[[-0.8113182 ]
 [ 1.4845988 ]
 [ 0.06532937]
 [ 0.0992484 ]
 [ 0.6396971 ]
 [ 1.6108712 ]
 [ 0.16353562]
 [-1.5157056 ]
 [ 1.3587774 ]
 [ 0.5417414 ]
 [-0.86009884]
 [-0.0040246 ]
 [ 0.55171245]
 [-0.13107552]
 [-0.04481387]
 [ 0.6709832 ]
 [-0.20888524]
 [ 0.00542188]
 [ 0.31266254]
 [ 0.5998527 ]
 [-0.36332107]
 [-0.07205155]
 [-0.5527937 ]
 [ 0.10289733]
 [-0.67590594]
 [ 0.2866583 ]
 [ 0.3215887 ]], shape=(27, 1), dtype=float32)
"""
print(c)

另外需要学习的一个函数是tf.transpose,它可以交换张量的维度,看下面代码注释

import tensorflow as tf

a = tf.Variable(initial_value=tf.random.truncated_normal(shape=(32, 28, 28, 3), seed=1.0))
b = tf.transpose(a=a, perm=(1, 2, 3, 0))  # 下标小数字代表移动之后的位置
print(a.shape)  # (32, 28, 28, 3)
print(b.shape)  # (28, 28, 3, 32)

#############################*我是分割线###########################
我们现在知道切片和维度变换的操作,如果我们有个需求,就是将多个输出变成一个输出,我们就需要把多个输出进行整合,这种整合操作就是将张量进行合并的操作。这种操作主要有两种,一种是concat,它不会增加维度,看下面代码注释分析:

import tensorflow as tf

a = tf.constant([[1.0, 2.0], [3.0, 4.0]])  # (2, 2)
b = tf.constant([[5.0, 6.0], [7.0, 8.0]])  # (2, 2)
c = tf.constant([[9.0, 10.0], [11.0, 12.0]])  # (2, 2)

d = tf.concat(values=[a, b, c], axis=0)  # 在第一个维度上进行连接
e = tf.concat(values=[a, b, c], axis=1)  # 在第二个维度上进行连接
print(d)
print(e)
"""
tf.Tensor(
[[ 1.  2.]
 [ 3.  4.]
 [ 5.  6.]
 [ 7.  8.]
 [ 9. 10.]
 [11. 12.]], shape=(6, 2), dtype=float32)
tf.Tensor(
[[ 1.  2.  5.  6.  9. 10.]
 [ 3.  4.  7.  8. 11. 12.]], shape=(2, 6), dtype=float32)
"""

另外一种是是堆叠,会增加维度,看下面代码分析

import tensorflow as tf

a = tf.constant([[1.0, 2.0], [3.0, 4.0]])  # (2, 2)
b = tf.constant([[5.0, 6.0], [7.0, 8.0]])  # (2, 2)
c = tf.constant([[9.0, 10.0], [11.0, 12.0]])  # (2, 2)

d = tf.stack(values=[a, b, c], axis=0)  # 增加一个第0维度,并在这个维度上面堆叠(常用)
e = tf.stack(values=[a, b, c], axis=1)  # 增加一个第1维度,并在这个维度上面堆叠
i = tf.stack(values=[a, b, c], axis=2)  # 增加一个第2维度,并在这个维度上面堆叠
print(d)
print(e)
print(i)

到这里所有张量的结构分析和总结就到这里,也许你跟我一样动力,也许你一刷而已,不过咩关系,总有一天你会吃亏然后再来把它们弄懂的,爱你哟么么哒

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值