Press "Enter" to skip to content

Tensorflow array ops

Tensorflow array ops

 

本文的目的是梳理一下 Tensorflow 实现的的各种 array 相关的 operation

 

Identity

 

输入:

 

 

    1. input: tensor类型

 

    1. name : 字符串 tensor 的名字 输出: 和 input 一样的 tensor

 

 

文档并没有描述清楚这个操作有何用处,输入一个 tensor 然后输出一个一样的 tensor 好像什幺都没做。其实不然,Identity会在计算图中添加一个新的节点因为这是一个 operation ,如果直接用 Python 的赋值运算不会在图上有任何的节点产生。下面举个例子

 

import tensorflow as tf
def python_assign():
    x = tf.Variable(0.0, name="x")
    x_plus_1 = tf.assign_add(x, 1, name="plus")
    with tf.control_dependencies([x_plus_1]):
        y = x
    init = tf.initialize_all_variables()
    with tf.Session() as session:
        init.run()
        writer = tf.summary.FileWriter( './python_assign', session.graph)
        for i in range(5):
            print(y.eval())

def tf_identity():
    x = tf.Variable(0.0, name="x")
    x_plus_1 = tf.assign_add(x, 1, name="plus")
    with tf.control_dependencies([x_plus_1]):
        y = tf.identity(x)
    init = tf.initialize_all_variables()
    with tf.Session() as session:
        writer = tf.summary.FileWriter( './tf_identity', session.graph)
        init.run()
        for i in range(5):
            print(y.eval())

 

分别运行下面这两个函数,python_assign y 的值一值都是 0 不会发生变化,对应的计算图分别如下,明显的看到会多出一个节点,Tensorflow 的机制是先构造好图然后才会计算,所以没有节点是不会每次都计算的。

 

(python_assgin) (tf_identity)

 

在构建 graph 的时候需要把某个临时变量比如 loss 加入到图中就可以使用这个函数。

 

expand_dims

 

作用:给一个 tensor 插入一个维度, 可以简单理解为对 expand 前 tensorflow 的 shape 的 list 是 l = [2,3] 。 expand_dim 的作用就是在 shape 的某个位置上 insert 一个 1 对应的 tensor 也随着发生相应的变化。本质上是和 reshape 是 特殊的 reshape 的操作。

 

看例子. t 是一个一维向量,t2 在 0 添加一个维度,就变成了 [1,2],t3 变成[2,1 ] 。

 

import tensorflow as tf
import numpy as np
t = tf.constant(np.array([1,2, 3]))
t2 = tf.expand_dims(t, 0)
t3 = tf.expand_dims(t, 1)
with tf.Session() as session:
   print("t:")
   print(session.run(t), "shape: ",t.get_shape().as_list())
   print("t_shape: ")
   print(t.get_shape().as_list())
   print("")
   print("t2: ")
   print(session.run(t2))
   print("t2_shape: ")
   print(t2.get_shape().as_list())
   print("")
   print("t3:")
   print(session.run(t3))
   print("t3_shape:")
   print(t3.get_shape().as_list())

 

slice

 

在 numpy 可以对矩阵进行切片,tensorflow 也实现了类似的功能通过 slice 。 slice(input_, begin, size, name=None) 参数 input_ 是一个 被切片的 tensor, begin 是开始位置,是一个和 input_的 shape 数组一样大小的数组, size 是一个同样长度的数组,每个元素标注了每个维度需要的元素个数,只不过开始元素是从1 开始的。

 

换算成 numpy 的方式可以如下计算:

 

t = tf.constant([[[1, 1, 1], [2, 2, 2]],
                 [[3, 3, 3], [4, 4, 4]],
                 [[5, 5, 5], [6, 6, 6]]])

a = np.array([[[1, 1, 1],
               [2, 2, 2]],
               [[3, 3, 3],
                [4, 4, 4]],
               [[5, 5, 5],
                [6, 6, 6]]])
with tf.Session() as sess:
    print("t.shape:", t.get_shape().as_list())
    print("")
    # a[1:2, :1, :]
    print(sess.run(tf.slice(t, [1, 0, 0], [1, 1, 3])))
    print("")
    # a[1:2, 0:2, 0: 3]
    print(sess.run(tf.slice(t, [1, 0, 0], [1, 2, 3])))
    print("")
    # a[1:2, 0:1, 0:3]
    print(sess.run(tf.slice(t, [1, 0, 0], [2, 1, 3])))

 

如果 t 是 三维的, a 是对应的numpy 矩阵,slice 的转换方式: a[begin[0]: begin[0] + size[0], begin[1]: begin[1]+ size[1], begin[2]:begin[2]+ size[2]]

 

strided_slice

 

和 slice 相似,只是多了一个取元素的步长,还有就是参数换成了,begin, end, 增加了一个 stride 参数

 

stack

 

把多个 tensor 拼在一起,最终的输出的 Rank 会增加 给定 N 个元素的 tensor 每个 tensor 的 shape 是(A, B, C) stack 的 axis = 0 的输出维度为 (N, A, B, C) stack 的 axis=1 的输出维度为 (A, N, B, C)

 

x = tf.constant([1, 4])
 y = tf.constant([2, 5])
 z = tf.constant([3, 6])
 tf.stack([x, y, z])  # [[1, 4], [2, 5], [3, 6]] (Pack along first dim.)
 tf.stack([x, y, z], axis=1)  # [[1, 2, 3], [4, 5, 6]]

 

parallel_stack

 

和 stack 的区别是在计算的时候需要所有的元素都被计算出来,我们知道 tensorflow 的计算图是有依赖关系的。而且少了个 axis 参数。

 

unstack

 

stack 的反向操作

 

import tensorflow as tf
t = tf.constant([[[1, 1, 1], [2, 2, 2]],
                [[3, 3, 3], [4, 4, 4]],
                [[5, 5, 5], [6, 6, 6]]])
ut = tf.unstack(t, axis=2)
with tf.Session() as sess:
   t1 = sess.run(ut[0])
   t2 = sess.run(ut[1])
   t3 = sess.run(ut[2])
   print('t1:')
   print(t1)
   print('t2:')
   print(t2)
   print('t3:')
   print(t3)

 

concat

 

拼接多个 tensor 和 stack 的区别是 tensor 的 Rank 不会发生变化

 

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

 

boolean_mask

 

可以用某种条件从 tensor 中取元素

 

tensor = [0, 1, 2, 3]
 mask = np.array([True, False, True, False])
 boolean_mask(tensor, mask)  # [0, 2]

 

还可以指定 aixs

 

tensor = [[1, 2], [3, 4], [5, 6]]
mask = np.array([True, False ])
m = tf.boolean_mask(tensor, mask, axis=1) #[[1],[3],[5]]
with tf.Session() as sess:
   print(sess.run(m))

 

sparse_mask

 

[TODO]

 

unique

 

split

 

transpose

 

matrix_transpose

 

pad

 

meshgrid

 

edit_distance

 

gather

 

reverse_sequence

 

one_hot

 

根据 indices 产生 one_hot 的矩阵

 

indices = [0, 1, 2]
 depth = 3
 tf.one_hot(indices, depth)  # output: [3 x 3]
  # [[1., 0., 0.],
  #  [0., 1., 0.],
  #  [0., 0., 1.]]

 

squeeze

 

where

 

reverse_sequence

 

zeros

 

zeros_like

 

ones_like

 

ones

 

shape

 

计算 tensor 的 shape 返回一个 1-D tensor

 

size

 

计算 tensor 中元素的个数

 

rank

 

计算 tensor 的 rank

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注