簡體   English   中英

張量流模型不更新權重

[英]tensorflow model not updating weights

我有一個正在訓練的模型(它會經歷步驟和時期並評估損失),但是權重卻不在訓練中。

我試圖訓練一個鑒別器,以區分圖像是合成圖像還是真實圖像。 這是GAN模型的一部分,我正在嘗試構建。

基本結構如下: 模型結構

我有兩個輸入:1.圖像(可以是真實或合成的)2.標簽(0代表真實,1代表合成)

源估計器是我從圖像中提取特征的地方。 我已經訓練了模型並恢復了權重和偏見。 這些層被凍結(不可訓練)。

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)

最后的損失和train_ops

##---------------------------------------- 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. 嘗試了大小學習率(0.1和1e-8)
  2. 嘗試使用SourceEstimator圖層trainable == True
  3. 翻轉標簽(0 ==合成,1 ==實數)
  4. 增加了區分符的內核大小和過濾器大小。

我已經在這個問題上停留了一段時間,我真的需要一些見解。 提前致謝。

------編輯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)

我可以看到您正在session.run()中調用最小化以及損失函數。 您應該只調用minimum()函數。 即只有self.model.disc_op將內部調用損失函數。 另外,我在任何地方都看不到您的會話初始化調用。 看到它只被調用一次。

查看更新的代碼,我可以看到您將tf.is_variable_initialized()調用等同於is_not_initialized。 因此,它正在初始化那些已經初始化的變量。

我從未設法找出代碼出了什么問題。

我的同事建議在不同的隔離環境中嘗試相同的模型,因此我使用Keras庫重寫了代碼。

現在它正在工作。 :/

我們仍然不知道上面的代碼到底出了什么問題-我沒有做任何更改。 我什至使用相同的代碼進行權重傳遞和變量初始化。

如果有人遇到類似的問題,我建議在不同的環境中嘗試相同的模型。

或者,如果有人知道上面的代碼出了什么問題,請分享!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM