变分自编码器 (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: 32data_params: data_path: "/train.parquet" train_batch_size: 4096 val_batch_size: 4096 num_workers: 8exp_params: LR: 0.005 weight_decay: 0.0 scheduler_gamma: 0.95 kld_weight: 0.00025 manual_seed: 1265trainer_params: gpus: [1] max_epochs: 300logging_params: save_dir: "logs/" name: "NumeraiVAE"
配置中的要害参数有:
in_channels:输出特色的数量
latent_dim:VAE 的潜在维度。
编码器/解码器包含线性层,而后是批量归一化和leakyReLU 激活。
编码器的模型定义:
# Build Encodermodules = [] 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: TrueTPU available: False, using: 0 TPU coresIPU available: False, using: 0 IPUs======= Training NumeraiVAE =======Global seed set to 1265initializing distributed: GLOBAL_RANK: 0, MEMBER: 1/1----------------------------------------------------------------------------------------------------distributed_backend=ncclAll 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 params0 Non-trainable params83.1 K Total params0.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