Tensorflow在反向传播期间不更新线性权重

问题描述 投票:2回答:1

Problem

在我的循环模型(顺序二进制分类器)中,每个时间步t我需要执行以下输入转换:

[32 x 4] --> [32 x 100]

所以,如果我的序列长度为3,我应该:

[32 x 4] --> [32 x 100]
[32 x 4] --> [32 x 100]
[32 x 4] --> [32 x 100]

我通过在每个时间步xW + b上对[32 x 4]张量应用线性变换t来做到这一点。我工作的模型Torch实现显示线性权重的平均值改变每个时期:

Epoch #1    
0.0012639100896195
0.0012639100896195  
0.0012639100896195

Epoch #2    
0.0039414558559656
0.0039414558559656
0.0039414558559656

Epoch #3
-0.0099147083237767 
-0.0099147083237767 
-0.0099147083237767

向后传递更新权重,一切正常。但是,当我尝试在Tensorflow中执行相同操作时,平均值保持不变或在每个时期稍微更新:

Epoch: 1
> lr update: 0.0497500005
#################### DEBUGGING ####################
0.051794354      Model/input_layer2/linear_weigth:0
0.06118914   Model/input_layer2_bias/linear_bias:0

Epoch: 2
> lr update: 0.049500001
#################### DEBUGGING ####################
0.051794227      Model/input_layer2/linear_weigth:0
0.06118797   Model/input_layer2_bias/linear_bias:0

Epoch: 3
> lr update: 0.0492500015
#################### DEBUGGING ####################
0.051794235      Model/input_layer2/linear_weigth:0
0.06118701   Model/input_layer2_bias/linear_bias:0

Tensorflow线性实现非常简单:

def linear(input)
    return tf.add(tf.matmul(input, self.linear_weight), self.linear_bias)

expanded = [linear(batch_seq) for batch_seq in unstacked_input]

self.linear_weightself.linear_bias都是可训练的,并且在图形构建期间被初始化为tf.Variables。 Torch和TF模型都使用相同的训练数据集,超参数。火炬和TF模型的大小(参数的数量)也是一样的。毋庸置疑,Torch模型训练并在测试数据上显示出良好的结果,而TF模型根本不训练。

Question:

由于我是TF的新手,你能否给出一些提示TF模型可能有什么问题?我知道这是一个很长的镜头没有完整的代码,但也许我在这里缺少特定于TF的东西。

Info

您可能已经注意到,在Torch中,我们在时间步长t时每个线性操作有3个平均值,而在TF中我得到2个平均值 - 一个来自线性,另一个来自偏差。如果不使用linear()我使用没有tf.layers.dense参数的name调用我实际上每个密集调用有3个平均值。但在这种情况下,TF将为每个密集呼叫创建一个不同的平均值,我们不想这样做。

这是TF代码的训练块,它应该执行所有前进/后退魔法,但它不会:

if self.training:
    self.lr = tf.Variable(0.0, trainable=False)
    tvars = tf.trainable_variables()
    # clip the gradient by norm
    grads, _ = tf.clip_by_global_norm(tf.gradients(self.cost, tvars), config.grad_clip)
    # update variables (weights, biases, embeddings...)
    with tf.name_scope("optimizer"):
        optimizer = tf.train.AdamOptimizer(self.lr)

        # compute grads/vars for tensorboard
        self.grads_and_vars = optimizer.compute_gradients(loss)

        # debugging only, this is how I get the weights and grads
        for g, v in self.grads_and_vars:
            self.param_vals[v.name] = v
            self.param_grads[v.name+'_grads'] = g

        self.train_op = optimizer.apply_gradients(zip(grads, tvars),
                        global_step=tf.train.get_or_create_global_step())

Tensorboard

由于验证损失,模型在38个时期之后停止训练后的Tensorboard屏幕截图不会再减少。我对结核病也不太熟悉,根据直方图,我只能说某些事情肯定是不对的。

# collecting data for tb
tf.summary.scalar("Training loss", model_train.cost)
tf.summary.scalar("Learning rate", model_train.lr)
tf.summary.histogram("Training loss", model_train.cost)

for g, v in model_train.grads_and_vars:
    tf.summary.histogram(v.name, v)
    tf.summary.histogram(v.name + '_grad', g)

enter image description here

enter image description here

python tensorflow machine-learning
1个回答
1
投票

似乎我正在应用loss = tf.sigmoid(logits)(如在原始的Torch模型中),然后将loss喂给tf.losses.sigmoid_cross_entropy。这使得渐变几乎为零,并且权重未正确更新。当我删除tf.sigmoid函数时,渐变增加了重量开始移动。

logits = tf.nn.xw_plus_b(last_layer, self.output_w, self.output_b)
floss = tf.losses.sigmoid_cross_entropy
#floss = tf.nn.sigmoid_cross_entropy_with_logits
loss = floss(self.targets_input, logits, weights=1.0, label_smoothing=0,
             scope="sigmoid_cross_entropy", loss_collection=tf.GraphKeys.LOSSES)
© www.soinside.com 2019 - 2024. All rights reserved.