Tensorflow2.0基础函数学习笔记(1)

数据类型

包括了数值型、字符串型和布尔型。

数值类型

  1. 标量
    tf.constant(1.2)
  2. 向量
    tf.constant([1.,2.,3.3])
  3. 矩阵
    tf.constant([[[1,2],[3,4]],[[5,6],[7,8]]]

字符串类型

tf.constant('Hello, Deep Learning.') 

布尔类型

tf.constant(True)

数值精度

tf.constant(123456789, dtype=tf.int16) 
tf.constant(123456789, dtype=tf.int32)
tf.constant(np.pi, dtype=tf.float32) 

读取精度

print('before:',a.dtype) 

类型转换

tf.constant(np.pi, dtype=tf.float16) 
tf.cast(a, tf.double) 

待优化张量

tf.Variable 类型在普通的张量类 型基础上添加了 name,trainable 等属性来支持计算图的构建。

a = tf.Variable([[1,2],[3,4]]) 
<tf.Variable 'Variable:0' shape=(2, 2) dtype=int32, numpy= 
array([[1, 2],  [3, 4]])> 

从 Numpy, List 对象创建

tf.convert_to_tensor([1,2.]) 
tf.convert_to_tensor(np.array([[1,2.],[3,4]])) 

Numpy 中浮点数数组默认使用 64-Bit 精度保存数据,转换到 Tensor 类型时 精度为 tf.float64,可以在需要的时候转换为 tf.float32 类型
实际上,tf.constant()和 tf.convert_to_tensor()都能够自动的把 Numpy 数组或者 Python List 数据类型转化为 Tensor 类型。

创建全 0,全 1 张量

a = tf.ones([2,3]) 
tf.zeros_like(a)

a = tf.zeros([3,2]) 
tf.ones_like(a)

创建自定义数值张量

创建元素为-1 的标量:
tf.fill([], -1) 
创建所有元素为-1 的向量:
tf.fill([1], -1) 
创建所有元素为 99 的矩阵:
tf.fill([2,2], 99) 

创建已知分布的张量

创建均值为 0,标准差为 1 的正太分布:
tf.random.normal([2,2])
创建采样自区间[0,1],shape 为[2,2]的矩 阵:
tf.random.uniform([2,2]) 
tf.random.uniform([2,2],maxval=100,dtype=tf.int32) 

创建序列

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

tf.range(10,delta=2)
<tf.Tensor: id=185, shape=(5,), dtype=int32, numpy=array([0, 2, 4, 6, 8])> 

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

张量的典型应用

标量

out = tf.random.uniform([4,10]) #随机模拟网络输出
y = tf.constant([2,3,2,0]) # 随机构造样本真实标签 
y = tf.one_hot(y, 	depth=10) # one-hot 编码 
loss = tf.keras.losses.mse(y, out) # 计算每个样本的 MSE  
loss = tf.reduce_mean(loss) # 平均 MSE 
print(loss)

向量

z = tf.random.normal([4,2]) 
b = tf.zeros([2]) # 模拟偏置向量 
z = z + b # 累加偏置 

通过高层接口类 Dense()方式创建的网络层,张量 W 和𝒃存储在类的内部,由类自动创 建并管理。可以通过全连接层的 bias 成员变量查看偏置变量𝒃,例如创建输入节点数为 4, 输出节点数为 3 的线性层网络,那么它的偏置向量 b 的长度应为 3:

fc = layers.Dense(3) # 创建一层 
Wx+b,输出节点为 3 # 通过 build 函数创建 W,b 张量,输入节点为 4 
fc.build(input_shape=(2,4))  
fc.bias # 查看偏置 

矩阵

矩阵也是非常常见的张量类型,比如全连接层的批量输入𝑋 = [𝑏,𝑑𝑖𝑛],其中𝑏表示输入 样本的个数,即 batch size,𝑑𝑖𝑛表示输入特征的长度。比如特征长度为 4,一共包含 2 个样 本的输入可以表示为矩阵:

w = tf.ones([4,3]) # 定义 W 张量 
b = tf.zeros([3]) # 定义 b 张量 
o = x@w+b # X@W+b 运算 

其中 X,W 张量均是矩阵。x@w+b 网络层称为线性层,在 TensorFlow 中可以通过 Dense 类直接实现,Dense 层也称为全连接层。我们通过 Dense 类创建输入 4 个节点,输出 3 个 节点的网络层,可以通过全连接层的 kernel 成员名查看其权值矩阵 W:

fc = layers.Dense(3) # 定义全连接层的输出节点为 3 fc.build(input_shape=(2,4)) # 定义全连接层的输入节点为 4 
fc.kernel 
Out[45]: 
<tf.Variable 'kernel:0' shape=(4, 3) dtype=float32, numpy= 
array([[ 0.06468129, -0.5146048 , -0.12036425], 
   [ 0.71618867, -0.01442951, -0.5891943 ], 
   [-0.03011459,  0.578704  ,  0.7245046 ], 
   [ 0.73894167, -0.21171576,  0.4820758 ]], dtype=float32)> 

3 维张量

三维的张量一个典型应用是表示序列信号,它的格式是 𝑋 = [𝑏,𝑠𝑒𝑞𝑢𝑒𝑛𝑐𝑒 𝑙𝑒𝑛,𝑓𝑒𝑎𝑡𝑢𝑟𝑒 𝑙𝑒𝑛] 其中𝑏表示序列信号的数量,sequence len 表示序列信号在时间维度上的采样点数,feature len 表示每个点的特征长度。

4 维张量

4 维张量在卷积神经网络中应用的非常广泛,它用于保存特征图(Feature maps)数据, 格式一般定义为 [𝑏,ℎ, ,𝑐]
其中𝑏表示输入的数量,h/w分布表示特征图的高宽,𝑐表示特征图的通道数,部分深度学 习框架也会使用[𝑏,𝑐,ℎ, ]格式的特征图张量,例如 PyTorch。图片数据是特征图的一种, 对于含有 RGB 3 个通道的彩色图片,每张图片包含了 h 行 w 列像素点,每个点需要 3 个数 值表示 RGB 通道的颜色强度,因此一张图片可以表示为[h,w,3]。

索引与切片

索引

通过索引与切片操作可以提取张量的部分数据,使用频率非常高。 

x = tf.random.normal([4,32,32,3])
接下来我们使用索引方式读取张量的部分数据。

取第 1 张图片的数据
x[0]
取第 1 张图片的第 2 行:
x[0][1]
取第 1 张图片,第 2 行,第 3 列的像素:
x[0][1][2]
取第 3 张图片,第 2 行,第 1 列的像素,B 通道(第 2 个通道)颜色强度值:
x[2][1][0][1]
当张量的维度数较高时,使用[𝑖][𝑗]…[𝑘]的方式书写不方便,可以采用[𝑖,𝑗,…,𝑘]的方 式索引,它们是等价的。
x[1,9,2]

切片

通过𝑠𝑡𝑎𝑟𝑡:𝑒𝑛𝑑:𝑠𝑡𝑒𝑝切片方式可以方便地提取一段数据,其中 start 为开始读取位置的 索引,end 为结束读取位置的索引(不包含 end 位),step 为读取步长。

以 shape 为[4,32,32,3]的图片张量为例:

读取第 2,3 张图片: 
In [56]: x[1:3] 
Out[56]: 
<tf.Tensor: id=441, shape=(2, 32, 32, 3), dtype=float32, numpy= 
array([[[[ 0.6920027 ,  0.18658352,  0.0568333 ], 
     [ 0.31422952,  0.75933754,  0.26853144], 
     [ 2.7898    , -0.4284912 , -0.26247284],...

start:end:step切片方式有很多简写方式,其中 start、end、step 3 个参数可以根据需要 选择性地省略,全部省略时即::,表示从最开始读取到最末尾,步长为 1,即不跳过任何元素。

如 x[0,::]表示读取第 1 张图片的所有行,其中::表示在行维度上读取所有行,它等于 x[0]的写法:

In [57]: x[0,::] 
Out[57]: 
<tf.Tensor: id=446, shape=(32, 32, 3), dtype=float32, numpy= 
array([[[ 1.3005302 ,  1.5301839 , -0.32005513], 
       [-1.3020388 ,  1.7837263 , -1.0747638 ], 
       [-1.1230233 , -0.35004002,  0.01514002], 
       ...  	       

为了更加简洁,::可以简写为单个冒号:,如

In [58]: x[:,0:28:2,0:28:2,:] 
Out[58]: 
<tf.Tensor: id=451, shape=(4, 14, 14, 3), dtype=float32, numpy= 
array([[[[ 1.3005302 ,  1.5301839 , -0.32005513], 
         [-1.1230233 , -0.35004002,  0.01514002], 
         [ 1.3474811 ,  0.639334  , -1.0826371 ], 
         ...  
切片方式意义
start:end :step从 start 开始读取到 end(不包含 end),步长为 step
start:end :从 start 开始读取到 end(不包含 end),步长为 1
start:从 start 开始读取完后续所有元素,步长为 1
start::step从 start 开始读取完后续所有元素,步长为 step
:end:step从 0 开始读取到 end(不包含 end),步长为 step
:end从 0 开始读取到 end(不包含 end),步长为 1
::step每隔 step-1 个元素采样所有
::读取所有元素
:读取所有元素

特别地,step 可以为负数,考虑最特殊的一种例子,step = −1时,start:end :−1表示 从 start 开始,逆序读取至 end 结束(不包含 end),索引号𝑒𝑛𝑑 ≤ 𝑠𝑡𝑎𝑟𝑡。考虑一 0~9 简单序 列,逆序取到第 1 号元素,不包含第 1号

In [59]: x = tf.range(9) 
x[8:0:-1] 
Out[59]: 
<tf.Tensor: id=466, shape=(8,), dtype=int32, numpy=array([8, 7, 6, 5, 4, 3, 
2, 1])> 

当张量的维度数量较多时,不需要采样的维度一般用单冒号:表示采样所有元素,此时 有可能出现大量的:出现。继续考虑[4,32,32,3]的图片张量,当需要读取 G 通道上的数据 时,前面所有维度全部提取,此时需要写为

In [63]: x[:,:,:,1] 
Out[63]: 
<tf.Tensor: id=492, shape=(4, 32, 32), dtype=float32, numpy= 
array([[[ 0.575703  ,  0.11028383, -0.9950867 , ...,  0.38083118, 
         -0.11705163, -0.13746642], 
        ...

为了避免出现像𝑥[:,:,:,1]这样出现过多冒号的情况,可以使用⋯符号表示取多个维度 上所有的数据,其中维度的数量需根据规则自动推断:当切片方式出现⋯符号时,⋯符号 左边的维度将自动对齐到最左边,⋯符号右边的维度将自动对齐到最右边,此时系统再自 动推断⋯符号代表的维度数量,它的切片方式总结如表格

切片方式意义
a,⋯,ba 维度对齐到最左边,b 维度对齐到最右边,中间的维度全部读取, 其他维度按 a/b 的方式读取
a,⋯a维度对齐到最左边,a 维度后的所有维度全部读取,a 维度按 a 方式 读取。这种情况等同于 a 索引/切片方式
⋯,bb 维度对齐到最右边,b 之前的所有维度全部读取,b 维度按 b 方式 读取
读取张量所有数据

读取第 1-2 张图片的 G/B 通道数据

In [64]: x[0:2,...,1:] 
Out[64]: 
<tf.Tensor: id=497, shape=(2, 32, 32, 2), dtype=float32, numpy= 
array([[[[ 0.575703  ,  0.8872789 ], 
         [ 0.11028383, -0.27128693], 
         [-0.9950867 , -1.7737272 ], 

读取 R/G 通道数据

In [66]: x[...,:2] 
Out[66]: 
<tf.Tensor: id=507, shape=(4, 32, 32, 2), dtype=float32, numpy= 
array([[[[-1.26881   ,  0.575703  ], 
         [ 0.98697686,  0.11028383], 
         [-0.66420585, -0.9950867 ], 
         ... 
 

小结

张量的索引与切片方式多种多样,尤其是切片操作,初学者容易犯迷糊。但其实本质 上切片操作只有𝑠𝑡𝑎𝑟𝑡:𝑒𝑛𝑑:𝑠𝑡𝑒𝑝这一种基本形式,通过这种基本形式有目的地省略掉默认 参数,从而衍生出多种简写方法,这也是很好理解的。它衍生的简写形式熟练后一看就能 推测出省略掉的信息,书写起来也更方便快捷。由于深度学习一般处理的维度数在 4 维以 内,⋯操作符完全可以用:符号代替,因此理解了这些就会发现张量切片操作并不复杂。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值