像 NumPy 一样使用 TensorFlow

张量和操作

可以使用tf.constant()创建张量

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity='all'
import tensorflow as tf
tf.constant([[1., 2., 3.], [4., 5., 6.]])
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)>

像 ndarray 一样,tf.Tensor 具有形状和数据类型(dtype):

t = tf.constant([[1., 2., 3.], [4., 5., 6.]])
t.shape
TensorShape([2, 3])
t.dtype
tf.float32

索引工作的方式也类似于NumPy

t[:, 1:]
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[2., 3.],
       [5., 6.]], dtype=float32)>
t[..., 1]
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([2., 5.], dtype=float32)>
t[..., 1, tf.newaxis]  # 提取所有行,第一列的数据并增加一个维度 所以形状是(2,1),上面没有增加新的维度形状就是(2,)
<tf.Tensor: shape=(2, 1), dtype=float32, numpy=
array([[2.],
       [5.]], dtype=float32)>

可以使用各种张量操作

t+10
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[11., 12., 13.],
       [14., 15., 16.]], dtype=float32)>
tf.square(t)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 1.,  4.,  9.],
       [16., 25., 36.]], dtype=float32)>
t@tf.transpose(t) # @运算符是矩阵乘法,相当于tf.matmul()函数
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[14., 32.],
       [32., 77.]], dtype=float32)>

张量和 NumPy

张量可以与NumPy配合使用:可以使用NumPy数组创建张量,也可以将TensorFlow操作应用于NumPy数组,将NumPy操作应用于张量:

import numpy as np
a=np.array([2.,4.,5.])
tf.constant(a)
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 4., 5.])>
t.numpy()
array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)
tf.square(a)
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([ 4., 16., 25.])>
np.square(a)
array([ 4., 16., 25.])

类型转换

类型转换会严重影响性能,并且自动完成转换很容易被忽视。为了避免这种情况TensorFlow不会自动执行任何类型转换:如果对不兼容类型的张量执行操作,会引发异常。例如:不能把浮点张量和整数张量相加,甚至不能相加32位浮点和64位浮点

tf.constant(2.0)+tf.constant(40)
---------------------------------------------------------------------------

InvalidArgumentError                      Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_12252/3002758296.py in <module>
----> 1 tf.constant(2.0)+tf.constant(40)


InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was expected to be a float tensor but is a int32 tensor [Op:AddV2]
tf.constant(2.0)+tf.constant(40,dtype=tf.float64)
---------------------------------------------------------------------------

InvalidArgumentError                      Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_12252/2939420824.py in <module>
----> 1 tf.constant(2.0)+tf.constant(40,dtype=tf.float64)
InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was expected to be a float tensor but is a double tensor [Op:AddV2]

需要转换类型时,可以使用tf.cast():

t2=tf.constant(40.,dtype=tf.float64)
tf.constant(2.)+tf.cast(t2,tf.float32)
<tf.Tensor: shape=(), dtype=float32, numpy=42.0>

变量

目前看到的tf.Tensor值是不变的,无法修改它们。不能使用常规张量在神经网络中实现权重,因为它们需要通过反向传播进行调整。另外还可能需要随时间改变其他参数(例如动量优化器跟踪过去的梯度)。这时就需要使用tf.Variable:

v=tf.Variable([[1.,2.,3.],[4.,5.,6.]])
v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)>

tf.Variable的行为和tf.Tensor的行为非常相似:可以使用它执行相同的操作,它在NumPy中也可以很好地发挥作用,并且对类型也很挑剔。但是可以使用assign()方法(或assign_add()或assign_sub(),给变量增加或减少给定值)进行修改。还可以使用切片的的assign()方法或使用scatter_update()或scatter_nd_update()方法来修改单个切片

v.assign(2*v)
v[0,1].assign(42)
v[:,2].assign([0.,1.])
v.scatter_nd_update(indices=[[0,0],[1,2]],updates=[100.,200.])
<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[ 2.,  4.,  6.],
       [ 8., 10., 12.]], dtype=float32)>






<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[ 2., 42.,  6.],
       [ 8., 10., 12.]], dtype=float32)>






<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[ 2., 42.,  0.],
       [ 8., 10.,  1.]], dtype=float32)>






<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[100.,  42.,   0.],
       [  8.,  10., 200.]], dtype=float32)>

其他数据结构

  • 稀疏张量(tf.SparseTensor)
    有效地表示主要包含零的张量。tf.sparse程序包包含稀疏张量的操作
  • 张量数组(tf.TensorArray)
    张量的列表。默认情况下,它们的大小是固定的,但可以选择动态设置。它们包含的所有张量必须具有相同的形状和数据类型
  • 不规则张量(tf.RaggedTensor)
    表示张量列表的静态列表,其中每个张量具有相同的形状和数据类型。tf.ragged程序包包含用于不规则的张量的操作
  • 字符串张量
    tf.string类型的常规张量。它表示字节字符串,而不是Unicode字符串,因此如果使用Unicode字符串创建字符串张量,则它将被自动编码为UTF-8。或者,可以使用类型为tf.int32的张量来表示Unicode字符串,其中每个项都表示一个Unicode代码点。tf.strings包包含用于字节字符串和Unicode字符串的操作(并将转换为另一个)。重要的是要注意,tf.string是原子级的,这意味着它的长度不会出现在张量的形状当中。一旦将其转换为Unicode张量(即包含Unicode代码点的tf.int32l类型的张量)后,长度就会显示在形状中
  • 集合
    表示为常见张量(或稀疏张量)。例如,tf.constant([[1,2.],[3.4]])代表两个集合{1,2}和{3,4}。通常,每个集合由张量的最后一个轴上的向量表示。可以使用tf.sets包中的操作来操作集。
  • 队列
    跨多个步骤存储的张量。TenorFlow提供了各种队列:简单的先进先出(FIFO)队列(FIFOQueue),可以区分某些元素优先级的队列(Priority Queue),将其元素(RandomShuffleQueue)随机排列,通过填充(PaddingFIFOQueue)批量处理具有不同形状的元素。这些类都在tf.queue包中。
posted @ 2021-10-09 20:46  里列昂遗失的记事本  阅读(135)  评论(0编辑  收藏  举报