tensorflow基本操作

  • tensorflow常见属性:每个变量都有一个device的属性,可以在创建的时候设定是在cpu上运行还是在gpu上运行;tensor和numpy可以互相转换
with tf.device("cpu"):
	a = tf.constant(1)   # 在cpu上
with tf.device("gpu"):
    b = tf.constant(1)   # 在gpu上
print(a.device)          # 查看属性
aa = a.gpu()             # 改变设备
bb = b.cpu()             # 改变设备
b.numpy()                # 将b从tensor类型转化为numpy类型
a.shape                  # 查看tensor的形状
tf.rank(a)               # 查看tensor的维度,返回一个Tensor。维度和形状的区别:[1, 3, 5]的形状 --> rank = 3
a.ndim                   # 直接返回维度
tf.is_tensor(a)          # 判断是不是tensor类型
a.dtype                  # 查看类型

d = np.arange(5)         # numpy类型
dd = tf.convert_to_tensor(d, dtype = tf.int32)  # 把numpy转换成tensor
ddd = tf.cast(dd, dtype = tf.float32)  # 修改tensor的数据类型

f = tf.range(5)          # 快速创建[0, 1, 2, 3, 4]的tensor
g = tf.Variable(6)       # 特殊的Tensor,是一个Variable
gg = tf.Variable(f, name = "xxxx")  # 把一个普通的tensor转成Variable,并且可以选择取名字,但是还是tensor,用tf.is_tensor(gg)是true
  • 创建tensor的方式
# 从numpy,list导出
a = tf.convert_to_tensor(np.ones([2,3]))
b = tf.convert_to_tensor(np.zeros([2,3]))  # 从numpy转变 
c = [3,5,6]
d = tf.convert_to_tensor(c)  # 从list转变

# tf.zeros([x,y...]) [x, y...]:是张量的形状shape
e = tf.zeros([2,3])  # 两行三列的0

f = tf.zeros_like(e)  # f的形状和e一样
g= tf.zeros(e.shape)  # g的方法与f的方法一致.同样的api还有ones系列

# tf.fill([x, y...], i) 初始化一个全是i的shape是[x, y...]的tensor
h = tf.fill([2, 3], 10)  # 2 * 3全为10	

# tf.random.normal([shape], mean = x, stddev = x)  随机生成  
# tf.random.uniform([shape], minval = x1, maxval = x2) 均匀分布
# tf.random.shuffle(tensor)  打散顺序

i = tf.random.normal([2,3], mean = 1, stddev = 1) # 生成2 * 3的正态分布的,均值为1,方差为1 
j = tf.random.truncated_normal([2, 3], mean = 1, stddev = 1) # 截断的正态分布,主要用于sigmoid这个初始化
k = tf.random.uniform([2,3], minval = 1, maxval = 10) # 均匀生成1-10的shape为2 * 3的tensor

index = tf.range(10)  # 0-9的tensor
index = tf.random.shuffle(index)  # 随机打散index这个tensor,一般这个shuffle需要搭配tf.gather(tensor, tensor)使用,将打散后的数据重组
l = tf.gather(a, index)  # 把a按照打乱的顺序重新生成一个tensor

# tf.constant() 创建Tensor
m = tf.constant([1, 2])  # 这个api与tf.convert_to_tensor()基本一致
  • Tensorflow的索引与切片
# tensor的特殊索引
a = tf.random.normal([4,28,28,3])
a[1,2,3]  # = a[1][2][3],其shape是[3]

b = tf.range(10)  # [0,1,2,3,4,5,6,7,8,9]
b[:]  # 全取
b[-1:]  # [9]
c = tf.constant([4,28,28,3])
c[:,:,:,0]  # shape = [4 * 28 * 28]
b[1:8:2]  # 第二个:是step
b[8:1:-1] # 第三个只要是负数就是逆序,无论负多少,就是间隔不同

# ...可以代表任意多个:,具体多少个需要推理
b[1,...] or b[..., 1]

# tf.gather(a, axis = x, indices = [...])
a = tf.zeros([2,35,8])
b = tf.gather(a, axis = 0, indices = [1, 3])  # 按照indices取第axis个维的数值

# tf.gather_nd(a, [xxxx])  a.shape = [4, 35, 8]
d = tf.gather_nd(a, [0,1])  # d.shape = [8]
e = tf.gather_nd(a, [1])  # e.shape = [35, 8]
f = tf.gather_nd(a, [[0,1], [1,2]]) # f.shape = [2, 8]

# tf.boolean_mask(a, mask=[True, True, Flase, Flase], axis = x) a.shape = [4, 28, 28, 3]
g = tf.boolean_mask(a, mask=[True, True, False, False], axis = 0)  # g.shape = [2, 28, 28, 3]
k.shape = [2, 3, 4]
h = tf.boolean_mask(k, mask=[[True,False,False],[False, True, True]])  # h.shape = [3, 4]
  • 维度变换
# tf.reshape(a, [xxxx]) 重新对view进行解释
a = tf.random.normal([4, 28, 28, 3])
a = tf.reshape(a, [4, 784, 3])  # the same as tf.reshape(a, [4, -1, 3])

# tf.transpose(a, perm = [xxx])  perm不指定的话就是全转
b = tf.random.normal([4,3,2,1])  # b.shape = [4,3,2,1]
c = b.transpose(b, perm = [0, 1, 3, 2])  # c.shape = [4,3,1,2]
d = b.transpose(b)  # d.shape = [1,2,3,4]

# 增加维度 tf.expand_dims(a, axis = x) 会在x那个轴加一个列,无论正负
f = tf.random.normal([4,28,36,6])
g = f.expand_dims(f, axis = 0)  # g.shape = [1, 4, 28,36,6]
h = f.expand_dims(f, axis = -2)  # h.shape = [4, 28, 36, 1, 6]

# 减少维度 减少维度只能减少shape = 1的那个维度,因为shape为1的那个维度是冗余信息
# tf.squeeze(a, axis = x)  axis不指定,1的会全部去掉
i = tf.zeros([1, 2, 1, 3])
j = tf.squeeze(i)  # j.shape = [2,3]
k = tf.squeeze(i, axis = 0)  # k.shape = [2,1,3]
  • broadcast
# broadcast : 从右边对其,不够维度扩张为1,如果是1可以扩张成一样的,如果不一样但不是1,就不能broadcast。这是一种隐式的优化方式
a = tf.random.normal([4,32,32,3])
a + tf,random.normal([3])  # ok
a + tf.random.normal([32, 32, 1])  # ok
a + tf.random.normal([4,1,1,1])  # ok
a + tf.random.normal([4,1])  # error
a + tf.random.normal([1,4,1,1])  # error

# 也可以显示的调用api:tf.broadcast_to(tensor1, tensor2)
b = tf.broadcast_to(tf.random.normal([4,1,1,1]), [4,32,32,3])
  • 数学运算
# + - * / //(整除) %:都是对tensor内部每个元素对应计算
a = tf.ones([2,2])
b = tf.fill([2,2], 3)
c = a + b  # c = [[4, 4],[4, 4]]
d = a * b  # d = [[3, 3],[3, 3]]

# tf.math.log(a) tf.exp(a)  也是对应到各个元素
e = tf.ones([2,2])
f = tf.math.log(e)  # f = [[0, 0],[0, 0]]
g = tf.exp(a)  #g = [[2.7, 2.7],[2.7,2.7]]

# tf.pow(a, 3) 张量a的每个元素的三次方
# a ** 3  与上面相同
# tf.sqrt(a) 开方
h = tf.fill([2,2], 3)
i = tf.pow(h, 3)  # i = [[8,8],[8,8]]
j = h ** 3  # j = [[8,8],[8,8]]
k = tf.sqrt(h)  # k = [[1.73, 1.73],[1.73, 1.73]]

# 矩阵运算:
# 矩阵相乘@:a @ b
# tf.matmul(a, b) 与上相同
l = tf.ones([2,2])
m = tf.fill([2,2], 2)
n = l@m  # n = [[4,4],[4,4]]
o = tf.matmul(l, m)  # o = [[4,4],[4,4]]
p = tf.ones([4,2,3])
q = tf.fill([4,3,5], 3)
p@q or tf.matmul(p,q) = [4,2,5]