最近主要调查了对序列数据进行数据增强的方法,以下是几种基于深度学习的生成对抗网络的数据增强方法
方法 | 描述 | 优缺点 |
---|---|---|
T-CGAN | 使用一维卷积的CGAN,条件输入为时间戳,时间戳可以间隔不等 | 可以针对时间间隔不规则的情况 |
WGAN | 适用于训练不稳定的传统GAN场景 | 在某些情况下,WGAN可能仍然无法生成与真实数据完全一致的样本 |
TimeGAN | 适用于训练不稳定的传统GAN场景 | 在某些情况下,WGAN可能仍然无法生成与真实数据完全一致的样本 |
C-RNN-GAN | 在生成音乐等连续数据方面表现出色 | 能够处理并生成较长的连续序列,这在处理如自然语言、音频等复杂数据时尤为重要,但对离散数据处理能力有限 |
RGAN、RCGAN | RGAN采用相对判别器,将真假样本对作为输入,以其中一个样本作为基准,得判别器更稳健,生成对抗网络训练更稳定 | 能够生成更高质量的数据样本,与真实数据难以区分,存在过拟合的风险,需要合理设置训练参数和策略 |
混合多个GAN | 用多个GAN,每一个生成特定标签的数据 | 数据生成具有针对性,可用于严重不平衡的数据集 |
目前主要针对WGAN做了复现和研究
判别器:
class Discriminator(nn.Module):
def __init__(self, input_dim):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, 32),
nn.ReLU(),
nn.Linear(32, 1),
nn.ReLU(),
)
def forward(self, x):
return self.model(x)
判别器模型结构:
生成器:
class Generator(nn.Module):
def __init__(self, input_dim, output_dim):
super(Generator, self).__init__()
self.model = nn.Sequential(
nn.Linear(input_dim, 32),
nn.ReLU(),
nn.Linear(32, output_dim),
# nn.ReLU(),
)
def forward(self, z):
return self.model(z)
生成器的结构:
对于该数据进行数据增强可有两种思路。
1.将生成器输入维度设置为5输出为6,创建维度为5的噪声,经由生成器输出维度为6的模拟数据,再经过dnn/mlp等模型预测其相对距离,最终得到维度为7的数据作为模拟数据
2.将生成器输入维度设置为6,创建维度为6的噪声,直接经由生成器输出维度为7的模拟数据
对于数据的选择也有两种思路:
1.选择混合后的五井数据作为原始数据进行数据增强
2.分别使用混合前的各井数据作为原始数据进行数据增强,增强后再进行混合
目前数据增强是按照思路1,数据选择按照也思路1
GAN模型训练:
def train_wgan(dnn, generator, discriminator, dataloader, num_epochs=3000, batch_size=8, n_critic=300):
generator_losses = []
discriminator_losses = []
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
generator.to(device)
discriminator.to(device)
gen_optimizer = optim.SGD(generator.parameters(), lr=0.0002)
disc_optimizer = optim.SGD(discriminator.parameters(), lr=0.0003)
dnn_optimizer = optim.SGD(dnn.parameters(), lr=0.0003)
scaler = StandardScaler()
columns = ['Column1', 'Column2', 'Column3', 'Column4', 'Column5', 'Column6', 'Column7']
output_filepath = 'generated_data/generated_data2.csv'
f = open(output_filepath,'w',encoding='utf-8')
csv_writer = csv.writer(f)
csv_writer.writerow(columns)
loss_func = nn.MSELoss() # 均方根误差损失函数
train_num = 0
train_loss = 0
for epoch in range(num_epochs):
for _ in range(len(dataloader) // batch_size):
real_data = next(iter(dataloader))
real_data = torch.stack(real_data).to(device)
X_real, y_real = np.split(real_data.squeeze(), [6], axis=1)
dnn_optimizer.zero_grad()
predict = dnn(X_real)
# print(predict)
loss = loss_func(predict, y_real)
loss.backward()
dnn_optimizer.step()
for _ in range(n_critic):
X_real = scaler.fit_transform(X_real.cpu().numpy())
X_real = torch.FloatTensor(X_real).to(device)
noise = torch.randn(batch_size, 5).to(device)
fake_data = generator(noise)
disc_real = discriminator(X_real)
disc_fake = discriminator(fake_data.detach())
disc_optimizer.zero_grad()
disc_loss = -torch.mean(disc_real) + torch.mean(disc_fake)
disc_optimizer.step()
for param in discriminator.parameters():
param.data.clamp_(-0.1, 0.1)
noise = torch.randn(batch_size, 5).to(device)
fake_data = generator(noise)
wasserstein_loss = discriminator(fake_data)
gen_loss = -torch.mean(wasserstein_loss)
gen_optimizer.zero_grad()
gen_loss.requires_grad_(True)
gen_loss.backward()
gen_optimizer.step()
generator_losses.append(gen_loss.item())
discriminator_losses.append(disc_loss.item())
print(f"Epoch {epoch}/{num_epochs} [D loss: {disc_loss.item()}] [G loss: {gen_loss.item()}]")
流程图:
目前采取的评判生成器和判别器是否收敛的方法——绘制损失函数图像,查看是否稳定收敛
数据增强后的效果(扩充数据为800条原为160条)
但是将目前数据用于实际模型预测中得到的效果较差:
所以又尝试更换其他的预测效果更好的CNN模型来进行预测,模型如下
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model1 = nn.Sequential(
nn.Conv1d(in_channels=6, out_channels=8, kernel_size=3, stride=1, padding=1),
nn.Tanh(),
# nn.MaxPool1d(2), # torch.Size([128, 16, 5])
nn.Conv1d(in_channels=8, out_channels=16, kernel_size=3, stride=1, padding=1),
nn.Tanh(),
# nn.MaxPool1d(2), # torch.Size([128, 32, 1])
# nn.AdaptiveMaxPool1d(1),
nn.Flatten(), # torch.Size([128, 32]) (假如上一步的结果为[128, 32, 2], 那么铺平之后就是[128, 64])
)
self.model2 = nn.Sequential(
# 如果要更改卷积核大小等,这里全连接层的输入特征数要改变
# nn.Linear(in_features=96, out_features=100, bias=True),
nn.Linear(in_features= 16, out_features=100, bias=True),
# 第二个隐含层
nn.Linear(100, 100),
# 第三个隐含层
nn.Linear(100, 50),
# 回归预测层
nn.Linear(50, 1)
)
def forward(self, input):
x = input.reshape(-1,6,1)
x = self.model1(x)
x = self.model2(x)
return x[:,0]
强化前:
强化后:
可以发现有了比较明显的提升,但是在很多次的强化结果中只有一次可以达到如上效果
后续尝试采用其他思路组合,并尝试优化生成器、判别器以及用于生成标签的模型选择。
根据定性生成数据与原真实数据对比来看,并不是适用于所有井,比如A1井和L3井对应的相对距离都在58米左右,但是猜测由于其在混合数据中数据占比少,导致数据增强所得数据中基本没有58米左右相对距离的数据.所以又尝试使用WGAN分别对单井数据进行数据增强,将各自的增强结果汇总。
初步通过汇总数据训练模型可得出如下效果:
并且此次数据增强全程采用WGAN进行标签的生成,标签生成的方面仍可继续进行优化。但与之前不同的是,此次生成的数据较为稳定,可以多次复现。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。