Skip to content

fix: temporarily fix the sequential nest error. #1086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private static (MetaGraphDef, Graph, TrackableSaver, AssetInfo, IList<Trackable>
{
if (ops.inside_function())
{
throw new AssertionError("`tf.saved_model.save` is not supported inside a traced @tf.function. " +
throw new AssertionError("`tf.saved_model.save` is not supported inside a traced [AutoGraph]. " +
"Move the call to the outer eagerly-executed context.");
}

Expand Down
14 changes: 14 additions & 0 deletions src/TensorFlowNET.Keras/Engine/Layer.Apply.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,19 @@ public Tensors Apply(Tensors inputs, Tensor state = null, bool training = false)

return outputs;
}

// TODO(Rinne): remove it and completely fix issue 1084
[Obsolete]
private bool _enforce_layer_construction = false;
[Obsolete]
internal void enforce_layer_construction()
{
_enforce_layer_construction = true;
}
[Obsolete]
internal void unset_layer_construction()
{
_enforce_layer_construction = false;
}
}
}
2 changes: 1 addition & 1 deletion src/TensorFlowNET.Keras/Engine/Layer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ internal virtual void Initialize(LayerArgs args)
bool _in_functional_construction_mode(Tensors inputs)
{
return tf.Context.executing_eagerly()
&& inputs.Count(x => x is not EagerTensor && x is not NDArray) == inputs.Count();
&& inputs.Count(x => x is not EagerTensor && x is not NDArray) == inputs.Count() || _enforce_layer_construction;
}

public void SetConnectivityMetadata(Tensors inputs, Tensors outputs)
Expand Down
12 changes: 11 additions & 1 deletion src/TensorFlowNET.Keras/Engine/Sequential.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,17 @@ public void InitLayers(IEnumerable<ILayer> layers)
{
foreach(var layer in layers)
{
// TODO(Rinne): remove it and completely fix issue 1084
if(layer is Sequential s)
{
s.Layers.ForEach(x => ((Layer)x).enforce_layer_construction());
}
add(layer);
// TODO(Rinne): remove it and completely fix issue 1084
if (layer is Sequential s2)
{
s2.Layers.ForEach(x => ((Layer)x).unset_layer_construction());
}
}
}

Expand Down Expand Up @@ -163,7 +173,7 @@ void _build_graph_network_for_inferred_shape(Shape input_shape, TF_DataType inpu
Tensors layer_output = null;
Tensors outputs = null;
List<INode> created_nodes = new List<INode>();
foreach (var layer in args.Layers)
foreach (var layer in Layers)
{
clear_previously_created_nodes(layer, _created_nodes);
layer_output = layer.Apply(layer_input);
Expand Down
31 changes: 28 additions & 3 deletions test/TensorFlowNET.Keras.UnitTest/Model/ModelBuildTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using static Tensorflow.Binding;
using static Tensorflow.KerasApi;

namespace Tensorflow.Keras.UnitTest.Model
{
Expand All @@ -14,24 +16,47 @@ public void DenseBuild()
var dense = tf.keras.layers.Dense(64);
var output = dense.Apply(input);
var model = tf.keras.Model(input, output);
model.compile(tf.keras.optimizers.Adam(), tf.keras.losses.CategoricalCrossentropy());

// one dimensions input with unknown batchsize
var input_2 = tf.keras.layers.Input((60));
var dense_2 = tf.keras.layers.Dense(64);
var output_2 = dense.Apply(input_2);
var output_2 = dense_2.Apply(input_2);
var model_2 = tf.keras.Model(input_2, output_2);
model_2.compile(tf.keras.optimizers.Adam(), tf.keras.losses.CategoricalCrossentropy());

// two dimensions input with specified batchsize
var input_3 = tf.keras.layers.Input((17, 60), 8);
var dense_3 = tf.keras.layers.Dense(64);
var output_3 = dense.Apply(input_3);
var output_3 = dense_3.Apply(input_3);
var model_3 = tf.keras.Model(input_3, output_3);
model_3.compile(tf.keras.optimizers.Adam(), tf.keras.losses.CategoricalCrossentropy());

// one dimensions input with specified batchsize
var input_4 = tf.keras.layers.Input((60), 8);
var dense_4 = tf.keras.layers.Dense(64);
var output_4 = dense.Apply(input_4);
var output_4 = dense_4.Apply(input_4);
var model_4 = tf.keras.Model(input_4, output_4);
model_4.compile(tf.keras.optimizers.Adam(), tf.keras.losses.CategoricalCrossentropy());
}

[TestMethod]
public void NestedSequential()
{
var block1 = keras.Sequential(new[] {
keras.layers.InputLayer((3, 3)),
keras.Sequential(new []
{
keras.layers.Flatten(),
keras.layers.Dense(5)
}
)
});
block1.compile(tf.keras.optimizers.Adam(), tf.keras.losses.CategoricalCrossentropy());

var x = tf.ones((1, 3, 3));
var y = block1.predict(x);
Console.WriteLine(y);
}
}
}