@@ -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 | |||
{ | |||
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)); | |||
} | |||
} | |||
} |