关于深度学习:在表格数据集上训练变分自编码器-VAE示例

34次阅读

共计 3485 个字符,预计需要花费 9 分钟才能阅读完成。

变分自编码器 (VAE) 是在图像数据利用中被提出,但 VAE 不仅能够利用在图像中。在这篇文章中,咱们将简略介绍什么是 VAE,以及解释“为什么”变分自编码器是能够利用在数值类型的数据上,最初应用 Numerai 数据集展现“如何”训练它。

Numerai 数据集数据集蕴含全球股市数十年的历史数据,在 Numerai 的锦标赛中,应用这个数据集来进行股票的投资收益预测和加密币 NMR 的收益预测。

为什么抉择 VAE?

一般来说 VAE 能够进行异样检测、去噪和生成合成数据。

异样检测

异样检测能够对于辨认偏离大多数数据和不合乎明确定义的失常行为概念的样本。在 Numerai 数据集中这些异样可能是存在财务异样期间,检测到这些期间会为咱们的预测提供额定的信息。

去噪

去噪是从信号中去除噪声的过程。咱们能够利用 VAE 对大多数偏离的特色进行降噪。去噪转换噪声特色,个别状况下咱们会将异样检测出的样本标记为噪声样本。

生成合成数据

应用 VAE,咱们能够从正态分布中采样并将其传递给解码器以取得新的样本。

为什么抉择变分自编码器呢?

什么是 VAE?

自编码器由两个次要局部组成:

1)将输出映射为潜在空间的编码器

2)应用潜在空间重构输出的解码器

潜在空间在原论文中也被称为示意变量或潜在变量。那么为什么称为变分呢? 将潜在示意的散布强制转换到一个已知的散布(如高斯分布),因为典型的自编码器不能管制潜在空间的散布而 (VAE) 提供了一种概率的形式来形容潜在空间中的察看。因而咱们构建的编码器不是输入单个值来形容每个潜在空间的属性,而是用编码器来形容每个潜在属性的概率分布。在本文中咱们应用了最原始的 VAE,咱们称之为 vanilla VAE(以下称为原始 VAE)

VAE 架构

编码器由一个或多个全连贯的层组成,其中最初一层输入正态分布的均值和方差。均值和方差值用于从相应的正态分布中采样,采样将作为输出到解码器。解码器由也是由一个或多个齐全连贯的层组成,并输入编码器输出的重建版本。下图展现了 VAE 的架构:

与一般主动编码器不同,VAE 编码器模型将输入埋伏空间中每个维度的散布特征参数,而不是潜在空间的值。编码器将输入两个向量,反映潜在状态散布的均值和方差,因为咱们假如先验具备正态分布。而后,解码器模型将通过从这些定义的散布中采样来构建一个潜在向量,之后它将为解码器的输出重建原始输出。

一般 VAE 的损失函数中有两个项:1)重建误差和 2)KL 散度:

一般 VAE 中应用的重建误差是均方误差 (MSE)。MSE 损失试图使重构的信号与输出信号相似性。KL 散度损失试图使代码的散布靠近正态分布。q(z|x) 是给定输出信号的代码散布,p(z) 是正态分布。PyTorch 代码如下所示:

recons_loss = F.mse_loss(recons, input)
kld_loss = torch.mean(-0.5 * torch.sum(1 + log_var - mu ** 2 - log_var.exp(), dim = 1), dim = 0)

原始 VAE 配置如下所示:

model_params:
  name: 'NumeraiHistogram of KL divergence (left) and mean-squared reconstruction lossVAE'
  in_channels: 1191
  latent_dim: 32

data_params:  
  data_path: "/train.parquet"
  train_batch_size: 4096  
  val_batch_size:  4096  
  num_workers: 8

exp_params:  
  LR: 0.005  
  weight_decay: 0.0  
  scheduler_gamma: 0.95  
  kld_weight: 0.00025  
  manual_seed: 1265

trainer_params:  
  gpus: [1]  
  max_epochs: 300

logging_params:  
  save_dir: "logs/"  
  name: "NumeraiVAE"

配置中的要害参数有:

in_channels:输出特色的数量

latent_dim:VAE 的潜在维度。

编码器 / 解码器包含线性层,而后是批量归一化和 leakyReLU 激活。

编码器的模型定义:

# Build Encoder
modules = []        
modules.append(            
  nn.Sequential(nn.Linear(in_channels, latent_dim),
    nn.BatchNorm1d(latent_dim),
    nn.LeakyReLU(),))
        
self.encoder = nn.Sequential(*modules)        
self.fc_mu = nn.Linear(latent_dim, latent_dim)        
self.fc_var = nn.Linear(latent_dim, latent_dim)

解码器的模型定义:

# Build Decoder        
modules = []
        
self.decoder_input = nn.Linear(latent_dim, latent_dim)
        
modules.append(            
  nn.Sequential(nn.Linear(latent_dim, in_channels),
    nn.BatchNorm1d(in_channels),
    nn.LeakyReLU()))
        
self.decoder = nn.Sequential(*modules)

训练 VAE

python3 run.py --config configs/numerai_vae.yaml

如果没有报错应该打印以下日志:

GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
======= Training NumeraiVAE =======
Global seed set to 1265
initializing distributed: GLOBAL_RANK: 0, MEMBER: 1/1
----------------------------------------------------------------------------------------------------
distributed_backend=nccl
All distributed processes registered. Starting with 1 processes
----------------------------------------------------------------------------------------------------
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1]| Name  | Type       | Params
-------------------------------------
0 | model | NumeraiVAE | 83.1 K
-------------------------------------
83.1 K    Trainable params
0         Non-trainable params
83.1 K    Total params
0.332     Total estimated model params size (MB)
Global seed set to 1265                                                                                                                          
Epoch 19: 100%|██████████████████████████████████████████████████████████████████████████| 592/592 [00:20<00:00, 28.49it/s, loss=0.0818, v_num=3]

VAE 的利用

如何应用 VAE 进行异样检测?

异样是具备高损失值的样本。损失值能够是重建损失、KL 散度损失或它们的组合。

Numerai 训练数据集上的 KL 散度的直方图

这是 MSE 损失的直方图。

下图是 Numerai 训练数据集的 KL 散度和均方误差的可视化。该图训练后的 VAE 的潜在维度为 2,因而咱们能够将其可视化。

如何用 VAE 去噪?

首先将带有噪声的输出传递给编码器以获取潜在空间。而后将潜在空间传递给解码器以取得去噪后输出(重建输出)。

如何应用 VAE 生成合成数据?

因为解码器的输出遵循已知散布(即高斯分布),咱们能够从高斯分布中采样并将值传递给解码器就能够取得新的合成数据。

https://avoid.overfit.cn/post/144af920f43240be9ed07f0a8e0d6051

作者:Amir Erfan Eshratifar

正文完
 0