我有1500张形状(64,64,3)的图像,我训练了一个WGAN模型来生成新的图像 . 但是在训练期间,发电机损耗总是增加,鉴别器损耗总是减少,这意味着发电机不能欺骗鉴别器 . 这是网络部分的代码:
class wgan_model:
def __init__(self,learning_rate,beta1,beta2,batch_size,num_epoches,model_num,z_dim=100,smooth=0.9,model_type='DCGAN',store_path='./ckpt/',
training_picture_path='./pictures/',generate_path='./generate/',print_every=10,show_every=50):
tf.reset_default_graph()
self.learning_rate=learning_rate
self.beta1=beta1
self.beta2=beta2
self.batch_size=batch_size
self.num_epoches=num_epoches
self.model_num=model_num
self.z_dim=z_dim
self.smooth=smooth
self.model_type=model_type
self.store_path=store_path
self.training_picture_path=training_picture_path
self.generate_path=generate_path
self.print_every=print_every
self.show_every=show_every
self.reader = DataReader()
self.img_tensor=self.reader.process()
self.image_batchs = self.__get_batch(self.img_tensor)
self.real_input_placeholder=tf.placeholder(tf.float32,[None,self.img_tensor.shape[1],self.img_tensor.shape[2],self.img_tensor.shape[3]],
name='real_input_placeholder')
self.z_input_placeholder=tf.placeholder(tf.float32,[None,self.z_dim],name='z_input_placeholder')
self.training_placeholder=tf.placeholder(tf.bool,name='training_placeholder')
self.g_output=self.__generator(self.training_placeholder)
self.d_logits_real,self.d_out_real=self.__discriminator(self.real_input_placeholder,
training_placeholder=self.training_placeholder)
self.d_logits_fake,self.d_out_fake=self.__discriminator(self.g_output,
training_placeholder=self.training_placeholder,reuse=True)
self.g_loss,self.d_loss=self.__loss()
self.g_opt,self.d_opt=self.__optimizer()
self.saver = tf.train.Saver()
print('Model graph has built')
def train(self):
print('Starts train')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
g_cost_epoche=[]
d_cost_epoche=[]
for e in range(self.num_epoches):
g_cost_batch=[]
d_cost_batch=[]
for i in range(len(self.image_batchs)):
#the amount should the same as the real ones in every batch
sample_z=np.random.uniform(-1,1,size=(len(self.image_batchs[i]),self.z_dim))
d_costs=[]
for _ in range(5):
feed = {self.z_input_placeholder:sample_z,self.real_input_placeholder:self.image_batchs[i],
self.training_placeholder:True}
_,d_cost=sess.run([self.d_opt,self.d_loss],feed_dict=feed)
d_costs.append(d_cost)
feed = {self.z_input_placeholder:sample_z,self.real_input_placeholder:self.image_batchs[i],
self.training_placeholder:True}
_,g_cost=sess.run([self.g_opt,self.g_loss],feed_dict=feed)
g_cost_batch.append(g_cost)
d_cost_batch.append(np.mean(d_costs))
if e%self.print_every==0:
print('Epoche '+str(e+1))
print('Generator loss = '+str(np.mean(g_cost_batch)))
print('Discriminator loss = '+str(np.mean(d_cost_batch)))
if e%self.show_every==0:
imgs=self.__view_example(sess)
g_cost_epoche.append(np.mean(g_cost_batch))
d_cost_epoche.append(np.mean(d_cost_batch))
self.__plot_cost(g_cost_epoche,d_cost_epoche)
self.saver.save(sess,self.store_path+'model_'+str(self.model_num)+'.ckpt')
print('Training finished')
return imgs
def __generator(self,training_placeholder,reuse=False):
with tf.variable_scope('generator',reuse=reuse):
layer=tf.layers.dense(self.z_input_placeholder,2*2*1024,activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.reshape(layer,(-1,2,2,1024))
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.relu(layer)
layer=tf.layers.conv2d_transpose(layer,512,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.relu(layer)
layer=tf.layers.conv2d_transpose(layer,256,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.relu(layer)
layer=tf.layers.conv2d_transpose(layer,128,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.relu(layer)
layer=tf.layers.conv2d_transpose(layer,64,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.relu(layer)
logits=tf.layers.conv2d_transpose(layer,3,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
out=tf.nn.tanh(logits)
print('Generator has built')
return out
def __discriminator(self,inputs,training_placeholder,reuse=False):
with tf.variable_scope('discriminator',reuse=reuse):
layer=tf.layers.conv2d(inputs,64,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.leaky_relu(layer)
layer=tf.layers.conv2d(layer,128,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.leaky_relu(layer)
layer=tf.layers.conv2d(layer,256,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.leaky_relu(layer)
layer=tf.layers.conv2d(layer,512,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.leaky_relu(layer)
layer=tf.layers.conv2d(layer,1024,5,strides=2,padding='same',activation=None,
kernel_initializer=tf.contrib.layers.xavier_initializer())
layer=tf.layers.batch_normalization(layer,training=training_placeholder)
layer=tf.nn.leaky_relu(layer)
layer=tf.reshape(layer,(-1,2*2*1024))
logits=tf.layers.dense(layer,1,activation=None)
out=tf.nn.sigmoid(logits)
print('Discriminator has built')
return logits,out
def __loss(self):
d_loss_real=tf.reduce_mean(self.d_logits_real)
d_loss_fake=tf.reduce_mean(self.d_logits_fake)
g_loss=-tf.reduce_mean(self.d_logits_fake)
d_loss=-(d_loss_real-d_loss_fake)
alpha=tf.random_uniform(shape=[1,1,1,1],minval=0.,maxval=1.)
difference=self.g_output-self.real_input_placeholder
interpolates=self.real_input_placeholder+(alpha*difference)
#interpolates.set_shape(self.real_input_placeholder.get_shape().as_list())
d_intepolates,_=self.__discriminator(interpolates,self.training_placeholder,reuse=True)
gradients=tf.gradients(d_intepolates,[interpolates])[0]
slops=tf.sqrt(tf.reduce_sum(tf.square(gradients),reduction_indices=[1]))
gradient_penalty=tf.reduce_mean((slops-1.)**2)
d_loss+=gradient_penalty*10.0
print('Loss has created')
return g_loss,d_loss
def __optimizer(self):
t_vars=tf.trainable_variables()
d_vars=[var for var in t_vars if var.name.startswith('discriminator')]
g_vars=[var for var in t_vars if var.name.startswith('generator')]
with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
g_opt=tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.g_loss,var_list=g_vars)
d_opt=tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.d_loss,var_list=d_vars)
print('Optimizers has built')
return g_opt,d_opt
学习率为0.00001,批量大小为128 .
我的WGAN实施有什么问题吗?特别是在损失部分和训练部分 . 根据WGAN的论文,在损失部分,我添加了梯度惩罚,并且在训练部分中,每一步我都更多地训练鉴别器 . 但在训练期间,我可以看到发电机的损耗增加,鉴别器损失减少 . 似乎原始GAN没有任何变化(我也训练了原始GAN,同时,发电机损耗增加,鉴别器损失减少) .
任何人都可以看看我的实现?非常感谢!!