keras flow_from_directory对类进行过采样或欠采样

时间:2017-01-23 20:48:07

标签: python machine-learning neural-network deep-learning keras

我尝试使用Keras执行二进制分类问题,使用ImageDataGenerator.flow_from_directory方法生成批处理。但是,我的类非常不平衡,比如在一个类中比另一个类大约多8倍或9倍,导致模型卡住为每个示例预测相同的输出类。有没有办法将flow_from_directory设置为从我的小类中过采样或在每个时期从我的大类中进行欠采样?现在,我刚刚在我的小班上创建了每个图像的多个副本,但我希望有更多的灵活性。

3 个答案:

答案 0 :(得分:8)

使用当前版本的Keras - 仅使用Keras内置方法无法平衡数据集。 flow_from_directory只是构建一个包含所有文件及其类的列表,对其进行混洗(如果需要),然后迭代它。

但你可以做一个不同的技巧 - 通过编写你自己的生成器来平衡python

def balanced_flow_from_directory(flow_from_directory, options):
    for x, y in flow_from_directory:
         yield custom_balance(x, y, options)

此处custom_balance应该是一个函数,给定批(x, y)正在平衡它并返回平衡批(x', y')。对于大多数应用程序,批处理的大小不需要相同 - 但是有一些奇怪的用例(例如stateful RNN) - 其中批处理大小应该具有固定的大小。)

答案 1 :(得分:2)

您可以做的一件事是在调用class_weightmodel.fit()时设置model.fit_generator()参数。

碰巧,您可以使用sklearnnumpy库轻松地计算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)

然后,它变得非常简单,只需将您的class_weights设置为等于class_weight参数:

model.fit_generator(..., class_weight=class_weights) 

答案 2 :(得分:0)

您还可以计算每个班级中的文件数量并规范化class_weights

files_per_class = []
for folder in os.listdir(input_foldr):
    if not os.path.isfile(folder):
            files_per_class.append(len(os.listdir(input_foldr + '/' + folder)))
total_files = sum(files_per_class)
class_weights = {}
for i in xrange(len(files_per_class)):
    class_weights[i] = 1 - (float(files_per_class[i]) / total_files)
print (class_weights)
...
...
...
model.fit_generator(... ,class_weight=class_weights)