2016-04-13 18 views
13

Metin oluşturmak için tensorflow'u kullanmak istiyorum ve bunu yapmak için LSTM öğreticisini (https://www.tensorflow.org/versions/master/tutorials/recurrent/index.html#recurrent-neural-networks) değiştirdim, ancak ilk çözümüm uzun süredir antrenmandan sonra bile anlamsız gibi görünüyor. gelişmez. Nedenini göremiyorum. Buradaki fikir, sıfır matris ile başlayıp her seferinde bir kelime üretmektir. TensorFlow metnin oluşturulmasında LSTM'leri kullanarak

Bu

hangi ı ptb_model ve ona değişkeni "olasılıkları" ekledik

def generate_text(session,m,eval_op): 

    state = m.initial_state.eval() 

    x = np.zeros((m.batch_size,m.num_steps), dtype=np.int32) 

    output = str() 
    for i in xrange(m.batch_size): 
     for step in xrange(m.num_steps): 
      try: 
       # Run the batch 
       # targets have to bee set but m is the validation model, thus it should not train the neural network 
       cost, state, _, probabilities = session.run([m.cost, m.final_state, eval_op, m.probabilities], 
                  {m.input_data: x, m.targets: x, m.initial_state: state}) 

       # Sample a word-id and add it to the matrix and output 
       word_id = sample(probabilities[0,:]) 
       output = output + " " + reader.word_from_id(word_id) 
       x[i][step] = word_id 

      except ValueError as e: 
       print("ValueError") 

    print(output) 

şöyle jeneratör görünüyor https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/models/rnn/ptb/ptb_word_lm.py

altında iki işlevi ekledik kod vardır basit bir şekilde logların üzerinde bir softmax.

self._probabilities = tf.nn.softmax(logits) 

Ve örnekleme: Ben senin kodu kullanabilirsiniz

def sample(a, temperature=1.0): 
    # helper function to sample an index from a probability array 
    a = np.log(a)/temperature 
    a = np.exp(a)/np.sum(np.exp(a)) 
    return np.argmax(np.random.multinomial(1, a, 1)) 

cevap

0

, bu doğru değil gibi görünüyor. Bu yüzden biraz değiştirdim, iş gibi görünüyor. İşte benim kodudur ve bunu doğru olduğundan emin değilim: Ben aynı hedefe doğru çalışıyor olması

def generate_text(session,m,eval_op, word_list): 
output = [] 
for i in xrange(20): 
    state = m.initial_state.eval() 
    x = np.zeros((1,1), dtype=np.int32) 
    y = np.zeros((1,1), dtype=np.int32) 
    output_str = "" 
    for step in xrange(100): 
     if True: 
      # Run the batch 
      # targets have to bee set but m is the validation model, thus it should not train the neural network 
      cost, state, _, probabilities = session.run([m.cost, m.final_state, eval_op, m.probabilities], 
                 {m.input_data: x, m.targets: y, m.initial_state: state}) 
      # Sample a word-id and add it to the matrix and output 
      word_id = sample(probabilities[0,:]) 
      if (word_id<0) or (word_id > len(word_list)): 
       continue 
      #print(word_id) 
      output_str = output_str + " " + word_list[word_id] 
      x[0][0] = word_id 
    print(output_str) 
    output.append(output_str) 
return output 
17

ve sadece o iş için var. Burada doğru değişikliklerin birçoğu var, ama sanırım birkaç adım atmışsın. İlk olarak, metin oluşturmak için, yalnızca tek bir zamanlamayı temsil eden modelin farklı bir sürümünü oluşturmanız gerekir. Bunun nedeni, modeli bir sonraki adımda besleyebilmemiz için her bir çıkışı y örneklememiz gerektiğidir. Ben de bu çizgilerle modele bir olasılıklarını eklendi num_steps ve batch_size hem eşit

class SmallGenConfig(object): 
    """Small config. for generation""" 
    init_scale = 0.1 
    learning_rate = 1.0 
    max_grad_norm = 5 
    num_layers = 2 
    num_steps = 1 # this is the main difference 
    hidden_size = 200 
    max_epoch = 4 
    max_max_epoch = 13 
    keep_prob = 1.0 
    lr_decay = 0.5 
    batch_size = 1 
    vocab_size = 10000 

1. kümelerini yeni yapılandırma yaparak bunu:

self._output_probs = tf.nn.softmax(logits) 

ve

@property 
def output_probs(self): 
    return self._output_probs 

O zaman, generate_text() işlevimde birkaç fark var. İlki, tf.train.Saver() nesnesini kullanarak kaydedilen model parametrelerini diskten yüklemem. PTBModel'i yukarıdaki yeni yapılandırma ile örnekledikten sonra bunu yaptığımızı unutmayın.

def generate_text(train_path, model_path, num_sentences): 
    gen_config = SmallGenConfig() 

    with tf.Graph().as_default(), tf.Session() as session: 
    initializer = tf.random_uniform_initializer(-gen_config.init_scale, 
               gen_config.init_scale)  
    with tf.variable_scope("model", reuse=None, initializer=initializer): 
     m = PTBModel(is_training=False, config=gen_config) 

    # Restore variables from disk. 
    saver = tf.train.Saver() 
    saver.restore(session, model_path) 
    print("Model restored from file " + model_path) 

ikinci fark

kelimesini dizeleri (aşağıda kodunu görmek, bu işlevi yazmak zorunda) için kimlikleri gelen arama tablosu elde ediyoruz.

words = reader.get_vocab(train_path) 

Ben ilk devleti de senin gibi kurmak, ama sonra farklı bir şekilde ilk belirteç kurdu. "Cümle sonu" belirtecini kullanmak istiyorum, böylece cümlemi doğru sözcüklerle başlatacağım. Ben kelime indeksi ile baktı ve <eos> indeksi 2 (deterministic) sahip olduğunu buldum, bu yüzden ben sadece kodlanmış kodlanmış. Sonunda, 1x1 Numpy Matrix içinde sarın, böylece model girişleri için doğru tip olur.

state = m.initial_state.eval() 
    x = 2 # the id for '<eos>' from the training set 
    input = np.matrix([[x]]) # a 2D numpy matrix 

Son olarak, işte cümle oluşturduğumuz kısım.session.run()’a output_probs ve final_state’u hesapladığımızı bildiririz. Ve biz ona girişi ve devleti veriyoruz. İlk yinelemede, girdi <eos> ve durum initial_state'dur, ancak sonraki yineleme işlemlerinde son örneklenen çıktımızı girdi olarak veririz ve durumu son yinelemeden geçiririz. Ayrıca, çıktı dizisinden kelime dizgisini aramak için words listesini kullandığımızı unutmayın.

text = "" 
    count = 0 
    while count < num_sentences: 
     output_probs, state = session.run([m.output_probs, m.final_state], 
            {m.input_data: input, 
            m.initial_state: state}) 
     x = sample(output_probs[0], 0.9) 
     if words[x]=="<eos>": 
     text += ".\n\n" 
     count += 1 
     else: 
     text += " " + words[x] 
     # now feed this new word as input into the next iteration 
     input = np.matrix([[x]]) 

Yapmamız gereken tek şey, biriktirdiğimiz metni yazdırmaktır. Bu, generate_text() işlevi için geçerlidir.

Son olarak, ben size reader.py koyduğum get_vocab() işlev tanımını göstereyim.

def get_vocab(filename): 
    data = _read_words(filename) 

    counter = collections.Counter(data) 
    count_pairs = sorted(counter.items(), key=lambda x: (-x[1], x[0])) 

    words, _ = list(zip(*count_pairs)) 

    return words 

yapmanız gereken son şey

save_path = saver.save(session, "/tmp/model.ckpt") 

benziyor ki, bunu eğitim sonrasında modelini kurtarmak için muktedir olduğunu Ve bu oluşturulurken daha sonra diskten yük olacak model Metin.

Bir sorun daha vardı: Bazen Tensorflow softmax işlevi tarafından üretilen olasılık dağılımının tam olarak 1.0 değerini almadığını buldum. Toplam 1.0'dan büyük olduğunda, np.random.multinomial() bir hata atar. O yüzden hep birlikte bu koyduğunuzda bu

def sample(a, temperature=1.0): 
    a = np.log(a)/temperature 
    a = np.exp(a)/np.sum(np.exp(a)) 
    r = random.random() # range: [0,1) 
    total = 0.0 
    for i in range(len(a)): 
    total += a[i] 
    if total>r: 
     return i 
    return len(a)-1 

benziyor kendi örnekleme fonksiyonu, yazmak zorunda, küçük modeli bana bazı serin cümleler oluşturmak başardı. İyi şanslar.