We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[vec] deal with class imbalances


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `paddlespeech/vector/utils/vector_utils.py`
Content:
```
1 # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 
16 def get_chunks(seg_dur, audio_id, audio_duration):
17     """Get all chunk segments from a utterance
18 
19     Args:
20         seg_dur (float): segment chunk duration, seconds
21         audio_id (str): utterance name, 
22         audio_duration (float): utterance duration, seconds
23 
24     Returns:
25         List: all the chunk segments 
26     """
27     num_chunks = int(audio_duration / seg_dur)  # all in seconds
28     chunk_lst = [
29         audio_id + "_" + str(i * seg_dur) + "_" + str(i * seg_dur + seg_dur)
30         for i in range(num_chunks)
31     ]
32     return chunk_lst
33 
34 
35 def Q_from_tokens(token_num):
36     """Get prior model, data from uniform, would support others(guassian) in future
37     """
38     freq = [1] * token_num
39     Q = paddle.to_tensor(freq, dtype='float64')
40     return Q / Q.sum()
41
```

Path: `paddlespeech/vector/modules/loss.py`
Content:
```
1 # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 # This is modified from SpeechBrain
15 # https://github.com/speechbrain/speechbrain/blob/085be635c07f16d42cd1295045bc46c407f1e15b/speechbrain/nnet/losses.py
16 import math
17 
18 import paddle
19 import paddle.nn as nn
20 import paddle.nn.functional as F
21 
22 
23 class AngularMargin(nn.Layer):
24     def __init__(self, margin=0.0, scale=1.0):
25         """An implementation of Angular Margin (AM) proposed in the following
26            paper: '''Margin Matters: Towards More Discriminative Deep Neural Network
27            Embeddings for Speaker Recognition''' (https://arxiv.org/abs/1906.07317)
28 
29         Args:
30             margin (float, optional): The margin for cosine similiarity. Defaults to 0.0.
31             scale (float, optional): The scale for cosine similiarity. Defaults to 1.0.
32         """
33         super(AngularMargin, self).__init__()
34         self.margin = margin
35         self.scale = scale
36 
37     def forward(self, outputs, targets):
38         outputs = outputs - self.margin * targets
39         return self.scale * outputs
40 
41 
42 class AdditiveAngularMargin(AngularMargin):
43     def __init__(self, margin=0.0, scale=1.0, easy_margin=False):
44         """The Implementation of Additive Angular Margin (AAM) proposed
45        in the following paper: '''Margin Matters: Towards More Discriminative Deep Neural Network Embeddings for Speaker Recognition'''
46        (https://arxiv.org/abs/1906.07317)
47 
48         Args:
49             margin (float, optional): margin factor. Defaults to 0.0.
50             scale (float, optional): scale factor. Defaults to 1.0.
51             easy_margin (bool, optional): easy_margin flag. Defaults to False.
52         """
53         super(AdditiveAngularMargin, self).__init__(margin, scale)
54         self.easy_margin = easy_margin
55 
56         self.cos_m = math.cos(self.margin)
57         self.sin_m = math.sin(self.margin)
58         self.th = math.cos(math.pi - self.margin)
59         self.mm = math.sin(math.pi - self.margin) * self.margin
60 
61     def forward(self, outputs, targets):
62         cosine = outputs.astype('float32')
63         sine = paddle.sqrt(1.0 - paddle.pow(cosine, 2))
64         phi = cosine * self.cos_m - sine * self.sin_m  # cos(theta + m)
65         if self.easy_margin:
66             phi = paddle.where(cosine > 0, phi, cosine)
67         else:
68             phi = paddle.where(cosine > self.th, phi, cosine - self.mm)
69         outputs = (targets * phi) + ((1.0 - targets) * cosine)
70         return self.scale * outputs
71 
72 
73 class LogSoftmaxWrapper(nn.Layer):
74     def __init__(self, loss_fn):
75         """Speaker identificatin loss function wrapper 
76            including all of compositions of the loss transformation
77         Args:
78             loss_fn (_type_): the loss value of a batch
79         """
80         super(LogSoftmaxWrapper, self).__init__()
81         self.loss_fn = loss_fn
82         self.criterion = paddle.nn.KLDivLoss(reduction="sum")
83 
84     def forward(self, outputs, targets, length=None):
85         targets = F.one_hot(targets, outputs.shape[1])
86         try:
87             predictions = self.loss_fn(outputs, targets)
88         except TypeError:
89             predictions = self.loss_fn(outputs)
90 
91         predictions = F.log_softmax(predictions, axis=1)
92         loss = self.criterion(predictions, targets) / targets.sum()
93         return loss
94 
95 
96 class NCELoss(nn.Layer):
97     """Noise Contrastive Estimation loss funtion
98 
99     Noise Contrastive Estimation (NCE) is an approximation method that is used to
100     work around the huge computational cost of large softmax layer.
101     The basic idea is to convert the prediction problem into classification problem
102     at training stage. It has been proved that these two criterions converges to
103     the same minimal point as long as noise distribution is close enough to real one.
104 
105     NCE bridges the gap between generative models and discriminative models,
106     rather than simply speedup the softmax layer.
107     With NCE, you can turn almost anything into posterior with less effort (I think).
108 
109     Refs:
110     NCE：http://www.cs.helsinki.fi/u/ahyvarin/papers/Gutmann10AISTATS.pdf
111     Thanks: https://github.com/mingen-pan/easy-to-use-NCE-RNN-for-Pytorch/blob/master/nce.py
112 
113     Examples:
114     Q = Q_from_tokens(output_dim)
115     NCELoss(Q)
116     """
117 
118     def __init__(self, Q, noise_ratio=100, Z_offset=9.5):
119         """Noise Contrastive Estimation loss funtion
120 
121         Args:
122             Q (tensor): prior model, uniform or guassian
123             noise_ratio (int, optional): noise sampling times. Defaults to 100.
124             Z_offset (float, optional): scale of post processing the score. Defaults to 9.5.
125         """
126         super(NCELoss, self).__init__()
127         assert type(noise_ratio) is int
128         self.Q = paddle.to_tensor(Q, stop_gradient=False)
129         self.N = self.Q.shape[0]
130         self.K = noise_ratio
131         self.Z_offset = Z_offset
132 
133     def forward(self, output, target):
134         """Forward inference
135         
136         Args:
137             output (tensor): the model output, which is the input of loss function
138         """
139         output = paddle.reshape(output, [-1, self.N])
140         B = output.shape[0]
141         noise_idx = self.get_noise(B)
142         idx = self.get_combined_idx(target, noise_idx)
143         P_target, P_noise = self.get_prob(idx, output, sep_target=True)
144         Q_target, Q_noise = self.get_Q(idx)
145         loss = self.nce_loss(P_target, P_noise, Q_noise, Q_target)
146         return loss.mean()
147 
148     def get_Q(self, idx, sep_target=True):
149         """Get prior model of batchsize data
150         """
151         idx_size = idx.size
152         prob_model = paddle.to_tensor(
153             self.Q.numpy()[paddle.reshape(idx, [-1]).numpy()])
154         prob_model = paddle.reshape(prob_model, [idx.shape[0], idx.shape[1]])
155         if sep_target:
156             return prob_model[:, 0], prob_model[:, 1:]
157         else:
158             return prob_model
159 
160     def get_prob(self, idx, scores, sep_target=True):
161         """Post processing the score of post model(output of nn) of batchsize data
162         """
163         scores = self.get_scores(idx, scores)
164         scale = paddle.to_tensor([self.Z_offset], dtype='float32')
165         scores = paddle.add(scores, -scale)
166         prob = paddle.exp(scores)
167         if sep_target:
168             return prob[:, 0], prob[:, 1:]
169         else:
170             return prob
171 
172     def get_scores(self, idx, scores):
173         """Get the score of post model(output of nn) of batchsize data
174         """
175         B, N = scores.shape
176         K = idx.shape[1]
177         idx_increment = paddle.to_tensor(
178             N * paddle.reshape(paddle.arange(B), [B, 1]) * paddle.ones([1, K]),
179             dtype="int64",
180             stop_gradient=False)
181         new_idx = idx_increment + idx
182         new_scores = paddle.index_select(
183             paddle.reshape(scores, [-1]), paddle.reshape(new_idx, [-1]))
184 
185         return paddle.reshape(new_scores, [B, K])
186 
187     def get_noise(self, batch_size, uniform=True):
188         """Select noise sample
189         """
190         if uniform:
191             noise = np.random.randint(self.N, size=self.K * batch_size)
192         else:
193             noise = np.random.choice(
194                 self.N, self.K * batch_size, replace=True, p=self.Q.data)
195         noise = paddle.to_tensor(noise, dtype='int64', stop_gradient=False)
196         noise_idx = paddle.reshape(noise, [batch_size, self.K])
197         return noise_idx
198 
199     def get_combined_idx(self, target_idx, noise_idx):
200         """Combined target and noise
201         """
202         target_idx = paddle.reshape(target_idx, [-1, 1])
203         return paddle.concat((target_idx, noise_idx), 1)
204 
205     def nce_loss(self, prob_model, prob_noise_in_model, prob_noise,
206                  prob_target_in_noise):
207         """Combined the loss of target and noise
208         """
209 
210         def safe_log(tensor):
211             """Safe log
212             """
213             EPSILON = 1e-10
214             return paddle.log(EPSILON + tensor)
215 
216         model_loss = safe_log(prob_model /
217                               (prob_model + self.K * prob_target_in_noise))
218         model_loss = paddle.reshape(model_loss, [-1])
219 
220         noise_loss = paddle.sum(
221             safe_log((self.K * prob_noise) /
222                      (prob_noise_in_model + self.K * prob_noise)), -1)
223         noise_loss = paddle.reshape(noise_loss, [-1])
224 
225         loss = -(model_loss + noise_loss)
226 
227         return loss
228
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/paddlespeech/vector/modules/loss.py b/paddlespeech/vector/modules/loss.py
--- a/paddlespeech/vector/modules/loss.py
+++ b/paddlespeech/vector/modules/loss.py
@@ -132,7 +132,7 @@
 
     def forward(self, output, target):
         """Forward inference
-        
+
         Args:
             output (tensor): the model output, which is the input of loss function
         """
@@ -161,7 +161,7 @@
         """Post processing the score of post model(output of nn) of batchsize data
         """
         scores = self.get_scores(idx, scores)
-        scale = paddle.to_tensor([self.Z_offset], dtype='float32')
+        scale = paddle.to_tensor([self.Z_offset], dtype='float64')
         scores = paddle.add(scores, -scale)
         prob = paddle.exp(scores)
         if sep_target:
@@ -225,3 +225,65 @@
         loss = -(model_loss + noise_loss)
 
         return loss
+
+
+class FocalLoss(nn.Layer):
+    """This criterion is a implemenation of Focal Loss, which is proposed in 
+    Focal Loss for Dense Object Detection.
+
+        Loss(x, class) = - \alpha (1-softmax(x)[class])^gamma \log(softmax(x)[class])
+
+    The losses are averaged across observations for each minibatch.
+
+    Args:
+        alpha(1D Tensor, Variable) : the scalar factor for this criterion
+        gamma(float, double) : gamma > 0; reduces the relative loss for well-classiﬁed examples (p > .5), 
+                                putting more focus on hard, misclassiﬁed examples
+        size_average(bool): By default, the losses are averaged over observations for each minibatch.
+                            However, if the field size_average is set to False, the losses are
+                            instead summed for each minibatch.
+    """
+
+    def __init__(self, alpha=1, gamma=0, size_average=True, ignore_index=-100):
+        super(FocalLoss, self).__init__()
+        self.alpha = alpha
+        self.gamma = gamma
+        self.size_average = size_average
+        self.ce = nn.CrossEntropyLoss(
+            ignore_index=ignore_index, reduction="none")
+
+    def forward(self, outputs, targets):
+        """Forword inference.
+
+        Args:
+            outputs: input tensor
+            target: target label tensor
+        """
+        ce_loss = self.ce(outputs, targets)
+        pt = paddle.exp(-ce_loss)
+        focal_loss = self.alpha * (1 - pt)**self.gamma * ce_loss
+        if self.size_average:
+            return focal_loss.mean()
+        else:
+            return focal_loss.sum()
+
+
+if __name__ == "__main__":
+    import numpy as np
+    from paddlespeech.vector.utils.vector_utils import Q_from_tokens
+    paddle.set_device("cpu")
+
+    input_data = paddle.uniform([5, 100], dtype="float64")
+    label_data = np.random.randint(0, 100, size=(5)).astype(np.int64)
+
+    input = paddle.to_tensor(input_data)
+    label = paddle.to_tensor(label_data)
+
+    loss1 = FocalLoss()
+    loss = loss1.forward(input, label)
+    print("loss: %.5f" % (loss))
+
+    Q = Q_from_tokens(100)
+    loss2 = NCELoss(Q)
+    loss = loss2.forward(input, label)
+    print("loss: %.5f" % (loss))
diff --git a/paddlespeech/vector/utils/vector_utils.py b/paddlespeech/vector/utils/vector_utils.py
--- a/paddlespeech/vector/utils/vector_utils.py
+++ b/paddlespeech/vector/utils/vector_utils.py
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import paddle
 
 
 def get_chunks(seg_dur, audio_id, audio_duration):

{"golden_diff": "diff --git a/paddlespeech/vector/modules/loss.py b/paddlespeech/vector/modules/loss.py\n--- a/paddlespeech/vector/modules/loss.py\n+++ b/paddlespeech/vector/modules/loss.py\n@@ -132,7 +132,7 @@\n \n     def forward(self, output, target):\n         \"\"\"Forward inference\n-        \n+\n         Args:\n             output (tensor): the model output, which is the input of loss function\n         \"\"\"\n@@ -161,7 +161,7 @@\n         \"\"\"Post processing the score of post model(output of nn) of batchsize data\n         \"\"\"\n         scores = self.get_scores(idx, scores)\n-        scale = paddle.to_tensor([self.Z_offset], dtype='float32')\n+        scale = paddle.to_tensor([self.Z_offset], dtype='float64')\n         scores = paddle.add(scores, -scale)\n         prob = paddle.exp(scores)\n         if sep_target:\n@@ -225,3 +225,65 @@\n         loss = -(model_loss + noise_loss)\n \n         return loss\n+\n+\n+class FocalLoss(nn.Layer):\n+    \"\"\"This criterion is a implemenation of Focal Loss, which is proposed in \n+    Focal Loss for Dense Object Detection.\n+\n+        Loss(x, class) = - \\alpha (1-softmax(x)[class])^gamma \\log(softmax(x)[class])\n+\n+    The losses are averaged across observations for each minibatch.\n+\n+    Args:\n+        alpha(1D Tensor, Variable) : the scalar factor for this criterion\n+        gamma(float, double) : gamma > 0; reduces the relative loss for well-classi\ufb01ed examples (p > .5), \n+                                putting more focus on hard, misclassi\ufb01ed examples\n+        size_average(bool): By default, the losses are averaged over observations for each minibatch.\n+                            However, if the field size_average is set to False, the losses are\n+                            instead summed for each minibatch.\n+    \"\"\"\n+\n+    def __init__(self, alpha=1, gamma=0, size_average=True, ignore_index=-100):\n+        super(FocalLoss, self).__init__()\n+        self.alpha = alpha\n+        self.gamma = gamma\n+        self.size_average = size_average\n+        self.ce = nn.CrossEntropyLoss(\n+            ignore_index=ignore_index, reduction=\"none\")\n+\n+    def forward(self, outputs, targets):\n+        \"\"\"Forword inference.\n+\n+        Args:\n+            outputs: input tensor\n+            target: target label tensor\n+        \"\"\"\n+        ce_loss = self.ce(outputs, targets)\n+        pt = paddle.exp(-ce_loss)\n+        focal_loss = self.alpha * (1 - pt)**self.gamma * ce_loss\n+        if self.size_average:\n+            return focal_loss.mean()\n+        else:\n+            return focal_loss.sum()\n+\n+\n+if __name__ == \"__main__\":\n+    import numpy as np\n+    from paddlespeech.vector.utils.vector_utils import Q_from_tokens\n+    paddle.set_device(\"cpu\")\n+\n+    input_data = paddle.uniform([5, 100], dtype=\"float64\")\n+    label_data = np.random.randint(0, 100, size=(5)).astype(np.int64)\n+\n+    input = paddle.to_tensor(input_data)\n+    label = paddle.to_tensor(label_data)\n+\n+    loss1 = FocalLoss()\n+    loss = loss1.forward(input, label)\n+    print(\"loss: %.5f\" % (loss))\n+\n+    Q = Q_from_tokens(100)\n+    loss2 = NCELoss(Q)\n+    loss = loss2.forward(input, label)\n+    print(\"loss: %.5f\" % (loss))\ndiff --git a/paddlespeech/vector/utils/vector_utils.py b/paddlespeech/vector/utils/vector_utils.py\n--- a/paddlespeech/vector/utils/vector_utils.py\n+++ b/paddlespeech/vector/utils/vector_utils.py\n@@ -11,6 +11,7 @@\n # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n # See the License for the specific language governing permissions and\n # limitations under the License.\n+import paddle\n \n \n def get_chunks(seg_dur, audio_id, audio_duration):\n", "issue": "[vec] deal with class imbalances\n\n", "before_files": [{"content": "# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\ndef get_chunks(seg_dur, audio_id, audio_duration):\n    \"\"\"Get all chunk segments from a utterance\n\n    Args:\n        seg_dur (float): segment chunk duration, seconds\n        audio_id (str): utterance name, \n        audio_duration (float): utterance duration, seconds\n\n    Returns:\n        List: all the chunk segments \n    \"\"\"\n    num_chunks = int(audio_duration / seg_dur)  # all in seconds\n    chunk_lst = [\n        audio_id + \"_\" + str(i * seg_dur) + \"_\" + str(i * seg_dur + seg_dur)\n        for i in range(num_chunks)\n    ]\n    return chunk_lst\n\n\ndef Q_from_tokens(token_num):\n    \"\"\"Get prior model, data from uniform, would support others(guassian) in future\n    \"\"\"\n    freq = [1] * token_num\n    Q = paddle.to_tensor(freq, dtype='float64')\n    return Q / Q.sum()\n", "path": "paddlespeech/vector/utils/vector_utils.py"}, {"content": "# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# This is modified from SpeechBrain\n# https://github.com/speechbrain/speechbrain/blob/085be635c07f16d42cd1295045bc46c407f1e15b/speechbrain/nnet/losses.py\nimport math\n\nimport paddle\nimport paddle.nn as nn\nimport paddle.nn.functional as F\n\n\nclass AngularMargin(nn.Layer):\n    def __init__(self, margin=0.0, scale=1.0):\n        \"\"\"An implementation of Angular Margin (AM) proposed in the following\n           paper: '''Margin Matters: Towards More Discriminative Deep Neural Network\n           Embeddings for Speaker Recognition''' (https://arxiv.org/abs/1906.07317)\n\n        Args:\n            margin (float, optional): The margin for cosine similiarity. Defaults to 0.0.\n            scale (float, optional): The scale for cosine similiarity. Defaults to 1.0.\n        \"\"\"\n        super(AngularMargin, self).__init__()\n        self.margin = margin\n        self.scale = scale\n\n    def forward(self, outputs, targets):\n        outputs = outputs - self.margin * targets\n        return self.scale * outputs\n\n\nclass AdditiveAngularMargin(AngularMargin):\n    def __init__(self, margin=0.0, scale=1.0, easy_margin=False):\n        \"\"\"The Implementation of Additive Angular Margin (AAM) proposed\n       in the following paper: '''Margin Matters: Towards More Discriminative Deep Neural Network Embeddings for Speaker Recognition'''\n       (https://arxiv.org/abs/1906.07317)\n\n        Args:\n            margin (float, optional): margin factor. Defaults to 0.0.\n            scale (float, optional): scale factor. Defaults to 1.0.\n            easy_margin (bool, optional): easy_margin flag. Defaults to False.\n        \"\"\"\n        super(AdditiveAngularMargin, self).__init__(margin, scale)\n        self.easy_margin = easy_margin\n\n        self.cos_m = math.cos(self.margin)\n        self.sin_m = math.sin(self.margin)\n        self.th = math.cos(math.pi - self.margin)\n        self.mm = math.sin(math.pi - self.margin) * self.margin\n\n    def forward(self, outputs, targets):\n        cosine = outputs.astype('float32')\n        sine = paddle.sqrt(1.0 - paddle.pow(cosine, 2))\n        phi = cosine * self.cos_m - sine * self.sin_m  # cos(theta + m)\n        if self.easy_margin:\n            phi = paddle.where(cosine > 0, phi, cosine)\n        else:\n            phi = paddle.where(cosine > self.th, phi, cosine - self.mm)\n        outputs = (targets * phi) + ((1.0 - targets) * cosine)\n        return self.scale * outputs\n\n\nclass LogSoftmaxWrapper(nn.Layer):\n    def __init__(self, loss_fn):\n        \"\"\"Speaker identificatin loss function wrapper \n           including all of compositions of the loss transformation\n        Args:\n            loss_fn (_type_): the loss value of a batch\n        \"\"\"\n        super(LogSoftmaxWrapper, self).__init__()\n        self.loss_fn = loss_fn\n        self.criterion = paddle.nn.KLDivLoss(reduction=\"sum\")\n\n    def forward(self, outputs, targets, length=None):\n        targets = F.one_hot(targets, outputs.shape[1])\n        try:\n            predictions = self.loss_fn(outputs, targets)\n        except TypeError:\n            predictions = self.loss_fn(outputs)\n\n        predictions = F.log_softmax(predictions, axis=1)\n        loss = self.criterion(predictions, targets) / targets.sum()\n        return loss\n\n\nclass NCELoss(nn.Layer):\n    \"\"\"Noise Contrastive Estimation loss funtion\n\n    Noise Contrastive Estimation (NCE) is an approximation method that is used to\n    work around the huge computational cost of large softmax layer.\n    The basic idea is to convert the prediction problem into classification problem\n    at training stage. It has been proved that these two criterions converges to\n    the same minimal point as long as noise distribution is close enough to real one.\n\n    NCE bridges the gap between generative models and discriminative models,\n    rather than simply speedup the softmax layer.\n    With NCE, you can turn almost anything into posterior with less effort (I think).\n\n    Refs:\n    NCE\uff1ahttp://www.cs.helsinki.fi/u/ahyvarin/papers/Gutmann10AISTATS.pdf\n    Thanks: https://github.com/mingen-pan/easy-to-use-NCE-RNN-for-Pytorch/blob/master/nce.py\n\n    Examples:\n    Q = Q_from_tokens(output_dim)\n    NCELoss(Q)\n    \"\"\"\n\n    def __init__(self, Q, noise_ratio=100, Z_offset=9.5):\n        \"\"\"Noise Contrastive Estimation loss funtion\n\n        Args:\n            Q (tensor): prior model, uniform or guassian\n            noise_ratio (int, optional): noise sampling times. Defaults to 100.\n            Z_offset (float, optional): scale of post processing the score. Defaults to 9.5.\n        \"\"\"\n        super(NCELoss, self).__init__()\n        assert type(noise_ratio) is int\n        self.Q = paddle.to_tensor(Q, stop_gradient=False)\n        self.N = self.Q.shape[0]\n        self.K = noise_ratio\n        self.Z_offset = Z_offset\n\n    def forward(self, output, target):\n        \"\"\"Forward inference\n        \n        Args:\n            output (tensor): the model output, which is the input of loss function\n        \"\"\"\n        output = paddle.reshape(output, [-1, self.N])\n        B = output.shape[0]\n        noise_idx = self.get_noise(B)\n        idx = self.get_combined_idx(target, noise_idx)\n        P_target, P_noise = self.get_prob(idx, output, sep_target=True)\n        Q_target, Q_noise = self.get_Q(idx)\n        loss = self.nce_loss(P_target, P_noise, Q_noise, Q_target)\n        return loss.mean()\n\n    def get_Q(self, idx, sep_target=True):\n        \"\"\"Get prior model of batchsize data\n        \"\"\"\n        idx_size = idx.size\n        prob_model = paddle.to_tensor(\n            self.Q.numpy()[paddle.reshape(idx, [-1]).numpy()])\n        prob_model = paddle.reshape(prob_model, [idx.shape[0], idx.shape[1]])\n        if sep_target:\n            return prob_model[:, 0], prob_model[:, 1:]\n        else:\n            return prob_model\n\n    def get_prob(self, idx, scores, sep_target=True):\n        \"\"\"Post processing the score of post model(output of nn) of batchsize data\n        \"\"\"\n        scores = self.get_scores(idx, scores)\n        scale = paddle.to_tensor([self.Z_offset], dtype='float32')\n        scores = paddle.add(scores, -scale)\n        prob = paddle.exp(scores)\n        if sep_target:\n            return prob[:, 0], prob[:, 1:]\n        else:\n            return prob\n\n    def get_scores(self, idx, scores):\n        \"\"\"Get the score of post model(output of nn) of batchsize data\n        \"\"\"\n        B, N = scores.shape\n        K = idx.shape[1]\n        idx_increment = paddle.to_tensor(\n            N * paddle.reshape(paddle.arange(B), [B, 1]) * paddle.ones([1, K]),\n            dtype=\"int64\",\n            stop_gradient=False)\n        new_idx = idx_increment + idx\n        new_scores = paddle.index_select(\n            paddle.reshape(scores, [-1]), paddle.reshape(new_idx, [-1]))\n\n        return paddle.reshape(new_scores, [B, K])\n\n    def get_noise(self, batch_size, uniform=True):\n        \"\"\"Select noise sample\n        \"\"\"\n        if uniform:\n            noise = np.random.randint(self.N, size=self.K * batch_size)\n        else:\n            noise = np.random.choice(\n                self.N, self.K * batch_size, replace=True, p=self.Q.data)\n        noise = paddle.to_tensor(noise, dtype='int64', stop_gradient=False)\n        noise_idx = paddle.reshape(noise, [batch_size, self.K])\n        return noise_idx\n\n    def get_combined_idx(self, target_idx, noise_idx):\n        \"\"\"Combined target and noise\n        \"\"\"\n        target_idx = paddle.reshape(target_idx, [-1, 1])\n        return paddle.concat((target_idx, noise_idx), 1)\n\n    def nce_loss(self, prob_model, prob_noise_in_model, prob_noise,\n                 prob_target_in_noise):\n        \"\"\"Combined the loss of target and noise\n        \"\"\"\n\n        def safe_log(tensor):\n            \"\"\"Safe log\n            \"\"\"\n            EPSILON = 1e-10\n            return paddle.log(EPSILON + tensor)\n\n        model_loss = safe_log(prob_model /\n                              (prob_model + self.K * prob_target_in_noise))\n        model_loss = paddle.reshape(model_loss, [-1])\n\n        noise_loss = paddle.sum(\n            safe_log((self.K * prob_noise) /\n                     (prob_noise_in_model + self.K * prob_noise)), -1)\n        noise_loss = paddle.reshape(noise_loss, [-1])\n\n        loss = -(model_loss + noise_loss)\n\n        return loss\n", "path": "paddlespeech/vector/modules/loss.py"}], "after_files": [{"content": "# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport paddle\n\n\ndef get_chunks(seg_dur, audio_id, audio_duration):\n    \"\"\"Get all chunk segments from a utterance\n\n    Args:\n        seg_dur (float): segment chunk duration, seconds\n        audio_id (str): utterance name, \n        audio_duration (float): utterance duration, seconds\n\n    Returns:\n        List: all the chunk segments \n    \"\"\"\n    num_chunks = int(audio_duration / seg_dur)  # all in seconds\n    chunk_lst = [\n        audio_id + \"_\" + str(i * seg_dur) + \"_\" + str(i * seg_dur + seg_dur)\n        for i in range(num_chunks)\n    ]\n    return chunk_lst\n\n\ndef Q_from_tokens(token_num):\n    \"\"\"Get prior model, data from uniform, would support others(guassian) in future\n    \"\"\"\n    freq = [1] * token_num\n    Q = paddle.to_tensor(freq, dtype='float64')\n    return Q / Q.sum()\n", "path": "paddlespeech/vector/utils/vector_utils.py"}, {"content": "# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n# This is modified from SpeechBrain\n# https://github.com/speechbrain/speechbrain/blob/085be635c07f16d42cd1295045bc46c407f1e15b/speechbrain/nnet/losses.py\nimport math\n\nimport paddle\nimport paddle.nn as nn\nimport paddle.nn.functional as F\n\n\nclass AngularMargin(nn.Layer):\n    def __init__(self, margin=0.0, scale=1.0):\n        \"\"\"An implementation of Angular Margin (AM) proposed in the following\n           paper: '''Margin Matters: Towards More Discriminative Deep Neural Network\n           Embeddings for Speaker Recognition''' (https://arxiv.org/abs/1906.07317)\n\n        Args:\n            margin (float, optional): The margin for cosine similiarity. Defaults to 0.0.\n            scale (float, optional): The scale for cosine similiarity. Defaults to 1.0.\n        \"\"\"\n        super(AngularMargin, self).__init__()\n        self.margin = margin\n        self.scale = scale\n\n    def forward(self, outputs, targets):\n        outputs = outputs - self.margin * targets\n        return self.scale * outputs\n\n\nclass AdditiveAngularMargin(AngularMargin):\n    def __init__(self, margin=0.0, scale=1.0, easy_margin=False):\n        \"\"\"The Implementation of Additive Angular Margin (AAM) proposed\n       in the following paper: '''Margin Matters: Towards More Discriminative Deep Neural Network Embeddings for Speaker Recognition'''\n       (https://arxiv.org/abs/1906.07317)\n\n        Args:\n            margin (float, optional): margin factor. Defaults to 0.0.\n            scale (float, optional): scale factor. Defaults to 1.0.\n            easy_margin (bool, optional): easy_margin flag. Defaults to False.\n        \"\"\"\n        super(AdditiveAngularMargin, self).__init__(margin, scale)\n        self.easy_margin = easy_margin\n\n        self.cos_m = math.cos(self.margin)\n        self.sin_m = math.sin(self.margin)\n        self.th = math.cos(math.pi - self.margin)\n        self.mm = math.sin(math.pi - self.margin) * self.margin\n\n    def forward(self, outputs, targets):\n        cosine = outputs.astype('float32')\n        sine = paddle.sqrt(1.0 - paddle.pow(cosine, 2))\n        phi = cosine * self.cos_m - sine * self.sin_m  # cos(theta + m)\n        if self.easy_margin:\n            phi = paddle.where(cosine > 0, phi, cosine)\n        else:\n            phi = paddle.where(cosine > self.th, phi, cosine - self.mm)\n        outputs = (targets * phi) + ((1.0 - targets) * cosine)\n        return self.scale * outputs\n\n\nclass LogSoftmaxWrapper(nn.Layer):\n    def __init__(self, loss_fn):\n        \"\"\"Speaker identificatin loss function wrapper \n           including all of compositions of the loss transformation\n        Args:\n            loss_fn (_type_): the loss value of a batch\n        \"\"\"\n        super(LogSoftmaxWrapper, self).__init__()\n        self.loss_fn = loss_fn\n        self.criterion = paddle.nn.KLDivLoss(reduction=\"sum\")\n\n    def forward(self, outputs, targets, length=None):\n        targets = F.one_hot(targets, outputs.shape[1])\n        try:\n            predictions = self.loss_fn(outputs, targets)\n        except TypeError:\n            predictions = self.loss_fn(outputs)\n\n        predictions = F.log_softmax(predictions, axis=1)\n        loss = self.criterion(predictions, targets) / targets.sum()\n        return loss\n\n\nclass NCELoss(nn.Layer):\n    \"\"\"Noise Contrastive Estimation loss funtion\n\n    Noise Contrastive Estimation (NCE) is an approximation method that is used to\n    work around the huge computational cost of large softmax layer.\n    The basic idea is to convert the prediction problem into classification problem\n    at training stage. It has been proved that these two criterions converges to\n    the same minimal point as long as noise distribution is close enough to real one.\n\n    NCE bridges the gap between generative models and discriminative models,\n    rather than simply speedup the softmax layer.\n    With NCE, you can turn almost anything into posterior with less effort (I think).\n\n    Refs:\n    NCE\uff1ahttp://www.cs.helsinki.fi/u/ahyvarin/papers/Gutmann10AISTATS.pdf\n    Thanks: https://github.com/mingen-pan/easy-to-use-NCE-RNN-for-Pytorch/blob/master/nce.py\n\n    Examples:\n    Q = Q_from_tokens(output_dim)\n    NCELoss(Q)\n    \"\"\"\n\n    def __init__(self, Q, noise_ratio=100, Z_offset=9.5):\n        \"\"\"Noise Contrastive Estimation loss funtion\n\n        Args:\n            Q (tensor): prior model, uniform or guassian\n            noise_ratio (int, optional): noise sampling times. Defaults to 100.\n            Z_offset (float, optional): scale of post processing the score. Defaults to 9.5.\n        \"\"\"\n        super(NCELoss, self).__init__()\n        assert type(noise_ratio) is int\n        self.Q = paddle.to_tensor(Q, stop_gradient=False)\n        self.N = self.Q.shape[0]\n        self.K = noise_ratio\n        self.Z_offset = Z_offset\n\n    def forward(self, output, target):\n        \"\"\"Forward inference\n\n        Args:\n            output (tensor): the model output, which is the input of loss function\n        \"\"\"\n        output = paddle.reshape(output, [-1, self.N])\n        B = output.shape[0]\n        noise_idx = self.get_noise(B)\n        idx = self.get_combined_idx(target, noise_idx)\n        P_target, P_noise = self.get_prob(idx, output, sep_target=True)\n        Q_target, Q_noise = self.get_Q(idx)\n        loss = self.nce_loss(P_target, P_noise, Q_noise, Q_target)\n        return loss.mean()\n\n    def get_Q(self, idx, sep_target=True):\n        \"\"\"Get prior model of batchsize data\n        \"\"\"\n        idx_size = idx.size\n        prob_model = paddle.to_tensor(\n            self.Q.numpy()[paddle.reshape(idx, [-1]).numpy()])\n        prob_model = paddle.reshape(prob_model, [idx.shape[0], idx.shape[1]])\n        if sep_target:\n            return prob_model[:, 0], prob_model[:, 1:]\n        else:\n            return prob_model\n\n    def get_prob(self, idx, scores, sep_target=True):\n        \"\"\"Post processing the score of post model(output of nn) of batchsize data\n        \"\"\"\n        scores = self.get_scores(idx, scores)\n        scale = paddle.to_tensor([self.Z_offset], dtype='float64')\n        scores = paddle.add(scores, -scale)\n        prob = paddle.exp(scores)\n        if sep_target:\n            return prob[:, 0], prob[:, 1:]\n        else:\n            return prob\n\n    def get_scores(self, idx, scores):\n        \"\"\"Get the score of post model(output of nn) of batchsize data\n        \"\"\"\n        B, N = scores.shape\n        K = idx.shape[1]\n        idx_increment = paddle.to_tensor(\n            N * paddle.reshape(paddle.arange(B), [B, 1]) * paddle.ones([1, K]),\n            dtype=\"int64\",\n            stop_gradient=False)\n        new_idx = idx_increment + idx\n        new_scores = paddle.index_select(\n            paddle.reshape(scores, [-1]), paddle.reshape(new_idx, [-1]))\n\n        return paddle.reshape(new_scores, [B, K])\n\n    def get_noise(self, batch_size, uniform=True):\n        \"\"\"Select noise sample\n        \"\"\"\n        if uniform:\n            noise = np.random.randint(self.N, size=self.K * batch_size)\n        else:\n            noise = np.random.choice(\n                self.N, self.K * batch_size, replace=True, p=self.Q.data)\n        noise = paddle.to_tensor(noise, dtype='int64', stop_gradient=False)\n        noise_idx = paddle.reshape(noise, [batch_size, self.K])\n        return noise_idx\n\n    def get_combined_idx(self, target_idx, noise_idx):\n        \"\"\"Combined target and noise\n        \"\"\"\n        target_idx = paddle.reshape(target_idx, [-1, 1])\n        return paddle.concat((target_idx, noise_idx), 1)\n\n    def nce_loss(self, prob_model, prob_noise_in_model, prob_noise,\n                 prob_target_in_noise):\n        \"\"\"Combined the loss of target and noise\n        \"\"\"\n\n        def safe_log(tensor):\n            \"\"\"Safe log\n            \"\"\"\n            EPSILON = 1e-10\n            return paddle.log(EPSILON + tensor)\n\n        model_loss = safe_log(prob_model /\n                              (prob_model + self.K * prob_target_in_noise))\n        model_loss = paddle.reshape(model_loss, [-1])\n\n        noise_loss = paddle.sum(\n            safe_log((self.K * prob_noise) /\n                     (prob_noise_in_model + self.K * prob_noise)), -1)\n        noise_loss = paddle.reshape(noise_loss, [-1])\n\n        loss = -(model_loss + noise_loss)\n\n        return loss\n\n\nclass FocalLoss(nn.Layer):\n    \"\"\"This criterion is a implemenation of Focal Loss, which is proposed in \n    Focal Loss for Dense Object Detection.\n\n        Loss(x, class) = - \\alpha (1-softmax(x)[class])^gamma \\log(softmax(x)[class])\n\n    The losses are averaged across observations for each minibatch.\n\n    Args:\n        alpha(1D Tensor, Variable) : the scalar factor for this criterion\n        gamma(float, double) : gamma > 0; reduces the relative loss for well-classi\ufb01ed examples (p > .5), \n                                putting more focus on hard, misclassi\ufb01ed examples\n        size_average(bool): By default, the losses are averaged over observations for each minibatch.\n                            However, if the field size_average is set to False, the losses are\n                            instead summed for each minibatch.\n    \"\"\"\n\n    def __init__(self, alpha=1, gamma=0, size_average=True, ignore_index=-100):\n        super(FocalLoss, self).__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n        self.size_average = size_average\n        self.ce = nn.CrossEntropyLoss(\n            ignore_index=ignore_index, reduction=\"none\")\n\n    def forward(self, outputs, targets):\n        \"\"\"Forword inference.\n\n        Args:\n            outputs: input tensor\n            target: target label tensor\n        \"\"\"\n        ce_loss = self.ce(outputs, targets)\n        pt = paddle.exp(-ce_loss)\n        focal_loss = self.alpha * (1 - pt)**self.gamma * ce_loss\n        if self.size_average:\n            return focal_loss.mean()\n        else:\n            return focal_loss.sum()\n\n\nif __name__ == \"__main__\":\n    import numpy as np\n    from paddlespeech.vector.utils.vector_utils import Q_from_tokens\n    paddle.set_device(\"cpu\")\n\n    input_data = paddle.uniform([5, 100], dtype=\"float64\")\n    label_data = np.random.randint(0, 100, size=(5)).astype(np.int64)\n\n    input = paddle.to_tensor(input_data)\n    label = paddle.to_tensor(label_data)\n\n    loss1 = FocalLoss()\n    loss = loss1.forward(input, label)\n    print(\"loss: %.5f\" % (loss))\n\n    Q = Q_from_tokens(100)\n    loss2 = NCELoss(Q)\n    loss = loss2.forward(input, label)\n    print(\"loss: %.5f\" % (loss))\n", "path": "paddlespeech/vector/modules/loss.py"}]}