大数据集的训练是单独的困难

keras training on big datasets seperately keras

我正在研究一个 keras 去噪神经网络,它可以对高维 x 射线图像进行去噪。这个想法是在一些数据集(例如 1、2、3)上进行训练,在获得权重后,另一个数据集(例如 4、5、6)将开始新的训练,权重从之前的训练中初始化。在实施方面它是有效的,但是最后一次轮换产生的权重仅在用于本次轮换训练的数据集上表现更好。其他旋转也是如此。

换句话说,数据集训练产生的权重:4、5、6 没有像在数据集上训练的权重那样在数据集 1 的图像上给出良好的结果: 1,2,3。这不应该是我打算做的

想法是应该调整权重以有效地处理所有数据集,因为对整个数据集的训练不适合内存。

我尝试了其他解决方案,例如创建自定义生成器,从磁盘获取图像并进行批量训练,这非常慢,因为它取决于磁盘上发生的 I/O 操作或自定义 keras 生成器内部发生的处理函数的时间复杂度!

下面的代码显示了我在做什么。我有 12 个数据集,分为 4 个检查点。加载数据并进行训练并将最终模型保存到数组中,下一次训练采用上一次旋转的权重并继续。

EPOCHES = 150
NUM_CHKPTS = 4
weights = []

for chk in range(1,NUM_CHKPTS+1):

    log_dir = os.path.join(os.getcwd(), 'resnet_checkpts_' + str(EPOCHES) + "_tl2_chkpt" + str(chk))
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir)
    else:
        print('Training log directory already exists @ {}.'.format(log_dir))
    tb_output = TensorBoard(log_dir=log_dir, histogram_freq=1)

    print("Loading Data From CHKPT #" + str(chk))

    h5f = h5py.File('C:\autoencoder\datasets\mix\chk' + str(chk) + '.h5','r')
    org_patch = h5f['train_data'][:]
    noisy_patch = h5f['train_noisy'][:]
    h5f.close()

    input_patch, test_patch, noisy_patch, test_noisy_patch = train_test_split(org_patch, noisy_patch, train_size=0.8, shuffle=True)


    print("Reshaping")
    train_data = np.array([np.reshape(input_patch[i], (52, 52, 1)) for i in range(input_patch.shape[0])], dtype = np.float32)
    train_noisy_data = np.array([np.reshape(noisy_patch[i], (52, 52, 1)) for i in range(noisy_patch.shape[0])], dtype = np.float32)

    test_data = np.array([np.reshape(test_patch[i], (52, 52, 1)) for i in range(test_patch.shape[0])], dtype = np.float32)
    test_noisy_data = np.array([np.reshape(test_noisy_patch[i], (52, 52, 1)) for i in range(test_noisy_patch.shape[0])], dtype = np.float32)

    print('Number of training samples are:', train_data.shape[0])
    print('Number of test samples are:', test_data.shape[0])

    # IN = np.ones((len(XTRAINFILES), 52, 52, 1 ))

    if chk == 1:
        print("Generating the Model For The First Time..")
        autoencoder_model = model_autoencoder(train_noisy_data)
        print("Done!")
    else:
        autoencoder_model=load_model(weights[chk-2])


    checkpt_path = log_dir + r"\cp-{epoch:04d}.ckpt"

    checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpt_path, verbose=0, save_weights_only=True, save_freq='epoch')


    optimizer = tf.keras.optimizers.Adam(lr=0.0001)
    autoencoder_model.compile(loss='mse',optimizer=optimizer) 

    autoencoder_model.fit(train_noisy_data, train_data,
                        batch_size=128,
                        epochs=EPOCHES, shuffle=True, verbose=1,
                        validation_data=(test_noisy_data, test_data),
                        callbacks=[tb_output, checkpoint_callback])

    weight_dir = log_dir+'\model_resnet_new_OL' + str(EPOCHES) + 'epochs.h5'
    weights.append(weight_dir)
    autoencoder_model.save(weight_dir)  # Defined saved model name by number of epochs.

Tensorboard 图表,从上到下旋转为 1,2,3,4 :

当您在新数据集上训练时,您的模型会忘记以前的数据集。

我读过强化学习,当游戏用于训练深度强化学习(DRL)时,你必须创建记忆回放,它收集不同回合游戏的数据,因为每一轮游戏都有不同的数据,所以随机选择一些数据来训练模型。这样 DRL 模型可以学习玩不同轮次的游戏而不会忘记前几轮。

您可以尝试通过从每个数据集中抽取一些随机样本来创建单个数据集。

当您在新数据集上训练模型时,确保所有先前旋转的数据都在当前旋转中。

同样在迁移学习中,当你在新数据集上训练模型时,你必须冻结之前的层,这样模型就不会忘记之前的训练。您没有使用迁移学习,但是当您开始对第二个数据集进行训练时,您的第一个数据集将慢慢从权重内存中删除。

你可以尝试冻结解码器的初始层,这样它们在提取特征时就不会更新,假设所有数据集都包含相似的图像,这样你的模型就不会像在迁移学习中那样忘记以前的训练。但是当你在新数据集上训练时,以前的数据仍然会被遗忘。