Skip to main content
 首页 » 编程设计

python之重置 tensorflow 流指标的变量

2025年05月04日21over140

我有一堆流媒体指标(tf.metrics.accuracy 和 custom 流媒体 micro、macro 和 weighted F1 分数)。

在训练期间,我得到了下面的那种情节(不要介意过度拟合)。

发生这种情况是因为为了计算验证集的指标,我调用了 tf.local_variables_initializer 来重置指标并且只有验证集的值。

这意味着 2 个副作用:

  1. 图像中的尖峰
  2. 在验证之间,即使每 2 个 epoch 进行一次验证,训练指标也会继续聚合

我可以通过让不同的张量保存每个指标(train 与 val)来部分解决这种情况。但它不会解决 2.

因此我有2个问题:

  • 根据您的经验,这是您希望看到的行为(还是没有?解决方案?)
  • 有没有办法只在最后 n 个批处理中流式传输指标?

请您参考如下方法:

如果您在训练之间重置指标,则此行为是预期的。 如果训练指标是两个不同的操作,则它们不会汇总验证指标。我将举例说明如何使这些指标保持不同以及如何仅重置其中一个指标。


玩具示例:

logits = tf.placeholder(tf.int64, [2,3]) 
labels = tf.Variable([[0, 1, 0], [1, 0, 1]]) 
 
#create two different ops 
with tf.name_scope('train'): 
   train_acc, train_acc_op = tf.metrics.accuracy(labels=tf.argmax(labels, 1),  
                                                 predictions=tf.argmax(logits,1)) 
with tf.name_scope('valid'): 
   valid_acc, valid_acc_op = tf.metrics.accuracy(labels=tf.argmax(labels, 1),  
                                                 predictions=tf.argmax(logits,1)) 

训练:

#initialize the local variables has it holds the variables used for metrics calculation. 
sess.run(tf.local_variables_initializer()) 
sess.run(tf.global_variables_initializer()) 
 
# initial state 
print(sess.run(train_acc, {logits:[[0,1,0],[1,0,1]]})) 
print(sess.run(valid_acc, {logits:[[0,1,0],[1,0,1]]})) 
 
#0.0 
#0.0 

初始状态如预期的那样是 0.0。

现在调用训练操作指标:

#training loop 
for _ in range(10): 
    sess.run(train_acc_op, {logits:[[0,1,0],[1,0,1]]})   
print(sess.run(train_acc, {logits:[[0,1,0],[1,0,1]]})) 
# 1.0 
print(sess.run(valid_acc, {logits:[[0,1,0],[1,0,1]]})) 
# 0.0 

只有训练精度得到更新,而有效精度仍然是 0.0。调用有效操作:

for _ in range(10): 
    sess.run(valid_acc_op, {logits:[[0,1,0],[0,1,0]]})  
print(sess.run(valid_acc, {logits:[[0,1,0],[1,0,1]]})) 
#0.5 
print(sess.run(train_acc, {logits:[[0,1,0],[1,0,1]]})) 
#1.0 

此处有效精度更新为新值,而训练精度保持不变。

让我们只重置验证操作:

stream_vars_valid = [v for v in tf.local_variables() if 'valid/' in v.name] 
sess.run(tf.variables_initializer(stream_vars_valid)) 
 
print(sess.run(valid_acc, {logits:[[0,1,0],[1,0,1]]})) 
#0.0 
print(sess.run(train_acc, {logits:[[0,1,0],[1,0,1]]})) 
#1.0 

有效精度重置为零,而训练精度保持不变。