| @@ -71,7 +71,7 @@ namespace Tensorflow.Keras.Engine | |||||
| NodesByDepth = nodes_by_depth; | NodesByDepth = nodes_by_depth; | ||||
| if (_layers.Count == 0) | if (_layers.Count == 0) | ||||
| _layers = layers; | _layers = layers; | ||||
| _self_tracked_trackables = layers; | |||||
| // Build self.input_names and self.output_names. | // Build self.input_names and self.output_names. | ||||
| _set_output_names(); | _set_output_names(); | ||||
| @@ -53,9 +53,9 @@ namespace Tensorflow.Keras.Engine | |||||
| //backend.track_variable(variable); | //backend.track_variable(variable); | ||||
| if (trainable == true) | if (trainable == true) | ||||
| trainable_weights.Add(variable); | |||||
| _trainable_weights.Add(variable); | |||||
| else | else | ||||
| non_trainable_weights.Add(variable); | |||||
| _non_trainable_weights.Add(variable); | |||||
| return variable; | return variable; | ||||
| } | } | ||||
| @@ -61,12 +61,12 @@ namespace Tensorflow.Keras.Engine | |||||
| protected InputSpec inputSpec; | protected InputSpec inputSpec; | ||||
| bool dynamic = true; | bool dynamic = true; | ||||
| public bool SupportsMasking { get; set; } | public bool SupportsMasking { get; set; } | ||||
| protected List<IVariableV1> trainable_weights; | |||||
| protected List<IVariableV1> _trainable_weights; | |||||
| public virtual List<IVariableV1> trainable_variables => trainable_weights; | |||||
| public virtual List<IVariableV1> trainable_variables => _trainable_weights; | |||||
| protected List<IVariableV1> non_trainable_weights; | |||||
| public List<IVariableV1> non_trainable_variables => non_trainable_weights; | |||||
| protected List<IVariableV1> _non_trainable_weights; | |||||
| public List<IVariableV1> non_trainable_variables => _non_trainable_weights; | |||||
| protected int id; | protected int id; | ||||
| public int Id => id; | public int Id => id; | ||||
| @@ -104,8 +104,8 @@ namespace Tensorflow.Keras.Engine | |||||
| id = ops.uid_layer(); | id = ops.uid_layer(); | ||||
| _init_set_name(args.Name); | _init_set_name(args.Name); | ||||
| trainable_weights = new List<IVariableV1>(); | |||||
| non_trainable_weights = new List<IVariableV1>(); | |||||
| _trainable_weights = new List<IVariableV1>(); | |||||
| _non_trainable_weights = new List<IVariableV1>(); | |||||
| computePreviousMask = false; | computePreviousMask = false; | ||||
| updates = new List<Operation>(); | updates = new List<Operation>(); | ||||
| _self_tracked_trackables = new List<ILayer>(); | _self_tracked_trackables = new List<ILayer>(); | ||||
| @@ -254,7 +254,7 @@ namespace Tensorflow.Keras.Engine | |||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| return trainable_weights; | |||||
| return _trainable_weights; | |||||
| } | } | ||||
| } | } | ||||
| @@ -262,7 +262,7 @@ namespace Tensorflow.Keras.Engine | |||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| return non_trainable_weights; | |||||
| return _non_trainable_weights; | |||||
| } | } | ||||
| } | } | ||||
| @@ -271,8 +271,8 @@ namespace Tensorflow.Keras.Engine | |||||
| get | get | ||||
| { | { | ||||
| var weights = new List<IVariableV1>(); | var weights = new List<IVariableV1>(); | ||||
| weights.AddRange(trainable_weights); | |||||
| weights.AddRange(non_trainable_weights); | |||||
| weights.AddRange(_trainable_weights); | |||||
| weights.AddRange(_non_trainable_weights); | |||||
| return weights; | return weights; | ||||
| } | } | ||||
| set | set | ||||
| @@ -4,6 +4,7 @@ using System.Collections.Generic; | |||||
| using System.Linq; | using System.Linq; | ||||
| using Tensorflow.Keras.ArgsDefinition; | using Tensorflow.Keras.ArgsDefinition; | ||||
| using Tensorflow.Keras.Engine.DataAdapters; | using Tensorflow.Keras.Engine.DataAdapters; | ||||
| using System.Diagnostics; | |||||
| namespace Tensorflow.Keras.Engine | namespace Tensorflow.Keras.Engine | ||||
| { | { | ||||
| @@ -87,25 +88,57 @@ namespace Tensorflow.Keras.Engine | |||||
| { | { | ||||
| stop_training = false; | stop_training = false; | ||||
| _train_counter.assign(0); | _train_counter.assign(0); | ||||
| Stopwatch sw = new Stopwatch(); | |||||
| foreach (var (epoch, iterator) in data_handler.enumerate_epochs()) | foreach (var (epoch, iterator) in data_handler.enumerate_epochs()) | ||||
| { | { | ||||
| reset_metrics(); | reset_metrics(); | ||||
| // callbacks.on_epoch_begin(epoch) | |||||
| on_epoch_begin(epoch, epochs); | |||||
| // data_handler.catch_stop_iteration(); | // data_handler.catch_stop_iteration(); | ||||
| foreach (var step in data_handler.steps()) | foreach (var step in data_handler.steps()) | ||||
| { | { | ||||
| // callbacks.on_train_batch_begin(step) | |||||
| sw.Start(); | |||||
| var results = train_step_function(iterator); | var results = train_step_function(iterator); | ||||
| if (verbose == 1) | |||||
| sw.Stop(); | |||||
| on_train_batch_begin(verbose, step, sw.ElapsedMilliseconds, results); | |||||
| // recycle memory more frequency | |||||
| if (sw.ElapsedMilliseconds > 100) | |||||
| { | { | ||||
| var result_pairs = string.Join(", ", results.Select(x => $"{x.Item1}: {(float)x.Item2:F6}")); | |||||
| Binding.tf_output_redirect.WriteLine($"Epoch: {epoch + 1:D3}/{epochs:D3}, Step: {step + 1:D4}/{data_handler.Inferredsteps:D4}, {result_pairs}"); | |||||
| GC.Collect(); | |||||
| } | } | ||||
| GC.Collect(); | |||||
| sw.Reset(); | |||||
| } | } | ||||
| Console.WriteLine(); | |||||
| GC.Collect(); | |||||
| GC.WaitForPendingFinalizers(); | GC.WaitForPendingFinalizers(); | ||||
| } | } | ||||
| } | } | ||||
| void on_epoch_begin(int epoch, int epochs) | |||||
| { | |||||
| Binding.tf_output_redirect.WriteLine($"Epoch: {epoch + 1:D3}/{epochs:D3}"); | |||||
| } | |||||
| void on_train_batch_begin(int verbose, long step, long elapse, IEnumerable<(string, Tensor)> results) | |||||
| { | |||||
| if (verbose == 1) | |||||
| { | |||||
| var result_pairs = string.Join(", ", results.Select(x => $"{x.Item1}: {(float)x.Item2:F6}")); | |||||
| var progress = ""; | |||||
| for (int i = 0; i < step + 1; i++) | |||||
| for (int j = 0; j < 30 / data_handler.Inferredsteps; j++) | |||||
| progress += "="; | |||||
| progress += ">"; | |||||
| var remaining = ""; | |||||
| for (int i = 1; i < 30 - progress.Length; i++) | |||||
| remaining += "."; | |||||
| Binding.tf_output_redirect.Write($"{step + 1:D4}/{data_handler.Inferredsteps:D4} [{progress}{remaining}] - {elapse}ms/step {result_pairs}"); | |||||
| Console.CursorLeft = 0; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -75,11 +75,26 @@ namespace Tensorflow.Keras.Engine | |||||
| get | get | ||||
| { | { | ||||
| var variables = new List<IVariableV1>(); | var variables = new List<IVariableV1>(); | ||||
| if (!Trainable) | |||||
| { | |||||
| return variables; | |||||
| } | |||||
| foreach (var trackable_obj in _self_tracked_trackables) | |||||
| { | |||||
| if (trackable_obj.Trainable) | |||||
| variables.AddRange(trackable_obj.trainable_variables); | |||||
| } | |||||
| foreach (var layer in _layers) | foreach (var layer in _layers) | ||||
| { | { | ||||
| if (layer.Trainable) | if (layer.Trainable) | ||||
| variables.AddRange(layer.trainable_variables); | variables.AddRange(layer.trainable_variables); | ||||
| } | } | ||||
| // variables.AddRange(_trainable_weights); | |||||
| return variables; | return variables; | ||||
| } | } | ||||
| } | } | ||||
| @@ -8,7 +8,7 @@ | |||||
| "name": "Python: Current File", | "name": "Python: Current File", | ||||
| "type": "python", | "type": "python", | ||||
| "request": "launch", | "request": "launch", | ||||
| "program": "${file}", | |||||
| "program": "${workspaceFolder}/xor_keras.py", | |||||
| "console": "integratedTerminal", | "console": "integratedTerminal", | ||||
| "justMyCode": false | "justMyCode": false | ||||
| } | } | ||||
| @@ -0,0 +1,23 @@ | |||||
| import os | |||||
| import numpy as np | |||||
| import tensorflow as tf | |||||
| os.environ["CUDA_VISIBLE_DEVICES"] = "-1" | |||||
| print(tf.__version__) | |||||
| # tf.compat.v1.enable_eager_execution() | |||||
| # tf.debugging.set_log_device_placement(True); | |||||
| tf.config.run_functions_eagerly(True) | |||||
| x = np.array([[ 0, 0 ], [ 0, 1 ], [ 1, 0 ], [ 1, 1 ]]) | |||||
| y = np.array([[ 0 ], [ 1 ], [ 1 ], [ 0 ] ]) | |||||
| model = tf.keras.Sequential() | |||||
| model.add(tf.keras.Input(2)) | |||||
| model.add(tf.keras.layers.Dense(32, "relu")) | |||||
| model.add(tf.keras.layers.Dense(1, "sigmoid")) | |||||
| model.compile(optimizer = tf.keras.optimizers.Adam(), | |||||
| loss = tf.keras.losses.MeanSquaredError(), | |||||
| metrics = ["accuracy"]) | |||||
| model.fit(x, y, 1, 100) | |||||
| result = model.evaluate(x, y) | |||||
| print(model.predict(x, 4)) | |||||