我正在使用keras
和tensorflow
(版本2.2.0)作为后端来训练一个分类器,以区分两个数据集A和B。我将这两个数据集混合到一个pandas DataFrame对象x_train
中(有两列),标签则存放在一个numpy数组y_train
中。为了考虑到A的数据样本远多于B,我希望进行样本加权。此外,A由两个数据集A1和A2组成,A1的样本数远大于A2;我希望通过样本权重来反映这一事实。我的样本权重存放在一个名为w_train
的numpy数组中。训练样本总数约为1000万个。
以下是示例代码:
model = Sequential()model.add(Dense(64, input_dim=x_train.shape[1], activation='relu')) model.add(Dropout(0.1))model.add(Dense(64, activation='relu'))model.add(Dropout(0.1))model.add(Dense(64, activation='relu'))model.add(Dropout(0.1))model.add(Dense(64, activation='relu'))model.add(Dropout(0.1))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(x_train.iloc, y_train, sample_weight=w_train)
当我在model.fit()
中使用sample_weight
参数时,我发现模型拟合的初始化时间(即keras
开始显示训练进度之前的过程)非常长,无法忍受。当我将数据集限制在1000个样本时,这个问题消失了,但当我增加到100000或1000000个样本时,我注意到初始化和拟合时间有显著差异,因此我怀疑这与数据加载方式有关。然而,仅仅添加sample_weights
参数就导致如此大的时间差异似乎很奇怪。
其他信息:我在CPU上使用Jupyter笔记本运行。
这里的问题是什么?我能否通过修改训练设置或其他方式来加速初始化(或训练)时间?
回答:
问题是由TensorFlow验证某些类型的输入对象的方式引起的。当数据肯定是正确的时,这样的验证完全是浪费时间(我希望未来能处理得更好)。
为了强制TensorFlow跳过这样的验证过程,你可以简单地将权重包装在一个Pandas Series中,如下所示:
model.fit(x_train.iloc, y_train, sample_weight=pd.Series(w_train))
请注意,在你的代码中你使用了metrics
关键字。如果你希望准确率实际基于提供的权重来加权,请使用weighted_metrics
参数代替。