我有一个数据集,其中包含 3 个特征、2 个浮点特征和 1 个包含 33 个类别的分类特征。 (此处称为 Float_A、Float_B 和 Cat_A)。
我正在尝试训练 CVAE 来生成合成数据。数据使用以下 sklearn 转换器进行转换:
df=df[["float_A","float_B","categorical_A"]]
transformers=[('float_A',Pipeline(steps=[('imputer',SimpleImputer(strategy='mean',add_indicator=True)),
('scaler',RobustScaler(quantile_range=(5,95)))]),
['float_A']),
('float_B',
Pipeline(steps=[('imputer',SimpleImputer(strategy='mean',add_indicator=True)),
('scaler',MinMaxScaler())]),
['float_B']),
('cats',OneHotEncoder(),categorical_columns)]`
transformer=ColumnTransformer(transformers,remainder='passthrough')
transformed_df=transformer.fit_transform(df)
我的第二个浮点数有一个 sigmoid 激活函数,其声明如下:
`Def sample(self,z):
reconstructed=self.decoder(z)
#Apply sigmoid activation to the float feature.
reconstructed[:,self.float_B_idx]=torch.sigmoid(reconstructed[:,self.float_B_idx])
returnreconstructed
Def forward(self,x):
z_mean,z_log_var=torch.chunk(self.encoder(x),2,dim=1)
z=self.reparameterize(z_mean,z_log_var)
reconstructed=self.decoder(z)
#Apply sigmoid activation to the float feature.
reconstructed[:,self.float_B_idx]=torch.sigmoid(reconstructed[:,self.float_B_idx])
return reconstructed,z_mean,z_log_var`
一旦 CVAE 被训练,(训练和验证损失似乎会减少,因为它们应该) ),我尝试使用以下命令生成随机样本:
random_latent_vectors=torch.randn(num_samples,latent_dim)
with torch.no_grad():
gen_df=model.sample(random_latent_vectors).detach().cpu().numpy()
但是 gen_df 中的所有样本都非常“未扩散”。
FloatA, FloatB, Cat[0:2]…
[[0.11782782 0.286538 0.646666 0.266387 0.09747571]
[0.0963359 0.29775462 0.58443785 0.29296008 0.1101962]
[0.1300626 0.31274286 0.59086925 0.30710378 0.10169853]
[0.1232817 0.32317564 0.56470346 0.29102385 0.11446829]
[0.13240162 0.28100765 0.6230704 0.29497638 0.08924796]]
然后,当我在 gen_df 上调用 scaler.inverse_transform 时,我实际上得到了所有相同的结果每行。
我尝试了各种方法,其中一个类别非常占主导地位(~90%),因此使用 imblearn 进行了一些类别不平衡欠采样,使其只有 50% 占主导地位,但仍然获得 100% 的样本。
我尝试向我的 CVAE 添加更多层和复杂性,但再次被证明是徒劳的。
听起来的 CVAE 模型正在生成崩溃,这意味着它生成的数据缺乏多样性,并且在的例子中过于集中在输入空间的狭窄范围内。这在 CVAE 中是一个常见问题,有几个潜在的原因和解决方案需要考虑:
可能的原因和解决方案:
- 潜在空间维度:
- 问题: 如果潜在空间(即从中采样随机向量以生成数据的空间)的维度太小,模型可能没有足够的容量来编码数据中所有必要的变化。
-
解决方案: 尝试增加潜在空间的维度。这将为模型提供更多空间来表示数据的不同方面。
-
KL 散度损失加权:
- 问题: CVAE 中的损失函数有两个组成部分:重建损失(鼓励模型生成类似于输入的数据)和 KL 散度损失(鼓励潜在空间遵循正态分布)。如果 KL 散度损失的权重相对于重建损失过高,则模型可能会优先使潜在空间正则化,从而牺牲数据多样性。
-
解决方案: 尝试降低 KL 散度损失的权重。这可以通过引入一个超参数 β 来实现,该参数乘以 KL 散度损失项。降低 β 会降低 KL 散度损失的影响,从而可能导致更多样化的生成数据。
-
模型容量和架构:
- 问题: 如果的编码器和/或解码器网络过于简单或容量不足,它们可能无法充分学习数据分布的复杂性。
-
解决方案: 尝试向编码器和解码器网络添加更多层或神经元。还可以尝试使用更具表现力的架构,例如使用卷积层来处理图像数据或使用递归层来处理顺序数据。
-
训练数据:
- 问题: 如果的训练数据量有限或类别分布不平衡,则模型可能难以学习真实数据分布。
-
解决方案: 如果可能,请收集更多训练数据。对于类别不平衡,可以尝试使用数据增强技术或对少数类别进行过采样来平衡类别分布。尝试过的类别不平衡欠采样也是一种有效的方法。
-
激活函数:
- 问题: 虽然对第二个浮点特征使用 sigmoid 激活函数是合理的,但这可能会限制生成数据的范围,尤其是在解码器中没有使用适当的缩放或偏移的情况下。
-
解决方案: 确保解码器的最终输出层中的激活函数和任何缩放操作与输入数据预处理相匹配。例如,如果在预处理期间使用
MinMaxScaler
将第二个浮点特征缩放到 [0, 1] 范围,则使用 sigmoid 激活函数并将输出缩放到原始范围是有意义的。 -
超参数调整:
- 问题: 学习率、批大小和其他超参数等训练超参数也会影响模型的性能及其生成数据的能力。
- 解决方案: 尝试使用不同的超参数组合,例如使用网格搜索或随机搜索等技术。
调试技巧:
- 可视化潜在空间: 通过将潜在空间表示(即编码器输出)降维到两个维度来可视化,例如使用 t-SNE 或 PCA。这可以帮助了解潜在空间是否被充分利用以及数据点在潜在空间中的分布情况。
- 检查重建: 从训练数据和生成数据中可视化重建样本。这可以帮助确定模型是否难以重建某些特征或数据点的某些方面。
- 监控训练进度: 密切关注训练过程中重建损失和 KL 散度损失。如果 KL 散度损失迅速下降到接近于零的值,则可能表明模型正在崩溃。
其他提示:
- 考虑尝试使用其他生成模型,例如生成对抗网络 (GAN),它们在生成多样化和逼真的数据方面可能更有效。
- 查阅有关 CVAE 崩溃的文献和资源,以获取更多见解和解决方案。
请记住,构建和训练生成模型可能具有挑战性,通常需要大量的实验和微调才能获得令人满意的结果。
标签:python,machine-learning,deep-learning,neural-network,autoencoder From: 78809995