当前位置:网站首页>基于BiGRU和GAN的数据生成方法
基于BiGRU和GAN的数据生成方法
2022-08-01 16:58:00 【InfoQ】
引言
1. 任务描述
- GRU网络邻近点数据拟合:根据任务描述可知,期望通过输入的长和宽来预测一系列数值,由于生成数据中包含了相关性不强的随机值,这给生成任务带来挑战。因此考虑利用起现有的数据,依照有监督的方法进行训练。参考与输入的长和宽邻近的n个样本数据进行拟合(邻近样本使用KD树查找)。对于枚举类型组合,统计邻近样本的枚举类型组合中每个类的数量,取数量最多的类作为输出。对于随机数组的生成,将选取的枚举类对应的随机数组组合成Data交给神经网络学习,因此交给网络的Data将是一个二维矩阵,矩阵的每一行都是一个与输入的长和宽临近样本的随机数组,为此考虑使用CNN或者RNN网络对这种多维数据提取信息,本文选用受限制的GRU网络作为数据提取方法,使用受限制的GRU在后文有详细介绍。
- GAN网络数据生成:枚举类型的生成使用GAN网络,将长和宽输入给生成器,生成器生成一组one-hot类型数据交给判别器判断。随机数组合拆分成5个分别使用MLP网络生成。
2. 数据集描述



3. BiGRU生成数据
3.1 GRU数据组织方法
from scipy import spatial
List_x_y = Data[:,-2:] # 数据中的长宽在最后两位,取出他们
KDTree = spatial.KDTree(List_x_y) # 构建KD树
position = List_x_y[i,:] # 组织样本时从现有的数据取
# KDTree.query会返回两个内容,索引0的部分是一组array形式的距离值,索引1是一组array形式的索引。
index = KDTree.query(position,(lib_n.search_size + 1))[1][1:] # 这样就返回了在 List_x_y 中距离(15,20)最近的 search_size + 1 个样本点[1:]表示不取最近的那个,也就是不取它本身
3.2 Limited BiGRU网络

r = (sigma(W_{ir} x + b_{ir} + W_{hr} h + b_{hr})) * 0.7 + 0.3 # 限制sigmoid输出之后加上一个定值,可以保证这个门控信息是不会置于0的
z = (sigma(W_{iz} x + b_{iz} + W_{hz} h + b_{hz})) * 0.6 + 0.4 # 并且仍给神经网络自适应的余地
n = softsign(W_{in} x + b_{in} + r * (W_{hn} h + b_{hn})) # softsign相对于tanh有着更平滑的梯度变化
h' = (1 - z) * n + z * h
class GRU_attention(nn.Module):
def __init__(self,lib):
super(GRU_attention,self).__init__()
self.gru = nn.GRU(input_size=lib.input_size,
hidden_size=lib.hidden_size_01,
num_layers=lib.num_layers,
batch_first=lib.batch_first,
bidirectional=lib.bidirectional)
self.f1 = nn.Linear(lib.hidden_size_01 * 2,lib.hidden_size_02)
self.bn1 = nn.BatchNorm1d(lib.hidden_size_02)
self.drop1 = nn.Dropout(0.8)
self.f2 = nn.Linear(lib.hidden_size_02,lib.output_size)
def forward(self,input):
out,_ = self.gru(input)
out = out[:, -1, :]
out = F.elu(self.f1(out))
out = self.bn1(out)
out = self.drop1(out)
out = self.f2(out)
return out
class Lib_net:
def __init__(self):
self.input_size = 5
self.hidden_size_01 = 128
self.hidden_size_02 = 128
self.output_size = 5
self.num_layers = 4
self.batch_first = True
self.batch_size = 1024
self.bidirectional = True
self.dropout = 0.8
self.learn_rate = 0.003
self.directions = 2 if self.bidirectional else 1
# 这个是Z-score归一化,比较适用于最大最小值不确定或者未来任务中会有更改的情况
from sklearn.preprocessing import StandardScaler
Data_random = scaler_random.fit_transform(df_total[['random0','random1','random2','random3','random4']])
# 归一化参数保存
joblib.dump(scaler_random,'./Random')
# 归一化参数读取
sclar_test_random = joblib.load("./Random")
# 归一化应用
Data_random = sclar_test_random.transform(df_total[['random0','random1','random2','random3','random4']])
# 反归一化
pride_inver_random = sclar_test_random.inverse_transform(pride)
# 学习率调整 这是峰值下降法 具有自适应性 这里再推荐一个余弦退火 余弦退火在前期实验中可以帮助更好的找到更优的学习率初始值
lr = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,'min',factor=0.8,patience=15,verbose=True,min_lr=0.00003)
4.GAN网络生成数据

4.1 GAN实现
'''
input : onehot类型的枚举数据
output: 一个值,0或1,负责判断。
'''
class Discriminator(nn.Module):
def __init__(self, lib):
super(Discriminator, self).__init__()
self.fc1 = nn.Linear(lib.input_size_D, lib.hidden_size_1)
self.fc2 = nn.Linear(lib.hidden_size_1, lib.hidden_size_2)
self.fc3 = nn.Linear(lib.hidden_size_2, lib.hidden_size_3)
self.fc4 = nn.Linear(lib.hidden_size_3, lib.output_size_D)
# self.fc5 = nn.Linear(lib.hidden_size_4, lib.output_size_D)
def forward(self, input):
out = F.leaky_relu(self.fc1(input),0.2)
out = F.dropout(out, 0.3)
out = F.elu(self.fc2(out))
out = F.dropout(out, 0.3)
out = F.elu(self.fc3(out))
out = F.dropout(out, 0.3)
# out = F.leaky_relu(self.fc4(out),0.2)
# out = F.dropout(out, 0.3)
return torch.sigmoid(self.fc4(out))
'''
input : 随机的x,z数据
output: 假的one-hot的数据
'''
class Generator(nn.Module):
def __init__(self, lib):
super(Generator, self).__init__()
self.f1 = nn.Linear(lib.input_size_G, lib.hidden_size_5)
self.f2 = nn.Linear(lib.hidden_size_5, lib.hidden_size_6)
self.f3 = nn.Linear(lib.hidden_size_6, lib.hidden_size_7)
self.f4 = nn.Linear(lib.hidden_size_7, lib.output_size_G)
# self.fc5 = nn.Linear(lib.hidden_size_8, lib.output_size_G)
def forward(self, input):
out = F.leaky_relu(self.f1(input),0.2)
out = F.elu(self.f2(out))
out = F.elu(self.f3(out))
# out = F.leaky_relu(self.fc4(out),0.2)
return self.f4(out)
for epoch in range(lib.epoch):
for i, batch in enumerate(Loader):
# ====+++++判别器训练+++++=====
# 设置模型训练状态
D_net.train()
G_net.train()
data,_ = batch
# print("data:\n{}".format(data))
data = data.to(lib.device)
# 真实值的计算
# 自拟label
real_label = torch.ones(lib.batch_size, 1).type(torch.FloatTensor).to(lib.device)
# 送入网络
predict_real = D_net(data)
real_score = predict_real
# 计算 loss
real_loss = criterion(predict_real,real_label)
# 真实值部分计算完毕
# 虚假值计算
# 随机生成(x, z) 按段生成,循环取样
if (i + 1) % 3 == 1:
x_column = np.random.uniform(1029,1085,size = (lib.batch_size,1))
z_column = np.random.uniform(1093,2439,size = (lib.batch_size,1))
gen_1 = np.hstack((x_column,z_column))
elif (i + 1) % 3 == 2:
x_column = np.random.uniform(1381, 1456, size=(lib.batch_size, 1))
z_column = np.random.uniform(1630, 3210, size=(lib.batch_size, 1))
gen_1 = np.hstack((x_column, z_column))
elif (i + 1) % 3 == 0:
x_column = np.random.uniform(1733, 1828, size=(lib.batch_size, 1))
z_column = np.random.uniform(2103, 3210, size=(lib.batch_size, 1))
gen_1 = np.hstack((x_column, z_column))
sclar_xz = joblib.load('D:/pycharm_workstation/GAN_NN_budiling/Scalers/xz')
gen_1_re = sclar_xz.transform(gen_1)
# 生成假标签
fake_label = torch.zeros(lib.batch_size, 1).type(torch.FloatTensor).to(lib.device)
gen_1_re = torch.from_numpy(gen_1_re).float().to(lib.device)
# 生成器产出假的枚举值序列
fake_data = G_net(gen_1_re)
# 把生成的序列交给判别器
predict_fake = D_net(fake_data)
# 计算loss
fake_loss = criterion(predict_fake,fake_label)
# 对于判别器,总的loss等于real_loss + fake_loss
total_loss = real_loss + fake_loss
# 记录loss在本轮epoch均值
loss_once_d = total_loss.item()
Loss_epoch_D.append(loss_once_d)
# 判别器梯度更新
optimizer_D.zero_grad()
total_loss.backward()
optimizer_D.step()
# ====+++++生成器训练+++++=====
# 生成一组假数据
if (i + 1) % 3 == 1:
x_column = np.random.uniform(1029,1085,size = (lib.batch_size,1))
z_column = np.random.uniform(1093,2439,size = (lib.batch_size,1))
gen_2 = np.hstack((x_column,z_column))
elif (i + 1) % 3 == 2:
x_column = np.random.uniform(1381, 1456, size=(lib.batch_size, 1))
z_column = np.random.uniform(1630, 3210, size=(lib.batch_size, 1))
gen_2 = np.hstack((x_column, z_column))
elif (i + 1) % 3 == 0:
x_column = np.random.uniform(1733, 1828, size=(lib.batch_size, 1))
z_column = np.random.uniform(2103, 3210, size=(lib.batch_size, 1))
gen_2 = np.hstack((x_column, z_column))
# 归一化
sclar_xz = joblib.load('D:/pycharm_workstation/GAN_NN_budiling/Scalers/xz')
gen_2_re = sclar_xz.transform(gen_2)
# save_data_generate = gen_2
gen_2_re = torch.from_numpy(gen_2_re).float().to(lib.device)
# 交给生成器生成
fake_generate = G_net(gen_2_re)
# 交给判别器判断
teacher = D_net(fake_generate)
fake_score = teacher
teacher_say = criterion(teacher,real_label)
# 记录loss在本轮epoch均值
loss_once_g = teacher_say.item()
Loss_epoch_G.append(loss_once_g)
# 生成器梯度更新
optimizer_G.zero_grad()
teacher_say.backward()
optimizer_G.step()
5. 解决办法


引用
边栏推荐
猜你喜欢
随机推荐
ROS2系列知识(7):用rqt_console查看日志logs
5年测试,只会功能要求17K,功能测试都敢要求这么高薪资了?
今晚直播!
2022强网杯CTF---强网先锋 ASR wp
【建议收藏】技术面必考题:多线程、多进程
08 Spark cluster construction
关于LocalDateTime的全局返回时间带“T“的时间格式处理
沈腾拯救暑期档
缓存一致性MESI与内存屏障
自定义注解实现日志打印时屏蔽特定字段不打印
Using Canvas to achieve web page mouse signature effect
变量交换;复合赋值;增递减运算符
[Dark Horse Morning Post] Hu Jun's endorsement of Wukong's financial management is suspected of fraud, which is suspected to involve 39 billion yuan; Fuling mustard responded that mustard ate toenails
Vulnhub靶机:HARRYPOTTER_ NAGINI
Flask框架实战
How to Efficiently Develop Jmix Extension Components
UI helper class for Winform - some components will use DevExpress components
谁还敢买影视股?
云商店携手快报税,解锁财务服务新体验!
The site is not found after the website is filed. You have not bound this domain name or IP to the corresponding site! The configuration file does not take effect!