MLP в Керасе всегда возвращает 0.0 потерь - PullRequest
1 голос
/ 12 февраля 2020

Я реализую многослойный персептрон с Keras, чтобы предсказать правильный порядок слов в предложении. Я использую train_on_batch(), потому что я конвертирую каждое предложение в дереве, а затем упорядочиваю каждое локальное поддерево: когда упорядочивается каждое поддерево, упорядочивается даже все дерево.

Во время обучения я замечаю странные вещи: поскольку с первой эпохи величина потерь равна 0,0. Моя форма набора данных (453732, 300) (изначально число объектов составляло 838, но я использую PCA для их уменьшения), и это код:

mlp = keras.models.Sequential()

# add input layer
mlp.add(
    keras.layers.Dense(
        units=training_dataset.shape[1],
        input_shape = (training_dataset.shape[1], ),
        kernel_initializer='glorot_uniform',
        bias_initializer='zeros',
        activation='tanh') 
)
# add hidden layer
mlp.add(
    keras.layers.Dense(
        units=training_dataset.shape[1] + 10,
        input_shape = (training_dataset.shape[1] + 10,),
        kernel_initializer='glorot_uniform',
        bias_initializer='zeros',
        activation='relu')
    )

mlp.add(
    keras.layers.Dropout(
        0.2, 
        input_shape=(training_dataset.shape[1] + 10,))
    )

# add output layer
mlp.add(
    keras.layers.Dense(
        units=1,
        input_shape = (1, ),
        kernel_initializer='glorot_uniform',
        bias_initializer='zeros',
        activation='softmax')
    )

# define SGD optimizer
sgd_optimizer = keras.optimizers.SGD(
    lr=0.01, decay=0.01, momentum=0.9, nesterov=True
)
# compile model

mlp.compile(
    optimizer=sgd_optimizer,
    loss=listnet_loss
)

mlp.summary() # print model settings

losses = np.array([])
# Training
with tf.device('/GPU:0'):
  for epoch in range(0, 10):
    print('Epoch {0} started!'.format(epoch))
    start_range = 0
    for group in groups_id_count:
      end_range = (start_range + group[1]) # Batch is a group of words with same group id
      batch_dataset = training_dataset[start_range:end_range, :]
      batch_labels = training_dataset_labels[start_range:end_range]
      batch_train_result = mlp.train_on_batch(batch_dataset, batch_labels)
      losses = np.append(losses, batch_train_result)
      start_range = end_range
    print('Epoch {0} loss: {1}'.format(epoch, np.mean(losses)))

listnet_loss является следующим:

def get_top_one_probability(vector):
  return (K.exp(vector) / K.sum(K.exp(vector)))

def listnet_loss(real_labels, predicted_labels):
  return -K.sum(get_top_one_probability(real_labels)) * tf.math.log(get_top_one_probability(predicted_labels))

groups_id_count - это список кортежей вида (#subtree_number,#number_of_words_in_subtree), где #subtree_number - это идентификатор поддерева, а #number_of_words_in_subtree - количество слов в поддереве. Затем моя партия является динамической c: партия состоит из количества слов в поддереве. Вот почему я использовал train_on_batch() для обучения своей модели.

Есть предложения? Заранее спасибо.

...