tf.tile,tf.gather,t f.concat,t f .expand_dims,tf.add_n, tf.stack,tf.sparse_to_dense

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010365819/article/details/88233385
temp = tf.range(0,10)*10 + tf.constant(1,shape=[10])
temp2 = tf.gather(temp,[1,5,9])

with tf.Session() as sess:

    print (sess.run(temp))
    print (sess.run(temp2))

输出结果

[ 1 11 21 31 41 51 61 71 81 91]
[11 51 91]

gather就和字面意思一样就是收集。从’params"中,按照axis坐标和indices标注的元素下标,把这些元素抽取出来组成新的tensor.

print("\n先测试一维张量\n")
t=np.random.randint(1,10,5)
g1=tf.gather(t,[2,1,4])
sess=tf.Session()
print(t)
print(sess.run(g1))
print("\n再测试二维张量\n")
t=np.random.randint(1,10,[4,5])
g2=tf.gather(t,[1,2,2],axis=0)
g3=tf.gather(t,[1,2,2],axis=1)
print(t)
print(sess.run(g2))
print(sess.run(g3))

输出结果:

先测试一维张量
[2 3 7 9 3]
[7 3 3]

再测试二维张量

[[6 9 2 8 9]
 [7 4 8 3 1]
 [9 8 3 3 3]
 [3 9 8 8 1]]
[[7 4 8 3 1]
 [9 8 3 3 3]
 [9 8 3 3 3]]
[[9 2 2]
 [4 8 8]
 [8 3 3]
 [9 8 8]]

tile()函数是用来对张量(Tensor)进行扩展的,其特点是对当前张量内的数据进行一定规则的复制。最终的输出张量维度不变。
tf.tile([1,2,3],[2])
b = tf.tile([[1,2],
             [3,4],
             [5,6]],[2,3])
with tf.Session() as sess:
    print(sess.run(a))
    print('-----')
    print(sess.run(b))

输出结果:

[1 2 3 1 2 3]
-----
[[1 2 1 2 1 2]
 [3 4 3 4 3 4]
 [5 6 5 6 5 6]
 [1 2 1 2 1 2]
 [3 4 3 4 3 4]
 [5 6 5 6 5 6]]

tf.concat 按照指定的维度,将指定的tensor连接起来

```python
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0)  # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1)  # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]

# tensor t3 with shape [2, 3]
# tensor t4 with shape [2, 3]
tf.shape(tf.concat([t3, t4], 0))  # [4, 3]
tf.shape(tf.concat([t3, t4], 1))  # [2, 6]
```


```python
t1 = [[[1, 2], [2, 3]], [[4, 4], [5, 3]]]
t2 = [[[7, 4], [8, 4]], [[2, 10], [15, 11]]]
tf.concat([t1, t2], -1)
```

would produce:

```python
[[[ 1,  2,  7,  4],
  [ 2,  3,  8,  4]],

 [[ 4,  4,  2, 10],
  [ 5,  3, 15, 11]]]
```
tf.expand_dims:

给定一个tensor,在指定的维度处,扩展一个维度。并返回一个新的tensor

a=tf.constant([[1,1,1],[2,2,2],[3,3,3]])
b=tf.expand_dims(a,0)
sess=tf.Session()
print(a.shape)
print('----')
print(sess.run(b))
print(b.shape)

在第一个维度处添加一个维度

输出结果:

(3, 3)
----
[[[1 1 1]
  [2 2 2]
  [3 3 3]]]
(1, 3, 3)

修改一个b=tf.expand_dims(a,1)

输出结果:

(3, 3)

----
[[[1 1 1]]

 [[2 2 2]]

 [[3 3 3]]]
(3, 1, 3)

tf.add_n:

对输入的tensor列表中对应位置的元素相加

input1 = tf.constant([[1.0, 2.0, 3.0],[1.0, 2.0, 3.0]])
input2 = tf.Variable(tf.random_uniform([2,3]))
output = tf.add_n([input1, input2])
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
  sess.run(init_op)
  print(sess.run(input1))
  print(sess.run(input2))
  print(sess.run(output))

输出的结果:

[[1. 2. 3.]
 [1. 2. 3.]]
[[0.2487799  0.78012884 0.33687603]
 [0.7201599  0.79775095 0.85197365]]
[[1.2487799 2.780129  3.336876 ]
 [1.7201599 2.797751  3.8519735]]

tf.stack:

stack(values, axis=0, name="stack")

将values中的tensor打包成一个新的tensor,在给定的axis维度处,这样就会导致维度增加。这个是和concat不同的一点

if `axis == 0` then the `output` tensor will have the shape `(N, A, B, C)`.
if `axis == 1` then the `output` tensor will have the shape `(A, N, B, C)`.
a = tf.constant([[1, 2],[3, 4],[5, 6]])
b = tf.constant([[7, 8],[9, 10],[11, 12]])
with tf.Session() as sess:
  print(sess.run(tf.stack([a,b])))
  print('------')
  print(sess.run(tf.stack([a,b],axis=1)))

输出结果:

[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]]
------
[[[ 1  2]
  [ 7  8]]

 [[ 3  4]
  [ 9 10]]

 [[ 5  6]
  [11 12]]]

tf.stack([a,b])在默认在维度0处打包,原先a和b的均为shape(3,2)那么打包后的tensor的结果shape=(2,3,3)。就是将a和b直接组成一个新的tensor

tf.stack([a,b],axis=1)在维度1处打包,那么打包之后的新的tensor的shape=(3,2,2)

tf.stack([a,b],axis=2)在维度2处打包,那么打包之后的新的tensor的shape=(3,2,2)

结果是:

[[[ 1  7]
  [ 2  8]]

 [[ 3  9]
  [ 4 10]]

 [[ 5 11]
  [ 6 12]]]
 

个人的一个总结吧,我觉得concat和stack其实还是有点相似的,容易弄混,不一样的地方是:

concat‘更加注重的是连接,真正的连接,把两个矩阵在指定的维度处直接的连起来。

但是stack其实不是简单的连接,更像是一个拼装,组合。stack下axis=0的时候组合是直接的tensor组合,axis为一的时候组合的其实是对应tensor的第一个维度,并不是第二个维度。当axis=2的时候组合的是tensor的第二个维度。(axis=0才是第一个维度)有点拗口,不太好理解。

tf.sparse_to_dense(sparse_indices, output_shape, sparse_values, default_value, name=None)
除去name参数用以指定该操作的name,与方法有关的一共四个参数:
第一个参数sparse_indices:稀疏矩阵中那些个别元素对应的索引值。

     有三种情况:

     sparse_indices是个数,那么它只能指定一维矩阵的某一个元素

     sparse_indices是个向量,那么它可以指定一维矩阵的多个元素

     sparse_indices是个矩阵,那么它可以指定二维矩阵的多个元素

第二个参数output_shape:输出的稀疏矩阵的shape

第三个参数sparse_values:个别元素的值。

     分为两种情况:

     sparse_values是个数:所有索引指定的位置都用这个数

     sparse_values是个向量:输出矩阵的某一行向量里某一行对应的数(所以这里向量的长度应该和输出矩阵的行数对应,不然报错)

第四个参数default_value:未指定元素的默认值,一般如果是稀疏矩阵的话就是0了

举一个例子:

在mnist里面有一个把数字标签转化成onehot标签的操作,所谓onehot标签就是:

如果标签是6那么对应onehot就是[ 0.  0.  0.  0.  0.  0.  1.  0.  0.  0.]

如果标签是1那么对应onehot就是[ 0.  1.  0.  0.  0.  0.  0.  0.  0.  0.]

如果标签是0那么对应onehot就是[ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

就是把标签变为适用于神经网络输出的形式。

label=tf.expand_dims(tf.constant([0,2,3,6,7,9]),1)
index=tf.expand_dims(tf.range(0, 6),1)
concated = tf.concat([index, label],1)
onehot_labels = tf.sparse_to_dense(concated, (6,10), 1.0, 0.0)
with tf.Session() as sess:
  print(sess.run(label))
  print('------')
  print(sess.run(index))
  print('------')
  print(sess.run(concated))
  print('------')
  print(sess.run(onehot_labels))

输出结果:

[[0]
 [2]
 [3]
 [6]
 [7]
 [9]]
------
[[0]
 [1]
 [2]
 [3]
 [4]
 [5]]
------
[[0 0]
 [1 2]
 [2 3]
 [3 6]
 [4 7]
 [5 9]]
------
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

猜你喜欢

转载自blog.csdn.net/u010365819/article/details/88233385
今日推荐