如何定义TF2.0+ keras CNN的加权损失函数进行图像分类?

Jos*_*dam 6 python keras tensorflow

我想整合weighted_cross_entropy_with_logits来处理数据不平衡。我不知道该怎么做。0 类有 10K 图像,1 类有 500 张图像。这是我的代码。

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), input_shape=(dim, dim, 3), activation='relu'),
    ....
    tf.keras.layers.Dense(2, activation='softmax')
])

model.compile(optimizer="nadam",
              loss=tf.keras.losses.CategoricalCrossentropy(),
              metrics=['accuracy'])


class_weight = {0: 1.,
                1: 20.}

model.fit(
    train_ds,
    val_ds,
    epochs=epc,
    verbose=1,
    class_weight=class_weight)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ani 5

您可以简单地包装tf.nn.weighted_cross_entropy_with_logits在自定义损失函数中。

还请记住,tf.nn.weighted_cross_entropy_with_logits需要 logits,因此您的网络必须生成它而不是概率(softmax从最后一层删除激活)

这是一个虚拟示例:

X = np.random.uniform(0,1, (10,32,32,3))
y = np.random.randint(0,2, (10,))
y = tf.keras.utils.to_categorical(y)

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), input_shape=(32, 32, 3), activation='relu'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(2) ### must be logits (remove softmax)
])

def my_loss(weight):
    def weighted_cross_entropy_with_logits(labels, logits):
        loss = tf.nn.weighted_cross_entropy_with_logits(
            labels, logits, weight
        )
        return loss
    return weighted_cross_entropy_with_logits

model.compile(optimizer="nadam",
              loss=my_loss(weight=0.8),
              metrics=['accuracy'])
model.fit(X,y, epochs=3)
Run Code Online (Sandbox Code Playgroud)

在推理时,您可以通过以下方式获得概率:

tf.nn.softmax(model.predict(X))
Run Code Online (Sandbox Code Playgroud)