2017-10-18 53 views
1

私はテンソルフローctc_costctc_greedy_decoderを使用しています。 ctc_costを最小化するモデルを訓練するとき、コストは下がりますが、それをデコードするときには常に何も入れません。これが起こる理由はありますか?私のコードは以下の通りです。テンソルフロー - CTC損失は減少しますがデコーダは空です

データを正しく前処理したかどうかは疑問です。私はfbankの特徴の与えられたフレームの電話のsequncesを予測しています。 48台の電話機(48クラス)があり、各フレームには69の機能があります。 num_classesを49に設定して、ログのサイズは(max_time_steps, num_samples, 49)になります。私のスパーステンソルの場合、値の範囲は0から47です(48は空白です)。自分のデータに空白を追加したことはありませんでした。私はそうすべきではないと思いますか? (そのようなことをすればいいですか?)

練習すると、繰り返しとエポックごとにコストが下がりますが、編集距離は決して減少しません。実際には、デコーダはほとんど常に予測し空のシーケンスをとるため、1にとどまります。私が間違っていることは何ですか?

graph = tf.Graph() 
with graph.as_default(): 

    inputs = tf.placeholder(tf.float32, [None, None, num_features]) 
    targets = tf.sparse_placeholder(tf.int32) 
    seq_len = tf.placeholder(tf.int32, [None]) 
    seq_len_t = tf.placeholder(tf.int32, [None]) 
    cell = tf.contrib.rnn.LSTMCell(num_hidden) 
    stack = tf.contrib.rnn.MultiRNNCell([cell] * num_layers) 
    outputs, _ = tf.nn.dynamic_rnn(stack, inputs, seq_len, dtype=tf.float32) 
    outputs, _ = tf.nn.dynamic_rnn(stack, inputs, seq_len, dtype=tf.float32) 

    input_shape = tf.shape(inputs) 
    outputs = tf.reshape(outputs, [-1, num_hidden]) 
    W = tf.Variable(tf.truncated_normal([num_hidden, 
            num_classes], 
            stddev=0.1)) 

    b = tf.Variable(tf.constant(0., shape=[num_classes])) 


    logits = tf.matmul(outputs, W) + b 

    logits = tf.reshape(logits, [input_shape[0], -1, num_classes]) 

    logits = tf.transpose(logits, (1, 0, 2)) 

    loss = tf.nn.ctc_loss(targets, logits, seq_len) 
    cost = tf.reduce_mean(loss) 

    decoded, log_probabilities = tf.nn.ctc_greedy_decoder(logits, seq_len, merge_repeated=True) 
    optimizer = tf.train.MomentumOptimizer(initial_learning_rate, 0.1).minimize(cost) 
    err = tf.reduce_mean(tf.edit_distance(tf.cast(decoded[0],tf.int32), targets)) 
    saver = tf.train.Saver()  

with tf.Session(graph=graph) as session: 

    X, Y, ids, seq_length, label_to_int, int_to_label = get_data('train') 

    session.run(tf.global_variables_initializer()) 

    print(seq_length) 

    num_batches = len(X)//batch_size + 1 



    for epoch in range(epochs): 
     print ('epoch'+str(epoch)) 
     for batch in range(num_batches): 
      input_X, target_input, seq_length_X = get_next_batch(batch,X, Y ,seq_length,batch_size) 
      feed = {inputs: input_X , 
      targets: target_input, 
      seq_len: seq_length_X} 

      print ('epoch'+str(epoch)) 
      _, print_cost, print_er = session.run([optimizer, cost, err], feed_dict = feed) 
      print('epoch '+ str(epoch)+' batch '+str(batch)+ ' cost: '+str(print_cost)+' er: '+str(print_er)) 

    save_path = saver.save(session, '/tmp/model.ckpt') 
    print('model saved') 

    X_t, ids_t, seq_length_t = get_data('test') 

    feed_t = {inputs: X_t, seq_len: seq_length_t} 
    print(X.shape) 
    print(X_t.shape) 
    print(type(seq_length_t[0])) 


    de, lo = session.run([decoded[0], log_probabilities],feed_dict = feed_t) 
    with open('predict.pickle', 'wb') as f: 
     pickle.dump((de, lo), f) 
+0

は完全に訓練されたネットワークです(トレーニングエラーが停滞しています)?空白のlabellingsは、通常、訓練の冒頭で遭遇するため。例えば。 「CTCでの面白い空白ラベル」を検索してください。そして、いいえ、ターゲットラベリングにブランクを追加する必要はありません。これらのブランクは内部使用のためのものです。 – Harry

答えて

0

私は同じ問題を抱え、初期学習率を上げることで解決しました。

さらに、トレーニングプロセスの進行状況を確認するには、検証セットでLERを出力する必要があります。

関連する問題