首页 > 解决方案 > 一次训练数据与分离训练数据时,MNIST 的验证准确度不同

问题描述

我有一个 27G 的数据集要分析,由于我的 RAM 的大小,我不能一次将所有数据输入我的神经网络,我必须导入它的一部分,学习它们,然后是另一部分,所以这个过程看起来像这样:

  1. 导入 10% 的数据
  2. 保存模型
  3. 删除 RAM 上的数据
  4. 导入接下来的 10%,依此类推

为了了解这将如何影响已知数据集,我在 MNIST 上对其进行了测试。以下是过程/程序:

for 35 times:
  import 1/5 of the data
  learn 
  delete
  import the next 1/5
  learn
  delete
  ...

这是从 tensorflow 导入数据集的代码:

from tensorflow.keras.datasets import mnist
(sep, label), (sep_t, label_t) = mnist.load_data()

然后,网络:

Dense = tf.keras.layers.Dense
fc_model = tf.keras.Sequential(
    [
      tf.keras.Input(shape=(28,28)),
      tf.keras.layers.Flatten(),
      Dense(128, activation='relu'),
      Dense(32, activation='relu'),
      Dense(10, activation='softmax')])
fc_model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])

下面是部分导入和学习 MNIST 数据集的代码:

for k in range(35):
    for j in range(5):
        if i == 0:
            history = fc_model.fit(sep[i*12000:(i+1)*12000-1], label[i*12000:(i+1)*12000-1], batch_size=128, validation_data=(sep_t, label_t) ,epochs=1)
            fc_model.save('Mytf.h5')
            i = i + 1
        else:
            fc_model = load_model('Mytf.h5')
            history = fc_model.fit(sep[i*12000:(i+1)*12000-1], label[i*12000:(i+1)*12000-1], batch_size=128, validation_data=(sep_t, label_t) ,epochs=1)
            fc_model.save('Mytf.h5')
        valacc.append(history.history['val_accuracy'])
    valacc_epc.append(history.history['val_accuracy'])

以下是在一个完整数据集中学习数据的代码:

history_new = fc_model.fit(sep, label, batch_size=128, validation_data=(sep_t, label_t) ,epochs=35)

下图是两种方法在验证数据准确性方面的比较:

在此处输入图像描述

即使差异为 1% (96(avg)-95(avg)=1%),这是否意味着当使用相同的保存和学习方法对不同的数据集进行测试时,这会导致准确性降低?做一些投资并在云计算平台上做会更好吗?

标签: pythontensorflowmachine-learningneural-networktf.keras

解决方案


对于这两种方法,批次的组织方式不同,因此必须存在一些偏差(类似于打乱数据与按特定顺序提供数据)。但是我们可以假设这些差异不会是一致的,除非我们在大量试验中观察到这一点。

在任何情况下,这是逐步加载大型数据集的常用方法:tf.keras 允许您传递 Python 生成器model.fit(x)(如果您想研究教程或使用较旧的 API:直到最近,这是一种单独的方法调用model.fit_generator请参阅 API)。

(x,y)数据生成器需要做的就是在每次调用时生成一批训练数据和标签。只要您使用fit. 结果是所有内容都被逐批读取到 RAM 中。一个非常基本的生成器模板是这样的(source):

def generator(features, labels, batch_size):
    # Create empty arrays to contain batch of features and labels#
    batch_features = np.zeros((batch_size, 64, 64, 3))
    batch_labels = np.zeros((batch_size,1))

    while True:
       for i in range(batch_size):
           # choose random index in features
           index= random.choice(len(features),1)
           batch_features[i] = some_processing(features[index])
           batch_labels[i] = labels[index]
       yield batch_features, batch_labels

推荐阅读