【问题标题】:Custom loss function for out of distribution detection using CNN in Tensorflow 2.0+在 Tensorflow 2.0+ 中使用 CNN 进行分布外检测的自定义损失函数
【发布时间】:2022-08-19 12:26:04
【问题描述】:

我的问题是参考论文Learning Confidence for Out-of-Distribution Detection in Neural Networks

我需要帮助来根据论文在 tensorflow 2.0+ 中创建自定义损失函数,以便从 CNN 对分布内(如果图像属于火车类别)图像进行自信的预测,而对分布外的图像进行低预测(任何随机图像)图像。该论文建议在任何传统的前馈架构中添加一个置信度估计分支,与原始类预测分支并行(参见下图)

为了定义损失函数,softmax 预测概率通过在原始预测 (pi) 和目标概率分布 y 之间进行插值来调整,其中插值的程度由网络的置信度 (c) 表示:

pi\'= c · pi + (1 − c)yi 最终损失为:

我需要帮助来实现这一点以及 Tensorflow 2.0+ 中的损失函数,据我所知,以下是我能想到的:

import tensorflow.keras.backend as k
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.applications import ResNet50

#Defining custom loss function
def custom_loss(c):
  def loss(y_true, y_pred):
    interpolated_p = c*y_pred+ (1-c)*y_true
    return -k.reduce_sum((k.log(interpolated_p) * y_true), axis=-1) - k.log(c)
  return loss

#Defining model strcuture using resnet50
basemodel = ResNet50(weights = \"imagenet\",include_top = False)
headmodel = basemodel.output
headmodel = layers.AveragePooling2D(pool_size = (7,7))(headmodel)

#Add a sigmoid layer to the pooling output
conf_branch = layers.Dense(1,activation = \"sigmoid\",name = \"confidence_branch\")(headmodel)

# Add a softmax layer after the pooling output 
softmax_branch = layers.Dense(10,activation = \"softmax\",name = \"softmax_branch\")(headmodel)

# Instantiate an end-to-end model predicting both confidence and class prediction
model = keras.Model(
    inputs=basemodel.input,
    outputs=[softmax_branch, conf_branch],
)

model.compile(loss=custom_loss(c=conf_branch.output), optimizer=\'rmsprop\')

感谢您对此的任何帮助!谢谢 !

  • 你能帮助我们澄清你在找什么吗?看来你已经拥有了你需要的一切。您是否正在寻找预测信心的功能?你不知道如何实现一些东西?此外,如果你想要代码,展示你的代码会很有帮助,对于这个问题,展示你当前的损失函数会很有用。
  • @Sorin:我已经更新了问题以及代码,看看。谢谢 !

标签: python tensorflow keras conv-neural-network


【解决方案1】:

以下是我为 keras 实现编写的代码:

num_classes = 10
basemodel = ResNet50(weights = "imagenet",include_top = False)
headmodel = basemodel.output
headmodel = layers.AveragePooling2D(pool_size = (7,7))(headmodel)
conf_branch = layers.Dense(1,activation = "sigmoid",name="confidence_branch")(headmodel)
softmax_branch = layers.Dense(num_classes,activation = "softmax",name = "softmax_branch")(headmodel)
output = Concatenate(axis=-1)([softmax_branch , conf_branch])

def custom_loss(y_true, y_pred, budget=0.3):
    with tf.compat.v1.variable_scope("LAMBDA", reuse=tf.compat.v1.AUTO_REUSE):
        LAMBDA = tf.compat.v1.get_variable("LAMBDA", dtype=tf.float32, initializer=tf.constant(0.1))
    pred_original = y_pred[:, 0:num_classes]
    confidence = y_pred[:, num_classes]
    eps = 1e-12
    pred_original = tf.clip_by_value(pred_original, 0. + eps, 1. - eps)
    confidence = tf.clip_by_value(confidence, 0. + eps, 1. - eps)
    b = np.random.uniform(size=y_true.shape[0], low=0.0, high=1.0)
    conf = confidence * b + (1 - b)
    conf = tf.expand_dims(conf, axis=-1)
    pred_new = pred_original * conf + y_true * (1 - conf)
    xentropy_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.math.log(pred_new), axis=-1))
    confidence_loss = tf.reduce_mean(-tf.math.log(confidence))
    total_loss = xentropy_loss + LAMBDA * confidence_loss

    def true_func():
        return LAMBDA / 1.01

    def false_func():
        return LAMBDA / 0.99

    LAMBDA_NEW = tf.cond(budget > confidence_loss, true_func, false_func)
    LAMBDA.assign(LAMBDA_NEW)
    # tf.print(LAMBDA)
    return total_loss

def accuracy(y_true, y_pred):
    y_pred = y_pred[:, :num_classes]
    correct_pred = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_true, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    return accuracy

model = Model(inputs=basemodel.input, outputs=output)
optimizer = keras.optimizers.Adam(learning_rate=0.001)
model.compile(loss=custom_loss, optimizer=optimizer, metrics=[accuracy])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2018-10-28
    • 2017-12-29
    • 2021-01-21
    • 2020-01-21
    • 2021-04-05
    • 2021-03-11
    • 2023-03-16
    相关资源
    最近更新 更多