2017-03-06 56 views
6

Jestem nowy w tensorflow i próbuję zaktualizować kod dla dwukierunkowego LSTM ze starej wersji tensorflow do najnowszej (1.0), ale ja ten błąd:Tensorflow: ValueError: Kształt musi być w rankingu 2, ale jest w rankingu 3

Shape must be rank 2 but is rank 3 for 'MatMul_3' (op: 'MatMul') with input shapes: [100,?,400], [400,2].

Błąd występuje na pred_mod.

_weights = { 
    # Hidden layer weights => 2*n_hidden because of foward + backward cells 
     'w_emb' : tf.Variable(0.2 * tf.random_uniform([max_features,FLAGS.embedding_dim], minval=-1.0, maxval=1.0, dtype=tf.float32),name='w_emb',trainable=False), 
     'c_emb' : tf.Variable(0.2 * tf.random_uniform([3,FLAGS.embedding_dim],minval=-1.0, maxval=1.0, dtype=tf.float32),name='c_emb',trainable=True), 
     't_emb' : tf.Variable(0.2 * tf.random_uniform([tag_voc_size,FLAGS.embedding_dim], minval=-1.0, maxval=1.0, dtype=tf.float32),name='t_emb',trainable=False), 
     'hidden_w': tf.Variable(tf.random_normal([FLAGS.embedding_dim, 2*FLAGS.num_hidden])), 
     'hidden_c': tf.Variable(tf.random_normal([FLAGS.embedding_dim, 2*FLAGS.num_hidden])), 
     'hidden_t': tf.Variable(tf.random_normal([FLAGS.embedding_dim, 2*FLAGS.num_hidden])), 
     'out_w': tf.Variable(tf.random_normal([2*FLAGS.num_hidden, FLAGS.num_classes]))} 

    _biases = { 
     'hidden_b': tf.Variable(tf.random_normal([2*FLAGS.num_hidden])), 
     'out_b': tf.Variable(tf.random_normal([FLAGS.num_classes]))} 


    #~ input PlaceHolders 
    seq_len = tf.placeholder(tf.int64,name="input_lr") 
    _W = tf.placeholder(tf.int32,name="input_w") 
    _C = tf.placeholder(tf.int32,name="input_c") 
    _T = tf.placeholder(tf.int32,name="input_t") 
    mask = tf.placeholder("float",name="input_mask") 

    # Tensorflow LSTM cell requires 2x n_hidden length (state & cell) 
    istate_fw = tf.placeholder("float", shape=[None, 2*FLAGS.num_hidden]) 
    istate_bw = tf.placeholder("float", shape=[None, 2*FLAGS.num_hidden]) 
    _Y = tf.placeholder("float", [None, FLAGS.num_classes]) 

    #~ transfortm into Embeddings 
    emb_x = tf.nn.embedding_lookup(_weights['w_emb'],_W) 
    emb_c = tf.nn.embedding_lookup(_weights['c_emb'],_C) 
    emb_t = tf.nn.embedding_lookup(_weights['t_emb'],_T) 

    _X = tf.matmul(emb_x, _weights['hidden_w']) + tf.matmul(emb_c, _weights['hidden_c']) + tf.matmul(emb_t, _weights['hidden_t']) + _biases['hidden_b'] 

    inputs = tf.split(_X, FLAGS.max_sent_length, axis=0, num=None, name='split') 

    lstmcell = tf.contrib.rnn.BasicLSTMCell(FLAGS.num_hidden, forget_bias=1.0, 
    state_is_tuple=False) 

    bilstm = tf.contrib.rnn.static_bidirectional_rnn(lstmcell, lstmcell, inputs, 
    sequence_length=seq_len, initial_state_fw=istate_fw, initial_state_bw=istate_bw) 


    pred_mod = [tf.matmul(item, _weights['out_w']) + _biases['out_b'] for item in bilstm] 

Każda pomoc doceniona.

+0

Jakie obliczenia próbujesz wykonać? TensorFlow 'tf.matmul()' może wykonywać pojedyncze multiplikacje macierzy lub multiplikacje macierzy wsadowych, ale potrzebuje informacji o kształtach, aby wiedzieć, który z nich powinien wykonać. – mrry

Odpowiedz

2

Dla każdego, kto napotka na ten problem w przyszłości, fragmentu powyżej nie należy używać.

Od tf.contrib.rnn.static_bidirectional_rnn dokumentacji v1.1:

Returns:

A tuple (outputs, output_state_fw, output_state_bw) where: outputs is a length T list of outputs (one for each input), which are depth-concatenated forward and backward outputs. output_state_fw is the final state of the forward rnn. output_state_bw is the final state of the backward rnn.

Lista rozumienie powyżej spodziewających wyjść LSTM i prawidłowy sposób, aby te to:

outputs, _, _ = tf.contrib.rnn.static_bidirectional_rnn(lstmcell, lstmcell, ...) 
pred_mod = [tf.matmul(item, _weights['out_w']) + _biases['out_b'] 
      for item in outputs] 

to będzie działać, ponieważ każdy z nich ma kształt [batch_size, 2 * num_hidden] i może być pomnożony przez wagi przez tf.matmul().


dodatek: z tensorflow v1.2 +, zalecana jest funkcja używać w innym opakowaniu: tf.nn.static_bidirectional_rnn. Zwracane tensory są takie same, więc kod niewiele się zmienia:

outputs, _, _ = tf.nn.static_bidirectional_rnn(lstmcell, lstmcell, ...) 
pred_mod = [tf.matmul(item, _weights['out_w']) + _biases['out_b'] 
      for item in outputs]