2017-09-15 3 views
1

Je souhaite découper un tenseur dans la dimension "Aucun".Comment découper un tenseur avec une dimension None dans Tensorflow

Par exemple,

tensor = tf.placeholder(tf.float32, shape=[None, None, 10], name="seq_holder") 
sliced_tensor = tensor[:,1:,:] # it works well! 

mais

# Assume that tensor's shape will be [3,10, 10] 
tensor = tf.placeholder(tf.float32, shape=[None, None, 10], name="seq_holder") 
sliced_seq = tf.slice(tensor, [0,1,0],[3, 9, 10]) # it doens't work! 

Il est même que je reçois un message quand je l'ai utilisé un autre place_holder pour alimenter le paramètre de taille pour tf.slice().

La deuxième méthode m'a donné le message d'erreur «La taille de l'entrée (profondeur des entrées) doit être accessible via l'inférence de forme».

J'aimerais savoir ce qui est différent entre deux méthodes et ce qui est plus tensorflow-ish.

[Modifié] code complet est ci-dessous

import tensorflow as tf 
import numpy as np 

print("Tensorflow for tests!") 

vec_dim = 5 
num_hidden = 10 
# method 1 
input_seq1 = np.random.random([3,7,vec_dim]) 

# method 2 
input_seq2 = np.random.random([5,10,vec_dim]) 
shape_seq2 = [5,9,vec_dim] 
# seq: [batch, seq_len] 
seq = tf.placeholder(tf.float32, shape=[None, None, vec_dim], name="seq_holder") 

# Method 1 
sliced_seq = seq[:,1:,:] 

# Method 2 
seq_shape = tf.placeholder(tf.int32, shape=[3]) 
sliced_seq = tf.slice(seq,[0,0,0], seq_shape) 

cell = tf.contrib.rnn.GRUCell(num_units=num_hidden) 
init_state = cell.zero_state(tf.shape(seq)[0], tf.float32) 

outputs, last_state = tf.nn.dynamic_rnn(cell, sliced_seq, initial_state=init_state) 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    # method 1 
    # states = sess.run([sliced_seq], feed_dict={seq:input_seq1}) 
    # print(states[0].shape) 

    # method 2 
    states = sess.run([sliced_seq], feed_dict={seq:input_seq2, seq_shape:shape_seq2}) 
    print(states[0].shape) 
+0

Avez-vous l'erreur lorsque vous définissez les opérations (lors de l'exécution de ces deux lignes) ou lorsque vous essayez de les exécuter (en appelant '.run' dans une session, par exemple) avec une entrée? Je n'ai aucun problème à exécuter ces deux instructions. – jdehesa

+0

J'ai eu une erreur quand j'ai mis le tenseur tranché (2ème méthode) en fonction dynamique rnn. Est-ce un problème de dynamic_rnn? –

+0

Hmm, difficile à dire ... pouvez-vous peut-être éditer votre question et ajouter plus de détails, peut-être un exemple reproductible minimal complet où votre problème apparaît? – jdehesa

Répondre

1

Votre problème est exactement décrit par issue #4590

Le problème est que tf.nn.dynamic_rnn a besoin de connaître la taille de la dernière dimension dans l'entrée (la " profondeur"). Malheureusement, comme le souligne le problème, actuellement, tf.slice ne peut déduire aucune taille de sortie si l'une des plages de tranches n'est pas entièrement connue au moment de la construction du graphique; par conséquent, sliced_seq finit par avoir une forme (?, ?, ?).

Dans votre cas, le premier problème est que vous utilisez un espace réservé de trois éléments pour déterminer la taille de la tranche; ce n'est pas la meilleure approche, puisque la dernière dimension ne devrait jamais changer (même si vous passez plus tard vec_dim, cela pourrait causer des erreurs). La solution la plus simple serait de transformer seq_shape dans un espace réservé de taille 2 (ou même deux espaces réservés séparés), puis faire le découpage en tranches comme:

sliced_seq = seq[:seq_shape[0], :seq_shape[1], :] 

Pour une raison quelconque, l'indexation de style NumPy semble avoir une meilleure forme capacités d'inférence, et cela permettra de préserver la taille de la dernière dimension en sliced_seq.

+0

Je reçois ceci :) Merci pour une explication détaillée! –