尝试使用train_on_batch训练具有多个输出的模型时,Keras中的sample_weight出现问题。

3
我正在使用Keras来训练深度神经网络。我使用train_on_batch函数来训练我的模型。我的模型有两个输出。我的意图是通过每个样本的特定值来修改每个样本的损失。由于Keras文档here所述,我需要将sample_weight参数分配为两个不同的权重。以下是我的代码,其中每个batch包含四个训练样例:
wights=[12,10,31,1];  
mod_loss = mymodel.train_on_batch([X_train], [Y1, Y2],sample_weight=[wights,[1.0,1.0,1.0,1.0]])

我使用 sample_weight 来仅对第一个输出进行加权而不是第二个输出。当我运行代码时,出现了以下错误:

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 1211, in train_on_batch
    class_weight=class_weight)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 801, in _standardize_user_data
    feed_sample_weight_modes)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 799, in <listcomp>
    for (ref, sw, cw, mode) in
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training_utils.py", line 470, in standardize_weights
    if sample_weight is not None and len(sample_weight.shape) != 1:
AttributeError: 'list' object has no attribute 'shape'

这给了我一个想法,如果我将分配给 sample_weight 的值更改为numpy数组,则问题将得到解决。因此,我将代码更改为以下内容:

wights=[12,10,31,1];  
mod_loss = mymodel.train_on_batch([X_train], [Y1, Y2],sample_weight=numpy.array([wights,[1.0,1.0,1.0,1.0]]))

我遇到了这个错误:
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 1211, in train_on_batch
    class_weight=class_weight)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 794, in _standardize_user_data
    sample_weight, feed_output_names)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training_utils.py", line 200, in standardize_sample_weights
    'sample_weight')
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training_utils.py", line 188, in standardize_sample_or_class_weights
    str(x_weight))
TypeError: The model has multiple outputs, so `sample_weight` should be either a list or a dict. Provided `sample_weight` type not understood: [[12.0  10.0 31.0  1.0]
 [ 1.          1.          1.          1.        ]]

我有点困惑,不确定这是否是Keras实现中的一个bug。我几乎找不到任何与此相关的工作或问题。你有什么想法吗?

2个回答

1
我用另一种方法解决了这个问题。 如果输出是Y1和Y2,它们的层名称分别为y1_layernamey2_layername,并且想象一下你想要应用一个权重向量,只作用于y2(假设y2是一个长度为4的向量),你可以按照以下方式编写代码:

Original Answer翻译成"最初的回答"
wights=[12,10,31,1];  
mod_loss = mymodel.train_on_batch([X_train], [Y1, Y2],sample_weight={"y2_layername":wights})

我测试过了,它运行良好。原始回答翻译成“最初的回答”。

如果样本权重等于零会怎样?它对应的样本会发生什么? - javac
@javac 你的意思是如果所有样本的重量都为零?那么就像你的所有数据样本都等于零一样,我怀疑这不是你想要的结果。 - alift
不是训练权重,我指的是样本权重类别 => model.train_on_batch(X, y_class, sample_weight=[sample_weights_class]) - javac

0

我有同样的问题,我不明白这是否是库中的一个错误,或者我们可能没有正确传递数组。我已经设法通过在training_utils.py文件中将列表转换为numpy数组来使其工作,并且还传递了没有名称但按样本排序的数组。


我已经自己找到了解决方案。我在这里放置答案。由于缺乏文档,这并不是微不足道的,但这个解决方案对我有效。希望这对你也有用。 - alift

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