| @@ -1,7 +1,16 @@ | |||||
| namespace Tensorflow.Keras | |||||
| using Newtonsoft.Json; | |||||
| using System.Collections.Generic; | |||||
| using Tensorflow.Keras.Saving.Common; | |||||
| namespace Tensorflow.Keras | |||||
| { | { | ||||
| public interface IRegularizer | |||||
| { | |||||
| Tensor Apply(RegularizerArgs args); | |||||
| [JsonConverter(typeof(CustomizedRegularizerJsonConverter))] | |||||
| public interface IRegularizer | |||||
| { | |||||
| [JsonProperty("class_name")] | |||||
| string ClassName { get; } | |||||
| [JsonProperty("config")] | |||||
| IDictionary<string, object> Config { get; } | |||||
| Tensor Apply(RegularizerArgs args); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,57 @@ | |||||
| using Newtonsoft.Json.Linq; | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| using Tensorflow.Operations.Regularizers; | |||||
| namespace Tensorflow.Keras.Saving.Common | |||||
| { | |||||
| class RegularizerInfo | |||||
| { | |||||
| public string class_name { get; set; } | |||||
| public JObject config { get; set; } | |||||
| } | |||||
| public class CustomizedRegularizerJsonConverter : JsonConverter | |||||
| { | |||||
| public override bool CanConvert(Type objectType) | |||||
| { | |||||
| return objectType == typeof(IRegularizer); | |||||
| } | |||||
| public override bool CanRead => true; | |||||
| public override bool CanWrite => true; | |||||
| public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) | |||||
| { | |||||
| var regularizer = value as IRegularizer; | |||||
| if (regularizer is null) | |||||
| { | |||||
| JToken.FromObject(null).WriteTo(writer); | |||||
| return; | |||||
| } | |||||
| JToken.FromObject(new RegularizerInfo() | |||||
| { | |||||
| class_name = regularizer.ClassName, | |||||
| config = JObject.FromObject(regularizer.Config) | |||||
| }, serializer).WriteTo(writer); | |||||
| } | |||||
| public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) | |||||
| { | |||||
| var info = serializer.Deserialize<RegularizerInfo>(reader); | |||||
| if (info is null) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| return info.class_name switch | |||||
| { | |||||
| "L1L2" => new L1L2 (info.config["l1"].ToObject<float>(), info.config["l2"].ToObject<float>()), | |||||
| "L1" => new L1(info.config["l1"].ToObject<float>()), | |||||
| "L2" => new L2(info.config["l2"].ToObject<float>()), | |||||
| }; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| using System; | |||||
| using Tensorflow.Keras; | |||||
| namespace Tensorflow.Operations.Regularizers | |||||
| { | |||||
| public class L1 : IRegularizer | |||||
| { | |||||
| float _l1; | |||||
| private readonly Dictionary<string, object> _config; | |||||
| public string ClassName => "L2"; | |||||
| public virtual IDictionary<string, object> Config => _config; | |||||
| public L1(float l1 = 0.01f) | |||||
| { | |||||
| // l1 = 0.01 if l1 is None else l1 | |||||
| // validate_float_arg(l1, name = "l1") | |||||
| // self.l1 = ops.convert_to_tensor(l1) | |||||
| this._l1 = l1; | |||||
| _config = new(); | |||||
| _config["l1"] = _l1; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| //return self.l1 * ops.sum(ops.absolute(x)) | |||||
| return _l1 * math_ops.reduce_sum(math_ops.abs(args.X)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| using System; | |||||
| using Tensorflow.Keras; | |||||
| namespace Tensorflow.Operations.Regularizers | |||||
| { | |||||
| public class L1L2 : IRegularizer | |||||
| { | |||||
| float _l1; | |||||
| float _l2; | |||||
| private readonly Dictionary<string, object> _config; | |||||
| public string ClassName => "L1L2"; | |||||
| public virtual IDictionary<string, object> Config => _config; | |||||
| public L1L2(float l1 = 0.0f, float l2 = 0.0f) | |||||
| { | |||||
| //l1 = 0.0 if l1 is None else l1 | |||||
| //l2 = 0.0 if l2 is None else l2 | |||||
| // validate_float_arg(l1, name = "l1") | |||||
| // validate_float_arg(l2, name = "l2") | |||||
| // self.l1 = l1 | |||||
| // self.l2 = l2 | |||||
| this._l1 = l1; | |||||
| this._l2 = l2; | |||||
| _config = new(); | |||||
| _config["l1"] = l1; | |||||
| _config["l2"] = l2; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| //regularization = ops.convert_to_tensor(0.0, dtype = x.dtype) | |||||
| //if self.l1: | |||||
| // regularization += self.l1 * ops.sum(ops.absolute(x)) | |||||
| //if self.l2: | |||||
| // regularization += self.l2 * ops.sum(ops.square(x)) | |||||
| //return regularization | |||||
| Tensor regularization = tf.constant(0.0, args.X.dtype); | |||||
| regularization += _l1 * math_ops.reduce_sum(math_ops.abs(args.X)); | |||||
| regularization += _l2 * math_ops.reduce_sum(math_ops.square(args.X)); | |||||
| return regularization; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| using System; | |||||
| using Tensorflow.Keras; | |||||
| namespace Tensorflow.Operations.Regularizers | |||||
| { | |||||
| public class L2 : IRegularizer | |||||
| { | |||||
| float _l2; | |||||
| private readonly Dictionary<string, object> _config; | |||||
| public string ClassName => "L2"; | |||||
| public virtual IDictionary<string, object> Config => _config; | |||||
| public L2(float l2 = 0.01f) | |||||
| { | |||||
| // l2 = 0.01 if l2 is None else l2 | |||||
| // validate_float_arg(l2, name = "l2") | |||||
| // self.l2 = l2 | |||||
| this._l2 = l2; | |||||
| _config = new(); | |||||
| _config["l2"] = _l2; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| //return self.l2 * ops.sum(ops.square(x)) | |||||
| return _l2 * math_ops.reduce_sum(math_ops.square(args.X)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,8 +1,17 @@ | |||||
| namespace Tensorflow.Keras | namespace Tensorflow.Keras | ||||
| { | { | ||||
| public class Regularizers | |||||
| { | |||||
| public IRegularizer l2(float l2 = 0.01f) | |||||
| => new L2(l2); | |||||
| } | |||||
| public class Regularizers | |||||
| { | |||||
| public IRegularizer l1(float l1 = 0.01f) | |||||
| => new Tensorflow.Operations.Regularizers.L1(l1); | |||||
| public IRegularizer l2(float l2 = 0.01f) | |||||
| => new Tensorflow.Operations.Regularizers.L2(l2); | |||||
| //From TF source | |||||
| //# The default value for l1 and l2 are different from the value in l1_l2 | |||||
| //# for backward compatibility reason. Eg, L1L2(l2=0.1) will only have l2 | |||||
| //# and no l1 penalty. | |||||
| public IRegularizer l1l2(float l1 = 0.00f, float l2 = 0.00f) | |||||
| => new Tensorflow.Operations.Regularizers.L1L2(l1, l2); | |||||
| } | |||||
| } | } | ||||
| @@ -1,19 +0,0 @@ | |||||
| using System; | |||||
| namespace Tensorflow.Keras | |||||
| { | |||||
| public class L1 : IRegularizer | |||||
| { | |||||
| float l1; | |||||
| public L1(float l1 = 0.01f) | |||||
| { | |||||
| this.l1 = l1; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| return l1 * math_ops.reduce_sum(math_ops.abs(args.X)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,24 +0,0 @@ | |||||
| using System; | |||||
| using static Tensorflow.Binding; | |||||
| namespace Tensorflow.Keras | |||||
| { | |||||
| public class L1L2 : IRegularizer | |||||
| { | |||||
| float l1; | |||||
| float l2; | |||||
| public L1L2(float l1 = 0.0f, float l2 = 0.0f) | |||||
| { | |||||
| this.l1 = l1; | |||||
| this.l2 = l2; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| Tensor regularization = tf.constant(0.0, args.X.dtype); | |||||
| regularization += l1 * math_ops.reduce_sum(math_ops.abs(args.X)); | |||||
| regularization += l2 * math_ops.reduce_sum(math_ops.square(args.X)); | |||||
| return regularization; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,17 +0,0 @@ | |||||
| namespace Tensorflow.Keras | |||||
| { | |||||
| public class L2 : IRegularizer | |||||
| { | |||||
| float l2; | |||||
| public L2(float l2 = 0.01f) | |||||
| { | |||||
| this.l2 = l2; | |||||
| } | |||||
| public Tensor Apply(RegularizerArgs args) | |||||
| { | |||||
| return l2 * math_ops.reduce_sum(math_ops.square(args.X)); | |||||
| } | |||||
| } | |||||
| } | |||||