2

我正在努力训练一个使用 tf.data.DataSet 作为输入的神经网络。

我发现,如果我.shuffle()在将整个数据集拆分为 train、val、test set 之前调用,val(在训练中)和 test(在评估中)的准确度是 91%,但是当我.evaluate()在测试集上运行多次时,准确度损失指标每次都在变化。在测试集上发生相同的行为.predict(),每次都更改类。

这是训练的输出,评估结束预测过程

    total_record: 93166 - trainin_size: 74534 - val_size: 9316 - test_size: 9316
Epoch 1/5
145/145 [==============================] - 42s 273ms/step - loss: 1.7143 - sparse_categorical_accuracy: 0.4051 - val_loss: 1.4997 - val_sparse_categorical_accuracy: 0.4885
Epoch 2/5
145/145 [==============================] - 40s 277ms/step - loss: 0.7571 - sparse_categorical_accuracy: 0.7505 - val_loss: 1.1634 - val_sparse_categorical_accuracy: 0.6050
Epoch 3/5
145/145 [==============================] - 41s 281ms/step - loss: 0.4894 - sparse_categorical_accuracy: 0.8223 - val_loss: 0.7628 - val_sparse_categorical_accuracy: 0.7444
Epoch 4/5
145/145 [==============================] - 38s 258ms/step - loss: 0.3417 - sparse_categorical_accuracy: 0.8656 - val_loss: 0.4236 - val_sparse_categorical_accuracy: 0.8579
Epoch 5/5
145/145 [==============================] - 40s 271ms/step - loss: 0.2660 - sparse_categorical_accuracy: 0.8926 - val_loss: 0.2807 - val_sparse_categorical_accuracy: 0.9105

accr = model.evaluate(test_set)
19/19 [==============================] - 1s 39ms/step - loss: 0.2622 - sparse_categorical_accuracy: 0.9153

accr = model.evaluate(test_set)
19/19 [==============================] - 1s 40ms/step - loss: 0.2649 - sparse_categorical_accuracy: 0.9170

accr = model.evaluate(test_set)
19/19 [==============================] - 1s 40ms/step - loss: 0.2726 - sparse_categorical_accuracy: 0.9141

accr = model.evaluate(test_set)
19/19 [==============================] - 1s 40ms/step - loss: 0.2692 - sparse_categorical_accuracy: 0.9166

pred = model.predict(test_set)
pred_class = np.argmax(pred, axis=1)
pred_class
Out[41]: array([0, 1, 5, ..., 2, 0, 1])

pred = model.predict(test_set)
pred_class = np.argmax(pred, axis=1)
pred_class
Out[42]: array([2, 3, 1, ..., 1, 2, 0])

pred = model.predict(test_set)
pred_class = np.argmax(pred, axis=1)
pred_class
Out[43]: array([1, 2, 4, ..., 1, 3, 0])

pred = model.predict(test_set)
pred_class = np.argmax(pred, axis=1)
pred_class
Out[44]: array([0, 3, 1, ..., 0, 5, 4])

因此,我尝试.shuffle()在拆分后仅在训练和验证上应用(注释主 .shuffle() 并取消注释 train_set 和 val_set 中的 shuffle)。

但在这种情况下,我发现网络仅在 5 个 epoch 后就进入了过度拟合(之前的训练过程回调以 94% 的 val 准确度阻止了 30° epoch 的训练),自 2° epoch 验证以来的准确度为 75%放。

但是,在这种情况下,如果我在尚未应用的测试集上运行.evaluate(),则指标和类在每次调用时都保持不变。.predict().shuffle ()

为什么会有这种行为?但特别是什么是伟大的方式,模型的真正准确性是什么?

谢谢

这是进程的代码

""" ### Make tf.data.Dataset """

dataset = tf.data.Dataset.from_tensor_slices(({ "features_emb_subj": features_emb_subj,
                                            "features_emb_snip": features_emb_snip,
                                            "features_emb_fromcat": features_emb_fromcat,
                                            "features_dense": features_dense,
                                            "features_emb_user": features_emb_user}, cat_labels))

dataset = dataset.shuffle(int(len(features_dense)), reshuffle_each_iteration=True)


""" ### Split in train,val,test """

train_size = int(0.8 * len(features_dense))
val_size = int(0.10 * len(features_dense))
test_size = int(0.10 * len(features_dense))

test_set = dataset.take(test_size)
validation_set = dataset.skip(test_size).take(val_size)
training_set = dataset.skip(test_size + val_size)

test_set = test_set.batch(BATCH_SIZE, drop_remainder=False)
#validation_set = validation_set.shuffle(val_size, reshuffle_each_iteration=True)
validation_set = validation_set.batch(BATCH_SIZE, drop_remainder=False)
#training_set = training_set.shuffle(train_size, reshuffle_each_iteration=True)
training_set = training_set.batch(BATCH_SIZE, drop_remainder=True)


"""### Train model """

callbacks = [EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001, restore_best_weights=True)]

history = model.fit(  training_set,
                      epochs = 5,
                      validation_data = validation_set,
                      callbacks=callbacks,
                      class_weight = setClassWeight(cat_labels),
                      verbose = 1)

"""### Evaluate model """
accr = model.evaluate(test_set)

"""### Predict test_test """
pred = model.predict(test_set)
pred_class = np.argmax(pred, axis=1)
pred_class
4

1 回答 1

1

在这个问题的评论中,您可以看到它shuffle适用于基础数据集,并且会传播到训练、测试和验证集中的引用。

我建议创建 3 个不同的数据集,sklearn.model_selection.train_test_split在原始数据上使用(例如),然后tf.data.Dataset.from_tensor_slices在那些拆分张量切片上使用,因此您只能shuffle在训练数据集上使用。

于 2021-04-12T09:05:40.690 回答