refactor: Standardize TensorFlowNET.Keras/Losses/*tags/v0.110.0-LSTM-Model
| @@ -1,8 +1,9 @@ | |||
| namespace Tensorflow.Keras.Losses; | |||
| public class BinaryCrossentropy : LossFunctionWrapper, ILossFunc | |||
| public class BinaryCrossentropy : LossFunctionWrapper | |||
| { | |||
| float label_smoothing; | |||
| public BinaryCrossentropy( | |||
| bool from_logits = false, | |||
| float label_smoothing = 0, | |||
| @@ -15,7 +16,6 @@ public class BinaryCrossentropy : LossFunctionWrapper, ILossFunc | |||
| this.label_smoothing = label_smoothing; | |||
| } | |||
| public override Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false, int axis = -1) | |||
| { | |||
| var sum = keras.backend.binary_crossentropy(y_true, y_pred, from_logits: from_logits); | |||
| @@ -1,8 +1,9 @@ | |||
| namespace Tensorflow.Keras.Losses; | |||
| public class CategoricalCrossentropy : LossFunctionWrapper, ILossFunc | |||
| public class CategoricalCrossentropy : LossFunctionWrapper | |||
| { | |||
| float label_smoothing; | |||
| public CategoricalCrossentropy( | |||
| bool from_logits = false, | |||
| float label_smoothing = 0, | |||
| @@ -15,7 +16,6 @@ public class CategoricalCrossentropy : LossFunctionWrapper, ILossFunc | |||
| this.label_smoothing = label_smoothing; | |||
| } | |||
| public override Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false, int axis = -1) | |||
| { | |||
| // Try to adjust the shape so that rank of labels = rank of logits - 1. | |||
| @@ -1,28 +1,22 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class CosineSimilarity : LossFunctionWrapper | |||
| { | |||
| public class CosineSimilarity : LossFunctionWrapper, ILossFunc | |||
| protected int axis = -1; | |||
| public CosineSimilarity( | |||
| string reduction = null, | |||
| int axis = -1, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "cosine_similarity" : name) | |||
| { | |||
| protected int axis=-1; | |||
| public CosineSimilarity( | |||
| string reduction = null, | |||
| int axis=-1, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "cosine_similarity" : name) | |||
| { | |||
| this.axis = axis; | |||
| } | |||
| this.axis = axis; | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_true_normalize = nn_impl.l2_normalize(y_true, axis : this.axis); | |||
| Tensor y_pred_normalize = nn_impl.l2_normalize(y_pred, axis: this.axis); | |||
| return -math_ops.reduce_sum(y_true_normalize * y_pred_normalize, axis : constant_op.constant(this.axis)); | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred = null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_true_normalize = nn_impl.l2_normalize(y_true, axis: this.axis); | |||
| Tensor y_pred_normalize = nn_impl.l2_normalize(y_pred, axis: this.axis); | |||
| return -math_ops.reduce_sum(y_true_normalize * y_pred_normalize, axis: constant_op.constant(this.axis)); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,36 +1,29 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class Huber : LossFunctionWrapper | |||
| { | |||
| public class Huber : LossFunctionWrapper, ILossFunc | |||
| protected Tensor delta = tf.Variable(1.0); | |||
| public Huber( | |||
| string reduction = null, | |||
| Tensor delta = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "huber" : name) | |||
| { | |||
| protected Tensor delta = tf.Variable(1.0) ; | |||
| public Huber ( | |||
| string reduction = null, | |||
| Tensor delta = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "huber" : name) | |||
| { | |||
| this.delta = delta==null? this.delta: delta; | |||
| } | |||
| this.delta = delta == null ? this.delta : delta; | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_cast = math_ops.cast(y_pred, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor y_true_cast = math_ops.cast(y_true, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor delta = math_ops.cast(this.delta, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor error = math_ops.subtract(y_pred_cast, y_true_cast); | |||
| Tensor abs_error = math_ops.abs(error); | |||
| Tensor half = ops.convert_to_tensor(0.5, dtype: abs_error.dtype); | |||
| return gen_math_ops.mean(array_ops.where_v2(abs_error <= delta, | |||
| half * math_ops.pow(error, 2), | |||
| half * math_ops.pow(delta, 2) + delta * (abs_error - delta)), | |||
| ops.convert_to_tensor(-1)); | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred = null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_cast = math_ops.cast(y_pred, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor y_true_cast = math_ops.cast(y_true, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor delta = math_ops.cast(this.delta, dtype: TF_DataType.TF_FLOAT); | |||
| Tensor error = math_ops.subtract(y_pred_cast, y_true_cast); | |||
| Tensor abs_error = math_ops.abs(error); | |||
| Tensor half = ops.convert_to_tensor(0.5, dtype: abs_error.dtype); | |||
| return gen_math_ops.mean(array_ops.where_v2(abs_error <= delta, | |||
| half * math_ops.pow(error, 2), | |||
| half * math_ops.pow(delta, 2) + delta * (abs_error - delta)), | |||
| ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| @@ -1,27 +1,20 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using Tensorflow.Operations; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class LogCosh : LossFunctionWrapper | |||
| { | |||
| public class LogCosh : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public LogCosh( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "log_cosh" : name){ } | |||
| public LogCosh( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "log_cosh" : name) | |||
| { } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor x = y_pred_dispatch - y_true_cast; | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred = null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor x = y_pred_dispatch - y_true_cast; | |||
| return gen_math_ops.mean(x + gen_nn_ops.softplus(-2.0 * x) - math_ops.cast(math_ops.log(tf.Variable(2.0)), x.dtype), | |||
| ops.convert_to_tensor(-1)); | |||
| } | |||
| return gen_math_ops.mean(x + gen_nn_ops.softplus(-2.0 * x) - math_ops.cast(math_ops.log(tf.Variable(2.0)), x.dtype), | |||
| ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,55 +1,51 @@ | |||
| using System; | |||
| using Tensorflow.Keras.Utils; | |||
| using Tensorflow.Keras.Utils; | |||
| namespace Tensorflow.Keras.Losses | |||
| namespace Tensorflow.Keras.Losses; | |||
| /// <summary> | |||
| /// Loss base class. | |||
| /// </summary> | |||
| public abstract class Loss : ILossFunc | |||
| { | |||
| /// <summary> | |||
| /// Loss base class. | |||
| /// </summary> | |||
| public abstract class Loss | |||
| protected string reduction; | |||
| protected string name; | |||
| bool _allow_sum_over_batch_size; | |||
| protected bool from_logits = false; | |||
| string _name_scope; | |||
| public string Reduction => reduction; | |||
| public string Name => name; | |||
| public Loss(string reduction = ReductionV2.AUTO, | |||
| string name = null, | |||
| bool from_logits = false) | |||
| { | |||
| protected string reduction; | |||
| protected string name; | |||
| bool _allow_sum_over_batch_size; | |||
| protected bool from_logits = false; | |||
| string _name_scope; | |||
| public string Reduction => reduction; | |||
| public string Name => name; | |||
| public Loss(string reduction = ReductionV2.AUTO, | |||
| string name = null, | |||
| bool from_logits = false) | |||
| { | |||
| this.reduction = reduction == null ? ReductionV2.SUM_OVER_BATCH_SIZE : reduction; | |||
| this.name = name; | |||
| this.from_logits = from_logits; | |||
| _allow_sum_over_batch_size = false; | |||
| } | |||
| this.reduction = reduction == null ? ReductionV2.SUM_OVER_BATCH_SIZE : reduction; | |||
| this.name = name; | |||
| this.from_logits = from_logits; | |||
| _allow_sum_over_batch_size = false; | |||
| } | |||
| public virtual Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false, int axis = -1) | |||
| { | |||
| throw new NotImplementedException(""); | |||
| } | |||
| public abstract Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false, int axis = -1); | |||
| public Tensor Call(Tensor y_true, Tensor y_pred, Tensor sample_weight = null) | |||
| { | |||
| var losses = Apply(y_true, y_pred, from_logits: from_logits); | |||
| var reduction = GetReduction(); | |||
| return losses_utils.compute_weighted_loss(losses, reduction: reduction, sample_weight: sample_weight); | |||
| } | |||
| public Tensor Call(Tensor y_true, Tensor y_pred, Tensor sample_weight = null) | |||
| { | |||
| var losses = Apply(y_true, y_pred, from_logits: from_logits); | |||
| var reduction = GetReduction(); | |||
| return losses_utils.compute_weighted_loss(losses, reduction: reduction, sample_weight: sample_weight); | |||
| } | |||
| string GetReduction() | |||
| { | |||
| return reduction switch | |||
| { | |||
| ReductionV2.AUTO => ReductionV2.SUM_OVER_BATCH_SIZE, | |||
| _ => reduction | |||
| }; | |||
| } | |||
| void _set_name_scope() | |||
| string GetReduction() | |||
| { | |||
| return reduction switch | |||
| { | |||
| _name_scope = name; | |||
| } | |||
| ReductionV2.AUTO => ReductionV2.SUM_OVER_BATCH_SIZE, | |||
| _ => reduction | |||
| }; | |||
| } | |||
| void _set_name_scope() | |||
| { | |||
| _name_scope = name; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,16 +1,14 @@ | |||
| using Tensorflow.Keras.Utils; | |||
| namespace Tensorflow.Keras.Losses | |||
| namespace Tensorflow.Keras.Losses; | |||
| public abstract class LossFunctionWrapper : Loss | |||
| { | |||
| public class LossFunctionWrapper : Loss | |||
| { | |||
| public LossFunctionWrapper(string reduction = ReductionV2.AUTO, | |||
| string name = null, | |||
| bool from_logits = false) | |||
| : base(reduction: reduction, | |||
| name: name, | |||
| from_logits: from_logits) | |||
| { | |||
| } | |||
| } | |||
| public LossFunctionWrapper(string reduction = ReductionV2.AUTO, | |||
| string name = null, | |||
| bool from_logits = false) | |||
| : base(reduction: reduction, | |||
| name: name, | |||
| from_logits: from_logits) | |||
| { } | |||
| } | |||
| @@ -1,23 +1,16 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class MeanAbsoluteError : LossFunctionWrapper | |||
| { | |||
| public class MeanAbsoluteError : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public MeanAbsoluteError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_absolute_error" : name){ } | |||
| public MeanAbsoluteError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_absolute_error" : name){ } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| return gen_math_ops.mean(math_ops.abs(y_pred_dispatch - y_true_cast), ops.convert_to_tensor(-1)); | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| return gen_math_ops.mean(math_ops.abs(y_pred_dispatch - y_true_cast), ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| @@ -1,24 +1,17 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class MeanAbsolutePercentageError : LossFunctionWrapper | |||
| { | |||
| public class MeanAbsolutePercentageError : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public MeanAbsolutePercentageError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_absolute_percentage_error" : name){ } | |||
| public MeanAbsolutePercentageError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_absolute_percentage_error" : name){ } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor diff = math_ops.abs(y_true_cast - y_pred_dispatch) / gen_math_ops.maximum(math_ops.abs(y_true_cast), gen_math_ops.cast(tf.constant(1e-7), y_pred_dispatch.dtype)); | |||
| return gen_math_ops.cast(tf.constant(100), y_pred_dispatch.dtype) * gen_math_ops.mean(diff, ops.convert_to_tensor(-1)); | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor diff = math_ops.abs(y_true_cast - y_pred_dispatch) / gen_math_ops.maximum(math_ops.abs(y_true_cast), gen_math_ops.cast(tf.constant(1e-7), y_pred_dispatch.dtype)); | |||
| return gen_math_ops.cast(tf.constant(100), y_pred_dispatch.dtype) * gen_math_ops.mean(diff, ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| @@ -1,23 +1,16 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class MeanSquaredError : LossFunctionWrapper | |||
| { | |||
| public class MeanSquaredError : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public MeanSquaredError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name==null? "mean_squared_error" : name){ } | |||
| public MeanSquaredError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name==null? "mean_squared_error" : name){ } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| return gen_math_ops.mean(gen_math_ops.squared_difference(y_pred_dispatch, y_true_cast), ops.convert_to_tensor(-1)); | |||
| } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| return gen_math_ops.mean(gen_math_ops.squared_difference(y_pred_dispatch, y_true_cast), ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| @@ -1,33 +1,28 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| using static Tensorflow.KerasApi; | |||
| namespace Tensorflow.Keras.Losses; | |||
| namespace Tensorflow.Keras.Losses | |||
| public class MeanSquaredLogarithmicError : LossFunctionWrapper | |||
| { | |||
| public class MeanSquaredLogarithmicError : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public MeanSquaredLogarithmicError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_squared_logarithmic_error" : name){ } | |||
| public MeanSquaredLogarithmicError( | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "mean_squared_logarithmic_error" : name) | |||
| { } | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred =null, bool from_logits = false, int axis = -1) | |||
| public override Tensor Apply(Tensor y_true = null, Tensor y_pred = null, bool from_logits = false, int axis = -1) | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor first_log = null, second_log = null; | |||
| if (y_pred_dispatch.dtype == TF_DataType.TF_DOUBLE) | |||
| { | |||
| first_log = math_ops.log(math_ops.maximum(y_pred_dispatch, 1e-7) + 1.0); | |||
| second_log = math_ops.log(math_ops.maximum(y_true_cast, 1e-7) + 1.0); | |||
| } | |||
| else | |||
| { | |||
| Tensor y_pred_dispatch = ops.convert_to_tensor(y_pred); | |||
| Tensor y_true_cast = gen_math_ops.cast(y_true, y_pred_dispatch.dtype); | |||
| Tensor first_log=null, second_log=null; | |||
| if (y_pred_dispatch.dtype == TF_DataType.TF_DOUBLE) { | |||
| first_log = math_ops.log(math_ops.maximum(y_pred_dispatch, 1e-7) + 1.0); | |||
| second_log = math_ops.log(math_ops.maximum(y_true_cast, 1e-7) + 1.0); | |||
| } | |||
| else { | |||
| first_log = math_ops.log(math_ops.maximum(y_pred_dispatch, 1e-7f) + 1.0f); | |||
| second_log = math_ops.log(math_ops.maximum(y_true_cast, 1e-7f) + 1.0f); | |||
| } | |||
| return gen_math_ops.mean(gen_math_ops.squared_difference(first_log, second_log), ops.convert_to_tensor(-1)); | |||
| first_log = math_ops.log(math_ops.maximum(y_pred_dispatch, 1e-7f) + 1.0f); | |||
| second_log = math_ops.log(math_ops.maximum(y_true_cast, 1e-7f) + 1.0f); | |||
| } | |||
| return gen_math_ops.mean(gen_math_ops.squared_difference(first_log, second_log), ops.convert_to_tensor(-1)); | |||
| } | |||
| } | |||
| } | |||
| @@ -2,7 +2,7 @@ | |||
| namespace Tensorflow.Keras.Losses; | |||
| public class SigmoidFocalCrossEntropy : LossFunctionWrapper, ILossFunc | |||
| public class SigmoidFocalCrossEntropy : LossFunctionWrapper | |||
| { | |||
| float _alpha; | |||
| float _gamma; | |||
| @@ -20,7 +20,6 @@ public class SigmoidFocalCrossEntropy : LossFunctionWrapper, ILossFunc | |||
| _gamma = gamma; | |||
| } | |||
| public override Tensor Apply(Tensor y_true, Tensor y_pred, bool from_logits = false, int axis = -1) | |||
| { | |||
| y_true = tf.cast(y_true, dtype: y_pred.dtype); | |||
| @@ -1,41 +1,41 @@ | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.Keras.Losses | |||
| namespace Tensorflow.Keras.Losses; | |||
| public class SparseCategoricalCrossentropy : LossFunctionWrapper | |||
| { | |||
| public class SparseCategoricalCrossentropy : LossFunctionWrapper, ILossFunc | |||
| private bool _from_logits = false; | |||
| public SparseCategoricalCrossentropy( | |||
| bool from_logits = false, | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "sparse_categorical_crossentropy" : name) | |||
| { | |||
| _from_logits = from_logits; | |||
| } | |||
| public override Tensor Apply(Tensor target, Tensor output, bool from_logits = false, int axis = -1) | |||
| { | |||
| private bool _from_logits = false; | |||
| public SparseCategoricalCrossentropy( | |||
| bool from_logits = false, | |||
| string reduction = null, | |||
| string name = null) : | |||
| base(reduction: reduction, name: name == null ? "sparse_categorical_crossentropy" : name) | |||
| target = tf.cast(target, dtype: TF_DataType.TF_INT64); | |||
| if (!_from_logits) | |||
| { | |||
| _from_logits = from_logits; | |||
| var epsilon = tf.constant(KerasApi.keras.backend.epsilon(), output.dtype); | |||
| output = tf.clip_by_value(output, epsilon, 1 - epsilon); | |||
| output = tf.log(output); | |||
| } | |||
| public override Tensor Apply(Tensor target, Tensor output, bool from_logits = false, int axis = -1) | |||
| // Try to adjust the shape so that rank of labels = rank of logits - 1. | |||
| var output_shape = array_ops.shape_v2(output); | |||
| var output_rank = output.shape.ndim; | |||
| var target_rank = target.shape.ndim; | |||
| var update_shape = target_rank != output_rank - 1; | |||
| if (update_shape) | |||
| { | |||
| target = tf.cast(target, dtype: TF_DataType.TF_INT64); | |||
| if (!_from_logits) | |||
| { | |||
| var epsilon = tf.constant(KerasApi.keras.backend.epsilon(), output.dtype); | |||
| output = tf.clip_by_value(output, epsilon, 1 - epsilon); | |||
| output = tf.log(output); | |||
| } | |||
| // Try to adjust the shape so that rank of labels = rank of logits - 1. | |||
| var output_shape = array_ops.shape_v2(output); | |||
| var output_rank = output.shape.ndim; | |||
| var target_rank = target.shape.ndim; | |||
| var update_shape = target_rank != output_rank - 1; | |||
| if (update_shape) | |||
| { | |||
| target = array_ops.reshape(target, new int[] { -1 }); | |||
| output = array_ops.reshape(output, new int[] { -1, output_shape[-1].numpy() }); | |||
| } | |||
| return tf.nn.sparse_softmax_cross_entropy_with_logits(target, output); | |||
| target = array_ops.reshape(target, new int[] { -1 }); | |||
| output = array_ops.reshape(output, new int[] { -1, output_shape[-1].numpy() }); | |||
| } | |||
| return tf.nn.sparse_softmax_cross_entropy_with_logits(target, output); | |||
| } | |||
| } | |||
| } | |||