diff --git a/tensorflow-framework/src/main/java/org/tensorflow/framework/losses/BinaryCrossentropy.java b/tensorflow-framework/src/main/java/org/tensorflow/framework/losses/BinaryCrossentropy.java new file mode 100644 index 00000000000..effdf990f71 --- /dev/null +++ b/tensorflow-framework/src/main/java/org/tensorflow/framework/losses/BinaryCrossentropy.java @@ -0,0 +1,231 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. +=======================================================================*/ +package org.tensorflow.framework.losses; + +import org.tensorflow.Operand; +import org.tensorflow.framework.losses.impl.LossesHelper; +import org.tensorflow.op.Ops; +import org.tensorflow.types.family.TNumber; + +import static org.tensorflow.framework.utils.CastHelper.cast; + +/** + * Computes the cross-entropy loss between true labels and predicted labels. + * + *
Use this cross-entropy loss when there are only two label classes (assumed to be 0 and 1). For + * each example, there should be a single floating-point value per prediction. + * + *
Standalone usage: + * + *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {0.f, 0.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.6f, 0.4f}, {0.4f, 0.6f}});
+ * BinaryCrossentropy bce = new BinaryCrossentropy(tf);
+ * Operand<TFloat32> result = bce.call(labels, predictions);
+ * // produces 0.815
+ *
+ *
+ * Calling with sample weight: + * + *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {1.f, 0.f});
+ * Operand<TFloat32> result = bce.call(labels, predictions, sampleWeight);
+ * // produces 0.458f
+ *
+ *
+ * Using SUM reduction type:
+ *
+ *
+ * BinaryCrossentropy bce = new BinaryCrossentropy(tf, Reduction.SUM); + * Operand<TFloat32> result = bce.call(labels, predictions); + * // produces 1.630f + *+ * + *
Using NONE reduction type:
+ *
+ *
+ * BinaryCrossentropy bce = new BinaryCrossentropy(tf, Reduction.NONE); + * Operand<TFloat32> result = bce.call(labels, predictions); + * // produces [0.916f, 0.714f] + *+ */ +public class BinaryCrossentropy extends Loss { + public static final boolean FROM_LOGITS_DEFAULT = false; + public static final float LABEL_SMOOTHING_DEFAULT = 0.0f; + + private final boolean fromLogits; + private final float labelSmoothing; + + /** + * Creates a Binary Crossentropy Loss using {@link Class#getSimpleName()} as the loss name, {@link + * #FROM_LOGITS_DEFAULT} for fromLogits, {@link #LABEL_SMOOTHING_DEFAULT} for labelSmoothing and a + * Loss Reduction of {@link Loss#REDUCTION_DEFAULT} + * + * @param tf the TensorFlow Ops + */ + public BinaryCrossentropy(Ops tf) { + this(tf, null, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT); + } + + /** + * Creates a Binary Crossentropy loss using {@link Class#getSimpleName()} as the loss name, {@link + * #FROM_LOGITS_DEFAULT} for fromLogits, and {@link #LABEL_SMOOTHING_DEFAULT} for labelSmoothing + * + * @param tf the TensorFlow Ops + * @param reduction Type of Reduction to apply to the loss. + */ + public BinaryCrossentropy(Ops tf, Reduction reduction) { + this(tf, null, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, reduction); + } + + /** + * Creates a Binary Crossentropy loss using using {@link Class#getSimpleName()} as the loss name, + * labelSmoothing of {@link #LABEL_SMOOTHING_DEFAULT}, a reduction of {@link + * Loss#REDUCTION_DEFAULT}, + * + * @param tf the TensorFlow Ops + * @param fromLogits Whether to interpret predictions as a tensor of logit values + */ + public BinaryCrossentropy(Ops tf, boolean fromLogits) { + this(tf, null, fromLogits, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT); + } + + /** + * Creates a Binary Crossentropy loss using labelSmoothing of {@link #LABEL_SMOOTHING_DEFAULT} a + * reduction of {@link Loss#REDUCTION_DEFAULT}. + * + * @param tf the TensorFlow Ops + * @param name the name of the loss + * @param fromLogits Whether to interpret predictions as a tensor of logit values + */ + public BinaryCrossentropy(Ops tf, String name, boolean fromLogits) { + this(tf, name, fromLogits, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT); + } + + /** + * Creates a Binary Crossentropy loss using using {@link Class#getSimpleName()} as the loss name, + * and a reduction of {@link Loss#REDUCTION_DEFAULT}. + * + * @param tf the TensorFlow Ops + * @param fromLogits Whether to interpret predictions as a tensor of logit values + * @param labelSmoothing A number in the range, [0, 1]. When 0, no smoothing occurs. When > 0, + * compute the loss between the predicted labels and a smoothed version of the true labels, + * where the smoothing squeezes the labels towards 0.5. Larger values of labelSmoothing + * correspond to heavier smoothing. + */ + public BinaryCrossentropy(Ops tf, boolean fromLogits, float labelSmoothing) { + this(tf, null, fromLogits, labelSmoothing, REDUCTION_DEFAULT); + } + + /** + * Creates a Binary Crossentropy loss using a reduction of {@link Loss#REDUCTION_DEFAULT}. + * + * @param tf the TensorFlow Ops + * @param name the name of the loss + * @param fromLogits Whether to interpret predictions as a tensor of logit values + * @param labelSmoothing A number in the range, [0, 1]. When 0, no smoothing occurs. When > 0, + * compute the loss between the predicted labels and a smoothed version of the true labels, + * where the smoothing squeezes the labels towards 0.5. Larger values of labelSmoothing + * correspond to heavier smoothing. + */ + public BinaryCrossentropy(Ops tf, String name, boolean fromLogits, float labelSmoothing) { + this(tf, name, fromLogits, labelSmoothing, REDUCTION_DEFAULT); + } + + /** + * Creates a Binary Crossentropy loss + * + * @param tf the TensorFlow Ops + * @param fromLogits Whether to interpret predictions as a tensor of logit values + * @param labelSmoothing A number in the range, [0, 1]. When 0, no smoothing occurs. When > 0, + * compute the loss between the predicted labels and a smoothed version of the true labels, + * where the smoothing squeezes the labels towards 0.5. Larger values of labelSmoothing + * correspond to heavier smoothing. + * @param reduction Type of Reduction to apply to the loss. + */ + public BinaryCrossentropy(Ops tf, boolean fromLogits, float labelSmoothing, Reduction reduction) { + this(tf, null, fromLogits, labelSmoothing, reduction); + } + + /** + * Creates a Binary Crossentropy loss + * + * @param tf the TensorFlow Ops + * @param name the name of the loss + * @param fromLogits Whether to interpret predictions as a tensor of logit values + * @param labelSmoothing A number in the range, [0, 1]. When 0, no smoothing occurs. When > 0, + * compute the loss between the predicted labels and a smoothed version of the true labels, + * where the smoothing squeezes the labels towards 0.5. Larger values of labelSmoothing + * correspond to heavier smoothing. + * @param reduction Type of Reduction to apply to the loss. + * @throws IllegalArgumentException if labelSmoothing is not in the inclusive range of 0. - 1. + */ + public BinaryCrossentropy( + Ops tf, String name, boolean fromLogits, float labelSmoothing, Reduction reduction) { + super(tf, name, reduction); + if (labelSmoothing < 0 || labelSmoothing > 1) + throw new IllegalArgumentException( + "labelSmoothing must be >= 0. and <= 1, found " + labelSmoothing); + this.fromLogits = fromLogits; + this.labelSmoothing = labelSmoothing; + } + + /** + * Generates an Operand that calculates the loss. + * + *
If run in Graph mode, the computation will throw {@link
+ * org.tensorflow.exceptions.TFInvalidArgumentException} if the predictions values are outside the
+ * range o [0. to 1.]. In Eager Mode, this call will throw {@link IllegalArgumentException}, if
+ * the predictions values are outside the range o [0. to 1.]
+ *
+ * @param labels the truth values or labels
+ * @param predictions the predictions, values must be in the range [0. to 1.] inclusive.
+ * @param sampleWeights Optional SampleWeights acts as a coefficient for the loss. If a scalar is
+ * provided, then the loss is simply scaled by the given value. If SampleWeights is a tensor
+ * of size [batch_size], then the total loss for each sample of the batch is rescaled by the
+ * corresponding element in the SampleWeights vector. If the shape of SampleWeights is
+ * [batch_size, d0, .. dN-1] (or can be broadcast to this shape), then each loss element of
+ * predictions is scaled by the corresponding value of SampleWeights. (Note on dN-1: all loss
+ * functions reduce by 1 dimension, usually axis=-1.)
+ * @param Use this crossentropy loss function when there are two or more label classes. We expect labels
+ * to be provided in a one_hot representation. If you want to provide labels as integers, please use
+ * {@link SparseCategoricalCrossentropy} loss. There should be Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using If run in Graph mode, the computation will throw {@link
+ * org.tensorflow.exceptions.TFInvalidArgumentException} if the predictions values are outside the
+ * range o [0. to 1.]. In Eager Mode, this call will throw {@link IllegalArgumentException}, if
+ * the predictions values are outside the range o [0. to 1.]
+ *
+ * @param labels the truth values or labels
+ * @param predictions the predictions, values must be in the range [0. to 1.] inclusive.
+ * @param sampleWeights Optional SampleWeights acts as a coefficient for the loss. If a scalar is
+ * provided, then the loss is simply scaled by the given value. If SampleWeights is a tensor
+ * of size [batch_size], then the total loss for each sample of the batch is rescaled by the
+ * corresponding element in the SampleWeights vector. If the shape of SampleWeights is
+ * [batch_size, d0, .. dN-1] (or can be broadcast to this shape), then each loss element of
+ * predictions is scaled by the corresponding value of SampleWeights. (Note on dN-1: all loss
+ * functions reduce by 1 dimension, usually axis=-1.)
+ * @param Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using Note that it is a number between Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using If run in Graph mode, the computation will throw {@link
+ * org.tensorflow.exceptions.TFInvalidArgumentException} if the label values are not in the set
+ * [-1., 0., 1.]. In Eager Mode, this call will throw {@link IllegalArgumentException}, if the
+ * label values are not in the set [-1., 0., 1.].
+ *
+ * @param labels the truth values or labels, must be either -1, 0, or 1. Values are expected to be
+ * -1 or 1. If binary (0 or 1) labels are provided they will be converted to -1 or 1.
+ * @param predictions the predictions, values must be in the range [0. to 1.] inclusive.
+ * @param sampleWeights Optional sampleWeights acts as a coefficient for the loss. If a scalar is
+ * provided, then the loss is simply scaled by the given value. If sampleWeights is a tensor
+ * of size [batch_size], then the total loss for each sample of the batch is rescaled by the
+ * corresponding element in the SampleWeights vector. If the shape of SampleWeights is
+ * [batch_size, d0, .. dN-1] (or can be broadcast to this shape), then each loss element of
+ * predictions is scaled by the corresponding value of SampleWeights. (Note on dN-1: all loss
+ * functions reduce by 1 dimension, usually axis=-1.)
+ * @param For each value x in where d is delta.
+ *
+ * Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using Standalone usage:
+ *
+ * Calling with sample weight:
+ *
+ * Using Using Note that it is a number between For each value x in error = labels - predictions:
+ *
+ * where d is delta.
+ *
+ * @param tf the TensorFlow Ops
+ * @param labels true targets
+ * @param predictions the predictions
+ * @param delta the point where the Huber loss function changes from quadratic to linear.
+ * @param The Poisson loss is the mean of the elements of the Tensor # classes floating point
+ * values per feature.
+ *
+ *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0, 1, 0}, {0, 0, 1}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.05f, 0.95f, 0f}, {0.1f, 0.8f, 0.1f}});
+ * CategoricalCrossentropy cce = new CategoricalCrossentropy(tf);
+ * Operand<TFloat32> result = cce.call(labels, predictions);
+ * // produces 1.177
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {0.3f, 0.7f});
+ * Operand<TFloat32> result = cce.call(labels, predictions, sampleWeight);
+ * // produces 0.814f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * CategoricalCrossentropy cce = new CategoricalCrossentropy(tf, Reduction.SUM);
+ * Operand<TFloat32> result = cce.call(labels, predictions);
+ * // produces 2.354f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * CategoricalCrossentropy cce =
+ * new CategoricalCrossentropy(tf, Reduction.NONE);
+ * Operand<TFloat32> result = cce.call(labels, predictions);
+ * // produces [0.0513f, 2.303f]
+ *
+ */
+public class CategoricalCrossentropy extends Loss {
+ public static final boolean FROM_LOGITS_DEFAULT = false;
+ public static final float LABEL_SMOOTHING_DEFAULT = 0.0f;
+ public static final int DEFAULT_AXIS = -1;
+
+ private final boolean fromLogits;
+ private final float labelSmoothing;
+ private final int axis;
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link Class#getSimpleName()} as the loss name,
+ * {@link #FROM_LOGITS_DEFAULT} for fromLogits, {@link #LABEL_SMOOTHING_DEFAULT} for
+ * labelSmoothing, a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}, and an axis of {@link
+ * #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public CategoricalCrossentropy(Ops tf) {
+ this(tf, null, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link #FROM_LOGITS_DEFAULT} for fromLogits,
+ * {@link #LABEL_SMOOTHING_DEFAULT} for labelSmoothing, a Loss Reduction of {@link
+ * Loss#REDUCTION_DEFAULT}, and an axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of this loss
+ */
+ public CategoricalCrossentropy(Ops tf, String name) {
+ this(tf, name, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link Class#getSimpleName()} as the loss name,
+ * {@link #FROM_LOGITS_DEFAULT} for fromLogits, {@link #LABEL_SMOOTHING_DEFAULT} for
+ * labelSmoothing and an axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to loss.
+ */
+ public CategoricalCrossentropy(Ops tf, Reduction reduction) {
+ this(tf, null, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, reduction, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss {@link #FROM_LOGITS_DEFAULT} for fromLogits, {@link
+ * #LABEL_SMOOTHING_DEFAULT} for labelSmoothing, and an axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of this loss
+ * @param reduction Type of Reduction to apply to loss.
+ */
+ public CategoricalCrossentropy(Ops tf, String name, Reduction reduction) {
+ this(tf, name, FROM_LOGITS_DEFAULT, LABEL_SMOOTHING_DEFAULT, reduction, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link Class#getSimpleName()} as the loss name,
+ * {@link #LABEL_SMOOTHING_DEFAULT} for labelSmoothing, a Loss Reduction of {@link
+ * Loss#REDUCTION_DEFAULT}, and an axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ */
+ public CategoricalCrossentropy(Ops tf, boolean fromLogits) {
+ this(tf, null, fromLogits, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link #LABEL_SMOOTHING_DEFAULT} for
+ * labelSmoothing, a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}, and a channel axis of
+ * {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of this loss
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ */
+ public CategoricalCrossentropy(Ops tf, String name, boolean fromLogits) {
+ this(tf, name, fromLogits, LABEL_SMOOTHING_DEFAULT, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link Class#getSimpleName()} as the loss name,
+ * a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}, and a channel axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ * @param labelSmoothing Float in [0, 1]. When > 0, label values are smoothed, meaning the
+ * confidence on label values are relaxed. e.g. labelSmoothing=0.2 means that we will use a
+ * value of 0.1 for label 0 and 0.9 for label 1
+ */
+ public CategoricalCrossentropy(Ops tf, boolean fromLogits, float labelSmoothing) {
+ this(tf, null, fromLogits, labelSmoothing, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using a Loss Reduction of {@link Loss#REDUCTION_DEFAULT},
+ * and a channel axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of this loss
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ * @param labelSmoothing Float in [0, 1]. When > 0, label values are smoothed, meaning the
+ * confidence on label values are relaxed. e.g. labelSmoothing=0.2 means that we will use a
+ * value of 0.1 for label 0 and 0.9 for label 1
+ */
+ public CategoricalCrossentropy(Ops tf, String name, boolean fromLogits, float labelSmoothing) {
+ this(tf, name, fromLogits, labelSmoothing, REDUCTION_DEFAULT, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss using {@link Class#getSimpleName()} as the loss name
+ * and a channel axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ * @param labelSmoothing Float in [0, 1]. When > 0, label values are smoothed, meaning the
+ * confidence on label values are relaxed. e.g. x=0.2 means that we will use a
+ * value of 0.1 for label 0 and 0.9 for label 1
+ * @param reduction Type of Reduction to apply to loss.
+ */
+ public CategoricalCrossentropy(
+ Ops tf, boolean fromLogits, float labelSmoothing, Reduction reduction) {
+ this(tf, null, fromLogits, labelSmoothing, reduction, DEFAULT_AXIS);
+ }
+
+ /**
+ * Creates a categorical cross entropy Loss
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of this loss
+ * @param fromLogits Whether to interpret predictions as a tensor of logit values
+ * @param labelSmoothing Float in [0, 1]. When > 0, label values are smoothed, meaning the
+ * confidence on label values are relaxed. e.g. labelSmoothing=0.2 means that we will use a
+ * value of 0.1 for label 0 and 0.9 for label 1
+ * @param reduction Type of Reduction to apply to loss.
+ * @param axis The channels axis. axis=-1 corresponds to data format `Channels Last'
+ * and axis=1 corresponds to data format 'Channels First'.
+ * @throws IllegalArgumentException if labelSmoothing is not in the inclusive range of 0. - 1.
+ */
+ public CategoricalCrossentropy(
+ Ops tf,
+ String name,
+ boolean fromLogits,
+ float labelSmoothing,
+ Reduction reduction,
+ int axis) {
+ super(tf, name, reduction);
+ if (labelSmoothing < 0 || labelSmoothing > 1)
+ throw new IllegalArgumentException(
+ "labelSmoothing must be >= 0. and <= 1, found " + labelSmoothing);
+ this.fromLogits = fromLogits;
+ this.labelSmoothing = labelSmoothing;
+ this.axis = axis;
+ }
+
+ /**
+ * Generates an Operand that calculates the loss.
+ *
+ * loss = maximum(neg - pos + 1, 0) where neg=maximum((1-labels)*predictions)
+ * and pos=sum(labels*predictions)
+ *
+ * labels values are expected to be 0 or 1.
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0, 1}, {0, 0}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.6f, 0.4f}, {0.4f, 0.6f}});
+ * CategoricalHinge categoricalHinge = new CategoricalHinge(tf);
+ * Operand<TFloat32> result = categoricalHinge.call(labels, predictions);
+ * // produces 1.4
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {1f, 0.f});
+ * Operand<TFloat32> result = categoricalHinge.call(labels, predictions, sampleWeight);
+ * // produces 0.6f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * CategoricalHinge categoricalHinge = new CategoricalHinge(tf, Reduction.SUM);
+ * Operand<TFloat32> result = categoricalHinge.call(labels, predictions);
+ * // produces 2.8f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * CategoricalHinge categoricalHinge =
+ * new CategoricalHinge(tf, Reduction.NONE);
+ * Operand<TFloat32> result = categoricalHinge.call(labels, predictions);
+ * // produces [1.2f, 1.6f]
+ *
+ */
+public class CategoricalHinge extends Loss {
+
+ /**
+ * Creates a Categorical Hinge Loss using {@link Class#getSimpleName()} as the loss name and a
+ * Loss Reduction of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public CategoricalHinge(Ops tf) {
+ super(tf);
+ }
+
+ /**
+ * Creates a Categorical Hinge Loss using {@link Class#getSimpleName()} as the loss name
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CategoricalHinge(Ops tf, Reduction reduction) {
+ super(tf, null, reduction);
+ }
+
+ /**
+ * Creates a Categorical Hinge
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CategoricalHinge(Ops tf, String name, Reduction reduction) {
+ super(tf, name, reduction);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public -1 and 1. When it is a negative number between -1 and 0, 0
+ * indicates orthogonality and values closer to -1indicate greater similarity. The values closer to
+ * 1 indicate greater dissimilarity. This makes it usable as a loss function in a setting where you
+ * try to maximize the proximity between predictions and targets. If either labels or predictions is
+ * a zero vector, cosine similarity will be 0 regardless of the proximity between predictions and
+ * targets.
+ *
+ * loss = -sum(l2Norm(labels) * l2Norm(predictions))
+ *
+ *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {1.f, 1.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{1.f, 0.f}, {1.f, 1.f}});
+ * CosineSimilarity cosineLoss = new CosineSimilarity(tf);
+ * Operand<TFloat32> result = cosineLoss.call(labels, predictions);
+ * // produces -0.5
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {0.8f, 0.2f});
+ * Operand<TFloat32> result = cosineLoss.call(labels, predictions, sampleWeight);
+ * // produces -0.0999f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * CosineSimilarity cosineLoss = new CosineSimilarity(tf, Reduction.SUM);
+ * Operand<TFloat32> result = cosineLoss.call(labels, predictions);
+ * // produces -0.999f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * CosineSimilarity cosineLoss = new CosineSimilarity(tf, Reduction.NONE);
+ * Operand<TFloat32> result = cosineLoss.call(labels, predictions);
+ * // produces [-0.f, -0.999f]
+ *
+ */
+public class CosineSimilarity extends Loss {
+ public static final int DEFAULT_AXIS = -1;
+ public static final Reduction DEFAULT_REDUCTION = Reduction.AUTO;
+
+ private final int axis;
+
+ /**
+ * Creates a Cosine Similarity Loss using {@link Class#getSimpleName()} as the loss name, an axis
+ * of {@link #DEFAULT_AXIS}, and a Loss Reduction of {@link #DEFAULT_REDUCTION}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public CosineSimilarity(Ops tf) {
+
+ this(tf, null, DEFAULT_AXIS, DEFAULT_REDUCTION);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using an axis of {@link #DEFAULT_AXIS}, and a Loss Reduction
+ * of {@link #DEFAULT_REDUCTION}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ */
+ public CosineSimilarity(Ops tf, String name) {
+
+ this(tf, name, DEFAULT_AXIS, DEFAULT_REDUCTION);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using {@link Class#getSimpleName()} as the loss name, and a
+ * Loss Reduction of {@link #DEFAULT_REDUCTION}
+ *
+ * @param tf the TensorFlow Ops
+ * @param axis The dimension along which the cosine similarity is computed.
+ */
+ public CosineSimilarity(Ops tf, int axis) {
+
+ this(tf, null, axis, DEFAULT_REDUCTION);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using a Loss Reduction of {@link #DEFAULT_REDUCTION}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param axis The dimension along which the cosine similarity is computed.
+ */
+ public CosineSimilarity(Ops tf, String name, int axis) {
+
+ this(tf, name, axis, DEFAULT_REDUCTION);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using {@link Class#getSimpleName()} as the loss name and an
+ * axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CosineSimilarity(Ops tf, Reduction reduction) {
+
+ this(tf, null, DEFAULT_AXIS, reduction);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using an axis of {@link #DEFAULT_AXIS}
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CosineSimilarity(Ops tf, String name, Reduction reduction) {
+
+ this(tf, name, DEFAULT_AXIS, reduction);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss using {@link Class#getSimpleName()} as the loss name
+ *
+ * @param tf the TensorFlow Ops
+ * @param axis The dimension along which the cosine similarity is computed.
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CosineSimilarity(Ops tf, int axis, Reduction reduction) {
+
+ this(tf, null, axis, reduction);
+ }
+
+ /**
+ * Creates a Cosine Similarity Loss
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param axis The dimension along which the cosine similarity is computed.
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public CosineSimilarity(Ops tf, String name, int axis, Reduction reduction) {
+ super(tf, name, reduction);
+ this.axis = axis;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public loss = maximum(1 - labels * predictions, 0)labels/code> values are expected to be -1 or 1.
+ * If binary (0 or 1) labels are provided, they will be converted to -1 or 1.
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {0.f, 0.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.6f, 0.4f}, {0.4f, 0.6f}});
+ * Hinge hingeLoss = new Hinge(tf);
+ * Operand<TFloat32> result = hingeLoss.call(labels, predictions);
+ * // produces 1.3f
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {1.f, 0.f});
+ * Operand<TFloat32> result = hingeLoss.call(labels, predictions, sampleWeight);
+ * // produces 0.55f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * Hinge hingeLoss = new Hinge(tf, Reduction.SUM);
+ * Operand<TFloat32> result = hingeLoss.call(labels, predictions);
+ * // produces 2.6f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * Hinge hingeLoss = new Hinge(tf, Reduction.NONE);
+ * Operand<TFloat32> result = hingeLoss.call(labels, predictions);
+ * // produces [1.1f, 1.5f]
+ *
+ */
+public class Hinge extends Loss {
+
+ /**
+ * Creates a Hinge Loss using {@link Class#getSimpleName()} as the loss name and a Loss Reduction
+ * of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public Hinge(Ops tf) {
+ this(tf, null, Reduction.AUTO);
+ }
+
+ /**
+ * Creates a Hinge Loss using {@link Class#getSimpleName()} as the loss name
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public Hinge(Ops tf, Reduction reduction) {
+ super(tf, null, reduction);
+ }
+
+ /**
+ * Creates a Hinge
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public Hinge(Ops tf, String name, Reduction reduction) {
+ super(tf, name, reduction);
+ }
+
+ /**
+ * Generates an Operand that calculates the loss.
+ *
+ * error = labels - predictions:
+ *
+ *
+ * loss = 0.5 * x^2 if |x| <= d
+ * loss = 0.5 * d^2 + d * (|x| - d) if |x| > d
+ *
+ *
+ *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {0.f, 0.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.6f, 0.4f}, {0.4f, 0.6f}});
+ * Huber huberLoss = new Huber(tf);
+ * Operand<TFloat32> result = huberLoss.call(labels, predictions);
+ * // produces 0.155
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {1.f, 0.f});
+ * Operand<TFloat32> result = huberLoss.call(labels, predictions, sampleWeight);
+ * // produces 0.09f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * Huber huberLoss = new Huber(tf, Reduction.SUM);
+ * Operand<TFloat32> result = huberLoss.call(labels, predictions);
+ * // produces 0.32f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * Huber huberLoss = new Huber(tf, Reduction.NONE);
+ * Operand<TFloat32> result = huberLoss.call(labels, predictions);
+ * // produces [0.18f, 0.13f]
+ *
+ *
+ * @see Huber loss
+ */
+public class Huber extends Loss {
+ public static final float DELTA_DEFAULT = 1.0f;
+
+ private final float delta;
+
+ /**
+ * Creates a Huber Loss using {@link Class#getSimpleName()} as the loss name, {@link
+ * #DELTA_DEFAULT} as the delta and a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public Huber(Ops tf) {
+ this(tf, null, DELTA_DEFAULT, Reduction.AUTO);
+ }
+
+ /**
+ * Creates a Huber Loss using {@link #DELTA_DEFAULT} as the delta and a Loss Reduction of {@link
+ * Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public Huber(Ops tf, String name) {
+ this(tf, name, DELTA_DEFAULT, Reduction.AUTO);
+ }
+
+ /**
+ * Creates a Huber Loss using {@link Class#getSimpleName()} as the loss name and and {@link
+ * #DELTA_DEFAULT} as the delta
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public Huber(Ops tf, Reduction reduction) {
+ this(tf, null, DELTA_DEFAULT, reduction);
+ }
+
+ /**
+ * Creates a Huber Loss using {@link #DELTA_DEFAULT} as the delta
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public Huber(Ops tf, String name, Reduction reduction) {
+ this(tf, name, DELTA_DEFAULT, reduction);
+ }
+
+ /**
+ * Creates a Huber Loss
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param delta the point where the Huber loss function changes from quadratic to linear.
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public Huber(Ops tf, String name, float delta, Reduction reduction) {
+ super(tf, name, reduction);
+ this.delta = delta;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public loss = labels * log(labels / predictions)
+ *
+ *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {0.f, 0.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{0.6f, 0.4f}, {0.4f, 0.6f}});
+ * KLDivergence kld = new KLDivergence(tf);
+ * Operand<TFloat32> result = kld.call(labels, predictions);
+ * // produces 0.458
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {0.8f, 0.2f});
+ * Operand<TFloat32> result = kld.call(labels, predictions, sampleWeight);
+ * // produces 0.366f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * KLDivergence kld = new KLDivergence(tf, Reduction.SUM);
+ * Operand<TFloat32> result = kld.call(labels, predictions);
+ * // produces 0.916f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * KLDivergence kld = new KLDivergence(tf, Reduction.NONE);
+ * Operand<TFloat32> result = kld.call(labels, predictions);
+ * // produces [0.916f, -3.08e-06f]
+ *
+ *
+ * @see Kullback?Leibler
+ * divergence
+ */
+public class KLDivergence extends Loss {
+
+ /**
+ * Creates a Kullback Leibler Divergence Loss using {@link Class#getSimpleName()} as the loss name
+ * and a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public KLDivergence(Ops tf) {
+ super(tf);
+ }
+
+ /**
+ * Creates a Kullback Leibler Divergence Loss Loss using {@link Class#getSimpleName()} as the loss
+ * name
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public KLDivergence(Ops tf, Reduction reduction) {
+ super(tf, null, reduction);
+ }
+
+ /**
+ * Creates a Kullback Leibler Divergence Loss
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public KLDivergence(Ops tf, String name, Reduction reduction) {
+ super(tf, name, reduction);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public logcosh = log((exp(x) + exp(-x))/2), where x is the error
+ * predictions - labels.
+ *
+ *
+ * Operand<TFloat32> labels =
+ * tf.constant(new float[][] {{0.f, 1.f}, {0.f, 0.f}});
+ * Operand<TFloat32> predictions =
+ * tf.constant(new float[][] {{1.f, 1.f}, {0.f, 0.f}});
+ * LogCosh logcosh = new LogCosh(tf);
+ * Operand<TFloat32> result = logcosh.call(labels, predictions);
+ * // produces 0.108
+ *
+ *
+ *
+ * Operand<TFloat32> sampleWeight = tf.constant(new float[] {0.8f, 0.2f});
+ * Operand<TFloat32> result = logcosh.call(labels, predictions, sampleWeight);
+ * // produces 0.087f
+ *
+ *
+ * SUM reduction type:
+ *
+ *
+ * LogCosh logcosh = new LogCosh(tf, Reduction.SUM);
+ * Operand<TFloat32> result = logcosh.call(labels, predictions);
+ * // produces 0.217f
+ *
+ *
+ * NONE reduction type:
+ *
+ *
+ * LogCosh logcosh = new LogCosh(tf, Reduction.NONE);
+ * Operand<TFloat32> result = logcosh.call(labels, predictions);
+ * // produces [0.217f, 0f]
+ *
+ */
+public class LogCosh extends Loss {
+
+ /**
+ * Creates a LogCosh Loss using {@link Class#getSimpleName()} as the loss name and a Loss
+ * Reduction of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public LogCosh(Ops tf) {
+ this(tf, null, Reduction.AUTO);
+ }
+
+ /**
+ * Creates a LogCosh Loss using a Loss Reduction of {@link Loss#REDUCTION_DEFAULT}
+ *
+ * @param tf the TensorFlow Ops
+ */
+ public LogCosh(Ops tf, String name) {
+ this(tf, name, Reduction.AUTO);
+ }
+
+ /**
+ * Creates a LogCosh Loss using {@link Class#getSimpleName()} as the loss name
+ *
+ * @param tf the TensorFlow Ops
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public LogCosh(Ops tf, Reduction reduction) {
+ this(tf, null, reduction);
+ }
+
+ /**
+ * Creates a LogCosh Loss
+ *
+ * @param tf the TensorFlow Ops
+ * @param name the name of the loss
+ * @param reduction Type of Reduction to apply to the loss.
+ */
+ public LogCosh(Ops tf, String name, Reduction reduction) {
+ super(tf, name, reduction);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public loss = reduceMean(abs(labels - predictions))
+ *
+ * @param tf The TensorFlow Ops
+ * @param labels the labels
+ * @param predictions the predictions
+ * @param loss = reduceMean(square(labels - predictions))
+ *
+ * @param tf The TensorFlow Ops
+ * @param labels the labels
+ * @param predictions the predictions
+ * @param loss = 100 * reduceMean(abs((labels - predictions) / labels))
+ *
+ * @param tf The TensorFlow Ops
+ * @param labels the labels
+ * @param predictions the predictions
+ * @param loss = reduceMean(square(log(labels + 1) - log(predictions + 1)))
+ *
+ * @param tf The TensorFlow Ops
+ * @param labels the labels
+ * @param predictions the predictions
+ * @param [0, 1]. When > 0, label values are smoothed, meaning the
+ * confidence on label values are relaxed. e.g. labelSmoothing=0.2 means that we will use a
+ * value of 0.1 for label 0 and 0.9 for label 1
+ * @param axis the
+ * @param -1 and 1, which is different from
+ * the mathematical definition of cosine similarity where 1 represents similar
+ * vectors, and 0 represents dissimilar vectors. In this function, the numbers are
+ * inverted in a range of -1 to 1. When it is a negative number between
+ * -1 and 0, 0 indicates orthogonality and values closer to
+ * -1 indicate greater similarity. The values closer to 1 indicate
+ * greater dissimilarity. This makes it usable as a loss function in a setting where you try to
+ * maximize the proximity between predictions and targets. If either labels or predictions is a
+ * zero vector, cosine similarity will be 0 regardless of the proximity between
+ * predictions and targets.
+ *
+ * loss = -sum(l2Norm(labels) * l2Norm(predictions))
+ *
+ * @param tf the TensorFlow Ops
+ * @param labels true targets
+ * @param predictions the predictions
+ * @param axis Axis along which to determine similarity.
+ * @param loss = reduceMean(maximum(1 - labels * predictions, 0))
+ *
+ * @param tf the TensorFlow Ops
+ * @param labels true targets, values are expected to be -1 or 1. If binary (0 or 1) labels are
+ * provided, they will be converted to -1 or 1.
+ * @param predictions the predictions
+ * @param
+ * loss = 0.5 * x^2 if |x| <= d
+ * loss = 0.5 * d^2 + d * (|x| - d) if |x| > d
+ *
+ *
+ * log(cosh(x)) is approximately equal to (x ** 2) / 2 for small
+ * x and to abs(x) - log(2) for large x. This means that
+ * 'logCosh' works mostly like the mean squared error, but will not be so strongly affected by the
+ * occasional wildly incorrect prediction.
+ *
+ * @param tf the TensorFlow Ops
+ * @param labels true targets
+ * @param predictions the predictions
+ * @param
+ * predictions - labels * log(predictions).
+ *
+ * @param tf the TensorFlow Ops
+ * @param labels true targets
+ * @param predictions the predictions
+ * @param