1.GAN:Generative Adversarial Network
2.生成器:随机生成一个一维的100个随机数(latent_dim)作为输入生成mnist图片
def build_generator(self):
model=Sequential()
model.add(Dense(256,input_dim=self.latent_dim))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(np.prod(self.img_shape),activation='tanh'))#全连接层,28*28*1个神经元
model.add(Reshape(self.img_shape))#变成图片的形状
noise=Input(shape=(self.latent_dim,))
img=model(noise)#建立了从输入100维随机向量》》》》到28,28,1大小的图片》》》生成模型
return Model(noise,img)
3.判别器:输入图片,输出一个一维判断结果(0或者1)
def build_discriminator(self):
model=Sequential()
model.add(Flatten(input_shape=self.img_shape))#将输入的图片扁平化,因为用的全是全连接层
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(1,activation='sigmoid'))#输出是一个维度,并用sigmoid映射到0到1
img=Input(shape=self.img_shape)
validity=model(img)#建立了从输入28,28,1图片》》》到输出一个维度的》》》》判别模型
return Model(img,validity)
4.1构建判别网络:训练判别器
self.discriminator=self.build_discriminator()#此类的评判标准由此类的动作函数生成
self.discriminator.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy'])#对评判标准的结果进行验证准确度
4.2训练判别器
#训练判别网络
idx=np.random.randint(0,x_train.shape[0],batch_size)#从train训练集里面随机找出batc——size大小(这么多个)的索引值
imgs=x_train[idx]#取出1个batch大小的图片
noise=np.random.normal(0,1,(batch_size,self.latent_dim))#正态分布生成batch_size个100维向量作为输入
gen_imgs=self.generator.predict(noise)#用生成model的predict方法(model内部方法)将输入进行生成输出
d_loss_real=self.discriminator.train_on_batch(imgs,valid)#输入真实图片和标签全1》》到判别model,》》计算判别模型的loss
d_loss_fake=self.discriminator.train_on_batch(gen_imgs,fake)#输入假的图片和标签全0》》到判别model,》计算判别模型的loss d_loss=0.5*np.add(d_loss_real,d_loss_fake)#将两者损失结合作为总损失
5.1构建生成判别网络:训练生成器
self.generator=self.build_generator()#模型的生成者
gan_input=Input(shape=(self.latent_dim,))#定义此类模型的输入层形状
img=self.generator(gan_input)#将输入送到生成者去生成图片
self.discriminator.trainable=False#此时只生成图片,不进行评判和两者改进
validity=self.discriminator(img)#评判生成的图片
self.combined=Model(gan_input,validity)#建立输入到评判结果的模型
self.combined.compile(loss='binary_crossentropy',optimizer=optimizer)#模型编译
5.2训练生成器
#训练生成网络
noise=np.random.normal(0,1,(batch_size,self.latent_dim))
g_loss=self.combined.train_on_batch(noise,valid)#如果输入噪音的输出是1,则正确,输入噪音输出是0,则生成网络需要改进,所以loss累加
6.全部代码
class GAN():
def __init__(self):
self.img_rows=28#定义图片属性
self.img_cols=28
self.channels=1
self.img_shape=(self.img_rows,self.img_cols,self.channels)#shape是元组属性值
self.latent_dim=100#随机生成input的形状属性值
optimizer=Adam(0.0002,0.5)#确定模型优化器参数属性值
self.discriminator=self.build_discriminator()#此类的评判标准由此类的动作函数生成
self.discriminator.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy'])#对评判标准的结果进行验证准确度
self.generator=self.build_generator()#模型的生成者
gan_input=Input(shape=(self.latent_dim,))#定义此类模型的输入层形状
img=self.generator(gan_input)#将输入送到生成者去生成图片
self.discriminator.trainable=False#此时只生成图片,不进行评判和两者改进
validity=self.discriminator(img)#评判生成的图片
self.combined=Model(gan_input,validity)#建立输入到评判结果的模型
self.combined.compile(loss='binary_crossentropy',optimizer=optimizer)#模型编译
def build_generator(self):
model=Sequential()
model.add(Dense(256,input_dim=self.latent_dim))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(np.prod(self.img_shape),activation='tanh'))#全连接层,28*28*1个神经元
model.add(Reshape(self.img_shape))#变成图片的形状
noise=Input(shape=(self.latent_dim,))
img=model(noise)#建立了从输入100维随机向量》》》》到28,28,1大小的图片》》》生成模型
return Model(noise,img)
def build_discriminator(self):
model=Sequential()
model.add(Flatten(input_shape=self.img_shape))#将输入的图片扁平化,因为用的全是全连接层
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(1,activation='sigmoid'))#输出是一个维度,并用sigmoid映射到0到1
img=Input(shape=self.img_shape)
validity=model(img)#建立了从输入28,28,1图片》》》到输出一个维度的》》》》判别模型
return Model(img,validity)
def train(self,epochs,batch_size=128,sample_interval=50):
(x_train,y_train),(x_test,y_test)=mnist.load_data()
x_train=x_train/127.5-1#将图片像素值映射到-1到1
x_train=np.expand_dims(x_train,axis=3)#输入时2维tensor,映射到三维,加了第三维1,表示1个通道
valid=np.ones((batch_size,1))#batch——size大小的全是1的标签
fake=np.zeros((batch_size,1))#batch_size大小全是0的标签
for epoch in range(epochs):
#训练判别网络
idx=np.random.randint(0,x_train.shape[0],batch_size)#从train训练集里面随机找出batc——size大小(这么多个)的索引值
imgs=x_train[idx]#取出1个batch大小的图片
noise=np.random.normal(0,1,(batch_size,self.latent_dim))#正态分布生成batch_size个100维向量作为输入
gen_imgs=self.generator.predict(noise)#用生成model的predict方法(model内部方法)将输入进行生成输出
d_loss_real=self.discriminator.train_on_batch(imgs,valid)#输入真实图片和标签全1》》到判别model,》》计算判别模型的loss
d_loss_fake=self.discriminator.train_on_batch(gen_imgs,fake)#输入假的图片和标签全0》》到判别model,》计算判别模型的loss
d_loss=0.5*np.add(d_loss_real,d_loss_fake)#将两者损失结合作为总损失
#训练生成网络
noise=np.random.normal(0,1,(batch_size,self.latent_dim))
g_loss=self.combined.train_on_batch(noise,valid)#如果输入噪音的输出是1,则正确,输入噪音输出是0,则生成网络需要改进,所以loss累加
print ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100*d_loss[1], g_loss))#说明生成网络的性能
if epoch %sample_interval==0:
self.sample_images(epoch)
def sample_images(self,epoch):#画出25张图片
r,c=5,5
noise=np.random.normal(0,1,(r*c,self.latent_dim))
gen_imgs=self.generator.predict(noise)
gen_imgs=0.5*gen_imgs+0.5
fig,axs=plt.subplots(r,c)
cnt=0
for i in range(r):
for j in range(c):
axs[i,j].imshow(gen_imgs[cnt,:,:,0],cmap='gray')
axs[i,j].axis('off')
cnt+=1
fig.savefig('images/%d.png'%epoch)
plt.close()
if __name__=='__main__':
if not os.path.exists('./images'):
os.makedirs('./images')
gan=GAN()
gan.train(epochs=600,batch_size=256,sample_interval=50)
参考:https://blog.csdn.net/weixin_44791964/article/details/103729797