Я хочу сделать нейронную сеть в этой блок-схемой , но я не уверен, как изменить форму входов или мой пользовательский слой внедрения. Он был создан модулем 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}}]]