一次性训练数据与分开训练数据时,MNIST 上的验证准确性不同

时间:2021-02-14 03:54:19

标签: python tensorflow machine-learning neural-network tf.keras

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

  1. 导入 10% 的数据
  2. 学习
  3. 保存模型
  4. 删除内存中的数据
  5. 导入接下来的 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)

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

enter image description here

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

1 个答案:

答案 0 :(得分:0)

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

无论如何,这是一点一点地加载大型数据集的常用方法:tf.keras 允许您为 model.fit(x) 传递 Python 生成器(如果您想研究教程或使用较旧的 API :直到最近,这是一个名为 model.fit_generator, see API 的单独方法。

数据生成器需要做的就是在每次调用时生成一批训练数据和标签 (x,y)。只要您使用 fit 传递它,API 就会为您调用它。结果是所有内容都被逐批读取到 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