| @@ -1,5 +1,6 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Diagnostics; | |||||
| using System.Dynamic; | using System.Dynamic; | ||||
| using System.Text; | using System.Text; | ||||
| @@ -7,6 +8,7 @@ namespace Tensorflow | |||||
| { | { | ||||
| public static partial class Binding | public static partial class Binding | ||||
| { | { | ||||
| [DebuggerNonUserCode] | |||||
| public static tensorflow tf { get; } = New<tensorflow>(); | public static tensorflow tf { get; } = New<tensorflow>(); | ||||
| /// <summary> | /// <summary> | ||||
| @@ -65,6 +65,7 @@ namespace Tensorflow.Contexts | |||||
| /// Checks whether the current thread has eager execution enabled. | /// Checks whether the current thread has eager execution enabled. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns></returns> | /// <returns></returns> | ||||
| [DebuggerStepThrough] | |||||
| public bool executing_eagerly() | public bool executing_eagerly() | ||||
| => context_switches.Current().EagerMode; | => context_switches.Current().EagerMode; | ||||
| @@ -16,7 +16,6 @@ namespace Tensorflow.Keras.Engine | |||||
| Mean _loss_metric; | Mean _loss_metric; | ||||
| bool _built; | bool _built; | ||||
| Tensor[] _per_output_metrics; | Tensor[] _per_output_metrics; | ||||
| List<Tensor> loss_values; | |||||
| List<Tensor> loss_metric_values; | List<Tensor> loss_metric_values; | ||||
| public LossesContainer(ILossFunc losses, string[] output_names = null) | public LossesContainer(ILossFunc losses, string[] output_names = null) | ||||
| @@ -25,7 +24,6 @@ namespace Tensorflow.Keras.Engine | |||||
| _user_losses = losses; | _user_losses = losses; | ||||
| _losses = losses; | _losses = losses; | ||||
| _loss_metric = new Mean(name: "loss"); | _loss_metric = new Mean(name: "loss"); | ||||
| loss_values = new List<Tensor>(); | |||||
| loss_metric_values = new List<Tensor>(); | loss_metric_values = new List<Tensor>(); | ||||
| _built = false; | _built = false; | ||||
| } | } | ||||
| @@ -37,15 +35,17 @@ namespace Tensorflow.Keras.Engine | |||||
| /// <param name="y_pred"></param> | /// <param name="y_pred"></param> | ||||
| public Tensor Call(Tensor y_true, Tensor y_pred) | public Tensor Call(Tensor y_true, Tensor y_pred) | ||||
| { | { | ||||
| Build(y_pred); | |||||
| if (!_built) | |||||
| Build(y_pred); | |||||
| var loss_value = _losses.Call(y_true, y_pred); | var loss_value = _losses.Call(y_true, y_pred); | ||||
| var loss_metric_value = loss_value; | var loss_metric_value = loss_value; | ||||
| var batch_dim = array_ops.shape(y_true)[0]; | var batch_dim = array_ops.shape(y_true)[0]; | ||||
| var loss_values = new List<Tensor>(); | |||||
| /*if (_losses.Reduction == ReductionV2.SUM_OVER_BATCH_SIZE | /*if (_losses.Reduction == ReductionV2.SUM_OVER_BATCH_SIZE | ||||
| || _losses.Reduction == ReductionV2.AUTO) | || _losses.Reduction == ReductionV2.AUTO) | ||||
| loss_value = losses_utils.scale_loss_for_distribution(loss_value);*/ | loss_value = losses_utils.scale_loss_for_distribution(loss_value);*/ | ||||
| loss_values.append(loss_value); | loss_values.append(loss_value); | ||||
| loss_metric_values.append(loss_metric_value); | loss_metric_values.append(loss_metric_value); | ||||
| @@ -11,6 +11,8 @@ namespace Tensorflow.Keras.Optimizers | |||||
| public class RMSprop : OptimizerV2 | public class RMSprop : OptimizerV2 | ||||
| { | { | ||||
| RMSpropArgs args; | RMSpropArgs args; | ||||
| bool centered => args.Centered; | |||||
| protected override string _name => "RMSprop"; | |||||
| public RMSprop(RMSpropArgs args) : base(args) | public RMSprop(RMSpropArgs args) : base(args) | ||||
| { | { | ||||
| @@ -18,5 +20,60 @@ namespace Tensorflow.Keras.Optimizers | |||||
| _set_hyper("rho", args.RHO); | _set_hyper("rho", args.RHO); | ||||
| _set_hyper("momentum", args.Momentum); | _set_hyper("momentum", args.Momentum); | ||||
| } | } | ||||
| protected override void _create_slots(IVariableV1[] var_list) | |||||
| { | |||||
| foreach (var var in var_list) | |||||
| add_slot(var, "rms"); | |||||
| if (_momentum) | |||||
| foreach (var var in var_list) | |||||
| add_slot(var, "momentum"); | |||||
| if (centered) | |||||
| foreach (var var in var_list) | |||||
| add_slot(var, "mg"); | |||||
| } | |||||
| protected override void _prepare_local(DeviceDType device_dtype, Dictionary<DeviceDType, Dictionary<string, Tensor>> _apply_state) | |||||
| { | |||||
| base._prepare_local(device_dtype, _apply_state); | |||||
| var rho = array_ops.identity(_get_hyper("rho", device_dtype.DType)); | |||||
| _apply_state[device_dtype]["neg_lr_t"] = -_apply_state[device_dtype]["lr_t"]; | |||||
| _apply_state[device_dtype]["epsilon"] = ops.convert_to_tensor(args.Epsilon, dtype: device_dtype.DType); | |||||
| _apply_state[device_dtype]["rho"] = rho; | |||||
| _apply_state[device_dtype]["momentum"] = array_ops.identity(_get_hyper("momentum", device_dtype.DType)); | |||||
| _apply_state[device_dtype]["one_minus_rho"] = 1.0f - rho; | |||||
| } | |||||
| protected override Operation _resource_apply_dense(IVariableV1 var, Tensor grad, Dictionary<DeviceDType, Dictionary<string, Tensor>> _apply_state) | |||||
| { | |||||
| Dictionary<string, Tensor> coefficients = null; | |||||
| foreach (var state in _apply_state) | |||||
| { | |||||
| if (state.Key.DType == var.dtype.as_base_dtype() | |||||
| && state.Key.Device == var.Device) | |||||
| { | |||||
| coefficients = state.Value; | |||||
| break; | |||||
| } | |||||
| } | |||||
| var rms = get_slot(var, "rms"); | |||||
| if (_momentum) | |||||
| { | |||||
| throw new NotImplementedException(""); | |||||
| } | |||||
| else | |||||
| { | |||||
| var rms_t = coefficients["rho"] * rms.AsTensor() + coefficients["one_minus_rho"] * math_ops.square(grad); | |||||
| rms_t = state_ops.assign(rms, rms_t, use_locking: _use_locking); | |||||
| var denom_t = rms_t; | |||||
| if (centered) | |||||
| { | |||||
| throw new NotImplementedException(""); | |||||
| } | |||||
| var var_t = var.AsTensor() - coefficients["lr_t"] * grad / (math_ops.sqrt(denom_t) + coefficients["epsilon"]); | |||||
| return state_ops.assign(var, var_t, use_locking: _use_locking).op; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -25,7 +25,11 @@ https://tensorflownet.readthedocs.io</Description> | |||||
| * Eager Mode is added finally. | * Eager Mode is added finally. | ||||
| * tf.keras is partially working. | * tf.keras is partially working. | ||||
| * tf.data is added. | * tf.data is added. | ||||
| * autograph works partially.</PackageReleaseNotes> | |||||
| * autograph works partially. | |||||
| TensorFlow .NET v0.30 is focused on making more Keras API work including: | |||||
| * tf.keras.datasets | |||||
| * Building keras model in subclass, functional and sequential api</PackageReleaseNotes> | |||||
| <FileVersion>0.30.0.0</FileVersion> | <FileVersion>0.30.0.0</FileVersion> | ||||
| <PackageLicenseFile>LICENSE</PackageLicenseFile> | <PackageLicenseFile>LICENSE</PackageLicenseFile> | ||||
| <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||||
| @@ -58,7 +58,7 @@ namespace Tensorflow | |||||
| /// The Operation that produces this tensor as an output. | /// The Operation that produces this tensor as an output. | ||||
| /// </summary> | /// </summary> | ||||
| public Operation op => _op; | public Operation op => _op; | ||||
| public Tensor[] outputs => op.outputs; | |||||
| public Tensor[] outputs => op?.outputs; | |||||
| /// <summary> | /// <summary> | ||||
| /// The string name of this tensor.<br/> | /// The string name of this tensor.<br/> | ||||