We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ValueError in guided alignment loss during training
Keras losses throw an exception when they are used within a distribution strategy scope and the reduction mode is unset.

```
ValueError: Please use `tf.keras.losses.Reduction.SUM` or `tf.keras.losses.Reduction.NONE` for loss reduction when losses are used with `tf.distribute.Strategy` outside of the built-in training loops. You can implement `tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE` using global batch size like:
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opennmt/utils/losses.py`
Content:
```
1 """Define losses."""
2 
3 import tensorflow as tf
4 
5 
6 def _smooth_one_hot_labels(logits, labels, label_smoothing):
7   label_smoothing = tf.constant(label_smoothing, dtype=logits.dtype)
8   num_classes = tf.shape(logits)[-1]
9   return tf.one_hot(
10       tf.cast(labels, tf.int32),
11       num_classes,
12       on_value=1.0 - label_smoothing,
13       off_value=label_smoothing / tf.cast(num_classes - 1, label_smoothing.dtype),
14       dtype=logits.dtype)
15 
16 def _softmax_cross_entropy(logits, labels, label_smoothing, training):
17   # Computes the softmax in full precision.
18   if logits.dtype.base_dtype != tf.float32:
19     logits = tf.cast(logits, tf.float32)
20   if training and label_smoothing > 0.0:
21     smoothed_labels = _smooth_one_hot_labels(logits, labels, label_smoothing)
22     return tf.nn.softmax_cross_entropy_with_logits(smoothed_labels, logits)
23   else:
24     return tf.nn.sparse_softmax_cross_entropy_with_logits(labels, logits)
25 
26 def cross_entropy_sequence_loss(logits,
27                                 labels,
28                                 sequence_length,
29                                 label_smoothing=0.0,
30                                 average_in_time=False,
31                                 training=None):
32   """Computes the cross entropy loss of sequences.
33 
34   Args:
35     logits: The unscaled probabilities.
36     labels: The true labels.
37     sequence_length: The length of each sequence.
38     label_smoothing: The label smoothing value.
39     average_in_time: If ``True``, also average the loss in the time dimension.
40     training: Compute training loss.
41 
42   Returns:
43     A tuple (cumulated loss, loss normalizer, token-level normalizer).
44   """
45   batch_size = tf.shape(logits)[0]
46   max_time = tf.shape(logits)[1]
47 
48   cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)
49   weights = tf.sequence_mask(
50       sequence_length, maxlen=max_time, dtype=cross_entropy.dtype)
51   loss = tf.reduce_sum(cross_entropy * weights)
52   loss_token_normalizer = tf.reduce_sum(weights)
53 
54   if average_in_time or not training:
55     loss_normalizer = loss_token_normalizer
56   else:
57     loss_normalizer = tf.cast(batch_size, loss.dtype)
58 
59   return loss, loss_normalizer, loss_token_normalizer
60 
61 def cross_entropy_loss(logits,
62                        labels,
63                        label_smoothing=0.0,
64                        training=None):
65   """Computes the cross entropy loss.
66 
67   Args:
68     logits: The unscaled probabilities.
69     labels: The true labels.
70     label_smoothing: The label smoothing value.
71     training: Compute training loss.
72 
73   Returns:
74     The cumulated loss and the loss normalizer.
75   """
76   cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)
77   loss = tf.reduce_sum(cross_entropy)
78   loss_normalizer = tf.cast(tf.shape(cross_entropy)[0], loss.dtype)
79   return loss, loss_normalizer
80 
81 def guided_alignment_cost(attention_probs,
82                           gold_alignment,
83                           sequence_length=None,
84                           cost_type="ce",
85                           weight=1):
86   """Computes the guided alignment cost.
87 
88   Args:
89     attention_probs: The attention probabilities, a float ``tf.Tensor`` of shape
90       :math:`[B, T_t, T_s]`.
91     gold_alignment: The true alignment matrix, a float ``tf.Tensor`` of shape
92       :math:`[B, T_t, T_s]`.
93     sequence_length: The length of each sequence.
94     cost_type: The type of the cost function to compute (can be: ce, mse).
95     weight: The weight applied to the cost.
96 
97   Returns:
98     The guided alignment cost.
99 
100   Raises:
101     ValueError: if :obj:`cost_type` is invalid.
102   """
103   if cost_type == "ce":
104     loss = tf.keras.losses.CategoricalCrossentropy()
105   elif cost_type == "mse":
106     loss = tf.keras.losses.MeanSquaredError()
107   else:
108     raise ValueError("invalid guided alignment cost: %s" % cost_type)
109 
110   if sequence_length is not None:
111     sample_weight = tf.sequence_mask(
112         sequence_length,
113         maxlen=tf.shape(attention_probs)[1],
114         dtype=attention_probs.dtype)
115     sample_weight = tf.expand_dims(sample_weight, -1)
116   else:
117     sample_weight = None
118 
119   cost = loss(
120       gold_alignment,
121       attention_probs,
122       sample_weight=sample_weight)
123   return weight * cost
124 
125 def regularization_penalty(regularization_type, scale, weights):
126   """Computes the weights regularization penalty.
127 
128   Args:
129     regularization_type: The regularization type: ``l1``, ``l2``, or ``l1_l2``.
130     scale: The regularization multiplier. If :obj:`regularization_type` is
131       ``l1_l2``, this should be a list or tuple containing the L1 regularization
132       scale and the L2 regularization scale.
133     weights: The list of weights.
134 
135   Returns:
136     The regularization penalty.
137 
138   Raises:
139     ValueError: if :obj:`regularization_type` is invalid or is ``l1_l2`` but
140       :obj:`scale` is not a sequence.
141   """
142   regularization_type = regularization_type.lower()
143   if regularization_type == "l1":
144     regularizer = tf.keras.regularizers.l1(l=float(scale))
145   elif regularization_type == "l2":
146     regularizer = tf.keras.regularizers.l2(l=float(scale))
147   elif regularization_type == "l1_l2":
148     if not isinstance(scale, (list, tuple)) or len(scale) != 2:
149       raise ValueError("l1_l2 regularization requires 2 scale values")
150     regularizer = tf.keras.regularizers.l1_l2(
151         l1=float(scale[0]), l2=float(scale[1]))
152   else:
153     raise ValueError("invalid regularization type %s" % regularization_type)
154 
155   weights = list(filter(lambda v: not _is_bias(v), weights))
156   penalty = tf.add_n([regularizer(w) for w in weights])
157   return penalty
158 
159 def _is_bias(variable):
160   return len(variable.shape) == 1 and variable.name.endswith("bias:0")
161 
162 def _negative_log_likelihood(logits, labels, sequence_length):
163   nll_num, nll_den, _ = cross_entropy_sequence_loss(
164       logits, labels, sequence_length, average_in_time=True)
165   return nll_num / nll_den
166 
167 def max_margin_loss(true_logits,
168                     true_labels,
169                     true_sequence_length,
170                     negative_logits,
171                     negative_labels,
172                     negative_sequence_length,
173                     eta=0.1):
174   """Computes the max-margin loss described in
175   https://www.aclweb.org/anthology/P19-1623.
176 
177   Args:
178     true_logits: The unscaled probabilities from the true example.
179     negative_logits: The unscaled probabilities from the negative example.
180     true_labels: The true labels.
181     true_sequence_length: The length of each true sequence.
182     negative_labels: The negative labels.
183     negative_sequence_length: The length of each negative sequence.
184     eta: Ensure that the margin is higher than this value.
185 
186   Returns:
187     The max-margin loss.
188   """
189   true_nll = _negative_log_likelihood(
190       true_logits, true_labels, true_sequence_length)
191   negative_nll = _negative_log_likelihood(
192       negative_logits, negative_labels, negative_sequence_length)
193   margin = true_nll - negative_nll + eta
194   return tf.maximum(margin, 0)
195
```
--- 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/opennmt/utils/losses.py b/opennmt/utils/losses.py
--- a/opennmt/utils/losses.py
+++ b/opennmt/utils/losses.py
@@ -101,9 +101,9 @@
     ValueError: if :obj:`cost_type` is invalid.
   """
   if cost_type == "ce":
-    loss = tf.keras.losses.CategoricalCrossentropy()
+    loss = tf.keras.losses.CategoricalCrossentropy(reduction=tf.keras.losses.Reduction.SUM)
   elif cost_type == "mse":
-    loss = tf.keras.losses.MeanSquaredError()
+    loss = tf.keras.losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM)
   else:
     raise ValueError("invalid guided alignment cost: %s" % cost_type)
 
@@ -113,13 +113,16 @@
         maxlen=tf.shape(attention_probs)[1],
         dtype=attention_probs.dtype)
     sample_weight = tf.expand_dims(sample_weight, -1)
+    normalizer = tf.reduce_sum(sequence_length)
   else:
     sample_weight = None
+    normalizer = tf.size(attention_probs)
 
   cost = loss(
       gold_alignment,
       attention_probs,
       sample_weight=sample_weight)
+  cost /= tf.cast(normalizer, cost.dtype)
   return weight * cost
 
 def regularization_penalty(regularization_type, scale, weights):

{"golden_diff": "diff --git a/opennmt/utils/losses.py b/opennmt/utils/losses.py\n--- a/opennmt/utils/losses.py\n+++ b/opennmt/utils/losses.py\n@@ -101,9 +101,9 @@\n     ValueError: if :obj:`cost_type` is invalid.\n   \"\"\"\n   if cost_type == \"ce\":\n-    loss = tf.keras.losses.CategoricalCrossentropy()\n+    loss = tf.keras.losses.CategoricalCrossentropy(reduction=tf.keras.losses.Reduction.SUM)\n   elif cost_type == \"mse\":\n-    loss = tf.keras.losses.MeanSquaredError()\n+    loss = tf.keras.losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM)\n   else:\n     raise ValueError(\"invalid guided alignment cost: %s\" % cost_type)\n \n@@ -113,13 +113,16 @@\n         maxlen=tf.shape(attention_probs)[1],\n         dtype=attention_probs.dtype)\n     sample_weight = tf.expand_dims(sample_weight, -1)\n+    normalizer = tf.reduce_sum(sequence_length)\n   else:\n     sample_weight = None\n+    normalizer = tf.size(attention_probs)\n \n   cost = loss(\n       gold_alignment,\n       attention_probs,\n       sample_weight=sample_weight)\n+  cost /= tf.cast(normalizer, cost.dtype)\n   return weight * cost\n \n def regularization_penalty(regularization_type, scale, weights):\n", "issue": "ValueError in guided alignment loss during training\nKeras losses throw an exception when they are used within a distribution strategy scope and the reduction mode is unset.\r\n\r\n```\r\nValueError: Please use `tf.keras.losses.Reduction.SUM` or `tf.keras.losses.Reduction.NONE` for loss reduction when losses are used with `tf.distribute.Strategy` outside of the built-in training loops. You can implement `tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE` using global batch size like:\r\n```\n", "before_files": [{"content": "\"\"\"Define losses.\"\"\"\n\nimport tensorflow as tf\n\n\ndef _smooth_one_hot_labels(logits, labels, label_smoothing):\n  label_smoothing = tf.constant(label_smoothing, dtype=logits.dtype)\n  num_classes = tf.shape(logits)[-1]\n  return tf.one_hot(\n      tf.cast(labels, tf.int32),\n      num_classes,\n      on_value=1.0 - label_smoothing,\n      off_value=label_smoothing / tf.cast(num_classes - 1, label_smoothing.dtype),\n      dtype=logits.dtype)\n\ndef _softmax_cross_entropy(logits, labels, label_smoothing, training):\n  # Computes the softmax in full precision.\n  if logits.dtype.base_dtype != tf.float32:\n    logits = tf.cast(logits, tf.float32)\n  if training and label_smoothing > 0.0:\n    smoothed_labels = _smooth_one_hot_labels(logits, labels, label_smoothing)\n    return tf.nn.softmax_cross_entropy_with_logits(smoothed_labels, logits)\n  else:\n    return tf.nn.sparse_softmax_cross_entropy_with_logits(labels, logits)\n\ndef cross_entropy_sequence_loss(logits,\n                                labels,\n                                sequence_length,\n                                label_smoothing=0.0,\n                                average_in_time=False,\n                                training=None):\n  \"\"\"Computes the cross entropy loss of sequences.\n\n  Args:\n    logits: The unscaled probabilities.\n    labels: The true labels.\n    sequence_length: The length of each sequence.\n    label_smoothing: The label smoothing value.\n    average_in_time: If ``True``, also average the loss in the time dimension.\n    training: Compute training loss.\n\n  Returns:\n    A tuple (cumulated loss, loss normalizer, token-level normalizer).\n  \"\"\"\n  batch_size = tf.shape(logits)[0]\n  max_time = tf.shape(logits)[1]\n\n  cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)\n  weights = tf.sequence_mask(\n      sequence_length, maxlen=max_time, dtype=cross_entropy.dtype)\n  loss = tf.reduce_sum(cross_entropy * weights)\n  loss_token_normalizer = tf.reduce_sum(weights)\n\n  if average_in_time or not training:\n    loss_normalizer = loss_token_normalizer\n  else:\n    loss_normalizer = tf.cast(batch_size, loss.dtype)\n\n  return loss, loss_normalizer, loss_token_normalizer\n\ndef cross_entropy_loss(logits,\n                       labels,\n                       label_smoothing=0.0,\n                       training=None):\n  \"\"\"Computes the cross entropy loss.\n\n  Args:\n    logits: The unscaled probabilities.\n    labels: The true labels.\n    label_smoothing: The label smoothing value.\n    training: Compute training loss.\n\n  Returns:\n    The cumulated loss and the loss normalizer.\n  \"\"\"\n  cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)\n  loss = tf.reduce_sum(cross_entropy)\n  loss_normalizer = tf.cast(tf.shape(cross_entropy)[0], loss.dtype)\n  return loss, loss_normalizer\n\ndef guided_alignment_cost(attention_probs,\n                          gold_alignment,\n                          sequence_length=None,\n                          cost_type=\"ce\",\n                          weight=1):\n  \"\"\"Computes the guided alignment cost.\n\n  Args:\n    attention_probs: The attention probabilities, a float ``tf.Tensor`` of shape\n      :math:`[B, T_t, T_s]`.\n    gold_alignment: The true alignment matrix, a float ``tf.Tensor`` of shape\n      :math:`[B, T_t, T_s]`.\n    sequence_length: The length of each sequence.\n    cost_type: The type of the cost function to compute (can be: ce, mse).\n    weight: The weight applied to the cost.\n\n  Returns:\n    The guided alignment cost.\n\n  Raises:\n    ValueError: if :obj:`cost_type` is invalid.\n  \"\"\"\n  if cost_type == \"ce\":\n    loss = tf.keras.losses.CategoricalCrossentropy()\n  elif cost_type == \"mse\":\n    loss = tf.keras.losses.MeanSquaredError()\n  else:\n    raise ValueError(\"invalid guided alignment cost: %s\" % cost_type)\n\n  if sequence_length is not None:\n    sample_weight = tf.sequence_mask(\n        sequence_length,\n        maxlen=tf.shape(attention_probs)[1],\n        dtype=attention_probs.dtype)\n    sample_weight = tf.expand_dims(sample_weight, -1)\n  else:\n    sample_weight = None\n\n  cost = loss(\n      gold_alignment,\n      attention_probs,\n      sample_weight=sample_weight)\n  return weight * cost\n\ndef regularization_penalty(regularization_type, scale, weights):\n  \"\"\"Computes the weights regularization penalty.\n\n  Args:\n    regularization_type: The regularization type: ``l1``, ``l2``, or ``l1_l2``.\n    scale: The regularization multiplier. If :obj:`regularization_type` is\n      ``l1_l2``, this should be a list or tuple containing the L1 regularization\n      scale and the L2 regularization scale.\n    weights: The list of weights.\n\n  Returns:\n    The regularization penalty.\n\n  Raises:\n    ValueError: if :obj:`regularization_type` is invalid or is ``l1_l2`` but\n      :obj:`scale` is not a sequence.\n  \"\"\"\n  regularization_type = regularization_type.lower()\n  if regularization_type == \"l1\":\n    regularizer = tf.keras.regularizers.l1(l=float(scale))\n  elif regularization_type == \"l2\":\n    regularizer = tf.keras.regularizers.l2(l=float(scale))\n  elif regularization_type == \"l1_l2\":\n    if not isinstance(scale, (list, tuple)) or len(scale) != 2:\n      raise ValueError(\"l1_l2 regularization requires 2 scale values\")\n    regularizer = tf.keras.regularizers.l1_l2(\n        l1=float(scale[0]), l2=float(scale[1]))\n  else:\n    raise ValueError(\"invalid regularization type %s\" % regularization_type)\n\n  weights = list(filter(lambda v: not _is_bias(v), weights))\n  penalty = tf.add_n([regularizer(w) for w in weights])\n  return penalty\n\ndef _is_bias(variable):\n  return len(variable.shape) == 1 and variable.name.endswith(\"bias:0\")\n\ndef _negative_log_likelihood(logits, labels, sequence_length):\n  nll_num, nll_den, _ = cross_entropy_sequence_loss(\n      logits, labels, sequence_length, average_in_time=True)\n  return nll_num / nll_den\n\ndef max_margin_loss(true_logits,\n                    true_labels,\n                    true_sequence_length,\n                    negative_logits,\n                    negative_labels,\n                    negative_sequence_length,\n                    eta=0.1):\n  \"\"\"Computes the max-margin loss described in\n  https://www.aclweb.org/anthology/P19-1623.\n\n  Args:\n    true_logits: The unscaled probabilities from the true example.\n    negative_logits: The unscaled probabilities from the negative example.\n    true_labels: The true labels.\n    true_sequence_length: The length of each true sequence.\n    negative_labels: The negative labels.\n    negative_sequence_length: The length of each negative sequence.\n    eta: Ensure that the margin is higher than this value.\n\n  Returns:\n    The max-margin loss.\n  \"\"\"\n  true_nll = _negative_log_likelihood(\n      true_logits, true_labels, true_sequence_length)\n  negative_nll = _negative_log_likelihood(\n      negative_logits, negative_labels, negative_sequence_length)\n  margin = true_nll - negative_nll + eta\n  return tf.maximum(margin, 0)\n", "path": "opennmt/utils/losses.py"}], "after_files": [{"content": "\"\"\"Define losses.\"\"\"\n\nimport tensorflow as tf\n\n\ndef _smooth_one_hot_labels(logits, labels, label_smoothing):\n  label_smoothing = tf.constant(label_smoothing, dtype=logits.dtype)\n  num_classes = tf.shape(logits)[-1]\n  return tf.one_hot(\n      tf.cast(labels, tf.int32),\n      num_classes,\n      on_value=1.0 - label_smoothing,\n      off_value=label_smoothing / tf.cast(num_classes - 1, label_smoothing.dtype),\n      dtype=logits.dtype)\n\ndef _softmax_cross_entropy(logits, labels, label_smoothing, training):\n  # Computes the softmax in full precision.\n  if logits.dtype.base_dtype != tf.float32:\n    logits = tf.cast(logits, tf.float32)\n  if training and label_smoothing > 0.0:\n    smoothed_labels = _smooth_one_hot_labels(logits, labels, label_smoothing)\n    return tf.nn.softmax_cross_entropy_with_logits(smoothed_labels, logits)\n  else:\n    return tf.nn.sparse_softmax_cross_entropy_with_logits(labels, logits)\n\ndef cross_entropy_sequence_loss(logits,\n                                labels,\n                                sequence_length,\n                                label_smoothing=0.0,\n                                average_in_time=False,\n                                training=None):\n  \"\"\"Computes the cross entropy loss of sequences.\n\n  Args:\n    logits: The unscaled probabilities.\n    labels: The true labels.\n    sequence_length: The length of each sequence.\n    label_smoothing: The label smoothing value.\n    average_in_time: If ``True``, also average the loss in the time dimension.\n    training: Compute training loss.\n\n  Returns:\n    A tuple (cumulated loss, loss normalizer, token-level normalizer).\n  \"\"\"\n  batch_size = tf.shape(logits)[0]\n  max_time = tf.shape(logits)[1]\n\n  cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)\n  weights = tf.sequence_mask(\n      sequence_length, maxlen=max_time, dtype=cross_entropy.dtype)\n  loss = tf.reduce_sum(cross_entropy * weights)\n  loss_token_normalizer = tf.reduce_sum(weights)\n\n  if average_in_time or not training:\n    loss_normalizer = loss_token_normalizer\n  else:\n    loss_normalizer = tf.cast(batch_size, loss.dtype)\n\n  return loss, loss_normalizer, loss_token_normalizer\n\ndef cross_entropy_loss(logits,\n                       labels,\n                       label_smoothing=0.0,\n                       training=None):\n  \"\"\"Computes the cross entropy loss.\n\n  Args:\n    logits: The unscaled probabilities.\n    labels: The true labels.\n    label_smoothing: The label smoothing value.\n    training: Compute training loss.\n\n  Returns:\n    The cumulated loss and the loss normalizer.\n  \"\"\"\n  cross_entropy = _softmax_cross_entropy(logits, labels, label_smoothing, training)\n  loss = tf.reduce_sum(cross_entropy)\n  loss_normalizer = tf.cast(tf.shape(cross_entropy)[0], loss.dtype)\n  return loss, loss_normalizer\n\ndef guided_alignment_cost(attention_probs,\n                          gold_alignment,\n                          sequence_length=None,\n                          cost_type=\"ce\",\n                          weight=1):\n  \"\"\"Computes the guided alignment cost.\n\n  Args:\n    attention_probs: The attention probabilities, a float ``tf.Tensor`` of shape\n      :math:`[B, T_t, T_s]`.\n    gold_alignment: The true alignment matrix, a float ``tf.Tensor`` of shape\n      :math:`[B, T_t, T_s]`.\n    sequence_length: The length of each sequence.\n    cost_type: The type of the cost function to compute (can be: ce, mse).\n    weight: The weight applied to the cost.\n\n  Returns:\n    The guided alignment cost.\n\n  Raises:\n    ValueError: if :obj:`cost_type` is invalid.\n  \"\"\"\n  if cost_type == \"ce\":\n    loss = tf.keras.losses.CategoricalCrossentropy(reduction=tf.keras.losses.Reduction.SUM)\n  elif cost_type == \"mse\":\n    loss = tf.keras.losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM)\n  else:\n    raise ValueError(\"invalid guided alignment cost: %s\" % cost_type)\n\n  if sequence_length is not None:\n    sample_weight = tf.sequence_mask(\n        sequence_length,\n        maxlen=tf.shape(attention_probs)[1],\n        dtype=attention_probs.dtype)\n    sample_weight = tf.expand_dims(sample_weight, -1)\n    normalizer = tf.reduce_sum(sequence_length)\n  else:\n    sample_weight = None\n    normalizer = tf.size(attention_probs)\n\n  cost = loss(\n      gold_alignment,\n      attention_probs,\n      sample_weight=sample_weight)\n  cost /= tf.cast(normalizer, cost.dtype)\n  return weight * cost\n\ndef regularization_penalty(regularization_type, scale, weights):\n  \"\"\"Computes the weights regularization penalty.\n\n  Args:\n    regularization_type: The regularization type: ``l1``, ``l2``, or ``l1_l2``.\n    scale: The regularization multiplier. If :obj:`regularization_type` is\n      ``l1_l2``, this should be a list or tuple containing the L1 regularization\n      scale and the L2 regularization scale.\n    weights: The list of weights.\n\n  Returns:\n    The regularization penalty.\n\n  Raises:\n    ValueError: if :obj:`regularization_type` is invalid or is ``l1_l2`` but\n      :obj:`scale` is not a sequence.\n  \"\"\"\n  regularization_type = regularization_type.lower()\n  if regularization_type == \"l1\":\n    regularizer = tf.keras.regularizers.l1(l=float(scale))\n  elif regularization_type == \"l2\":\n    regularizer = tf.keras.regularizers.l2(l=float(scale))\n  elif regularization_type == \"l1_l2\":\n    if not isinstance(scale, (list, tuple)) or len(scale) != 2:\n      raise ValueError(\"l1_l2 regularization requires 2 scale values\")\n    regularizer = tf.keras.regularizers.l1_l2(\n        l1=float(scale[0]), l2=float(scale[1]))\n  else:\n    raise ValueError(\"invalid regularization type %s\" % regularization_type)\n\n  weights = list(filter(lambda v: not _is_bias(v), weights))\n  penalty = tf.add_n([regularizer(w) for w in weights])\n  return penalty\n\ndef _is_bias(variable):\n  return len(variable.shape) == 1 and variable.name.endswith(\"bias:0\")\n\ndef _negative_log_likelihood(logits, labels, sequence_length):\n  nll_num, nll_den, _ = cross_entropy_sequence_loss(\n      logits, labels, sequence_length, average_in_time=True)\n  return nll_num / nll_den\n\ndef max_margin_loss(true_logits,\n                    true_labels,\n                    true_sequence_length,\n                    negative_logits,\n                    negative_labels,\n                    negative_sequence_length,\n                    eta=0.1):\n  \"\"\"Computes the max-margin loss described in\n  https://www.aclweb.org/anthology/P19-1623.\n\n  Args:\n    true_logits: The unscaled probabilities from the true example.\n    negative_logits: The unscaled probabilities from the negative example.\n    true_labels: The true labels.\n    true_sequence_length: The length of each true sequence.\n    negative_labels: The negative labels.\n    negative_sequence_length: The length of each negative sequence.\n    eta: Ensure that the margin is higher than this value.\n\n  Returns:\n    The max-margin loss.\n  \"\"\"\n  true_nll = _negative_log_likelihood(\n      true_logits, true_labels, true_sequence_length)\n  negative_nll = _negative_log_likelihood(\n      negative_logits, negative_labels, negative_sequence_length)\n  margin = true_nll - negative_nll + eta\n  return tf.maximum(margin, 0)\n", "path": "opennmt/utils/losses.py"}]}