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中摘出来的,现成的不香么,非要自己造轮子,还都是错的
tensorflow 中损失函数
最新推荐文章于 2022-02-09 12:00:30 发布