2

Я как бы потерял в создании сложной модели LSTM для классификации текста в TensorFlow.Уложенная установка модели RNN в TensorFlow

Мой ввод данных было что-то вроде:

x_train = [[1.,1.,1.],[2.,2.,2.],[3.,3.,3.],...,[0.,0.,0.],[0.,0.,0.], 
      ...... #I trained the network in batch with batch size set to 32. 
      ] 
y_train = [[1.,0.],[1.,0.],[0.,1.],...,[1.,0.],[0.,1.]] 
# binary classification 

скелет моего кода выглядит следующим образом:

self._input = tf.placeholder(tf.float32, [self.batch_size, self.max_seq_length, self.vocab_dim], name='input') 
self._target = tf.placeholder(tf.float32, [self.batch_size, 2], name='target') 

lstm_cell = rnn_cell.BasicLSTMCell(self.vocab_dim, forget_bias=1.) 
lstm_cell = rnn_cell.DropoutWrapper(lstm_cell, output_keep_prob=self.dropout_ratio) 
self.cells = rnn_cell.MultiRNNCell([lstm_cell] * self.num_layers) 
self._initial_state = self.cells.zero_state(self.batch_size, tf.float32) 

inputs = tf.nn.dropout(self._input, self.dropout_ratio) 
inputs = [tf.reshape(input_, (self.batch_size, self.vocab_dim)) for input_ in 
       tf.split(1, self.max_seq_length, inputs)] 

outputs, states = rnn.rnn(self.cells, inputs, initial_state=self._initial_state) 

# We only care about the output of the last RNN cell... 
y_pred = tf.nn.xw_plus_b(outputs[-1], tf.get_variable("softmax_w", [self.vocab_dim, 2]), tf.get_variable("softmax_b", [2])) 

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_pred, self._target)) 
correct_pred = tf.equal(tf.argmax(y_pred, 1), tf.argmax(self._target, 1)) 
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) 

train_op = tf.train.AdamOptimizer(self.lr).minimize(loss) 

init = tf.initialize_all_variables() 

with tf.Session() as sess: 
     initializer = tf.random_uniform_initializer(-0.04, 0.04) 
     with tf.variable_scope("model", reuse=True, initializer=initializer): 
      sess.run(init) 
      # generate batches here (omitted for clarity) 
      print sess.run([train_op, loss, accuracy], feed_dict={self._input: batch_x, self._target: batch_y}) 

Проблема заключается в том, что независимо от того, насколько большой набор данных, потеря и точность имеет никаких признаков улучшения (выглядит полностью стохастическим). Я что-то делаю неправильно?

Update:

# First, load Word2Vec model in Gensim. 
model = Doc2Vec.load(word2vec_path) 

# Second, build the dictionary. 
gensim_dict = Dictionary() 
gensim_dict.doc2bow(model.vocab.keys(), allow_update=True) 
w2indx = {v: k + 1 for k, v in gensim_dict.items()} 
w2vec = {word: model[word] for word in w2indx.keys()} 

# Third, read data from a text file. 
for fname in fnames: 
     i = 0 
     with codecs.open(fname, 'r', encoding='utf8') as fr: 
      for line in fr: 
       tmp = [] 
       for t in line.split(): 

        tmp.append(t) 

       X_train.append(tmp) 
       i += 1 
       if i is samples_count: 
        break 

# Fourth, convert words into vectors, and pad each sentence with ZERO arrays to a fixed length. 
result = np.zeros((len(data), self.max_seq_length, self.vocab_dim), dtype=np.float32) 
    for rowNo in xrange(len(data)): 
     rowLen = len(data[rowNo]) 
     for colNo in xrange(rowLen): 
      word = data[rowNo][colNo] 
      if word in w2vec: 
       result[rowNo][colNo] = w2vec[word] 
      else: 
       result[rowNo][colNo] = [0] * self.vocab_dim 
     for colPadding in xrange(rowLen, self.max_seq_length): 
      result[rowNo][colPadding] = [0] * self.vocab_dim 
    return result 

# Fifth, generate batches and feed them to the model. 
... Trivias ... 
+0

Это поможет, если вы предоставите более скелетный код, так как я не могу решить, глядя на скелет, проблема заключается в вашей реализации модели или что-то более фундаментальное в самой модели. Например, вы устанавливаете 'initializer' в конструкцию' with', но перед этим создаются все ваши переменные. В этом случае будет использоваться инициализатор по умолчанию ([uniform_unit_scaling_initializer] (https://www.tensorflow.org/versions/master/api_docs/python/state_ops.html#uniform_unit_scaling_initializer)), а не 'random_uniform_initializer', как вы, вероятно, , – keveman

+0

Спасибо, @keveman! Как вы сказали, я добавил больше кода к вопросу. Я тренировал его всю ночь, он просто не учился. Я проверил предвзятость и обнаружил, что он действительно обновляется. Я пробовал несколько учебных курсов, таких как 0.1, 0.01, 0.001 и 0.0001, но все напрасно. Пожалуйста, помогите проверить, есть ли что-то неправильно в другом месте ... –

ответ

1

Вот несколько причин, не может быть обучение и предложения попробовать:

  • Вы не позволяя обновлять векторы слов, пространство заранее узнал векторов может не работают должным образом.

  • RNNs действительно требуется градиентный отсечение при обучении. Вы можете попробовать добавить что-то вроде this.

  • Инициализация единицы измерения кажется более эффективной, так как она учитывает размер слоя и позволяет градиенту масштабироваться должным образом по мере его углубления.

  • Вам следует попытаться удалить отсева и второй уровень - просто проверьте, правильно ли переданы ваши данные, и что ваша потеря вообще снижается.

Я могу также рекомендую попробовать этот пример с вашими данными: https://github.com/tensorflow/skflow/blob/master/examples/text_classification.py

Готовит векторы слов с нуля, уже имеет градиент вырезки и использует GRUCells, которые обычно легче обучать. Вы также можете увидеть красивые визуализации для потери и другие вещи, запустив tensorboard logdir=/tmp/tf_examples/word_rnn.

+0

Спасибо за ваш совет. Я попытаюсь добавить обрезку градиента и, возможно, нормализацию позже. Предварительно изученные векторы должны работать должным образом, потому что я использовал его для другой задачи, и все прошло хорошо. –

Смежные вопросы