不确定有什么比像你一样的自定义损失更好,但有一个更干净的方法:
def weightedLoss(w):
def loss(true, pred):
error = K.square(true - pred)
error = K.switch(K.equal(true, 0), w * error , error)
return error
return loss
您还可以return K.mean(error)
,但没有mean
您仍然可以从其他 Keras 选项中受益,例如添加样本权重和其他内容。
编译时选择权重:
model.compile(loss = weightedLoss(0.1), ...)
如果数组中有全部数据,您可以执行以下操作:
w = K.mean(y_train)
w = w / (1 - w) #this line compesates the lack of the 90% weights for class 1
另一种可以避免使用自定义损失但需要更改数据和模型的解决方案是:
- 改变你的
y
每个输出都转化为一个二类问题。形状=(batch, originalClasses, 2)
.
对于零值,使两个类中的第一个 = 1
对于 one 值,使两个类中的第二个 = 1
newY = np.stack([1-oldY, oldY], axis=-1)
调整模型以输出这个新形状。
...
model.add(Dense(2*classes))
model.add(Reshape((classes,2)))
model.add(Activation('softmax'))
确保您使用的是softmax
and a categorical_crossentropy
作为损失。
然后使用参数class_weight={0: w, 1: 1}
in fit
.