张量数据的一系列操作
相关函数操作
张量的数据类型 基本 和 numpy 差不多 ,基本函数操作联想一下就行
常量 tf.constant() 不可变
变量 tf.Variable()
#变量的值可以改变,可以通过assign, assign_add等方法给变量重新赋值
v = tf.Variable([1.0,2.0],name = "v")
v.assign_add([1.0,1.0])# 重新赋值后 值改变了 没有改变
#tf.rank() 类似于 np.ndim()** 显示张量维度 ,有几层中括号,就有多少维张量。
tf.rank(vector)
np.ndim(vector.numpy())
# tf.cast(a,tf.float32) 改变张量的数据类型
a= tf.constant([1,2],dtype = tf.int32)
b = tf.cast(a,tf.float32)
#a.numpy() a.shape 张量转numpy 查看shape
u = tf.constant(u"你好 世界")
u.numpy() #b'\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\x96\xe7\x95\x8c'
u.numpy().decode("utf-8")#你好 世界
#Id(a) 张量的唯一的ID
一、 索引切片
张量的索引切片方式和numpy几乎是一样的。切片时支持缺省参数和省略号.
1 silce 与 列表切片
tf.random.set_seed(3)
t = tf.random.uniform([5,5],minval=0,maxval=10,dtype=tf.int32)
tf.print(t)
t[0]#第0行
tf.print(t[-1])#倒数第一行
#第1行第3列
tf.print(t[1,3])
tf.print(t[1][3])
#tf.slice(input,begin_vector,size_vector)
tf.slice(t,[1,0],[3,5]) or t[1:4,:]
第1行至第3行
tf.slice(input,begin_vector,size_vector)
#第1行至最后一行,第0列到最后一列每隔两列取一列
tf.print(t[1:4,:4:2])
:4:2 # :4 到第四列 :2 每2列取数 如图是 0 2列
二、不规则切片
对于不规则的切片提取,可以使用tf.gather , tf.gather_nd ,tf.boolean_mask。
tf.boolean_mask功能最为强大,它可以实现tf.gather,tf.gather_nd的功能,并且tf.boolean_mask还可以实现布尔索引。
如果要通过修改张量的某些元素得到新的张量,可以使用tf.where,tf.scatter_nd。
1 gather
#有4个班级,每个班级10个学生,每个学生7门科目成绩。可以用一个4×10×7的张量来表示。
tf.random.set_seed(1)
scores = tf.random.uniform([4,10,7],minval=0,maxval=100,dtype=tf.int32)
#axis 班级 0 学生1 成绩2
tf.print(scores,summarize=-1)#summarize=-1 显示所有条目信息
#抽取每个班级第0个学生,第5个学生,第9个学生的全部成绩
#学生的维度是1
tf.print(tf.gather(scores,[0,5,9],axis=1))
2 gather_nd
tf.gather_nd(params, indices, batch_dims=0, name=None)
#抽取每个班级第0个学生,第5个学生,第9个学生的第1门课程,第3门课程,第6门课程成绩
tf.gather(tf.gather(scores,[0,5,9],axis=1),[1,3,6],axis=2)
#抽取第0个班级第0个学生,第2个班级的第4个学生,第3个班级的第6个学生的全部成绩
#indices的长度为采样样本的个数,每个元素为采样位置的坐标
tf.gather_nd(scores,indices=[(0,0),(2,4),(3,6)])
3 boolean_mask
以上tf.gather和tf.gather_nd的功能也可以用tf.boolean_mask来实现
#维度 4 * 10 * 7
#抽取每个班级第0个学生,第5个学生,第9个学生的全部成绩
tf.boolean_mask(scores,[True,False,False,False,False,
True,False,False,False,True],axis=1)
#抽取第0个班级第0个学生,第2个班级的第4个学生,第3个班级的第6个学生的全部成绩
tf.boolean_mask(scores,[[**True**,False,False,False,False,False,False,False,False,False],
[False,False,False,False,False,False,False,False,False,False],
[False,False,False,False,**True**,False,False,False,False,False],
[False,False,False,False,False,False,**True**,False,False,False]])
利用tf.boolean_mask可以实现布尔索引 找到矩阵中过滤条件的的元素
三、修改张量元素
修改张量的部分元素值得到新的张量,可以使用tf.where和tf.scatter_nd。
tf.where可以理解为if的张量版本,此外它还可以用于找到满足条件的所有元素的位置坐标。
tf.scatter_nd的作用和tf.gather_nd有些相反,
tf.gather_nd用于收集张量的给定位置的元素,
而tf.scatter_nd可以将某些值插入到一个给定shape的全0的张量的指定位置处。
1 where
tf.where和np.where作用类似
tf.where(condition, x=None, y=None, name=None)
c = tf.constant([[-1,1,-1],[2,2,-2],[3,-3,3]],dtype=tf.float32)
tf.where(c>0)#获取的是满足条件的索引
tf.where(c<0,tf.fill(c.shape,0.0),c)#对小于0的 拿0进行填充
2 scatter_nd
将指定位置的数替换为0
indices = tf.where(c<0) # 得到的是小于0元素的下标
tf.gather_nd(c,indices) # 根据下标 得到该下标的元素
tf.scatter_nd(indices,tf.gather_nd(c,indices),c.shape) # 根据下标元素 生成维度为c的张量矩阵
####通过张量相减 就完成替换为0的操作
四、维度问题
tf.reshape 可以改变张量的形状
tf.squeeze 可以减少维度。
tf.expand_dims 可以增加维度。
tf.transpose 可以交换维度
reshape、sequeeze、expand_dims、transpose
reshape可以改变张量的形状,但是其本质上不会改变张量元素的存储顺序,所以,该操作实际上非常迅速,并且是可逆的
a = tf.random.uniform(shape=[1,3,3,2],
minval=0,maxval=10,dtype=tf.int32)
tf.print(a.shape) # shape [1, 3, 3, 2]
tf.reshape(a,[3,6])# shape [3, 6]
tf.reshape(a,[1,3,3,2])# shape [1, 3, 3, 2]
tf.squeeze(a) # shape [3, 3, 2]
tf.expand_dims(s,axis=0) # shape=(1, 3, 3, 2)
如果张量在某个维度上只有一个元素,利用tf.squeeze可以消除这个维度。
tf.transpose可以交换张量的维度,与tf.reshape不同,它会改变张量元素的存储顺序。
tf.transpose常用于图片存储格式的变换上
五、数据合并与分割操作
concat 与 stack 与 split
类似于pandas的 concat 和 stack
tf.concat和tf.stack有略微的区别,tf.concat是连接,不会增加维度,而tf.stack是堆叠,会增加维度。
tf.concat([a,b],axis=0)#axis = 0 纵向拼接,axis=1 横向拼接
#shape a (2,2) b(2,2) concat->shape(4,2),stack->shape(2,2,2)
split
#tf.split(value,num_or_size_splits,axis)
# c shape=(6, 2)
tf.split(c,3,axis = 0) #指定分割份数,平均分割
tf.split(c,[2,2,2],axis = 0) #指定每份的记录数量
- List item