2017-06-08 10 views
-1

Donc j'ai un tenseur h_in de forme (50, ?, 1, 100) que je voudrais maintenant transformer en forme (50, 1, 1, 100) en prenant le maximum sur l'axe 1.tensorflow - get max du tenseur

Comment puis-je faire cela?

J'ai essayé

h_out = max_pool(h_in) 

avec

def max_pool(h,ksize=[1,-1,1,1],strides=[1,1,1,1],padding='VALID'): 
    return tf.nn.max_pool(h,ksize=ksize,strides=strides,padding=padding) 

mais cela ne semble pas réduire la taille.

exemple runnable:

import tensorflow as tf 
import numpy as np 
import numpy.random as nprand 

def _weight_variable(shape,name): 
    initial = tf.truncated_normal(shape,stddev=0.1) 
    v = tf.Variable(initial,name=name) 
    return v 

def _bias_variable(shape,name): 
    initial = tf.constant(0.1,shape=shape) 
    v = tf.Variable(initial,name=name) 
    return v 

def _embedding_variable(shape,name): 
    initial = tf.truncated_normal(shape) 
    v = tf.Variable(initial,name=name) 
    return v 

def conv2d(x,W,strides=[1,1,1,1],padding='VALID'): 
    return tf.nn.conv2d(x,W,strides=strides,padding=padding) 

def max_pool(h,ksize=[1,-1,1,1],strides=[1,1,1,1],padding='VALID'): 
    return tf.nn.max_pool(h,ksize=ksize,strides=strides,padding=padding) 

nof_embeddings= 55000 
dim_embeddings = 300 

batch_size = 50 
filter_size = 100 
x_input = tf.placeholder(tf.int32, shape=[batch_size, None]) 

def _model(): 

    embeddings = _embedding_variable([nof_embeddings,dim_embeddings],'embeddings') 

    h_lookup = tf.nn.embedding_lookup(embeddings,x_input) 
    h_embed = tf.reshape(h_lookup,[batch_size,-1,dim_embeddings,1]) 

    f = 3 

    W_conv1f = _weight_variable([f,dim_embeddings,1,filter_size],f'W_conv1_{f}') 
    b_conv1f = _bias_variable([filter_size],f'b_conv1_{f}') 
    h_conv1f = tf.nn.relu(conv2d(h_embed,W_conv1f) + b_conv1f) 

    h_pool1f = max_pool(h_conv1f) 

    print("h_embed:",h_embed.get_shape()) 
    print() 
    print(f'h_conv1_{f}:',h_conv1f.get_shape()) 
    print(f'h_pool1_{f}:',h_pool1f.get_shape()) 
    print() 

    return tf.shape(h_pool1f) 

if __name__ == '__main__': 

    tensor_length = 35 

    model = _model() 
    with tf.Session() as sess: 
     tf.global_variables_initializer().run() 
     batch = nprand.randint(0,nof_embeddings,size=[batch_size,tensor_length]) 
     shape = sess.run(model, 
         feed_dict ={ 
           x_input : batch 
           }) 
     print('result:',shape) 

qui délivre en sortie

h_embed: (50, ?, 300, 1) 

h_conv1_3: (50, ?, 1, 100) 
h_pool1_3: (50, ?, 1, 100) 

result: [ 50 35 1 100] 

Disons que je hardcode plutôt la taille que je veux:

h_pool1f = max_pool(h_conv1f,ksize=[1,35-f+1,1,1]) 

qui fonctionne. Mais maintenant je suis en difficulté dès que je change le tensor_length (qui est déterminé à l'exécution, donc non, je ne peux pas le coder en dur). Une "solution" serait de souffler l'entrée jusqu'à une longueur maximale fixe par rembourrage, ou quelque chose, mais encore une fois, cela introduit des calculs inutiles et une casquette artificielle, que je voudrais beaucoup éviter.

Alors, est-il

  • un moyen de faire tensorflow "correctement" reconnaître le -1 dans k_size?
  • ou une autre façon de calculer le max?
+0

Je pense que 'tf.reduce_max' est ce que vous cherchez –

+0

@PietroTortella testé un peu, prêt à croire qu'il fait ce que je cherche, merci. Voulez-vous développer votre commentaire dans une réponse? – User1291

Répondre

2

Je pense que tf.reduce_max est ce que vous cherchez: https://www.tensorflow.org/api_docs/python/tf/reduce_max

Utilisation:

tens = some tensorflow.Tensor 
ax = some positive integer, or -1 or None 
red_m = tf.reduce_max(tens, axis=ax) 

Si des dizaines a la forme [shape_0, shape_1, shape_2], le tenseur résultant red_m aura la forme [shape_1, shape_2] si ax=0, la forme [shape_0, shape_2] si ax=1, et ainsi de suite. Si ax=-1, les derniers axes sont déduits, tandis que si ax=None, la réduction se produira le long de tous les axes.