我在训练一个TensorFlow Keras顺序模型,数据大约有20+ GB,基于PostgreSQL数据库中的文本类别数据,我需要为模型设置类别权重。我目前的做法如下:
class_weights = sklearn.utils.class_weight.compute_class_weight('balanced', classes, y)model.fit(x, y, epochs=100, batch_size=32, class_weight=class_weights, validation_split=0.2, callbacks=[early_stopping])
由于我无法将所有数据加载到内存中,我考虑使用Keras模型中的fit_generator方法。
然而,如何在这个数据集上计算类别权重呢?sklearn并没有提供专门的函数来处理这个问题,它是否适合这种情况?
我考虑在多个随机样本上进行计算,但有没有更好的方法可以使用全部数据?
回答:
你可以使用生成器,同时也可以计算类别权重。
假设你的生成器是这样定义的
train_generator = train_datagen.flow_from_directory( 'train_directory', target_size=(224, 224), batch_size=32, class_mode = "categorical" )
训练集的类别权重可以这样计算
class_weights = class_weight.compute_class_weight( 'balanced', np.unique(train_generator.classes), train_generator.classes)
[EDIT 1]由于你在评论中提到了PostgreSQL,我在这里添加了原型答案。
首先从PostgreSQL中使用单独的查询获取每个类别的计数,并使用这些计数来计算类别权重。你可以手动计算。基本逻辑是,权重最小的类别的计数值为1,其余类别的权重根据与最小的类别的相对计数设置为<1。
例如,你有三个类别A、B、C,计数分别为100、200、150,那么类别权重将变为{A:1,B:0.5,C:0.66}。
在从PostgreSQL获取值后,我们手动计算它。
[Query]
cur.execute("SELECT class, count(*) FROM table group by classes order by 1")rows = cur.fetchall()
上述查询将返回按类别名称和每个类别的计数排序的元组,从最少到最多。
然后下面的代码将创建类别权重字典
class_weights = {}for row in rows: class_weights[row[0]]=rows[0][1]/row[1] # 用最小的值除以当前值来获得权重, # 这样最小的值变为1, # 其他值变为<1