是否可以从Keras中的目录中的flow_自动推断类_权重?

是否可以从Keras中的目录中的flow_自动推断类_权重?,keras,deep-learning,Keras,Deep Learning,我有一个不平衡的多类数据集,我想使用fit\u generator中的class\u weight参数根据每个类的图像数量为类赋予权重。我正在使用ImageDataGenerator.flow\u from\u directory从目录加载数据集 是否可以从ImageDataGenerator对象直接推断class\u weight参数?刚刚找到了一种实现方法 from collections import Counter train_datagen = ImageDataGenerator()

我有一个不平衡的多类数据集,我想使用
fit\u generator
中的
class\u weight
参数根据每个类的图像数量为类赋予权重。我正在使用
ImageDataGenerator.flow\u from\u directory
从目录加载数据集


是否可以从
ImageDataGenerator
对象直接推断
class\u weight
参数?

刚刚找到了一种实现方法

from collections import Counter
train_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(...)

counter = Counter(train_generator.classes)                          
max_val = float(max(counter.values()))       
class_weights = {class_id : max_val/num_images for class_id, num_images in counter.items()}                     

model.fit_generator(...,
                    class_weight=class_weights)
train\u generator.classes
是每个图像的类列表。
计数器(train\u generator.classes)
创建每个类中图像数量的计数器

请注意,这些权重可能不利于收敛,但您可以将其用作基于发生次数的其他类型权重的基础


这个答案的灵感来源于:

或者,您可以简单地执行以下操作:

from sklearn.utils import class_weight
import numpy as np

class_weights = class_weight.compute_class_weight(
               'balanced',
                np.unique(train_generator.classes), 
                train_generator.classes)
然后您可以设置(根据上面的注释):


我尝试了两种解决方案和
sklearn.utils.class\u weight

其中一个给出了更好的准确性,尽管我不知道为什么。它们并不都产生相同的类权重

正如文章中所建议的,分配类权重的一个好方法是使用:

(1 / class_count) * (total_count/2)
因此,稍微修改Fábio Perez提出的上述方法:

counter = Counter(train_generator.classes)
total = float(sum(counter.values()))
class_weight = {class_id : (1/num_images)*(total)/2.0 for class_id, num_images in counter.items()}

Pasha Dembo建议的代码运行得非常好。但是,在插入模型拟合生成器之前,应在字典中对其进行转换:

from sklearn.utils import class_weight import numpy as np

class_weights = class_weight.compute_class_weight(
           'balanced',
            np.unique(train_generator.classes), 
            train_generator.classes)

train_class_weights = dict(enumerate(class_weights))
model.fit_generator(..., class_weight=train_class_weights)

或者,您可以简单地执行以下操作:

 from sklearn.utils import class_weight import numpy as np
 
 class_weights = class_weight.compute_class_weight(
                'balanced',
                 np.unique(train_generator.classes), 
                 train_generator.classes) You can then set (as per comment above):
 
 model.fit_generator(..., class_weight=class_weights)

我认为这是不可能的。为什么不能只计算一次呢?但是train_generator.classes只返回一个类列表,就像一个集合一样,不是吗?它为每个图像返回一个类列表。例如,如果我们有三个图像,前两个来自类1,最后一个来自类0,
train\u generator。类
等于
[1,1,0]
。事实上,刚刚去看了源代码:)干得好,谢谢。你能详细解释一下“这些权重可能不利于收敛”是什么意思吗?但在numpy、pythor或tensorflow中如何做到这一点(即,当图像标签是numpy数组时)?如果你看每种情况下类的权重比率,它是相同的。你得到了多大的差异@大卫·布朗
 from sklearn.utils import class_weight import numpy as np
 
 class_weights = class_weight.compute_class_weight(
                'balanced',
                 np.unique(train_generator.classes), 
                 train_generator.classes) You can then set (as per comment above):
 
 model.fit_generator(..., class_weight=class_weights)