Skip to content

Commit dea2a0e

Browse files
committed
[Image Segmentation Function] dice and pixel-wise softmax
1 parent 1897d37 commit dea2a0e

File tree

4 files changed

+81
-35
lines changed

4 files changed

+81
-35
lines changed

docs/modules/activation.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,26 @@ For more complex activation, TensorFlow API will be required.
2929
identity
3030
ramp
3131
leaky_relu
32+
pixel_wise_softmax
3233

3334

3435
Activation functions
3536
---------------------
3637

38+
Identity
39+
^^^^^^^^^^
3740
.. autofunction:: identity
41+
42+
Ramp
43+
^^^^^
3844
.. autofunction:: ramp
45+
46+
Leaky Relu
47+
^^^^^^^^^^^
3948
.. autofunction:: leaky_relu
49+
50+
51+
Pixel-wise Softmax
52+
^^^^^^^^^^^^^^^^^^^^
53+
54+
.. autofunction:: pixel_wise_softmax

docs/modules/cost.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ to the cost function.
110110
cross_entropy
111111
binary_cross_entropy
112112
mean_squared_error
113+
dice_coe
113114
cross_entropy_seq
114115
li_regularizer
115116
lo_regularizer
@@ -123,6 +124,7 @@ Cost functions
123124
.. autofunction:: cross_entropy
124125
.. autofunction:: binary_cross_entropy
125126
.. autofunction:: mean_squared_error
127+
.. autofunction:: dice_coe
126128
.. autofunction:: cross_entropy_seq
127129

128130

tensorlayer/activation.py

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -72,38 +72,31 @@ def leaky_relu(x=None, alpha=0.1, name="LeakyReLU"):
7272
#Shortcut
7373
lrelu = leaky_relu
7474

75-
#
76-
# ## Alternatively we can use tl.layers.PReluLayer()
77-
# def prelu(x, channel_shared=False, W_init=tf.constant_initializer(value=0.0), W_init_args={}, restore=True, name="PReLU"):
78-
# """ Parametric Rectified Linear Unit.
79-
#
80-
# Parameters
81-
# ----------
82-
# x : A `Tensor` with type `float`, `double`, `int32`, `int64`, `uint8`,
83-
# `int16`, or `int8`.
84-
# channel_shared : `bool`. Single weight is shared by all channels
85-
# W_init: weights initializer, default zero constant.
86-
# The initializer for initializing the alphas.
87-
# restore : `bool`. Restore or not alphas
88-
# name : A name for this activation op (optional).
89-
#
90-
# Returns
91-
# -------
92-
# A `Tensor` with the same type as `x`.
93-
#
94-
# References
95-
# -----------
96-
# - `Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification <http://arxiv.org/pdf/1502.01852v1.pdf>`_
97-
# """
98-
# print(' prelu: untested !!!')
99-
# if channel_shared:
100-
# w_shape = (1,)
101-
# else:
102-
# w_shape = int(x._shape[-1:])
103-
#
104-
# with tf.name_scope(name) as scope:
105-
# W_init = initializations.get(weights_init)()
106-
# alphas = tf.get_variable(name='alphas', shape=w_shape, initializer=W_init, **W_init_args )
107-
# x = tf.nn.relu(x) + tf.mul(alphas, (x - tf.abs(x))) * 0.5
108-
#
109-
# return x
75+
def pixel_wise_softmax(output, name='pixel_wise_softmax'):
76+
"""Return the softmax outputs of images, every pixels have multiple label, the sum of a pixel is 1.
77+
Usually be used for image segmentation.
78+
79+
Parameters
80+
------------
81+
output : tensor
82+
- For 2d image, 4D tensor [batch_size, height, weight, channel], channel >= 2.
83+
- For 3d image, 5D tensor [batch_size, depth, height, weight, channel], channel >= 2.
84+
85+
Examples
86+
---------
87+
>>> outputs = pixel_wise_softmax(network.outputs)
88+
>>> dice_loss = 1 - dice_coe(outputs, y_, epsilon=1e-5)
89+
90+
References
91+
-----------
92+
- `tf.reverse <https://www.tensorflow.org/versions/master/api_docs/python/array_ops.html#reverse>`_
93+
"""
94+
with tf.name_scope(name) as scope:
95+
exp_map = tf.exp(output)
96+
if output.get_shape().ndims == 4: # 2d image
97+
evidence = tf.add(exp_map, tf.reverse(exp_map, [False, False, False, True]))
98+
elif output.get_shape().ndims == 5: # 3d image
99+
evidence = tf.add(exp_map, tf.reverse(exp_map, [False, False, False, False, True]))
100+
else:
101+
raise Exception("output parameters should be 2d or 3d image, not %s" % str(output._shape))
102+
return tf.div(exp_map, evidence)

tensorlayer/cost.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,42 @@ def mean_squared_error(output, target):
7474
mse = tf.reduce_sum(tf.squared_difference(output, target), reduction_indices = 1)
7575
return tf.reduce_mean(mse)
7676

77+
78+
79+
def dice_coe(output, target, epsilon=1e-10):
80+
"""Sørensen–Dice coefficient for comparing the similarity of two distributions,
81+
usually be used for binary image segmentation i.e. labels are binary.
82+
The coefficient = [0, 1], 1 if totally match.
83+
84+
Parameters
85+
-----------
86+
output : tensor
87+
A distribution with shape: [batch_size, ....], (any dimensions).
88+
target : tensor
89+
A distribution with shape: [batch_size, ....], (any dimensions).
90+
91+
Examples
92+
---------
93+
>>> outputs = pixel_wise_softmax(network.outputs)
94+
>>> dice_loss = 1 - dice_coe(outputs, y_, epsilon=1e-5)
95+
96+
References
97+
-----------
98+
- `wiki-dice <https://en.wikipedia.org/wiki/Sørensen–Dice_coefficient>`_
99+
"""
100+
# inse = tf.reduce_sum( tf.mul(output, target) )
101+
# l = tf.reduce_sum( tf.mul(output, output) )
102+
# r = tf.reduce_sum( tf.mul(target, target) )
103+
inse = tf.reduce_sum( output * target )
104+
l = tf.reduce_sum( output * output )
105+
r = tf.reduce_sum( target * target )
106+
dice = 2 * (inse) / (l + r)
107+
if epsilon == 0:
108+
return dice
109+
else:
110+
return tf.clip_by_value(dice, 0, 1.0-epsilon)
111+
112+
77113
def cross_entropy_seq(logits, target_seqs, batch_size=1, num_steps=None):
78114
"""Returns the expression of cross-entropy of two sequences, implement
79115
softmax internally. Normally be used for Fixed Length RNN outputs.

0 commit comments

Comments
 (0)