| @@ -71,7 +71,7 @@ namespace Tensorflow.Keras.Engine | |||
| NodesByDepth = nodes_by_depth; | |||
| if (_layers.Count == 0) | |||
| _layers = layers; | |||
| _self_tracked_trackables = layers; | |||
| // Build self.input_names and self.output_names. | |||
| _set_output_names(); | |||
| @@ -53,9 +53,9 @@ namespace Tensorflow.Keras.Engine | |||
| //backend.track_variable(variable); | |||
| if (trainable == true) | |||
| trainable_weights.Add(variable); | |||
| _trainable_weights.Add(variable); | |||
| else | |||
| non_trainable_weights.Add(variable); | |||
| _non_trainable_weights.Add(variable); | |||
| return variable; | |||
| } | |||
| @@ -61,12 +61,12 @@ namespace Tensorflow.Keras.Engine | |||
| protected InputSpec inputSpec; | |||
| bool dynamic = true; | |||
| 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; | |||
| public int Id => id; | |||
| @@ -104,8 +104,8 @@ namespace Tensorflow.Keras.Engine | |||
| id = ops.uid_layer(); | |||
| _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; | |||
| updates = new List<Operation>(); | |||
| _self_tracked_trackables = new List<ILayer>(); | |||
| @@ -254,7 +254,7 @@ namespace Tensorflow.Keras.Engine | |||
| { | |||
| get | |||
| { | |||
| return trainable_weights; | |||
| return _trainable_weights; | |||
| } | |||
| } | |||
| @@ -262,7 +262,7 @@ namespace Tensorflow.Keras.Engine | |||
| { | |||
| get | |||
| { | |||
| return non_trainable_weights; | |||
| return _non_trainable_weights; | |||
| } | |||
| } | |||
| @@ -271,8 +271,8 @@ namespace Tensorflow.Keras.Engine | |||
| get | |||
| { | |||
| 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; | |||
| } | |||
| set | |||
| @@ -4,6 +4,7 @@ using System.Collections.Generic; | |||
| using System.Linq; | |||
| using Tensorflow.Keras.ArgsDefinition; | |||
| using Tensorflow.Keras.Engine.DataAdapters; | |||
| using System.Diagnostics; | |||
| namespace Tensorflow.Keras.Engine | |||
| { | |||
| @@ -87,25 +88,57 @@ namespace Tensorflow.Keras.Engine | |||
| { | |||
| stop_training = false; | |||
| _train_counter.assign(0); | |||
| Stopwatch sw = new Stopwatch(); | |||
| foreach (var (epoch, iterator) in data_handler.enumerate_epochs()) | |||
| { | |||
| reset_metrics(); | |||
| // callbacks.on_epoch_begin(epoch) | |||
| on_epoch_begin(epoch, epochs); | |||
| // data_handler.catch_stop_iteration(); | |||
| foreach (var step in data_handler.steps()) | |||
| { | |||
| // callbacks.on_train_batch_begin(step) | |||
| sw.Start(); | |||
| 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(); | |||
| } | |||
| } | |||
| 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 | |||
| { | |||
| 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) | |||
| { | |||
| if (layer.Trainable) | |||
| variables.AddRange(layer.trainable_variables); | |||
| } | |||
| // variables.AddRange(_trainable_weights); | |||
| return variables; | |||
| } | |||
| } | |||
| @@ -8,7 +8,7 @@ | |||
| "name": "Python: Current File", | |||
| "type": "python", | |||
| "request": "launch", | |||
| "program": "${file}", | |||
| "program": "${workspaceFolder}/xor_keras.py", | |||
| "console": "integratedTerminal", | |||
| "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)) | |||