我有一个正在训练的模型(它会经历步骤和时期并评估损失),但是权重却不在训练中。
我试图训练一个鉴别器,以区分图像是合成图像还是真实图像。这是GAN模型的一部分,我正在尝试构建。
我有两个输入: 1.图片(可以是真实的或合成的)2.标签(0代表真实,1代表合成)
Source Estimator是我从图像中提取特征的地方。我已经训练了模型并恢复了权重和偏见。这些图层是冻结的(不可训练)。
def SourceEstimator(eye, name, trainable = True):
# source estimator and target representer shares the same structure.
# SE is not trainable, while TR is.
net = tf.layers.conv2d(eye, 32, 3, (1,1), padding='same', activation=tf.nn.leaky_relu, trainable=trainable, name=name+'_conv2d_1')
net = tf.layers.conv2d(net, 32, 3, (1,1), padding='same', activation=tf.nn.leaky_relu, trainable=trainable, name=name+'_conv2d_2')
net = tf.layers.conv2d(net, 64, 3, (1,1), padding='same', activation=tf.nn.leaky_relu, trainable=trainable, name=name+'_conv2d_3')
c3 = net
net = tf.layers.max_pooling2d(net, 3, (2,2), padding='same', name=name+'_maxpool_4')
net = tf.layers.conv2d(net, 80, 3, (1,1), padding='same', activation=tf.nn.leaky_relu, trainable=trainable, name=name+'_conv2d_5')
net = tf.layers.conv2d(net, 192, 3, (1,1), padding='same', activation=tf.nn.leaky_relu, trainable=trainable, name=name+'_conv2d_6')
c5 = net
return (c3, c5)
鉴别器如下:
def DiscriminatorModel(features, reuse=False):
with tf.variable_scope('discriminator', reuse=tf.AUTO_REUSE):
net = tf.layers.conv2d(features, 64, 3, 2, padding='same', kernel_initializer='truncated_normal', activation=tf.nn.leaky_relu, trainable=True, name='discriminator_c1')
net = tf.layers.conv2d(net, 128, 3, 2, padding='same', kernel_initializer='truncated_normal', activation=tf.nn.leaky_relu, trainable=True, name='discriminator_c2')
net = tf.layers.conv2d(net, 256, 3, 2, padding='same', kernel_initializer='truncated_normal', activation=tf.nn.leaky_relu, trainable=True, name='discriminator_c3')
net = tf.contrib.layers.flatten(net)
net = tf.layers.dense(net, units=1, activation=tf.nn.softmax, name='descriminator_out', trainable=True)
return net
输入进入SourceEstimator模型并提取特征(c3,c5)。
然后,将c3和c5沿着通道轴串联起来,并传递给鉴别器模型。
c3, c5 = CommonModel(self.left_eye, 'el', trainable=False)
c5 = tf.image.resize_images(c5, size=(self.config.img_size,self.config.img_size))
features = tf.concat([c3, c5], axis=3)
##---------------------------------------- DISCRIMINATOR ------------------------------------------##
with tf.variable_scope('discriminator'):
logit = DiscriminatorModel(features)
最后的损失和trainsops
##---------------------------------------- LOSSES ------------------------------------------##
with tf.variable_scope("discriminator_losses"):
self.loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logit, labels=self.label))
##---------------------------------------- TRAIN ------------------------------------------##
# optimizers
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
disc_optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate)
self.disc_op = disc_optimizer.minimize(self.loss, global_step=self.global_step_tensor, name='disc_op')
训练步伐和时代。我正在使用32个批处理大小。和数据生成器类一起获取图像的每一步。
def train_epoch(self):
num_iter_per_epoch = self.train_data.get_size() // self.config.get('batch_size')
loop = tqdm(range(num_iter_per_epoch))
for i in loop:
dloss = self.train_step(i)
loop.set_postfix(loss='{:05.3f}'.format(dloss))
def train_step(self, i):
el, label = self.train_data.get_batch(i)
## ------------------- train discriminator -------------------##
feed_dict = {
self.model.left_eye: el,
self.model.label: label
}
_, dloss = self.sess.run([self.model.disc_op, self.model.loss], feed_dict=feed_dict)
return dloss
模型经过各个步骤和各个阶段时,权重保持不变。
在训练步骤中损失有所波动,但每个时期的损失都是相同的。例如,如果我没有在每个时期都对数据集进行混洗,那么图的损失将遵循每个时期的相同模式。
我认为这意味着模型可以识别出不同的损失,但并没有根据损失来更新参数。
以下是我尝试过但没有帮助的其他事情:
我已经在这个问题上停留了一段时间,我真的需要一些见解。提前致谢。
------编辑1 -----
def initialize_uninitialized(sess):
global_vars = tf.global_variables()
is_initialized= sess.run([tf.is_variable_initialized(var) for var in global_vars])
not_initialized_vars = [v for (v, f) in zip(global_vars, is_initialized) if not f]
# for var in not_initialized_vars: # only for testing
# print(var.name)
if len(not_initialized_vars):
sess.run(tf.variables_initializer(not_initialized_vars))
self.sess = tf.Session()
## inbetween here I create data generator, model and restore pretrained model.
self.initilize_uninitialized(self.sess)
for current_epoch in range(self.model.current_epoch_tensor.eval(self.sess), self.config.num_epochs, 1)
self.train_epoch() # included above
self.sess.run(self.model.increment_current_epoch_tensor)
答案 0 :(得分:1)
我可以看到您正在session.run()中调用最小化以及损失函数。您应该只调用minimum()函数。即只有self.model.disc_op会在内部调用损失函数。 另外,我在任何地方都看不到您的会话初始化调用。看到它只被调用一次。
查看更新的代码,我可以看到您将tf.is_variable_initialized()调用等同于is_not_initialized。因此,它正在初始化那些已经初始化的变量。
答案 1 :(得分:0)
我从来没有设法找出代码出了什么问题。
我的同事建议在不同的隔离环境中尝试相同的模型,因此我使用Keras库重写了代码。
现在可以正常工作了。 :/
我们仍然不知道上面的代码到底出了什么问题-我没有做任何更改。我什至使用相同的代码进行权重传递和变量初始化。
如果有人遇到类似问题,我建议在不同的环境中尝试相同的模型。
或者如果有人知道上面的代码出了什么问题,请分享!