Tensorflow Keras中的自定义模型在第一次运行时无法适应

Tensorflow Keras中的自定义模型在第一次运行时无法适应,tensorflow,keras,python-3.6,Tensorflow,Keras,Python 3.6,我在Keras有一个定制模型。它本质上是RNN模型,每一步都计算负采样损失,即正对数和负对数上的s形 from tensorflow.keras.layers import Input, Embedding, GRU, dot, Dense, add, concatenate, multiply, Subtract class rnn_neg_sampling(keras.models.Model): def __init__(self, vocab_size, dim, seq_le

我在Keras有一个定制模型。它本质上是RNN模型,每一步都计算负采样损失,即正对数和负对数上的s形

from tensorflow.keras.layers import Input, Embedding, GRU, dot, Dense, add, concatenate, multiply, Subtract

class rnn_neg_sampling(keras.models.Model):
    def __init__(self, vocab_size, dim, seq_length, num_negatives=10):
        super(rnn_neg_sampling, self).__init__()

        self.num_negatives = num_negatives 

        self.embedding_input = Embedding(
            input_dim=vocab_size+1, 
            output_dim=dim,
            mask_zero=True,
            input_length=seq_length
        )
        self.embedding_output = Embedding(
            input_dim=vocab_size+1, 
            output_dim=dim,
            mask_zero=True,
            input_length=seq_length
        )

        self.gru = GRU(dim, return_sequences=True)

    def call(self, input):
        inputs, targets, negatives = input

        embedded_inputs = self.embedding_input(inputs)
        # https://keras.io/layers/recurrent/#gru
        gru_output = self.gru(embedded_inputs)

        embedded_targets = self.embedding_output(targets)
        embedded_negatives = self.embedding_output(negatives)

        positive_dots = K.expand_dims(multiply([gru_output, embedded_targets]), axis=1)
        negative_dots = multiply([K.repeat_elements(K.expand_dims(gru_output, axis=1),
                                                      rep=self.num_negatives, 
                                                      axis=1),
                                    embedded_negatives
                                   ])

        positive_logits = K.sum(positive_dots, axis=-1)
        negative_logits = -K.sum(negative_dots, axis=-1)
        logits = K.concatenate([positive_logits, negative_logits], axis=1)

        self.add_loss(-K.mean(K.log(K.sigmoid(logits))))
我创建的模型如下所示:

neg_number = 3
vector_dim=10
sequence_length = 5
vocab_size = 100

ns_model = rnn_neg_sampling(vocab_size, vector_dim, sequence_length, neg_number)
X_inputs = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_targets = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_negatives = np.random.randint(0, 5, size=(batch_size, neg_number, sequence_length))
ns_model.compile(loss=None, optimizer='rmsprop')
history = ns_model.fit([X_inputs, X_targets, X_negatives], epochs=1)
创建的数据如下所示:

neg_number = 3
vector_dim=10
sequence_length = 5
vocab_size = 100

ns_model = rnn_neg_sampling(vocab_size, vector_dim, sequence_length, neg_number)
X_inputs = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_targets = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_negatives = np.random.randint(0, 5, size=(batch_size, neg_number, sequence_length))
ns_model.compile(loss=None, optimizer='rmsprop')
history = ns_model.fit([X_inputs, X_targets, X_negatives], epochs=1)
我将其编译和拟合如下:

neg_number = 3
vector_dim=10
sequence_length = 5
vocab_size = 100

ns_model = rnn_neg_sampling(vocab_size, vector_dim, sequence_length, neg_number)
X_inputs = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_targets = np.random.randint(0, 5, size=(batch_size, sequence_length))
X_negatives = np.random.randint(0, 5, size=(batch_size, neg_number, sequence_length))
ns_model.compile(loss=None, optimizer='rmsprop')
history = ns_model.fit([X_inputs, X_targets, X_negatives], epochs=1)
但是,它失败时会出现以下日志:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1343-a8447c14a3a4> in <module>
      1 ns_model.compile(loss=None, optimizer='rmsprop')
----> 2 history = ns_model.fit([X_inputs, X_targets, X_negatives], epochs=1)

~/miniconda3/envs/ml.crash-course/lib/python3.6/site-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, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
    966           validation_steps=validation_steps,
    967           validation_freq=validation_freq,
--> 968           steps_name='steps_per_epoch')
    969 
    970   def evaluate(self,

~/miniconda3/envs/ml.crash-course/lib/python3.6/site-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, validation_freq, mode, validation_in_fit, prepared_feed_values_from_dataset, steps_name, **kwargs)
    147 
    148   # Get step function and loop type.
--> 149   f = _make_execution_function(model, mode)
    150   use_steps = is_dataset or steps_per_epoch is not None
    151   do_validation = val_inputs is not None

~/miniconda3/envs/ml.crash-course/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py in _make_execution_function(model, mode)
    490   if model._distribution_strategy:
    491     return distributed_training_utils._make_execution_function(model, mode)
--> 492   return model._make_execution_function(mode)
    493 
    494 

~/miniconda3/envs/ml.crash-course/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in _make_execution_function(self, mode)
   2156   def _make_execution_function(self, mode):
   2157     if mode == ModeKeys.TRAIN:
-> 2158       self._make_fit_function()
   2159       return self._fit_function
   2160     if mode == ModeKeys.TEST:

~/miniconda3/envs/ml.crash-course/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in _make_fit_function(self)
   2099     ]
   2100     self._make_train_function_helper(
-> 2101         '_fit_function', [self.total_loss] + metrics_tensors)
   2102 
   2103   def _make_test_function_helper(self, fn_name, outputs, metric_updates=None):

AttributeError: 'rnn_neg_sampling' object has no attribute 'total_loss'
我怎样才能制作出一个第一次就适合的模型