From b3b5de0f1392eae262325301049e96492a098572 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 4 Oct 2018 17:03:03 -0700 Subject: [PATCH 01/35] COsine Embedding Loss function added --- python/mxnet/gluon/loss.py | 51 +++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 2be43981a64c..e31e8e4bdb2a 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -23,7 +23,7 @@ 'SigmoidBinaryCrossEntropyLoss', 'SigmoidBCELoss', 'SoftmaxCrossEntropyLoss', 'SoftmaxCELoss', 'KLDivLoss', 'CTCLoss', 'HuberLoss', 'HingeLoss', - 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss'] + 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss', 'CosineEmbeddingLoss'] from .. import ndarray from ..base import numeric_types @@ -706,3 +706,52 @@ def hybrid_forward(self, F, pred, positive, negative): axis=self._batch_axis, exclude=True) loss = F.relu(loss + self._margin) return _apply_weighting(F, loss, self._weight, None) + +class CosineEmbeddingLoss(Loss): + r"""For a target label 1 or -1, vectors target and pred, the function computes the cosine distance + between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. + + + `pred`, `target` can have arbitrary shape as long as they have the same number of elements. + + Parameters + ---------- + weight : float or None + Global scalar weight for loss. + batch_axis : int, default 0 + The axis that represents mini-batch. + margin : float + Margin of separation between correct and incorrect pair. + + + Inputs: + ------ + - **pred**: prediction tensor with arbitrary shape + - **target**: target tensor with same shape as pred. + - **sample_weight**: element-wise weighting tensor. Must be broadcastable + to the same shape as pred. For example, if pred has shape (64, 10) + and you want to weigh each sample in the batch separately, + sample_weight should have shape (64, 1). + + Outputs: + -------- + - **loss**: Average loss (shape=(1,1)) of the loss tensor with shape (batch_size,). + """ + def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): + super(CosineEmbeddingLoss, self).__init__(weight, batch_axis, **kwargs) + self._margin = margin + + def hybrid_forward(self, F, pred, target, label): + pred = _reshape_like(F, pred, target) + cos_sim = self.cosine_similarity(F, pred, target) + y_1 = label == 1 + y_minus_1 = label == -1 + cos_sim_a = cos_sim * y_1 + cos_sim_b = y_minus_1 * (1 - cos_sim - self._margin) + return cos_sim_a + cos_sim_b + + def cosine_similarity(self, F, F1, F2, axis=-1): + F1_norm = F1.norm(axis=axis).reshape(-1, 1) + F2_norm = F2.norm(axis=axis).reshape(-1, 1) + F1_dot_F2 = F.sum(F1*F2, axis=axis).reshape(-1, 1) + return (F1_dot_F2 / F.broadcast_maximum(F1_norm * F2_norm, F.array([1e-12]))) From eb9b9b48b73d373ab4c96a114f75a88bdcfa6d2a Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 4 Oct 2018 22:49:40 -0700 Subject: [PATCH 02/35] Added unit tests for Cosine Embedding Loss Function --- python/mxnet/gluon/loss.py | 5 +++-- tests/python/unittest/test_loss.py | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index e31e8e4bdb2a..4fa0ffb6b4fe 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -732,6 +732,7 @@ class CosineEmbeddingLoss(Loss): to the same shape as pred. For example, if pred has shape (64, 10) and you want to weigh each sample in the batch separately, sample_weight should have shape (64, 1). + - label: A 1-D tensor indicating for each pair input and pred, target label is 1 or -1 Outputs: -------- @@ -746,8 +747,8 @@ def hybrid_forward(self, F, pred, target, label): cos_sim = self.cosine_similarity(F, pred, target) y_1 = label == 1 y_minus_1 = label == -1 - cos_sim_a = cos_sim * y_1 - cos_sim_b = y_minus_1 * (1 - cos_sim - self._margin) + cos_sim_a = (1 - cos_sim) * y_1 + cos_sim_b = F.broadcast_maximum(F.array([0]), y_minus_1 * (cos_sim - self._margin), axis=1) return cos_sim_a + cos_sim_b def cosine_similarity(self, F, F1, F2, axis=-1): diff --git a/tests/python/unittest/test_loss.py b/tests/python/unittest/test_loss.py index a931a300636b..ab877ed1abdb 100644 --- a/tests/python/unittest/test_loss.py +++ b/tests/python/unittest/test_loss.py @@ -348,6 +348,22 @@ def test_triplet_loss(): optimizer='adam') assert mod.score(data_iter, eval_metric=mx.metric.Loss())[0][1] < 0.05 +@with_seed() +def test_cosine_loss(): + #For similarity check + label = mx.nd.array([1]) + pred = mx.nd.array([[1, 1, 1, 1], + [1, 2, 3, 4]]) + target = mx.nd.array([[1, 1, 1, 1], + [1, 2, 3, 4]]) + Loss = gluon.loss.CosineEmbeddingLoss() + loss = Loss(pred, target, label) + + #computing numpy way + numerator = mx.nd.sum(pred * target, keepdims=True, axis=1) + denominator = mx.nd.sqrt(mx.nd.sum(pred**2, axis=1, keepdims=True)) \ + * mx.nd.sqrt(mx.nd.sum(target**2, axis=1, keepdims=True)) + assert_almost_equal(loss.asnumpy(), (1-numerator/denominator).asnumpy()) if __name__ == '__main__': import nose From 7fdd85d340374dc4a7321aa6230edb43120634bc Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Sun, 7 Oct 2018 15:49:43 -0700 Subject: [PATCH 03/35] Added Latex code for formula for cosine embedding loss --- python/mxnet/gluon/loss.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 4fa0ffb6b4fe..aac72f16153f 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -710,7 +710,31 @@ def hybrid_forward(self, F, pred, positive, negative): class CosineEmbeddingLoss(Loss): r"""For a target label 1 or -1, vectors target and pred, the function computes the cosine distance between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. - + .. math:: + Cosine\_loss = \begin{gather*} + \begin{cases} + 1 - cos\_sim(pred, target) & \text{if } label = 1\\ + cos\_sim(pred, target) & \text{if } label = -1 + \end{cases} + \end{gather*} + If + \begin{equation} + pred = p_1x + p_2y + p_3z + \end{equation} + and + \begin{equation} + target = t_1x + t_2y + t_3z + \end{equation}\\ + Cosine Similarity:\\ + \begin{equation} + cos\_sim = \frac{pred.target} + {||pred||.||target||} + \end{equation} + + \begin{equation} + cos\_sim(pred, target) = \frac{p_1.t_1 + p_2.t_2 + p_3.t_3} + {\sqrt{p_1^2 + p_2^2 + p_3^2}.\sqrt{t_1^2 + t_2^2 + t_3^2}} + \end{equation} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From 013a604f8f7f00177420a2fb10388e78b643806b Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 11:49:25 -0700 Subject: [PATCH 04/35] Fixing document rendering --- python/mxnet/gluon/loss.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index aac72f16153f..f5c604c86247 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -710,7 +710,9 @@ def hybrid_forward(self, F, pred, positive, negative): class CosineEmbeddingLoss(Loss): r"""For a target label 1 or -1, vectors target and pred, the function computes the cosine distance between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. + .. math:: + \usepackage{amsmath} Cosine\_loss = \begin{gather*} \begin{cases} 1 - cos\_sim(pred, target) & \text{if } label = 1\\ From aac12ad49c191a2c13daff245a7966b7d69b5241 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 13:38:19 -0700 Subject: [PATCH 05/35] Fixing documentation issue --- python/mxnet/gluon/loss.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index f5c604c86247..71b760767689 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -712,8 +712,7 @@ class CosineEmbeddingLoss(Loss): between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. .. math:: - \usepackage{amsmath} - Cosine\_loss = \begin{gather*} + L = \begin{gather*} \begin{cases} 1 - cos\_sim(pred, target) & \text{if } label = 1\\ cos\_sim(pred, target) & \text{if } label = -1 @@ -726,8 +725,8 @@ class CosineEmbeddingLoss(Loss): and \begin{equation} target = t_1x + t_2y + t_3z - \end{equation}\\ - Cosine Similarity:\\ + \end{equation} + Cosine Similarity: \begin{equation} cos\_sim = \frac{pred.target} {||pred||.||target||} @@ -751,17 +750,15 @@ class CosineEmbeddingLoss(Loss): Inputs: - ------ - - **pred**: prediction tensor with arbitrary shape + - **pred**: prediction tensor with arbitrary shape - **target**: target tensor with same shape as pred. - **sample_weight**: element-wise weighting tensor. Must be broadcastable to the same shape as pred. For example, if pred has shape (64, 10) and you want to weigh each sample in the batch separately, sample_weight should have shape (64, 1). - - label: A 1-D tensor indicating for each pair input and pred, target label is 1 or -1 + - **label**: A 1-D tensor indicating for each pair input and pred, target label is 1 or -1 Outputs: - -------- - **loss**: Average loss (shape=(1,1)) of the loss tensor with shape (batch_size,). """ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): @@ -778,6 +775,7 @@ def hybrid_forward(self, F, pred, target, label): return cos_sim_a + cos_sim_b def cosine_similarity(self, F, F1, F2, axis=-1): + # Calculates the cosine similarity between 2 vectors F1_norm = F1.norm(axis=axis).reshape(-1, 1) F2_norm = F2.norm(axis=axis).reshape(-1, 1) F1_dot_F2 = F.sum(F1*F2, axis=axis).reshape(-1, 1) From 1c979242ef53e917fe148a9307ce40d65932deed Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 13:51:04 -0700 Subject: [PATCH 06/35] PR Comments addressed for using F (NDArray or Symbol) to calculate norm, renaming parameters --- python/mxnet/gluon/loss.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 71b760767689..07bb1a817f10 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -774,9 +774,9 @@ def hybrid_forward(self, F, pred, target, label): cos_sim_b = F.broadcast_maximum(F.array([0]), y_minus_1 * (cos_sim - self._margin), axis=1) return cos_sim_a + cos_sim_b - def cosine_similarity(self, F, F1, F2, axis=-1): + def cosine_similarity(self, F, x, y, axis=-1): # Calculates the cosine similarity between 2 vectors - F1_norm = F1.norm(axis=axis).reshape(-1, 1) - F2_norm = F2.norm(axis=axis).reshape(-1, 1) - F1_dot_F2 = F.sum(F1*F2, axis=axis).reshape(-1, 1) - return (F1_dot_F2 / F.broadcast_maximum(F1_norm * F2_norm, F.array([1e-12]))) + x_norm = F.norm(x, axis=axis).reshape(-1, 1) + y_norm = F.norm(y, axis=axis).reshape(-1, 1) + x_dot_y = F.sum(x*y, axis=axis).reshape(-1, 1) + return (x_dot_y / F.broadcast_maximum(x_norm * y_norm, F.array([1e-12]))) From 976698312746184610b22c390217dec70920f43c Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 14:44:07 -0700 Subject: [PATCH 07/35] Markdown file updated. Added entry for CosineEmbeddingLoss --- docs/api/python/gluon/loss.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/python/gluon/loss.md b/docs/api/python/gluon/loss.md index 1aeb340a3db6..4e1790dab43c 100644 --- a/docs/api/python/gluon/loss.md +++ b/docs/api/python/gluon/loss.md @@ -25,6 +25,7 @@ This package includes several commonly used loss functions in neural networks. LogisticLoss TripletLoss CTCLoss + CosineEmbeddingLoss ``` From f05eb7bcababb684332abf06fbc2508d8dc387f3 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 21:27:46 -0700 Subject: [PATCH 08/35] Added a line after .. math:: to fix documentation --- python/mxnet/gluon/loss.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 07bb1a817f10..cda80e7443e1 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -712,6 +712,7 @@ class CosineEmbeddingLoss(Loss): between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. .. math:: + L = \begin{gather*} \begin{cases} 1 - cos\_sim(pred, target) & \text{if } label = 1\\ From c02e1118f048fff19a63a161e8c22a0c04022159 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 8 Oct 2018 21:35:12 -0700 Subject: [PATCH 09/35] Documentation check - pylint fix --- python/mxnet/gluon/loss.py | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index cda80e7443e1..610755e0c6e1 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -712,31 +712,18 @@ class CosineEmbeddingLoss(Loss): between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. .. math:: - - L = \begin{gather*} - \begin{cases} - 1 - cos\_sim(pred, target) & \text{if } label = 1\\ - cos\_sim(pred, target) & \text{if } label = -1 - \end{cases} - \end{gather*} - If - \begin{equation} - pred = p_1x + p_2y + p_3z - \end{equation} - and - \begin{equation} - target = t_1x + t_2y + t_3z - \end{equation} - Cosine Similarity: - \begin{equation} - cos\_sim = \frac{pred.target} - {||pred||.||target||} - \end{equation} - - \begin{equation} - cos\_sim(pred, target) = \frac{p_1.t_1 + p_2.t_2 + p_3.t_3} - {\sqrt{p_1^2 + p_2^2 + p_3^2}.\sqrt{t_1^2 + t_2^2 + t_3^2}} - \end{equation} + L = \[\begin{gathered} + \begin{cases} + 1 - cos\_sim(pred, target) & \text{if } label = 1\\ + cos\_sim(pred, target) & \text{if } label = -1 + \end{cases} + \end{gathered}\] If +\[pred = p_1x + p_2y + p_3z\] and \[target = t_1x + t_2y + t_3z\] Cosine +Similarity: \[cos\_sim = \frac{pred.target} + {||pred||.||target||}\] + +\[cos\_sim(pred, target) = \frac{p_1.t_1 + p_2.t_2 + p_3.t_3} + {\sqrt{p_1^2 + p_2^2 + p_3^2}.\sqrt{t_1^2 + t_2^2 + t_3^2}}\] `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From c10f1efb8f299471be64ce82c21fa361f31f479e Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 07:42:54 -0700 Subject: [PATCH 10/35] Formula update --- python/mxnet/gluon/loss.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 610755e0c6e1..a9d2237c3119 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -712,18 +712,12 @@ class CosineEmbeddingLoss(Loss): between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. .. math:: - L = \[\begin{gathered} - \begin{cases} - 1 - cos\_sim(pred, target) & \text{if } label = 1\\ - cos\_sim(pred, target) & \text{if } label = -1 - \end{cases} - \end{gathered}\] If -\[pred = p_1x + p_2y + p_3z\] and \[target = t_1x + t_2y + t_3z\] Cosine -Similarity: \[cos\_sim = \frac{pred.target} - {||pred||.||target||}\] - -\[cos\_sim(pred, target) = \frac{p_1.t_1 + p_2.t_2 + p_3.t_3} - {\sqrt{p_1^2 + p_2^2 + p_3^2}.\sqrt{t_1^2 + t_2^2 + t_3^2}}\] + L = \begin{gather*} + \begin{cases} +         1 - cos\_sim(pred, target) & \text{if } label = 1\\ +         cos\_sim(pred, target)   & \text{if } label = -1 +     \end{cases} + \end{gather*} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From 95dd2a7a7b648e32501a8b81b5dfb79e6abc6b01 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 10:08:57 -0700 Subject: [PATCH 11/35] Making the formula simpler for correct rendering incrementally - Update 1 --- python/mxnet/gluon/loss.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index a9d2237c3119..38ad9f68210c 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -712,12 +712,10 @@ class CosineEmbeddingLoss(Loss): between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. .. math:: - L = \begin{gather*} - \begin{cases} -         1 - cos\_sim(pred, target) & \text{if } label = 1\\ -         cos\_sim(pred, target)   & \text{if } label = -1 + + L = \begin{cases} (1 - {cos_sim(pred, target)}) & {if } label = 1\\ + ({cos_sim(pred, target)}) & {if } label = -1      \end{cases} - \end{gather*} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From 01607b471c098c897cac2306205182882c3c72be Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 10:13:27 -0700 Subject: [PATCH 12/35] Making the formula simpler for correct rendering incrementally - Update 2 --- python/mxnet/gluon/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 38ad9f68210c..594e76c90f00 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -713,8 +713,8 @@ class CosineEmbeddingLoss(Loss): .. math:: - L = \begin{cases} (1 - {cos_sim(pred, target)}) & {if } label = 1\\ - ({cos_sim(pred, target)}) & {if } label = -1 + L = \sum_i \begin{cases} (1 - {cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = 1\\ + ({cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = -1      \end{cases} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From c8bca0b5fdaf3aee99fcda485f2c8d864314afd0 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 10:18:30 -0700 Subject: [PATCH 13/35] Making the formula simpler for correct rendering incrementally - Update 3 --- python/mxnet/gluon/loss.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 594e76c90f00..530983fdbaf2 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -714,8 +714,7 @@ class CosineEmbeddingLoss(Loss): .. math:: L = \sum_i \begin{cases} (1 - {cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = 1\\ - ({cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = -1 -     \end{cases} + ({cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = -1 \end{cases} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From 5194cd8d8777d20dd4ad90f5bf4ee2142c6b64e4 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 12:58:20 -0700 Subject: [PATCH 14/35] Making the formula simpler for correct rendering incrementally - Update 4 --- python/mxnet/gluon/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 530983fdbaf2..e2829520d5fc 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -713,8 +713,8 @@ class CosineEmbeddingLoss(Loss): .. math:: - L = \sum_i \begin{cases} (1 - {cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = 1\\ - ({cos_sim({pred}_i, {target}_i)}) & {if } {label}_i = -1 \end{cases} + L = \sum_i \begin{cases} 1 - {cos_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = 1\\ + {cos_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = -1 \end{cases} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From c01f8cbf5bad193e5bdab645f213de3a1c5e8390 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 13:24:11 -0700 Subject: [PATCH 15/35] Making the formula simpler for correct rendering incrementally - Update 5 --- python/mxnet/gluon/loss.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index e2829520d5fc..5fdc9676c329 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -713,8 +713,9 @@ class CosineEmbeddingLoss(Loss): .. math:: - L = \sum_i \begin{cases} 1 - {cos_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = 1\\ - {cos_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = -1 \end{cases} + L = \sum_i \begin{cases} 1 - {cos\_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = 1\\ + {cos\_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = -1 \end{cases} + cos\_sim = \frac{pred.target}{||pred||.||target||} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. From 4b3fe8153f51cf4c4df70a602c6d45db2e67b537 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 15:22:06 -0700 Subject: [PATCH 16/35] Trigger CI From 78bd7257b8a14cd313f986b22dd3bea234564f0a Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Tue, 9 Oct 2018 16:24:10 -0700 Subject: [PATCH 17/35] making the utility function cosine similarity internal --- python/mxnet/gluon/loss.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 5fdc9676c329..dacec5233879 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -739,7 +739,7 @@ class CosineEmbeddingLoss(Loss): - **label**: A 1-D tensor indicating for each pair input and pred, target label is 1 or -1 Outputs: - - **loss**: Average loss (shape=(1,1)) of the loss tensor with shape (batch_size,). + - **loss**: The loss tensor with shape (batch_size,). """ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): super(CosineEmbeddingLoss, self).__init__(weight, batch_axis, **kwargs) @@ -747,14 +747,14 @@ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): def hybrid_forward(self, F, pred, target, label): pred = _reshape_like(F, pred, target) - cos_sim = self.cosine_similarity(F, pred, target) + cos_sim = self._cosine_similarity(F, pred, target) y_1 = label == 1 y_minus_1 = label == -1 cos_sim_a = (1 - cos_sim) * y_1 cos_sim_b = F.broadcast_maximum(F.array([0]), y_minus_1 * (cos_sim - self._margin), axis=1) return cos_sim_a + cos_sim_b - def cosine_similarity(self, F, x, y, axis=-1): + def _cosine_similarity(self, F, x, y, axis=-1): # Calculates the cosine similarity between 2 vectors x_norm = F.norm(x, axis=axis).reshape(-1, 1) y_norm = F.norm(y, axis=axis).reshape(-1, 1) From 3b3e117c793c418f3c014cb83e6289ca5eaf41bd Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Wed, 10 Oct 2018 10:20:39 -0700 Subject: [PATCH 18/35] Added a test case for label = -1, for dissimilar vectors --- tests/python/unittest/test_loss.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/python/unittest/test_loss.py b/tests/python/unittest/test_loss.py index ab877ed1abdb..a104b62683a8 100644 --- a/tests/python/unittest/test_loss.py +++ b/tests/python/unittest/test_loss.py @@ -365,6 +365,18 @@ def test_cosine_loss(): * mx.nd.sqrt(mx.nd.sum(target**2, axis=1, keepdims=True)) assert_almost_equal(loss.asnumpy(), (1-numerator/denominator).asnumpy()) + # Label == -1 + pred = mx.nd.array([[1, 1, 1, 1], + [1, 2, 3, 4]]) + target = mx.nd.array([[2, 2, 2, 2], + [5, 6, 7, 8]]) + label = mx.nd.array([-1]) + loss = Loss(pred, target, label) + #computing numpy way + numerator = mx.nd.sum(pred * target, keepdims=True, axis=1) + denominator = mx.nd.sqrt(mx.nd.sum(pred**2, axis=1, keepdims=True)) \ + * mx.nd.sqrt(mx.nd.sum(target**2, axis=1, keepdims=True)) + assert_almost_equal(loss.asnumpy(), (numerator/denominator).asnumpy()) if __name__ == '__main__': import nose nose.runmodule() From 2df695356e09853470b1a167d9712e67fb13c676 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Wed, 10 Oct 2018 13:16:14 -0700 Subject: [PATCH 19/35] Refactored names of parameters to the loss functions and updated the formula in docstring --- python/mxnet/gluon/loss.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index dacec5233879..36c2c8ec0667 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -713,9 +713,9 @@ class CosineEmbeddingLoss(Loss): .. math:: - L = \sum_i \begin{cases} 1 - {cos\_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = 1\\ - {cos\_sim({pred}_i, {target}_i)} & \text{ if } {label}_i = -1 \end{cases} - cos\_sim = \frac{pred.target}{||pred||.||target||} + L = \sum_i \begin{cases} 1 - {cos\_sim({input1}_i, {input2}_i)} & \text{ if } {label}_i = 1\\ + {cos\_sim({input1}_i, {input2}_i)} & \text{ if } {label}_i = -1 \end{cases}\\ + cos\_sim(input1, input2) = \frac{{input1}_i.{input2}_i}{||{input1}_i||.||{input2}_i||} `pred`, `target` can have arbitrary shape as long as they have the same number of elements. @@ -730,13 +730,14 @@ class CosineEmbeddingLoss(Loss): Inputs: - - **pred**: prediction tensor with arbitrary shape - - **target**: target tensor with same shape as pred. + - **input1**: a tensor with arbitrary shape + - **input2**: another tensor with same shape as pred to which input1 is + compared for similarity and loss calculation - **sample_weight**: element-wise weighting tensor. Must be broadcastable - to the same shape as pred. For example, if pred has shape (64, 10) + to the same shape as input1. For example, if input1 has shape (64, 10) and you want to weigh each sample in the batch separately, sample_weight should have shape (64, 1). - - **label**: A 1-D tensor indicating for each pair input and pred, target label is 1 or -1 + - **label**: A 1-D tensor indicating for each pair input1 and input2, target label is 1 or -1 Outputs: - **loss**: The loss tensor with shape (batch_size,). @@ -745,9 +746,9 @@ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): super(CosineEmbeddingLoss, self).__init__(weight, batch_axis, **kwargs) self._margin = margin - def hybrid_forward(self, F, pred, target, label): - pred = _reshape_like(F, pred, target) - cos_sim = self._cosine_similarity(F, pred, target) + def hybrid_forward(self, F, input1, input2, label): + input1 = _reshape_like(F, input1, input2) + cos_sim = self._cosine_similarity(F, input1, input2) y_1 = label == 1 y_minus_1 = label == -1 cos_sim_a = (1 - cos_sim) * y_1 From 5c642cb88b1c6f7cbff005cf881b8f1e1fbf86df Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Wed, 10 Oct 2018 13:48:24 -0700 Subject: [PATCH 20/35] PR comments addressed changes in documentation --- python/mxnet/gluon/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 36c2c8ec0667..396da7a5e419 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -717,7 +717,7 @@ class CosineEmbeddingLoss(Loss): {cos\_sim({input1}_i, {input2}_i)} & \text{ if } {label}_i = -1 \end{cases}\\ cos\_sim(input1, input2) = \frac{{input1}_i.{input2}_i}{||{input1}_i||.||{input2}_i||} - `pred`, `target` can have arbitrary shape as long as they have the same number of elements. + `input1`, `input2` can have arbitrary shape as long as they have the same number of elements. Parameters ---------- From 4be510437033742624cb40da7db25a54c21275d0 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 11 Oct 2018 11:29:46 -0700 Subject: [PATCH 21/35] Added random input vectors and labelled tests --- python/mxnet/gluon/loss.py | 1 + tests/python/unittest/test_loss.py | 41 +++++++++++------------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 396da7a5e419..0f8b8d43a96e 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -748,6 +748,7 @@ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): def hybrid_forward(self, F, input1, input2, label): input1 = _reshape_like(F, input1, input2) + label = label.reshape((-1,1)) cos_sim = self._cosine_similarity(F, input1, input2) y_1 = label == 1 y_minus_1 = label == -1 diff --git a/tests/python/unittest/test_loss.py b/tests/python/unittest/test_loss.py index a104b62683a8..eba3a55b37cc 100644 --- a/tests/python/unittest/test_loss.py +++ b/tests/python/unittest/test_loss.py @@ -350,33 +350,22 @@ def test_triplet_loss(): @with_seed() def test_cosine_loss(): - #For similarity check - label = mx.nd.array([1]) - pred = mx.nd.array([[1, 1, 1, 1], - [1, 2, 3, 4]]) - target = mx.nd.array([[1, 1, 1, 1], - [1, 2, 3, 4]]) + #Generating samples + input1 = mx.nd.random.randn(3, 2) + input2 = mx.nd.random.randn(3, 2) + label = mx.nd.sign(mx.nd.random.randn(input1.shape[0])) + #Calculating loss from cosine embedding loss function in Gluon Loss = gluon.loss.CosineEmbeddingLoss() - loss = Loss(pred, target, label) - - #computing numpy way - numerator = mx.nd.sum(pred * target, keepdims=True, axis=1) - denominator = mx.nd.sqrt(mx.nd.sum(pred**2, axis=1, keepdims=True)) \ - * mx.nd.sqrt(mx.nd.sum(target**2, axis=1, keepdims=True)) - assert_almost_equal(loss.asnumpy(), (1-numerator/denominator).asnumpy()) - - # Label == -1 - pred = mx.nd.array([[1, 1, 1, 1], - [1, 2, 3, 4]]) - target = mx.nd.array([[2, 2, 2, 2], - [5, 6, 7, 8]]) - label = mx.nd.array([-1]) - loss = Loss(pred, target, label) - #computing numpy way - numerator = mx.nd.sum(pred * target, keepdims=True, axis=1) - denominator = mx.nd.sqrt(mx.nd.sum(pred**2, axis=1, keepdims=True)) \ - * mx.nd.sqrt(mx.nd.sum(target**2, axis=1, keepdims=True)) - assert_almost_equal(loss.asnumpy(), (numerator/denominator).asnumpy()) + loss = Loss(input1, input2, label) + + # Calculating the loss Numpy way + numerator = mx.nd.sum(input1 * input2, keepdims=True, axis=1) + denominator = mx.nd.sqrt(mx.nd.sum(input1**2, axis=1, keepdims=True)) \ + * mx.nd.sqrt(mx.nd.sum(input2**2, axis=1, keepdims=True)) + final_numpy_array = mx.nd.where(label == 1, 1-numerator/denominator, \ + mx.nd.broadcast_maximum(mx.nd.array([0]), numerator/denominator, axis=1)) + assert_almost_equal(loss.asnumpy(), final_numpy_array.asnumpy(), rtol=1e-3, atol=1e-5) + if __name__ == '__main__': import nose nose.runmodule() From 410a708b06487b7381d1e8053570772cb0126bab Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 11 Oct 2018 11:31:38 -0700 Subject: [PATCH 22/35] Renaming variables --- tests/python/unittest/test_loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/python/unittest/test_loss.py b/tests/python/unittest/test_loss.py index eba3a55b37cc..c9b36ce9371c 100644 --- a/tests/python/unittest/test_loss.py +++ b/tests/python/unittest/test_loss.py @@ -362,9 +362,9 @@ def test_cosine_loss(): numerator = mx.nd.sum(input1 * input2, keepdims=True, axis=1) denominator = mx.nd.sqrt(mx.nd.sum(input1**2, axis=1, keepdims=True)) \ * mx.nd.sqrt(mx.nd.sum(input2**2, axis=1, keepdims=True)) - final_numpy_array = mx.nd.where(label == 1, 1-numerator/denominator, \ + numpy_loss = mx.nd.where(label == 1, 1-numerator/denominator, \ mx.nd.broadcast_maximum(mx.nd.array([0]), numerator/denominator, axis=1)) - assert_almost_equal(loss.asnumpy(), final_numpy_array.asnumpy(), rtol=1e-3, atol=1e-5) + assert_almost_equal(loss.asnumpy(), numpy_loss.asnumpy(), rtol=1e-3, atol=1e-5) if __name__ == '__main__': import nose From 1f484291f403049663b45f23863a86c41446ec36 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 11 Oct 2018 11:40:40 -0700 Subject: [PATCH 23/35] Pylint issues fixed --- python/mxnet/gluon/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 0f8b8d43a96e..fb95b8dbff25 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -748,7 +748,7 @@ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): def hybrid_forward(self, F, input1, input2, label): input1 = _reshape_like(F, input1, input2) - label = label.reshape((-1,1)) + label = label.reshape((-1, 1)) cos_sim = self._cosine_similarity(F, input1, input2) y_1 = label == 1 y_minus_1 = label == -1 From ed762e57be365dc52e84d08f8aed2b8f158a5021 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 15 Oct 2018 09:46:00 -0700 Subject: [PATCH 24/35] Resolving conflicts --- python/mxnet/gluon/loss.py | 6 +----- tests/python/unittest/test_loss.py | 5 ++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 74e2eec7aad6..9a10e367801c 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -23,11 +23,7 @@ 'SigmoidBinaryCrossEntropyLoss', 'SigmoidBCELoss', 'SoftmaxCrossEntropyLoss', 'SoftmaxCELoss', 'KLDivLoss', 'CTCLoss', 'HuberLoss', 'HingeLoss', -<<<<<<< HEAD - 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss', 'CosineEmbeddingLoss'] -======= - 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss', 'PoissonNLLLoss'] ->>>>>>> upstream/master + 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss', 'PoissonNLLLoss', 'CosineEmbeddingLoss'] import numpy as np from .. import ndarray diff --git a/tests/python/unittest/test_loss.py b/tests/python/unittest/test_loss.py index 14df75729ded..18d1ebf8fb11 100644 --- a/tests/python/unittest/test_loss.py +++ b/tests/python/unittest/test_loss.py @@ -349,7 +349,6 @@ def test_triplet_loss(): assert mod.score(data_iter, eval_metric=mx.metric.Loss())[0][1] < 0.05 @with_seed() -<<<<<<< HEAD def test_cosine_loss(): #Generating samples input1 = mx.nd.random.randn(3, 2) @@ -366,7 +365,7 @@ def test_cosine_loss(): numpy_loss = mx.nd.where(label == 1, 1-numerator/denominator, \ mx.nd.broadcast_maximum(mx.nd.array([0]), numerator/denominator, axis=1)) assert_almost_equal(loss.asnumpy(), numpy_loss.asnumpy(), rtol=1e-3, atol=1e-5) -======= + def test_poisson_nllloss(): pred = mx.nd.random.normal(shape=(3, 4)) min_pred = mx.nd.min(pred) @@ -421,7 +420,7 @@ def test_poisson_nllloss_mod(): initializer=mx.init.Normal(sigma=0.1), eval_metric=mx.metric.Loss(), optimizer='adam') assert mod.score(data_iter, eval_metric=mx.metric.Loss())[0][1] < 0.05 ->>>>>>> upstream/master + if __name__ == '__main__': import nose From 89aafbc07accd27848757c6345099c0cec42833f Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 15 Oct 2018 09:55:36 -0700 Subject: [PATCH 25/35] Pylint issues fixed --- python/mxnet/gluon/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 9a10e367801c..fc7b37e6b318 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -820,7 +820,7 @@ def hybrid_forward(self, F, input1, input2, label): if F is ndarray: z_array = F.array([0]) else: - z_array = F.zeros((1,1)) + z_array = F.zeros((1, 1)) cos_sim_b = F.broadcast_maximum(z_array, y_minus_1 * (cos_sim - self._margin), axis=1) return cos_sim_a + cos_sim_b @@ -832,5 +832,5 @@ def _cosine_similarity(self, F, x, y, axis=-1): if F is ndarray: eps_arr = F.array([1e-12]) else: - eps_arr = F.full((1,1),1e-12) + eps_arr = F.full((1, 1), 1e-12) return (x_dot_y / F.broadcast_maximum(x_norm * y_norm, eps_arr)) \ No newline at end of file From 4a3167bf0863967a00ae60d84841dbb7f1105ce4 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Mon, 15 Oct 2018 10:29:07 -0700 Subject: [PATCH 26/35] Style issues fixed trailing whitespaces removed --- python/mxnet/gluon/loss.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index fc7b37e6b318..63ac9ee34544 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -772,15 +772,15 @@ def hybrid_forward(self, F, pred, target, sample_weight=None, epsilon=1e-08): class CosineEmbeddingLoss(Loss): r"""For a target label 1 or -1, vectors target and pred, the function computes the cosine distance between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. - + .. math:: - + L = \sum_i \begin{cases} 1 - {cos\_sim({input1}_i, {input2}_i)} & \text{ if } {label}_i = 1\\ {cos\_sim({input1}_i, {input2}_i)} & \text{ if } {label}_i = -1 \end{cases}\\ cos\_sim(input1, input2) = \frac{{input1}_i.{input2}_i}{||{input1}_i||.||{input2}_i||} - + `input1`, `input2` can have arbitrary shape as long as they have the same number of elements. - + Parameters ---------- weight : float or None @@ -789,7 +789,7 @@ class CosineEmbeddingLoss(Loss): The axis that represents mini-batch. margin : float Margin of separation between correct and incorrect pair. - + Inputs: - **input1**: a tensor with arbitrary shape @@ -800,30 +800,29 @@ class CosineEmbeddingLoss(Loss): and you want to weigh each sample in the batch separately, sample_weight should have shape (64, 1). - **label**: A 1-D tensor indicating for each pair input1 and input2, target label is 1 or -1 - + Outputs: - **loss**: The loss tensor with shape (batch_size,). """ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): super(CosineEmbeddingLoss, self).__init__(weight, batch_axis, **kwargs) self._margin = margin - + def hybrid_forward(self, F, input1, input2, label): - input1 = _reshape_like(F, input1, input2) label = label.reshape((-1, 1)) cos_sim = self._cosine_similarity(F, input1, input2) y_1 = label == 1 y_minus_1 = label == -1 cos_sim_a = (1 - cos_sim) * y_1 - + if F is ndarray: z_array = F.array([0]) else: z_array = F.zeros((1, 1)) cos_sim_b = F.broadcast_maximum(z_array, y_minus_1 * (cos_sim - self._margin), axis=1) return cos_sim_a + cos_sim_b - + def _cosine_similarity(self, F, x, y, axis=-1): # Calculates the cosine similarity between 2 vectors x_norm = F.norm(x, axis=axis).reshape(-1, 1) @@ -833,4 +832,4 @@ def _cosine_similarity(self, F, x, y, axis=-1): eps_arr = F.array([1e-12]) else: eps_arr = F.full((1, 1), 1e-12) - return (x_dot_y / F.broadcast_maximum(x_norm * y_norm, eps_arr)) \ No newline at end of file + return (x_dot_y / F.broadcast_maximum(x_norm * y_norm, eps_arr)) From d80baac13f2f4689b3ffb6a42692168ba6ee86f8 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 25 Oct 2018 16:47:28 -0700 Subject: [PATCH 27/35] Review comment addressed, sample_weight added in the parameter --- python/mxnet/gluon/loss.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 63ac9ee34544..b1f4a77cf186 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -808,7 +808,7 @@ def __init__(self, weight=None, batch_axis=0, margin=0, **kwargs): super(CosineEmbeddingLoss, self).__init__(weight, batch_axis, **kwargs) self._margin = margin - def hybrid_forward(self, F, input1, input2, label): + def hybrid_forward(self, F, input1, input2, label, sample_weight=None): input1 = _reshape_like(F, input1, input2) label = label.reshape((-1, 1)) cos_sim = self._cosine_similarity(F, input1, input2) @@ -821,7 +821,9 @@ def hybrid_forward(self, F, input1, input2, label): else: z_array = F.zeros((1, 1)) cos_sim_b = F.broadcast_maximum(z_array, y_minus_1 * (cos_sim - self._margin), axis=1) - return cos_sim_a + cos_sim_b + loss = cos_sim_a + cos_sim_b + loss = _apply_weighting(F, loss, self._weight, sample_weight) + return loss def _cosine_similarity(self, F, x, y, axis=-1): # Calculates the cosine similarity between 2 vectors From c195ed071d7ad53a5e262511d8db3e2469accd54 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 25 Oct 2018 18:10:16 -0700 Subject: [PATCH 28/35] Trigger CI From 308666bff582b6394e9ed15e5d896cf5f98c8a77 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 25 Oct 2018 20:36:29 -0700 Subject: [PATCH 29/35] Reordered Parameter description --- python/mxnet/gluon/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index b1f4a77cf186..5356413b1f97 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -795,11 +795,11 @@ class CosineEmbeddingLoss(Loss): - **input1**: a tensor with arbitrary shape - **input2**: another tensor with same shape as pred to which input1 is compared for similarity and loss calculation + - **label**: A 1-D tensor indicating for each pair input1 and input2, target label is 1 or -1 - **sample_weight**: element-wise weighting tensor. Must be broadcastable to the same shape as input1. For example, if input1 has shape (64, 10) and you want to weigh each sample in the batch separately, sample_weight should have shape (64, 1). - - **label**: A 1-D tensor indicating for each pair input1 and input2, target label is 1 or -1 Outputs: - **loss**: The loss tensor with shape (batch_size,). From 16c3ecdcd1f453e3f965b108f2721a60cd6cec56 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Thu, 25 Oct 2018 22:51:48 -0700 Subject: [PATCH 30/35] comments addressed - spelling errors --- python/mxnet/gluon/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index 5356413b1f97..e0200e1f6b8e 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -770,8 +770,8 @@ def hybrid_forward(self, F, pred, target, sample_weight=None, epsilon=1e-08): class CosineEmbeddingLoss(Loss): - r"""For a target label 1 or -1, vectors target and pred, the function computes the cosine distance - between the vectors. This can be interpretted as how similar/dissimilar two input vectors are. + r"""For a target label 1 or -1, vectors input1 and inout2, the function computes the cosine distance + between the vectors. This can be interpreted as how similar/dissimilar two input vectors are. .. math:: From 2dfeaa28234750ec4862b46a8506ca5ade5c8714 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Fri, 26 Oct 2018 10:52:09 -0700 Subject: [PATCH 31/35] nit comments addressed --- python/mxnet/gluon/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/gluon/loss.py b/python/mxnet/gluon/loss.py index e0200e1f6b8e..da43b62a1c34 100644 --- a/python/mxnet/gluon/loss.py +++ b/python/mxnet/gluon/loss.py @@ -770,7 +770,7 @@ def hybrid_forward(self, F, pred, target, sample_weight=None, epsilon=1e-08): class CosineEmbeddingLoss(Loss): - r"""For a target label 1 or -1, vectors input1 and inout2, the function computes the cosine distance + r"""For a target label 1 or -1, vectors input1 and input2, the function computes the cosine distance between the vectors. This can be interpreted as how similar/dissimilar two input vectors are. .. math:: From 0bd4b24396cd553c025363d0bdad75aa4b02bade Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Fri, 26 Oct 2018 12:10:03 -0700 Subject: [PATCH 32/35] Trigger CI From ede1588b92158162ef0a5042190336dbad8b8b45 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Fri, 26 Oct 2018 13:54:37 -0700 Subject: [PATCH 33/35] Trugger CI From 67572c59c937e47947480b042c92c2e3138af769 Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Fri, 26 Oct 2018 13:54:44 -0700 Subject: [PATCH 34/35] Trigger CI From 55d4b1ed1652d5abc2d002c177f4adfbe0dcf0de Mon Sep 17 00:00:00 2001 From: gaurav-gireesh Date: Fri, 26 Oct 2018 22:25:29 -0700 Subject: [PATCH 35/35] Trigger CI