2016-02-02 8 views

Odpowiedz

9

Istnieją trzy istotne ops wykonawcze Theano na dimshuffle w TensorFlow:

  • tf.transpose() służy do permutacji wymiarów tensora. Jeśli wzorzec określony w argumentach dla dimshuffle jest permutacją wymiarów tensora wejściowego (tj. Nie ma 'x' lub brakującego wymiaru), można użyć tf.transpose() do wdrożenia dimshuffle().

  • tf.expand_dims() służy do dodania jednego lub więcej wymiarów rozmiaru 1 do tensora. Obsługuje to przypadek, w którym 'x' jest określony jako część wzorca dimshuffle(), ale nie zmienia kolejności istniejących wymiarów.

  • tf.squeeze() służy do usunięcia jednego lub więcej wymiarów rozmiaru 1 z tensora. Obsługuje to przypadek, w którym wymiar jest pomijany ze wzoru dimshuffle(), ale nie zmienia kolejności istniejących wymiarów.

Zakładając, że sygnał wejściowy jest wektorem, swoją przykład (dimshuffle(0, 'x')) może być wyrażony za pomocą tf.expand_dims() wyłącznie:

input = tf.placeholder(tf.float32, [None]) # Defines an arbitrary-sized vector. 
result = tf.expand_dims(input, 1) 

print result.get_shape() # ==> TensorShape([Dimension(None), Dimension(1)]) 

Biorąc bardziej skomplikowanego przykładu, dimshuffle(1, 'x', 0) stosowane do matrycy będzie:

input = tf.placeholder(tf.float32, [128, 32]) # Defines a matrix. 
output = tf.expand_dims(tf.transpose(input, [1, 0]), 1) 

print output.get_shape() 
# ==> TensorShape([Dimension(32), Dimension(1), Dimension(128)]) 
0

Zaimplementowałem dimshuffle dla TensorFlow w our framework Returnn (here). Kod jest to:

def expand_multiple_dims(x, axes, name="expand_multiple_dims"): 
    """ 
    :param tf.Tensor x: 
    :param list[int]|tuple[int] axes: after completion, tf.shape(y)[axis] == 1 for axis in axes 
    :param str name: scope name 
    :return: y where we have a new broadcast axis for each axis in axes 
    :rtype: tf.Tensor 
    """ 
    with tf.name_scope(name): 
    for i in sorted(axes): 
     x = tf.expand_dims(x, axis=i, name="expand_axis_%i" % i) 
    return x 


def dimshuffle(x, axes, name="dimshuffle"): 
    """ 
    Like Theanos dimshuffle. 
    Combines tf.transpose, tf.expand_dims and tf.squeeze. 

    :param tf.Tensor x: 
    :param list[int|str]|tuple[int|str] axes: 
    :param str name: scope name 
    :rtype: tf.Tensor 
    """ 
    with tf.name_scope(name): 
    assert all([i == "x" or isinstance(i, int) for i in axes]) 
    real_axes = [i for i in axes if isinstance(i, int)] 
    bc_axes = [i for (i, j) in enumerate(axes) if j == "x"] 
    if x.get_shape().ndims is None: 
     x_shape = tf.shape(x) 
     x = tf.reshape(x, [x_shape[i] for i in range(max(real_axes) + 1)]) # will have static ndims 
    assert x.get_shape().ndims is not None 

    # First squeeze missing axes. 
    i = 0 
    while i < x.get_shape().ndims: 
     if i not in real_axes: 
     x = tf.squeeze(x, axis=i) 
     real_axes = [(j if (j < i) else (j - 1)) for j in real_axes] 
     else: 
     i += 1 

    # Now permute. 
    assert list(sorted(real_axes)) == list(range(x.get_shape().ndims)) 
    if real_axes != list(range(x.get_shape().ndims)): 
     x = tf.transpose(x, real_axes) 

    # Now add broadcast dimensions. 
    if bc_axes: 
     x = expand_multiple_dims(x, bc_axes) 
    assert len(axes) == x.get_shape().ndims 
    return x 
0

Jeśli tensorflow to backend

from keras import baskend as K 
K.permute_dimension should do