同时使用sample_weight和class_weight

时间:2018-01-09 16:59:20

标签: python tensorflow keras

我的数据集已经有加权示例。在这个二进制分类中,与第二类相比,我也有更多的第一类。

我可以同时使用char o; char n; int count=0; for(int i=0; i<read.size(); i++) { o = read[i]; n = read[++i]; while(o == n) { count++; } cout << o << count; if(o != n) { cout << o << "1"; } count = 0; } return 0; 并在sample_weight函数中使用class_weight进一步加权吗?

或者我首先制作一个新的new_weights数组并将其作为model.fit()传递给fit函数?

编辑:

为了进一步说明,我已经为我的数据集中的每个样本设置了单独的权重,并且为了进一步增加复杂性,第一类的样本权重的总和远远大于第二类的总样本权重。

例如我目前有:

  

y = [0,0,0,0,1,1]

     

sample_weights = [0.01,0.03,0.05,0.02,0.01,0.02]

因此类'0'权重总和 0.11 class'1' 0.03 即可。所以我应该:

  

class_weight = {0:1.,1:0.11 / 0.03}

我需要同时使用sample_weightsample_weight功能。如果一个覆盖另一个,那么我将不得不创建新的sample_weights,然后使用class_weightfit()

所以我的问题是,我可以同时使用两者吗,还是覆盖另一部分?

2 个答案:

答案 0 :(得分:5)

如果你愿意,你肯定可以做到这两件事,如果这是你需要的东西。根据keras docs

  
      
  • class_weight:可选字典将类索引(整数)映射到权重(浮点)值,用于加权损失函数(仅限训练期间)。这可以用于告诉模型更多关注&#34;来自代表性不足的课程的样本

  •   
  • sample_weight:训练样本的可选Numpy权重数组,用于加权损失函数(仅限训练期间)。您可以传递平坦(1D)Numpy数组,其长度与输入样本相同(权重和样本之间的1:1映射),或者在时间数据的情况下[...]。

  •   

所以考虑到你提到你&#34;与第二个&#34; 相比,他们拥有更多的第一堂课。我认为你应该选择class_weight参数。在那里,您可以指出数据集所呈现的比率,以便您可以补偿不平衡的数据类。当您想为每个数据元素定义权重或重要性时,sample_weight更多。

例如,如果您通过:

class_weight = {0 : 1. , 1: 50.}

你会说来自班级1的每个样本都会计入来自班级0的50个样本,因此会提供更多&#34;重要性&#34;来自班级1的元素(因为你肯定少了那些样本)。您可以根据自己的需要进行定制。更多关于this问题的不平衡数据集。

注意:要进一步比较这两个参数,请注意将class_weight作为{0:1., 1:50.}传递等同于将sample_weight作为[1.,1.,1.,...,50.,50.,...]传递,鉴于你的样本的类别为[0,0,0,...,1,1,...]

正如我们所看到的,在这种情况下使用class_weight更为实际,而sample_weight可能会用于更具体的情况,您实际上想要给予&#34;重要性&#34 ;单独地对每个样品。如果案例需要,也可以使用两者,但必须记住它的累积效应。

修改:根据您的新问题,挖掘Keras source code似乎确实 sample_weights会覆盖class_weights ,这是在_standarize_weigths方法(第499行)上执行此操作的代码:

if sample_weight is not None:
    #...Does some error handling...
    return sample_weight #simply returns the weights you passed

elif isinstance(class_weight, dict):
    #...Some error handling and computations...
    #Then creates an array repeating class weight to match your target classes
    weights = np.asarray([class_weight[cls] for cls in y_classes
                          if cls in class_weight])

    #...more error handling...
    return weights

这意味着您只能使用其中一个,但不能同时使用两者。因此,您确实需要将sample_weights乘以补偿不平衡所需的比率。

答案 1 :(得分:0)

对于确实需要同时使用班级权重和样本权重的那些人,为DarkCygnus答案添加一些内容:
这是我用来生成样本权重以对序列中的多类时间数据进行分类的代码:
(targets是维[#temporal,#categories]的数组,值在set(#classes)中,class_weights是[#categories,#classes]的数组)。
生成的序列与目标数组的长度相同,并且批处理中的常见用例是将目标填充为零,并且样本权重也达到相同大小,从而使网络忽略填充的数据

def multiclass_temoral_class_weights(targets, class_weights):
    s_weights = np.ones((targets.shape[0],))
    # if we are counting the classes, the weights do not exist yet!
    if class_weights is not None:
        for i in range(len(s_weights)):
            weight = 0.0
            for itarget, target in enumerate(targets[i]):
                weight += class_weights[itarget][int(round(target))]
            s_weights[i] = weight
    return s_weights