Tensorflow DataSet Shuffle 影响验证训练的准确性和模棱两可的行为
Posted
技术标签:
【中文标题】Tensorflow DataSet Shuffle 影响验证训练的准确性和模棱两可的行为【英文标题】:Tensorflow DataSet Shuffle Impact the validation training accuracy and ambiguous behavior 【发布时间】:2021-07-06 02:39:40 【问题描述】:我正在努力训练一个使用 tf.data.DataSet 作为输入的神经网络。
我发现,如果我在将整个数据集拆分为 train、val、test set 之前调用 .shuffle()
,则 val(在训练中)和 test(在评估中)的准确度为 91%,但是当我运行 @987654322 时@ 在测试集上多次准确率和损失指标每次都发生变化。测试集上的.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° 以来的准确率为 75%验证集上的纪元。
但是,在这种情况下,如果我在未应用 .shuffle ()
的测试集上运行 .evaluate()
和 .predict()
,则每次调用的指标和类都保持不变。
为什么会有这种行为? 但是特别是什么是好方法,模型的真正准确度是多少?
谢谢
这是进程的代码
""" ### 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
【问题讨论】:
【参考方案1】:在 Question 的 cmets 中,您可以看到 shuffle
适用于基础数据集,并且会传播到训练、测试和验证集中的引用。
我建议创建 3 个不同的数据集,在原始数据上使用(例如)sklearn.model_selection.train_test_split
,然后在那些拆分张量切片上使用tf.data.Dataset.from_tensor_slices
,因此您只能在训练数据集上使用shuffle
。
【讨论】:
以上是关于Tensorflow DataSet Shuffle 影响验证训练的准确性和模棱两可的行为的主要内容,如果未能解决你的问题,请参考以下文章
『TensorFlow』数据读取类_data.Dataset
tensorflow dataset.shuffle dataset.batch dataset.repeat 理解 注意点
tensorflow的keras实现搭配dataset 之一
在tensorflow中使用`dataset.map()`访问张量numpy数组