Как изменить форму слоя для ввода LSTM? - PullRequest
0 голосов
/ 17 апреля 2019

Я хочу сделать нейронную сеть в этой блок-схемой , но я не уверен, как изменить форму входов или мой пользовательский слой внедрения. Он был создан модулем Google TensorFlow Hub для предоставления слоям LSTM трехмерных входных данных.

Обычно, когда нам нужно что-то изменить для сети LSTM, мы изменяем вход, а не другой слой. В частности - в соответствии с Как изменить входные данные для длинных сетей кратковременной памяти в Керасе мы хотим, чтобы форма обозначала:

  • Образцы: одна последовательность - один образец. Партия состоит из одного или нескольких образцов.

  • Временные шаги: один временной шаг - одна точка наблюдения в выборке.

  • Особенности: одна особенность - это одно наблюдение за шагом.

Мой код:

import tensorflow_hub as hub
from tensorflow.dtypes import as_string
import tensorflow as tf
import numpy as np

embedding_shape = (32,32,32)
def embedding(x):
    module = hub.Module("https://tfhub.dev/google/nnlm-en-dim128/1")
    return_tensor = module(tf.squeeze(tf.cast(x, tf.string)),signature="default", as_dict=True)["default"]
    try:
      return_tensor = tf.cast(return_tensor,tf.float32)
    except ValueError:
      print("Embedding function could not cast return_tensor to float")
    print ("Returning tensor with shape",return_tensor.get_shape())
    return return_tensor
def split(x,col):
    return tf.reshape(x[:,col:col+1],(-1,))
def flatten_tensor(x):
    flat_tensor = tf.keras.backend.flatten(x)
    assert (len(flat_tensor.get_shape())==1)
    return flat_tensor
def flatten_layer():
    return Lambda(flatten_tensor)

input_questions = Input(shape=(1,),dtype=tf.string)
questions_embedded = Lambda(embedding)(input_questions)
questions_rnn = LSTM(32,return_sequences=True)(questions_embedded)
left_branch_outputs = questions_rnn
input_context = Input(shape=(1,),dtype=tf.string)
context_embedded = Lambda(embedding)(input_context)
context_rnn = LSTM(32,return_sequences=True)(context_embedded)
right_branch_outputs = context_rnn
main_branch_inputs = Add()([left_branch_outputs,right_branch_outputs])
main_outputs = Dense(24,activation="softmax")(Flatten()(main_branch_inputs))
answers_network_rnn = tf.keras.Model(inputs=[input_questions,input_context],outputs=main_outputs)
answers_network_rnn.compile("adam","categorical_crossentropy",metrics=['accuracy'])
answers_network_rnn_checkpoint = ModelCheckpoint('answers_network-rnn-best.h5', verbose=1, monitor='val_acc',save_best_only=True, mode='auto')

with tf.Session() as session:
    session.run([tf.global_variables_initializer(), tf.tables_initializer()])
    X_2_train_text = np.array(
      [["how much wood would a woodchuck chuck if a woodchuck could chuck wood",
        "a woodchuck would chuck as much wood as a woodchuck could chuck if a woodchuck could chuck wood"]
      ,["who sells seashells by the seashore",
       "she sells seashells by the seashore"]])
    y=session.run(tf.one_hot(np.array([23,0]),24))
    print(X_2_train_text.shape)
    print(y.shape)
    x = np.hsplit(X_2_train_text,2)
    print(x)
    answers_network_rnn.fit(x=x,y=y)

Нейронная сеть должна иметь возможность выводить одномерный вектор для каждого образца.

Ошибка:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-40-cb0103df9a44> in <module>()
     13   x = np.hsplit(X_2_train_text,2)
     14   print(x)
---> 15   answers_network_rnn.fit(x=x,y=y)

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, max_queue_size, workers, use_multiprocessing, **kwargs)
    878           initial_epoch=initial_epoch,
    879           steps_per_epoch=steps_per_epoch,
--> 880           validation_steps=validation_steps)
    881 
    882   def evaluate(self,

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training_arrays.py in model_iteration(model, inputs, targets, sample_weights, batch_size, epochs, verbose, callbacks, val_inputs, val_targets, val_sample_weights, shuffle, initial_epoch, steps_per_epoch, validation_steps, mode, validation_in_fit, **kwargs)
    327 
    328         # Get outputs.
--> 329         batch_outs = f(ins_batch)
    330         if not isinstance(batch_outs, list):
    331           batch_outs = [batch_outs]

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py in __call__(self, inputs)
   3074 
   3075     fetched = self._callable_fn(*array_vals,
-> 3076                                 run_metadata=self.run_metadata)
   3077     self._call_fetch_callbacks(fetched[-len(self._fetches):])
   3078     return nest.pack_sequence_as(self._outputs_structure,

/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py in __call__(self, *args, **kwargs)
   1437           ret = tf_session.TF_SessionRunCallable(
   1438               self._session._session, self._handle, args, status,
-> 1439               run_metadata_ptr)
   1440         if run_metadata:
   1441           proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/errors_impl.py in __exit__(self, type_arg, value_arg, traceback_arg)
    526             None, None,
    527             compat.as_text(c_api.TF_Message(self.status.status)),
--> 528             c_api.TF_GetCode(self.status.status))
    529     # Delete the underlying status object from memory otherwise it stays alive
    530     # as there is a reference to status from this from the traceback due to

InvalidArgumentError: Incompatible shapes: [2,24] vs. [32,24]
     [[{{node training_8/Adam/gradients/loss_21/dense_loss/mul_grad/BroadcastGradientArgs}}]]

1 Ответ

0 голосов
/ 17 июня 2019

Предоставлено @Lescurel:

Когда вы используете вложение предложения, вы кодируете все предложение в вектор.Так что я не вижу смысла в использовании LSTM здесь.Вы должны спросить себя, каковы ваши TimeSteps и ваши функции.В вашем случае, наивно, поскольку ваши функции - это 1D 128 векторов, ваш временной шаг равен 1. А LSTM с временным шагом 1 - это просто слой FC с tanh.Либо ваши вопросы связаны друг с другом, и вы можете обрабатывать их в пакетном режиме, либо кодировать слова 1 к 1 (например, с помощью Word2Vec) и обрабатывать их с помощью скользящих окон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...