我的最终目标是通过将数据生成器输入keras API中的 * fit * 方法来拟合ML自动编码器,但是,我发现使用生成器拟合的模型不如使用原始数据拟合的模型。
为了证明这一点,我采取了以下步骤:
1.定义一个数据生成器来创建一组可变阻尼正弦波。重要的是,我定义生成器的批量大小等于整个训练数据集。通过这种方式,我可以消除批量大小作为模型与生成器拟合性能差的可能原因。
1.定义一个非常简单的ML自动编码器。注意自动编码器的潜在空间比原始数据的大小要大,所以它应该学会如何相对快速地重现原始信号。
1.使用发生器训练一个模型
1.使用发生器的__getitem__
方法创建一组训练数据,并使用这些数据拟合相同的ML模型。
在发生器上训练的模型的结果远不如在数据本身上训练的结果。
我的发电机公式一定是错的,但是,为了我的生命,我找不到我的错误。作为参考,我模拟发电机讨论here和here。
更新:
我简化了问题,使得发生器不是产生一系列随机参数化的阻尼正弦波,而是现在产生一个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()
1条答案
按热度按时间aydmsdu91#
我犯了一个新手错误,忘记了
model.fit
默认为batch_size = 32
。因此,上面发布的实验没有进行“苹果对苹果”的比较,因为与生成器拟合的模型使用了batch_size=800
,而与数据本身拟合的模型使用了batch_size=32
。当为两个实验设置相同的批量大小时,两个模型的性能相似。p.s.如果对任何人有帮助:我没有意识到批量大小作为一个超参数有多么重要。当然,有一些警告、细微差别和例外,但显然较小的批量大小有助于概括模型。我不想赘述这个主题,但有一些有趣的阅读here、here和here