tensorflow 中损失函数

import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import tensorflow as tf
import numpy as np
import tensorlayer as tl
from keras import backend as K


def t1():
    dropout = tf.placeholder(tf.float32)
    x = tf.Variable(tf.ones([10, 10]))
    y = tf.nn.dropout(x, dropout)
    print(x)
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    out = sess.run(y, feed_dict={dropout: 0.4})
    out = out.reshape((-1))
    count = 0
    for i in range(100):
        if out[i] > 0:
            count = count + 1
    print(count)
    print(out)


def t2():
    # our NN's logits
    logits = tf.constant([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])
    # step1:do softmax
    y = tf.nn.softmax(logits)
    # true label
    y_ = tf.constant([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
    # step2:do cross_entropy
    cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
    # do cross_entropy just one step
    cross_entropy2 = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=logits,))  # dont forget tf.reduce_sum()!!
    with tf.Session() as sess:
        softmax = sess.run(y)
        c_e = sess.run(cross_entropy)
        c_e2 = sess.run(cross_entropy2)
        print("step1:softmax result=")
        print(softmax)
        print("step2:cross_entropy result=")
        print(c_e)
        print("Function(softmax_cross_entropy_with_logits) result=")
        print(c_e2)


def t3():
    # 代码段1,手动算出代价函数
    # our NN's logits
    # logits = tf.constant(np.random.normal(loc=0.0, scale=1.0, size=(10, 10)).astype(np.float32))
    logits = tf.ones([1, 2])
    # step1:do softmax
    y = tf.nn.softmax(logits)
    # true label
    # 注意这里标签必须是浮点数
    # y_ = tf.fill([10], 0.5)
    # y_ = tf.constant(np.random.normal(loc=0.0, scale=1.0, size=(10, 10)).astype(np.float32))
    y_ = tf.constant([[1.0, 0.0]])
    # step2:do log
    tf_log = tf.log(y)
    # step3:do mult
    pixel_wise_mult = tf.multiply(y_, tf_log)
    # step4:do cross_entropy
    cross_entropy = -tf.reduce_sum(pixel_wise_mult)
    # 代码段2,使用tf.nn.softmax_cross_entropy_with_logits 算出代价函数
    cross_entropy2 = tf.reduce_sum(
        tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_))  # dont forget tf.reduce_sum()!!

    # 代码段3,使用tf.nn.sparse_softmax_cross_entropy_with_logits()算出代价函数
    # 将标签稠密化
    labels = tf.arg_max(y_, 1)
    cross_entropy3 = tf.reduce_sum(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits))

    # 代码段4,验证结果
    with tf.Session() as sess:
        result1, result2, result3, y, y1 = sess.run([cross_entropy, cross_entropy2, cross_entropy3, logits, y_])
        print("method1 : %s" % result1)
        print("method2 : %s" % result2)
        print("method3 : %s" % result3)
        print("method3 : %s" % y)
        print("method3 : %s" % y1)


def get_cost(Y_pred, Y_gt,cost_name="dice coefficient"):
    Y_gt = tf.constant(Y_gt)
    Y_pred = tf.constant(Y_pred)
    N, H, W, C = Y_gt.get_shape().as_list()
    if cost_name == "dice_coe":
        smooth = 1e-10
        pred_flat = tf.reshape(Y_pred, [-1, H * W * C])
        true_flat = tf.reshape(Y_gt, [-1, H * W * C])
        intersection = 2 * tf.reduce_sum(pred_flat * true_flat, axis=1)
        denominator = tf.reduce_sum(pred_flat, axis=1) + tf.reduce_sum(true_flat, axis=1)  # + smooth
        loss = 1 - tf.reduce_mean(intersection / denominator)
    if cost_name == "pixelwise_cross entroy":
        assert (C == 1)
        flat_logit = tf.reshape(Y_pred, [-1])
        flat_label = tf.reshape(Y_gt, [-1])
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=flat_logit, labels=flat_label))
        # loss = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(logits=flat_logit, labels=flat_label))
    return loss


def dice_coe(y_pred, y_true, cost_name="dice_coe", axis=[1, 2, 3], threshold=0.5, smooth=0):
    """
    s = 2|A∩B|/(|A|+|B|)
    d = 1 - s
    """
    if cost_name == "dice_coe":
        loss_type = "jaccard"
        intersection = tf.reduce_sum(y_pred * y_true, axis=axis)  # compute intersection A∩B
        if loss_type == "jaccard":  # default loss type, in fact, jaccard and soresen are the same thing
            A = tf.reduce_sum(y_true * y_true, axis=axis)  # number of pixels in y_true
            B = tf.reduce_sum(y_pred * y_pred, axis=axis)  # number of pixels in y_pred
        elif loss_type == "sorensen":
            A = tf.reduce_sum(y_true, axis=axis)
            B = tf.reduce_sum(y_pred, axis=axis)
        else:
            raise Exception("Unknow loss_type")
        dice = (2.0 * intersection) / (A + B + smooth)  # compute dice coefficient
        loss = 1 - tf.reduce_mean(dice)  # dice coefficient is a scalar between 0 and 1
    if cost_name == "pixel_loss1":
        # loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=y_true, labels=y_pred))
        # loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=flat_logit, labels=flat_label))
        loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=tf.reshape(y_pred, [-1]), labels=tf.reshape(y_true, [-1])))
    return loss


def iou_coe(logits, labels, threshold=0.5, axis=(1, 2, 3), smooth=1e-5):
    """Non-differentiable Intersection over Union (IoU) for comparing the
    similarity of two batch of data, usually be used for evaluating binary image segmentation.
    The coefficient between 0 to 1, and 1 means totally match.

    Parameters
    -----------
    logits : tensor
        A batch of distribution with shape: [batch_size, ....], (any dimensions).
    labels : tensor
        The labels distribution, format the same with `logits`.
    threshold : float
        The threshold value to be true.
    axis : tuple of integer
        All dimensions are reduced, default ``(1,2,3)``.
    smooth : float
        This small value will be added to the numerator and denominator, see ``dice_coe``.

    Notes
    ------
    - IoU cannot be used as training loss, people usually use dice coefficient for training, IoU and hard-dice for evaluating.

    """
    pre = tf.cast(logits > threshold, dtype=tf.float32)
    truth = tf.cast(labels > threshold, dtype=tf.float32)
    inse = tf.reduce_sum(tf.multiply(pre, truth), axis=axis)  # AND
    union = tf.reduce_sum(tf.cast(tf.add(pre, truth) >= 1, dtype=tf.float32), axis=axis)  # OR
    ## old axis=[0,1,2,3]
    # epsilon = 1e-5
    # batch_iou = inse / (union + epsilon)
    ## new haodong
    batch_iou = (inse + smooth) / (union + smooth)
    iou = tf.reduce_mean(batch_iou)
    return iou  #, pre, truth, inse, union


def binary_crossentropy(target, output, from_logits=False, smooth=1e-7):
    """Binary crossentropy between an output tensor and a target tensor.

    # Arguments
        target: A tensor with the same shape as `output`.
        output: A tensor.
        from_logits: Whether `output` is expected to be a logits tensor.
            By default, we consider that `output`
            encodes a probability distribution.

    # Returns
        A tensor.
    """
    # Note: tf.nn.sigmoid_cross_entropy_with_logits
    # expects logits, Keras expects probabilities.
    if not from_logits:
        # transform back to logits
        output = tf.clip_by_value(output, smooth, 1 - smooth)  # 把output里面的值压缩到  (smooth,1 - smooth)之间
        output = tf.log(output / (1 - output))
    return tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output))


def t5(logits, lables):
    loss = get_cost(logits, lables, cost_name="dice_coe")
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    loss = sess.run(loss)
    print("get_cost loss={}".format(loss))

    loss = dice_coe(logits, lables, axis=[1, 2, 3], cost_name="dice_coe")
    loss = sess.run(loss)
    print("dice_coe loss={}".format(loss))

    loss = 1 - iou_coe(logits, lables)
    loss = sess.run(loss)
    print("iou_coe={}".format(loss))

    loss = binary_crossentropy(logits, lables)
    loss = sess.run(loss)
    print("binary_crossentropy ={}".format(loss))


if __name__ == "__main__":
    # logits = tf.ones([4, 2, 2, 1], dtype=tf.float32)
    lables = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]).astype(np.float).reshape(-1, 4, 4, 1)
    logits = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]).astype(np.float).reshape(-1, 4, 4, 1)
    t5(logits, lables)
网上很多代码都是相互拷贝,净扯些没用的,直接上干货,具体解释别人都千篇一律,我也懒得复制粘贴,这些代码都是从Keras 和Tensorlayer中摘出来的,现成的不香么,非要自己造轮子,还都是错的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值