文章目录
摘要
第一部分的论文是RNN-GAN产生时序数据的文章,TimeGAN同时学习嵌入特征,生成表示,随时间迭代。嵌入网络提供了潜在的空间,对抗网络在该空间内运行,真实数据和合成数据的潜在动态通过监督丢失而同步。
第二部分学习了GAN的基础知识。
文献阅读
Time-series Generative Adversarial Networks
- 会议:33rd Conference on Neural Information Processing Systems (NeurIPS 2019), Vancouver, Canada.
- 作者及单位:Jinsung Yoon,Daniel Jarrett,Mihaela van der Schaar;加利福尼亚大学,剑桥大学,艾伦图灵研究所
论文摘要
为了充分考虑时间序列生成模型能够生成真实的temporal dynamics,提出了time-series GAN。
该框架将无监督范式的灵活性与监督训练提供的控制(确定性)相结合。通过结合监督目标和对抗目标共同优化的学习型嵌入空间,让网络在采样过程中遵守训练数据的动态。
定性和定量地评估该方法使用各种真实和合成时间序列数据集生成真实样本的能力,均可以始终显著优于最先进的基准。
研究内容
TimeGAN:
1.除了利用无监督学习的real和fake样本的对抗loss,还引入了,用原始数据作为监督项的逐步监督损失,明确的让模型捕捉序列数据中的逐步条件分布。这样做的好处是,比起到达基准是真实的还是合成的,训练数据中的信息更多。 我们可以从真实序列的转移动态中明确学习。
2.引入了一种嵌入网络embedding network,以提供特征和潜在表示之间的可逆映射,从而降低了对抗性学习空间的高维性。这利用了以下事实:即使是复杂系统的时间动态也往往是由较少且较低维的变化因素驱动的。
3.重要的是,通过联合训练嵌入网络和生成器网络,可以将监督损失最小化,以使潜在空间不仅可以提高参数效率,而且还可以通过特定条件来方便生成器学习时间关系。
4.最后,将框架通用化以处理混合数据设置,在该设置中可以同时生成静态数据和时间序列数据。
创新点
1.无监督GAN于有监督的自回归的第一次结合。
2.定性地,进行t-SNE 和PC]分析以可视化生成的分布与原始分布的相似程度。
3.定量的,事后分类器如何区分真实序列和生成序列。 此外,通过将“综合训练,真实测试(TSTR)”框架应用于序列预测任务,可以评估生成的数据保留原始数据的预测特征的程度。
作者的研究思路或研究方法
一个好的时间序列数据生成模型应该保持时间动态,即新序列尊重跨时间变量之间的原始关系。将生成性对抗网络(GAN)引入序列环境的现有方法没有充分考虑时间序列数据特有的时间相关性。同时,允许对网络动态进行更精细控制的序列预测监督模型具有固有的确定性。总之,时序生成模型不仅应该捕捉每个时间步的特征分布,还需要捕捉时间步之间潜在的复杂的关系。
一些相关的工作:
一方面,自回归模型明确的将时间序列模型,分解为条件分布的乘积。尽管自回归方法在预测中很有效,但是本质上是确定性的。从无需添加外部条件就能获得新序列的角度看,也不是一种“生成”方法。
另一方面,直接用RNN初始化GAN生成,这种直接简单地对于序列数据应用标准的loss函数,不能满足捕捉序列之间的逐步依赖关系。
因此作者将两者结合起来提出新的机制可以显式的保留temporal dynamics。
用哪些数据来论证的
数据集:
- Stock:多变量时间序列,特征之间有相关, 连续实值,具有周期性。volume and high, low, opening, closing, and adjusted closing prices.等特征
- Sine:模拟具有不同频率η和相位θ的多元正弦序列,提供连续值,周期性,多元数据,其中每个特征彼此独立。
- Energy:具有高噪声周期性,较高维数和相关特征的数据集。 UCI Appliances的能量预测数据集由多变量,连续值的测量组成,包括以紧密间隔测量的众多时间特征。
- Event(离散数据集):离散值和不规则时间戳为特征的数据集。 我们使用由事件序列及其时间组成的大型私人肺癌通路数据集,并对事件类型的单编码序列以及事件时间进行建模。
评测指标:多样性、保真度、实用性(用合成的样本训练,测试真实样本)
可视化:t-SNE和PCA在二维平面进行模型分布比较。
判别得分(discrimination score):真是样本标为1,合成样本标为0;训练一个现成的LSTM分类器,然后用测试集的错误率作为得分。
预测得分(predictive score):用合成样本集训练一个LSTM模型,预测下一时间步的值。再用模型在原始数据集测试。
对比方法:
类似的方法:RCGAN,C-RNN-GAN
自回归模型:RNN with Teacher-forcing/Professor-forcing
额外的:WaveGAN(基于WaveNet)
基础知识
季节效应
查找论文时,发现很多文章,尤其是金融的时间序列,预测时都需要考虑季节效应。环境数据应该也需要考虑时间自相关性。
现构造一个周期函数,这个周期函数的自变量是时间
t
t
t,假设循环成分为
s
(
t
)
s(t)
s(t),若以年为周期,则P为365;若以周为周期,则P为7。循环的傅里叶变换写为:
估计循环成分,需要2N个参数:
β
=
[
a
1
,
b
1
,
.
.
.
,
a
N
,
b
N
]
T
\beta = [a_1,b_1,...,a_N,b_N]^T
β=[a1,b1,...,aN,bN]T。把傅里叶变换的基函数写成一个向量,那么傅里叶变换可以写成两个向量的点乘。
例如,假设给定20个基函数(10个sin,10个cos),假设时间序列的周期为1年,则基函数向量可以写成如下行向量:
则季节循环成分写成
再假设
β
∼
N
(
0
,
σ
2
)
\beta\thicksim N(0,\sigma^2)
β∼N(0,σ2)可以给出季节性成分一个平滑的先验分布
GAN
在GAN的每一步训练中,取 m 个真实数据,使用 G 和 m 组随机数(一般使用服从正态分布的随机数)生成 m 个假数据
根据 max 部分的目标更新 D 的参数,提高 D 的分辨能力
根据 min 部分的目标更新 G 的参数,使 G 生成的数据更有迷惑性
CNN和GAN结合–DCGAN:
把上述的G和D换成了两个卷积神经网络(CNN)。但不是直接换就可以了,DCGAN对卷积神经网络的结构做了一些改变,以提高样本的质量和收敛的速度,这些改变有:
1.取消所有pooling层。G网络中使用转置卷积(transposed convolutional layer)进行上采样,D网络中用加入stride的卷积代替pooling。
2.在D和G中均使用batch normalization
3.去掉FC层,使网络变为全卷积网络
4.G网络中使用ReLU作为激活函数,最后一层使用tanh
5.D网络中使用LeakyReLU作为激活函数
DCGAN中的G网络示意:
DCGAN的Pytorch
class Generator(nn.Module):
def __init__(self, z_dim, ):
super().__init__()
self.z_dim = z_dim
net = []
# 1:设定每次反卷积的输入和输出通道数等
# 卷积核尺寸固定为4,反卷积输出为“SAME”模式
channels_in = [self.z_dim, 512, 256, 128, 64]
channels_out = [512, 256, 128, 64, 3]
active = ["R", "R", "R", "R", "tanh"]
stride = [1, 2, 2, 2, 2]
padding = [0, 1, 1, 1, 1]
for i in range(len(channels_in)):
net.append(nn.ConvTranspose2d(in_channels=channels_in[i], out_channels=channels_out[i],
kernel_size=4, stride=stride[i], padding=padding[i], bias=False))
if active[i] == "R":
net.append(nn.BatchNorm2d(num_features=channels_out[i]))
net.append(nn.ReLU())
elif active[i] == "tanh":
net.append(nn.Tanh())
self.generator = nn.Sequential(*net)
self.weight_init()
def forward(self, x):
out = self.generator(x)
return out
def weight_init(self):
for m in self.generator.modules():
if isinstance(m, nn.ConvTranspose2d):
nn.init.normal_(m.weight.data, 0, 0.02)
elif isinstance(m, nn.BatchNorm2d):
nn.init.normal_(m.weight.data, 0, 0.02)
nn.init.constant_(m.bias.data, 0)
class Discriminator(nn.Module):
def __init__(self):
"""
initialize
:param image_size: tuple (3, h, w)
"""
super().__init__()
net = []
# 1:预先定义
channels_in = [3, 64, 128, 256, 512]
channels_out = [64, 128, 256, 512, 1]
padding = [1, 1, 1, 1, 0]
active = ["LR", "LR", "LR", "LR", "sigmoid"]
for i in range(len(channels_in)):
net.append(nn.Conv2d(in_channels=channels_in[i], out_channels=channels_out[i],
kernel_size=4, stride=2, padding=padding[i], bias=False))
if i == 0:
net.append(nn.LeakyReLU(0.2))
elif active[i] == "LR":
net.append(nn.BatchNorm2d(num_features=channels_out[i]))
net.append(nn.LeakyReLU(0.2))
elif active[i] == "sigmoid":
net.append(nn.Sigmoid())
self.discriminator = nn.Sequential(*net)
self.weight_init()
def weight_init(self):
for m in self.discriminator.modules():
if isinstance(m, nn.ConvTranspose2d):
nn.init.normal_(m.weight.data, 0, 0.02)
elif isinstance(m, nn.BatchNorm2d):
nn.init.normal_(m.weight.data, 0, 0.02)
nn.init.constant_(m.bias.data, 0)
def forward(self, x):
out = self.discriminator(x)
out = out.view(x.size(0), -1)
return out
带毕设
.NET项目跑通,开始后端的模型训练和插值结果显示