@@ -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)) |