单特征生成
代码主体部分如下(不含预处理部分)
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
import random
BATCH_SIZE = 1
LR_G = 0.0008 # learning rate for generator
LR_D = 0.0004 # learning rate for discriminator
N_IDEAS = 200 # think of this as number of ideas for generating an art work (Generator)
# k = random.randint(0,len(datas)1)
k = 2#第k个样本
ART_COMPONENTS = len(list(datas[k-2])) # it could be total point G can draw in the canvas
PAINT_POINTS = np.vstack([np.linspace(-1, 1, ART_COMPONENTS) for _ in range(BATCH_SIZE)])
def artist_works(datas): # painting from the famous artist (real target)
paintings = []
painting = list(datas[k-2].T)
paintings.append(painting)
paintings = torch.from_numpy(np.array(paintings))
return paintings
# 生成器
G = nn.Sequential(
nn.Linear(N_IDEAS, 150),
nn.ReLU(),
nn.Linear(150, ART_COMPONENTS),
)
# 判别器
D = nn.Sequential(
nn.Linear(ART_COMPONENTS, 100),
nn.ReLU(),
nn.Linear(100, 1),
nn.Sigmoid(),
)
#优化器
opt_D = torch.optim.Adam(D.parameters(), lr=LR_D)
opt_G = torch.optim.Adam(G.parameters(), lr=LR_G)
plt.ion()
p=[]
for i in range(ART_COMPONENTS):
p.append(i)
for step in range(2000):
artist_paintings = artist_works(datas) # 真实数据
artist_paintings = artist_paintings.to(torch.float32)
G_ideas = torch.randn(BATCH_SIZE, N_IDEAS)
#Generator先通过随机点创造图,并把图给Discriminator
G_paintings = G(G_ideas) # 生成假数据
prob_artist1 = D(G_paintings) # D试图减少这种问题
G_loss = torch.mean(torch.log(1. - prob_artist1))
opt_G.zero_grad()
G_loss.backward()
opt_G.step()
#Discriminator比较真实图和生成图,找出两者的区别并减小这种区别
prob_artist0 = D(artist_paintings) # D试图增加这个概率
prob_artist1 = D(G_paintings.detach()) # D试图减少这种问题
D_loss = - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1))
opt_D.zero_grad()
D_loss.backward(retain_graph=True)
opt_D.step()
if (step+1) % 50 == 0: # plotting
scaler = joblib.load("D:/PYthon代码/归一化/scalar")#加载
G_paintings = scaler.fit_transform(G_paintings.T.detach().numpy())#生成数据
scaler = joblib.load("D:/PYthon代码/归一化/scalar")#加载
G_paintings = scaler.inverse_transform(G_paintings)
scaler = joblib.load("D:/PYthon代码/归一化/scalar")#加载
artist_paintings = artist_paintings.permute(0, 2, 1)
artist_paintings = artist_paintings[-1,:,:]
artist_paintings = scaler.inverse_transform(artist_paintings.T)#反归一化
plt.plot( p[::30], list(G_paintings)[::30], lw = 1,label='Generated painting')
plt.plot( p[::30], list(artist_paintings[0])[::30], lw = 1, label='data')
plt.legend()
plt.ioff()
plt.show()
pt = []
for i in G_paintings:
pt.append(i[0])
rpt = []
for i in artist_paintings[0]:
rpt.append(i)
g_s_m = pd.Series(pt) #利用Series将列表转换成新的、pandas可处理的数据
g_a_d = pd.Series(rpt)
print("第{}次训练".format(step+1))
print("真数据和合成数据的相关系数:{:.4f}".format(g_s_m.corr(g_a_d)))
print("真数据概率:{:.4f}%".format(float(prob_artist0)))
print("合成数据概率:{:.4f}%".format(float(prob_artist1)))
|