警告:tensorflow:样本权重模式已从...强制转换为['...']

65

使用.fit_generator().fit()训练图像分类器,并将字典作为参数传递给class_weight=

在TF1.x中我从未遇到过错误,但在2.1中开始训练时会得到以下输出:

WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
将某个东西从 ... 转换为 ['...'] 是什么意思?
这是在 tensorflow 存储库上发出的警告,其源代码可以在此处找到:here。相关的评论如下:

Attempt to coerce sample_weight_modes to the target structure. This implicitly depends on the fact that Model flattens outputs for its internal representation.


7
很有趣,看到最近的一个问题是我自己警告的唯一搜索结果。 - jmkjaer
1
@jorijnsmit,你能提供复制问题/警告的代码吗? - thushv89
2
实际上,只需使用%tensorflow_version 2.x切换到TF2即可出现此警告:https://colab.research.google.com/gist/jorijnsmit/9a8fe5020f1c4d6e0c3a4a60329d3083/untitled2.ipynb - gosuto
1
@jorijnsmit,不,我收到相同的警告,但实际上已经安装了TF2.1(在pyenv/virtualenv环境中使用pip install tensorflow)。 - lurix66
1
是的,@lurix66,生成此错误的代码是在2.1.0rc0中引入的。 - gosuto
显示剩余2条评论
4个回答

23

这似乎是一条虚假的信息。我在升级到TensorFlow 2.1后收到了同样的警告消息,但我根本没有使用任何类权重或样本权重。我确实使用了一个返回像这样元组的生成器:

return inputs, targets

现在我只是将它改成以下内容以消除警告:

return inputs, targets, [None]

我不知道这是否相关,但我的模型使用三个输入,因此我的inputs变量实际上是一个包含3个numpy数组的列表。targets只是一个单独的numpy数组。

无论如何,这只是一个警告。训练可以正常进行。

针对TensorFlow 2.2的编辑:

这个bug似乎已经在TensorFlow 2.2中被修复了,这很好。但是升级到2.2时,上面的修复将会失败,因为它将尝试获取样本权重的形状,这显然会导致AttributeError: 'NoneType' object has no attribute 'shape'。因此,在升级到2.2时撤销上述修复。


天啊,这个AttributeError简直要了我的命...非常感谢你! - dexter2406

20
我认为这是tensorflow的一个bug,当您使用默认参数sample_weight_mode=None调用model.compile(),然后使用指定的sample_weightclass_weight调用model.fit()时会发生这种情况。
来自tensorflow repos:
  • fit()最终调用_process_training_inputs()
  • _process_training_inputs() 设置sample_weight_modes = [None],基于model.sample_weight_mode = None,然后创建一个DataAdapter,其中sample_weight_modes = [None]
  • DataAdapter初始化期间使用sample_weight_modes = [None]调用broadcast_sample_weight_modes()
  • broadcast_sample_weight_modes()似乎期望sample_weight_modes = None,但接收到[None]
  • 它断言[None]sample_weight/class_weight不同的结构,通过适应sample_weight/class_weight的结构将其覆盖回None并输出警告

除了警告之外,这对fit()没有影响,因为DataAdapter中的sample_weight_modes被设置回None

注意,TensorFlow 文档 表明 sample_weight 必须是一个numpy数组。如果你使用 sample_weight.tolist() 调用 fit() ,你将不会收到警告,但当 preprocessing 中的 _process_numpy_inputs() 接收到长度大于1的输入时,sample_weight 会被静默地覆盖为 None

2
非常详细的解释,谢谢。唯一我不明白的是警告描述了 ... 被强制转换为 [...],而在您的情况下 [None] 被强制转换为 None... - gosuto

7
我已经采用了你的Gist并安装了Tensorflow 2.0,而不是TFA,并且它可以正常工作,没有任何警告。
这里是完整代码的Gist。以下是安装Tensorflow的代码:
!pip install tensorflow==2.0

下面展示了成功执行的截图:

enter image description here

更新: 此错误已在Tensorflow版本2.2中修复。


5
谢谢您的回复。您是正确的,警告信息直到版本2.1.0rc0才被引入。然而,恐怕我的问题仍然存在:“将某物从...强制转换为['...']是什么意思?” - gosuto
3
sample_weight_mode=Nonetarget_structuredict 类型时,我注意到会发生一些可能是无意的事情,sample_weight_modes 此时为 [None],由于 target_structure 是字典类型,所以在 broadcast_sample_weight_modes 中会捕获异常。这可以被认为是一个 bug 吗? - Franz Knülle
3
没错。这个问题一直在吸引点击和点赞,但没有得到任何答案。 - gosuto
1
如果您认为这是一个错误,请在 Github Tensorflow 存储库中提交一个 Bug。 - user11530462
1
这绝对是一个 bug,但在 TensorFlow 2.2 中已经修复了。 - jlh
显示剩余3条评论

4

不提供字典,

weights = {'0': 42.0, '1': 1.0}

我尝试了一个列表。
weights = [42.0, 1.0]

然后警告消失了。


谢谢,伙计!我之前尝试使用字典但没有成功。现在改用列表后错误已经解决了! - Victor Mondejar-Guerra
虽然这样做可以消除错误,但对我来说会破坏每个类别的权重并产生更差的结果。在切换到列表之前,我建议先检查一致性。 - CanofDrink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接