Keras中用数据生成器训练自编码器效果劣于原始数据的问题
问题:Keras生成器训练自编码器性能远低于直接传入数据
我的最终目标是通过Keras API的fit方法传入数据生成器来训练机器学习自编码器,但发现用生成器训练的模型性能远劣于直接用原始数据训练的模型。
为验证该问题,我执行了以下步骤:
- 定义一个数据生成器生成可变阻尼正弦波,将生成器的batch size设为整个训练数据集,排除batch size对模型性能的影响;
- 定义一个结构简单的ML自编码器,其潜在空间大于原始数据尺寸,理论上应能快速学习还原原始信号;
- 使用生成器训练一个模型;
- 通过生成器的
__getitem__方法生成训练数据,用这些数据训练同一个模型。
结果显示,用生成器训练的模型性能远逊于后者。我认为生成器的实现存在问题,但始终无法定位错误,参考了相关教程仍未解决。
更新内容
我简化了问题,让生成器不再生成随机参数化的阻尼正弦波,而是生成全1向量(即np.ones(batch_size, 1000, 1)),训练自编码器后,用生成器训练的模型性能仍劣于直接用原始数据训练的模型。
附更新后的代码
import numpy as np import matplotlib.pyplot as plt import keras from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Conv1D, Conv1DTranspose, MaxPool1D import tensorflow as tf """ Generate training/testing data data (i.e., a vector of ones) """ class DataGenerator(keras.utils.Sequence): def __init__( self, batch_size, vector_length, ): self.batch_size = batch_size self.vector_length = vector_length def __getitem__(self, index): x = np.ones((self.batch_size, self.vector_length, 1)) y = np.ones((self.batch_size, self.vector_length, 1)) return x, y def __len__(self): return 1 #one batch of data vector_length = 1000 train_gen = DataGenerator(800, vector_length) test_gen = DataGenerator(200, vector_length) """ Machine Learning Model and Training """ # Class to hold ML model class MLModel: def __init__(self, n_inputs): self.n_inputs = n_inputs visible = Input(shape=n_inputs) encoder = Conv1D( filters=1, kernel_size=100, padding="same", strides=1, activation="LeakyReLU", )(visible) encoder = MaxPool1D(pool_size=2)(encoder) # decoder decoder = Conv1DTranspose( filters=1, kernel_size=100, padding="same", strides=2, activation="linear", )(encoder) model = Model(inputs=visible, outputs=decoder) model.compile(optimizer="adam", loss="mse") self.model = model """ EXPERIMENT 1 """ # instantiate a model n_inputs = (vector_length, 1) model1 = MLModel(n_inputs).model # train first model! model1.fit(x=train_gen, epochs=10, validation_data=test_gen) """ EXPERIMENT 2 """ # use the generator to create training and testing data train_x, train_y = train_gen.__getitem__(0) test_x, test_y = test_gen.__getitem__(0) # instantiate a new model model2 = MLModel(n_inputs).model # train second model! history = model2.fit(train_x, train_y, validation_data=(test_x, test_y), epochs=10) """ Model evaluation and plotting """ pred_y1 = model1.predict(test_x) pred_y2 = model2.predict(test_x) plt.ion() plt.clf() n = 0 plt.plot(test_y[n, :, 0], label="True Signal") plt.plot(pred_y1[n, :, 0], label="Model1 Prediction") plt.plot(pred_y2[n, :, 0], label="Model2 Prediction") plt.legend()
内容的提问来源于stack exchange,提问作者Alex Witsil
相关产品推荐
相关产品推荐

