tensorflow笔记(二十七)——重要tensor操作函数

1.合并

多个tensor的合并主要包括2个函数:tf.concat和tf.stack,他们的输出参数都是list of tensor。区别是:

  • tf.concat是沿某一维度拼接shape相同的张量,拼接生成的新张量维度不会增加。
  • tf.stack是在新的维度上拼接,拼接后维度加1。
import tensorflow as tf
a = tf.constant([[1,2,3],[4,5,6]]) 
b = tf.constant([[7,8,9],[10,11,12]])
ab1 = tf.concat([a,b],axis=0)
ab2 = tf.stack([a,b], axis=0)
sess = tf.Session()
print(sess.run(ab1)) 
print(sess.run(ab2))
print ab1
print ab2

结果:

[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]#ab1的值

 [[[ 1  2  3]
   [ 4  5  6]]
  [[ 7  8  9]
   [10 11 12]]]#ab2的值
Tensor("concat:0", shape=(4, 3), dtype=int32)#ab1的属性
Tensor("stack:0", shape=(2, 2, 3), dtype=int32)#ab2的属性

2 拆分

将1个tensor拆分成多个tensor,主要包括2个函数:tf.split和tf.unstack。区别是:

  • tf.split(x, num_or_size_splits, axis),其中num_or_size_splits可以是数字或者list,分别表示拆分成多少份和每份长度。
  • tf.unstack(x, num, axis):希望在某个维度上全部按长度为 1 的方式分割。
a = tf.constant([[1,2,3,4,5],[6,7,8,9,10]])
b = tf.split(a, 2, axis=0)
c = tf.split(a, [1,2,2], axis=1)
d = tf.unstack(a, axis=0)
e = tf.unstack(a, axis=1)
sess=tf.Session()
print(sess.run(b))
print(sess.run(c))
print(sess.run(d))
print(sess.run(e))

结果

[array([[1, 2, 3, 4, 5]], dtype=int32), array([[ 6,  7,  8,  9, 10]], dtype=int32)] #b
[array([[1],[6]], dtype=int32), array([[2, 3], [7, 8]], dtype=int32), array([[ 4,  5],[ 9, 10]], dtype=int32)] #c
[array([1, 2, 3, 4, 5], dtype=int32), array([ 6,  7,  8,  9, 10], dtype=int32)] #d
[array([1, 6], dtype=int32), array([2, 7], dtype=int32), array([3, 8], dtype=int32), array([4, 9], dtype=int32), array([ 5, 10], dtype=int32)] #e

3.累加

常用多个tensor累加函数主要是tf.math.add, tf.math.add_n和+运算符。区别:

  • tf.math.add:两个tensor,元素相加,支持广播;
  • tf.math.add_n: list of tensors支持多个tensor,元素相加,不支持广播;
  • +元算符:与tf.math.add数学逻辑一致,只是不能加name参数。
a = tf.constant([[3, 5], [4, 8]])
b = tf.constant([[1, 6], [2, 9]])
c = tf.constant([1])
d = tf.math.add_n([a, b, a])
e = tf.math.add(a, c)
f = a + c
sess=tf.Session()
print(sess.run(d))
print(sess.run(e))
print(sess.run(f))

结果:

[[ 7 16]
 [10 25]] #d

[[4 6]
 [5 9]] #e

[[4 6]
 [5 9]] #f

4.转置

tensor的转置主要用tf.transpose函数,tf.transpose(a, perm=None, conjugate=False, name=‘transpose’),其中a是源tensor,perm是排列顺序,conjugate是bool参数用于复数共轭配置。在一些维度变换场景很有用。

import tensorflow as tf
a = tf.constant([[[1,2],[3,4]],[[5,6],[7,8]]])
b = tf.transpose(a)
c = tf.transpose(a, [0,2,1])
sess = tf.Session()
print(sess.run(a))
print(sess.run(b))
print(sess.run(c))

结果:

[[[1 2]
  [3 4]]
 [[5 6]
  [7 8]]] # a

[[[1 5]
  [3 7]]
 [[2 6]
  [4 8]]] # b
  
[[[1 3]
  [2 4]]
 [[5 7]
  [6 8]]] # c

默认perm是将源tensor的维度逆向,原始a是3维tensor,那么对应的转置b应该是将a的[0,1,2]维向量放到[2,1,0]维的位置,比如a中的7的坐标是(1, 1, 0),那么转置之后其坐标刚好颠倒是(0, 1, 1)。对于c是指定了perm参数,也就指定了转置顺序是[0, 2, 1],也就是第0维不变,第1和2维互换位置,那么a中7在c中的位置就是(1, 0, 1)。
上面可能有些抽象,在实际场景中,transpose常常用于多维tensor的调整。如下,获取特征embedding的过程:

# 一个常见的特征embedding过程
def get_features_embedding(self, features):
    multi_field_embedings = []
    for fea in features:
		# every fea is batch_size*multi_value_size
		field_embedding = tf.nn.embedding_lookup(self.embeddings, fea)
		# multi_value feature embedding mean
		field_embedding = tf.reduce_mean(field_embedding, [1])
		multi_field_embedings.append(field_embedding)
	# multi_field_size * batch_size * embedding_size
	features_embedding = tf.stack(multi_field_embedings)
	# batch_size * multi_field_size * embedding_size
	features_embedding = tf.transpose(features_embedding, (1, 0, 2))
	# batch_size * (multi_field_size * embedding_size)
	features_embedding = tf.reshape(
	    features_embedding, (-1, self.fields_size * self.embedding_size))
	return features_embedding

你可能感兴趣的:(tensorflow,tensorflow,python,transpose,stack,concat)