Browse Source

modify api

tags/v1.2.0-rc1
Jiaqi 4 years ago
parent
commit
cc4d87cb1d
3 changed files with 45 additions and 27 deletions
  1. +8
    -11
      mindspore/nn/loss/loss.py
  2. +37
    -15
      mindspore/nn/metrics/hausdorff_distance.py
  3. +0
    -1
      mindspore/nn/metrics/mean_surface_distance.py

+ 8
- 11
mindspore/nn/loss/loss.py View File

@@ -184,9 +184,6 @@ class RMSELoss(_Loss):
.. math:: .. math::
loss = \sqrt{\frac{1}{M}\sum_{m=1}^{M}{(x_m-y_m)^2}} loss = \sqrt{\frac{1}{M}\sum_{m=1}^{M}{(x_m-y_m)^2}}


Args:
reduction (str): Type of reduction to be applied to loss. The optional values are "mean", "sum", and "none".
Default: "mean".


Inputs: Inputs:
- **logits** (Tensor) - Tensor of shape :math:`(x_1, x_2, ..., x_R)`. - **logits** (Tensor) - Tensor of shape :math:`(x_1, x_2, ..., x_R)`.
@@ -429,6 +426,10 @@ class DiceLoss(_Loss):
Outputs: Outputs:
Tensor, a tensor of shape with the per-example sampled Dice losses. Tensor, a tensor of shape with the per-example sampled Dice losses.


Raises:
ValueError: If the dimensions are different.
TypeError: If the type of inputs are not Tensor.

Supported Platforms: Supported Platforms:
``Ascend`` ``GPU`` ``CPU`` ``Ascend`` ``GPU`` ``CPU``


@@ -439,10 +440,6 @@ class DiceLoss(_Loss):
>>> output = loss(y_pred, y) >>> output = loss(y_pred, y)
>>> print(output) >>> print(output)
[0.7953220862819745] [0.7953220862819745]

Raises:
ValueError: If the dimensions are different.
TypeError: If the type of inputs are not Tensor.
""" """
def __init__(self, smooth=1e-5): def __init__(self, smooth=1e-5):
super(DiceLoss, self).__init__() super(DiceLoss, self).__init__()
@@ -494,6 +491,10 @@ class MultiClassDiceLoss(_Loss):
Outputs: Outputs:
Tensor, a tensor of shape with the per-example sampled MultiClass Dice Losses. Tensor, a tensor of shape with the per-example sampled MultiClass Dice Losses.


Raises:
ValueError: If the shapes are different.
TypeError: If the type of inputs are not Tensor.

Supported Platforms: Supported Platforms:
``Ascend`` ``GPU`` ``CPU`` ``Ascend`` ``GPU`` ``CPU``


@@ -504,10 +505,6 @@ class MultiClassDiceLoss(_Loss):
>>> output = loss(y_pred, y) >>> output = loss(y_pred, y)
>>> print(output) >>> print(output)
[0.7761003] [0.7761003]

Raises:
ValueError: If the shapes are different.
TypeError: If the type of inputs are not Tensor.
""" """
def __init__(self, weights=None, ignore_indiex=None, activation="softmax"): def __init__(self, weights=None, ignore_indiex=None, activation="softmax"):
super(MultiClassDiceLoss, self).__init__() super(MultiClassDiceLoss, self).__init__()


+ 37
- 15
mindspore/nn/metrics/hausdorff_distance.py View File

@@ -85,6 +85,16 @@ class HausdorffDistance(Metric):
crop (bool): Crop input images and only keep the foregrounds. In order to maintain two inputs' shapes, crop (bool): Crop input images and only keep the foregrounds. In order to maintain two inputs' shapes,
here the bounding box is achieved by (y_pred | y) which represents the union set of two images. here the bounding box is achieved by (y_pred | y) which represents the union set of two images.
Default: True. Default: True.

Examples:
>>> x = Tensor(np.array([[3, 0, 1], [1, 3, 0], [1, 0, 2]]))
>>> y = Tensor(np.array([[0, 2, 1], [1, 2, 1], [0, 0, 1]]))
>>> metric = nn.HausdorffDistance
>>> metric.clear()
>>> metric.update(x, y, 0)
>>> mean_average_distance = metric.eval()
>>> print(mean_average_distance)
1.4142135623730951
""" """
def __init__(self, distance_metric="euclidean", percentile=None, directed=False, crop=True): def __init__(self, distance_metric="euclidean", percentile=None, directed=False, crop=True):
super(HausdorffDistance, self).__init__() super(HausdorffDistance, self).__init__()
@@ -205,6 +215,31 @@ class HausdorffDistance(Metric):


return surface_distance return surface_distance


def _get_mask_edges_distance(self, y_pred, y):
"""
Do binary erosion and use XOR for input to get the edges. This function is helpful to further
calculate metrics such as Average Surface Distance and Hausdorff Distance.

Args:
y_pred (np.ndarray): the edge of the predictions.
y (np.ndarray): the edge of the ground truth.
"""
if self.crop:
if not np.any(y_pred | y):
res1 = np.zeros_like(y_pred)
res2 = np.zeros_like(y)
return res1, res2

y_pred, y = np.expand_dims(y_pred, 0), np.expand_dims(y, 0)
box_start, box_end = self._create_space_bounding_box(y_pred | y)
cropper = _ROISpatialData(roi_start=box_start, roi_end=box_end)
y_pred, y = np.squeeze(cropper(y_pred)), np.squeeze(cropper(y))

y_pred = morphology.binary_erosion(y_pred) ^ y_pred
y = morphology.binary_erosion(y) ^ y

return y_pred, y

def clear(self): def clear(self):
"""Clears the internal evaluation result.""" """Clears the internal evaluation result."""
self.y_pred_edges = 0 self.y_pred_edges = 0
@@ -223,6 +258,7 @@ class HausdorffDistance(Metric):
Raises: Raises:
ValueError: If the number of the inputs is not 3. ValueError: If the number of the inputs is not 3.
""" """
self._is_update = True
if len(inputs) != 3: if len(inputs) != 3:
raise ValueError('HausdorffDistance need 3 inputs (y_pred, y, label), but got {}'.format(len(inputs))) raise ValueError('HausdorffDistance need 3 inputs (y_pred, y, label), but got {}'.format(len(inputs)))
y_pred = self._convert_data(inputs[0]) y_pred = self._convert_data(inputs[0])
@@ -234,21 +270,7 @@ class HausdorffDistance(Metric):


y_pred = (y_pred == label_idx) if y_pred.dtype is not bool else y_pred y_pred = (y_pred == label_idx) if y_pred.dtype is not bool else y_pred
y = (y == label_idx) if y.dtype is not bool else y y = (y == label_idx) if y.dtype is not bool else y

res1, res2 = None, None
if self.crop:
if not np.any(y_pred | y):
res1 = np.zeros_like(y_pred)
res2 = np.zeros_like(y)

y_pred, y = np.expand_dims(y_pred, 0), np.expand_dims(y, 0)
box_start, box_end = self._create_space_bounding_box(y_pred | y)
cropper = _ROISpatialData(roi_start=box_start, roi_end=box_end)
y_pred, y = np.squeeze(cropper(y_pred)), np.squeeze(cropper(y))

self.y_pred_edges = morphology.binary_erosion(y_pred) ^ y_pred if res1 is None else res1
self.y_edges = morphology.binary_erosion(y) ^ y if res2 is None else res2
self._is_update = True
self.y_pred_edges, self.y_edges = self._get_mask_edges_distance(y_pred, y)


def eval(self): def eval(self):
""" """


+ 0
- 1
mindspore/nn/metrics/mean_surface_distance.py View File

@@ -41,7 +41,6 @@ class MeanSurfaceDistance(Metric):
>>> mean_average_distance = metric.eval() >>> mean_average_distance = metric.eval()
>>> print(mean_average_distance) >>> print(mean_average_distance)
0.8047378541243649 0.8047378541243649

""" """


def __init__(self, symmetric=False, distance_metric="euclidean"): def __init__(self, symmetric=False, distance_metric="euclidean"):


Loading…
Cancel
Save