张量(Tensor)是TensorFlow的基本数据结构。张量即多维数组,Tensorflow的张量和Numpy中的ndarray对象很类似,用来定义一个 n 维数组对象,它是一个一系列相同类型元素组成的数组集合。从操作行为角度来看,TensorFlow中定义了两种类型的张量:常量(constant)和变量(Variable)。其中常量的值在计算图中不可以被重新赋值,而变量在计算图中可以使用assign等算子进行重新赋值。一般在模型中需要被训练的参数需要被设置成变量,而在整个训练过程中保持不变的参数,则被设置程常量。下面用个简单的实例来展示常量和变量的不同,代码如下:
import tensorflow as tf
import numpy as np
#创建一个常量tensor
a_c = tf.constant([1,2,3], dtype = tf.int32)
#创建一个变量tensor
a_v = tf.Variable([1,2,3], dtype = tf.int32)
#打印两个张量在内存中的id
print(id(a_c), id(a_v))
结果如下:
2979942624944 2979988437072
接下来我们分别对这两个tensor进行操作,用他们加上另外一个tensor。代码如下:
#分别修改常量和变量
a_c = a_c + tf.constant([1,1,1])
a_v.assign_add([1,1,1])
print("a_c:", a_c)
print("a_v:", a_v)
#打印两个张量在内存中的id
print(id(a_c), id(a_v))
结果如下:
a_c: tf.Tensor([2 3 4], shape=(3,), dtype=int32)
a_v: <tf.Variable 'Variable:0' shape=(3,) dtype=int32, numpy=array([2, 3, 4])>
2979942625120 2979988437072
通过对比我们发现,常量是不可修改的,每次对原常量的操作都会新建一个新的常量对象,而张量变量通过assign等操作在原内存空间中对值内容进行修改,并不创建新的对象。以上就是简单的对TensorFlow中的Tensor数据结构的常量和变量的区别做了个简单的展示,下面将详细介绍张量上的结构操作和数学运算。其中结构操作包括:张量创建,索引切片,维度变换以及合并分割,数学运算包括:标量运算,向量运算,矩阵运算及广播。
一,创建张量
TensorFlow中张量的创建和Numpy中ndarray的创建很类似,而且很多方法的名称和用法都基本一致,下面就几种常见的张量常见方式进行演示,默认以Tensor常量的创建做为实例。
标量的创建,即0维张量的创建,代码如下:
i = tf.constant(6) #创建一个数据类型默认为tf.int32的0维张量
l = tf.constant(6, dtype=tf.int64) #创建一个数据类型为tf.int64的0维张量
f = tf.constant(3.14) #创建一个数据类型默为tf.float32的0维张量
d = tf.constant(1.414, dtype=tf.double)#创建一个数据类型为tf.double的0维张量
s = tf.constant('Hello world~') #创建一个数据类型为tf.string的0维张量
b = tf.constant(False) #创建一个数据类型为tf.bool的0维张量
print(b)
print(tf.rank(b)) #打印张量b的维度
print(b.numpy().ndim) # tf.rank的作用和ndarray的ndim方法相同
结果如下:
tf.Tensor(False, shape=(), dtype=bool)
tf.Tensor(0, shape=(), dtype=int32)
0
向量的创建,即1维张量的创建,代码如下:
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0]) #使用1维数组创建1维张量
b = tf.range(1, 5, delta = 1) #使用range方法创建1维张量
c = tf.linspace(1, 5, 5) #使用linspace方法创建1维张量
tf.random.set_seed(1.0)
d = tf.random.uniform([5], minval=0, maxval = 10)#使用均匀分布随机创建1维张量
tf.print(a)
print("a.rank:", tf.rank(a))
tf.print(b)
print("b.rank:", tf.rank(b))
tf.print(c)
print("c.rank:", tf.rank(c))
tf.print(d)
print("d.rank:", tf.rank(d))
结果如下:
[1 2 3 4 5]
a.rank: tf.Tensor(1, shape=(), dtype=int32)
[1 2 3 4]
b.rank: tf.Tensor(1, shape=(), dtype=int32)
[1 2 3 4 5]
c.rank: tf.Tensor(1, shape=(), dtype=int32)
[1.65130854 9.01481247 6.30974197 4.34546089 2.9193902]
d.rank: tf.Tensor(1, shape=(), dtype=int32)
多维张量的创建基本上类似于Numpy中的多维数组ndarray,创建方式也是大同小异,结果中一般几层中括号就代表创建的几维的张量,示例代码如下:
tensor2_array = tf.constant([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]]) #利用二维数组创建矩阵
tensor3_array = tf.constant([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]]) #利用三维数组,创建三维张量
tf.print("tensor2_array:\n", tensor2_array)
print("----------------------------------")
tf.print("\ntensor3_array:\n", tensor3_array)
print("----------------------------------")
tensor2_ones = tf.ones([2, 2]) #利用tf.ones创建默认值为1的二维张量
tensor3_ones = tf.ones([2, 2, 2]) #利用tf.ones创建默认值为1的三维张量
tf.print("\ntensor2_ones:\n", tensor2_ones)
print("----------------------------------")
tf.print("\ntensor3_ones:\n", tensor3_ones)
print("----------------------------------")
tensor2_fill = tf.fill([2, 2], 2) #利用tf.fill创建默认值为指定值的二维张量
tensor3_fill = tf.fill([2, 2, 2], 2) #利用tf.fill创建默认值为指定值的三维张量
tf.print("\ntensor2_fill:\n", tensor2_fill)
print("----------------------------------")
tf.print("\ntensor3_fill:\n", tensor3_fill)
print("----------------------------------")
tf.random.set_seed(1.0)
tensor2_rand_uniform = tf.random.uniform([2, 2], minval=0, maxval=10) #利用均匀分布随机创建二维张量
tensor3_rand_uniform = tf.random.uniform([2, 2, 2], minval=0, maxval=10) #利用均匀分布随机创建三维张量
tf.print("\ntensor2_rand_uniform:\n", tensor2_rand_uniform)
print("----------------------------------")
tf.print("\ntensor3_rand_uniform:\n", tensor3_rand_uniform)
print("----------------------------------")
tensor2_rand_norm = tf.random.normal([2, 2], mean=0.0, stddev=1.0)#利用正态分布随机创建二维张量
tensor3_rand_norm = tf.random.normal([2, 2, 2], mean=0.0, stddev=1.0)#利用正态分布随机创建三维张量
tf.print("\ntensor2_rand_norm:\n", tensor2_rand_norm)
print("----------------------------------")
tf.print("\ntensor3_rand_norm:\n", tensor3_rand_norm)
print("----------------------------------")
# 特殊二维张量
I = tf.eye(2,2) #单位矩阵
tf.print("\nI:\n", I)
print("----------------------------------")
diag = tf.linalg.diag([1,2,3]) #对角阵
tf.print("\ndiag:\n", diag)
print("----------------------------------")
结果如下:
tensor2_array:
[[1 2 3]
[4 5 6]]
----------------------------------
tensor3_array:
[[1 2 3]
[4 5 6]
[7 8 9]]
----------------------------------
tensor2_ones:
[[1 1]
[1 1]]
----------------------------------
tensor3_ones:
[[[1 1]
[1 1]]
[[1 1]
[1 1]]]
----------------------------------
tensor2_fill:
[[2 2]
[2 2]]
----------------------------------
tensor3_fill:
[[[2 2]
[2 2]]
[[2 2]
[2 2]]]
----------------------------------
tensor2_rand_uniform:
[[1.65130854 9.01481247]
[6.30974197 4.34546089]]
----------------------------------
tensor3_rand_uniform:
[[[5.1010704 4.43531752]
[4.08533096 9.92492294]]
[[6.8866396 3.45849633]
[4.36067 6.01060963]]]
----------------------------------
tensor2_rand_norm:
[[-0.457012236 -0.406867266]
[0.728577733 -0.892977774]]
----------------------------------
tensor3_rand_norm:
[[[1.6940167 0.119693168]
[-1.15846 0.172604024]]
[[-0.714496315 0.689600587]
[-1.0908159 -1.18651032]]]
----------------------------------
I:
[[1 0]
[0 1]]
----------------------------------
diag:
[[1 0 0]
[0 2 0]
[0 0 3]]
----------------------------------
上面简单介绍了一下几种不同类型和维度的张量的创建方法,接下来我们将针对Tensor操作中的索引切片进行简单的介绍。
网友评论