Closed SchoenTannenbaum closed 1 month ago
Please take a look into https://github.com/SciSharp/TensorFlow.NET/blob/8775b0b87adf5462c51a6a4340fdbf99d2e670e9/src/TensorFlowNET.Keras/Utils/generic_utils.cs#L62
and
In this method, we use reflection to create an object according to the loaded class name and args. Generally you will see a class name related with IRegularizer
here.
Besides, since your error is related with json serialization, please also look into this folder, which contains many json converters. Maybe you need to add a similar converter of IRegularizer.
I feel sorry but I don't have enough time to write the code and fix this issue recently. However, if you would like to dig into it, I'd like to help you with your questions here.
Hi @AsakusaRinne,
Thank you for your response and for helping!
Like you mentioned, the error is coming from a call to the method deserialize_keras_object(string class_name, JToken config)
, with the exception thrown specifically on this line: https://github.com/SciSharp/TensorFlow.NET/blob/8775b0b87adf5462c51a6a4340fdbf99d2e670e9/src/TensorFlowNET.Keras/Utils/generic_utils.cs#L72
I'm not to familiar with how reflection is done here, but in trying to construct Tensorflow.Keras.ArgsDefinition.Conv2DArg
via Invoke()
with the config as param, it chokes when going through this JSON object from inside the config:
"bias_regularizer": {
"class_name": "L1L2",
"config": {
"l1": 9.999999747378752E-05,
"l2": 0.0
},
"shared_object_id": 3
}
What kind of custom JsonConverter should I put together to get it to create the required C# object without problems? How do these custom converters in that folder get called?
Hi, please add a converter named CustomizedRegularizerJsonConverter
. You could refer to the implementation of CustomizedIinitializerJsonConverter. You need to implement two methods, which are WriteJson
and ReadJson
.
Don't worry, since there's only three regularizers now (L1, L2 and L1L2), when reading the json, you only need to switch the class name and create corresponding object for it. When writing the json, you have two choices. One is to switch the object type and write to json object manually, the other is to add properties with [JsonProperty(NAME)]
to L1, L2 and L1L1 classes.
After adding the converter, please add an attribute [JsonConverter(typeof(CustomizedRegularizerJsonConverter))]
to IRegularizer
.
Thanks!
I noticed that in Project Tensorflow.Keras
there are already L1
, L2
, and L1L2
classes that implement IRegularizer
. Should these be moved to Project Tensorflow.Bindings
in somewhere like namespace Tensorflow.Operations.Regularizers
and modified there instead?
As well, are the operations already implemented in the Apply()
methods of the L1
, L2
, and L1L2
classes in Project Tensorflow.Keras
correct?
I noticed that in Project Tensorflow.Keras there are already L1, L2, and L1L2 classes that implement IRegularizer. Should these be moved to Project Tensorflow.Bindings in somewhere like namespace Tensorflow.Operations.Regularizers and modified there instead?
They are supposed to be in the keras package. :)
As well, are the operations already implemented in the Apply() methods of the L1, L2, and L1L2 classes in Project Tensorflow.Keras correct?
TBH I've never used them. That's why the serialization and deserialization of them were left not implemented... They were added before I began to contribute to Tensorflow.NET. I'll help you if you find the implementation incorrect.
They are supposed to be in the keras package. :)
I guess I'm a bit confused how things are organized and the naming of the projects...
IRegularizer
is in namespace Tensorflow.Keras
of Project Tensorflow.Bindings
, though the L1
, L2
, and L1L2
classes of Project Tensorflow.Keras
through its dependency on Project Tensorflow.Bindings
refer that interface .
I may very well be implementing something wrong... but since Project Tensorflow.Bindings
does not depend on Project Tensorflow.Keras
, rather than either duplicating the classes on both projects, Project Tensorflow.Keras
could just refer to the classes if we move them there?
TBH I've never used them. That's why the serialization and deserialization of them were left not implemented... They were added before I began to contribute to Tensorflow.NET. I'll help you if you find the implementation incorrect.
I'll see if the regularizer operations are correct. Hopefully the implementer checked how it was done in the original.
I may very well be implementing something wrong... but since Project Tensorflow.Bindings does not depend on Project Tensorflow.Keras, rather than either duplicating the classes on both projects, Project Tensorflow.Keras could just refer to the classes if we move them there?
Since Tensorflow.Keras
depends on Tensorflow.Binding
, a recycling reference will be detected if making Tensorflow.Keras
of one of Tensorflow.Binding
's dependency. The reason of putting IRegularizer in
Tensorflow.Bindingis because it's needed in
Tensorflow.Binding`.
TBH I don't like this design, which is from the creator of tf.net. I prefer to include Tensorflow.Keras
in Tensorflow.Binding
so that it won't be confusing. However, it will make huge break change so at this time we still need to follow the design...
a recycling reference will be detected if making Tensorflow.Keras of one of Tensorflow.Binding's dependency.
I understand that Project Tensorflow.Keras
should not be one of Project Tensorflow.Binding
's dependencies. What I'm saying is that since the classes in Project Tensorflow.Keras
are already using IRegularizer
there and the dependency is already there, they might as well be move so that we don't duplicate these classes.
I understand what you are talking about. However, L1L2
regularizer seems to be a part of keras instead of tensorflow itself. Tensorflow.NET is a binding for tensorflow so I think we should either do nothing or merge these two packages (making keras a namespace of tf.net package).
So where should we locate the regularizer classes? Tensorflow.Binding needs L1L2
in its project to deserialize these objects, which would mean that if we don't move them from the Tensorflow.Keras
projects we would have to 1) do a circular reference or 2) make the same copy in both projects. Both these ways are not ideal.
I'm looking at the TF 2.15 doc and though L1L2
is in Keras, it is also part of the TF API https://www.tensorflow.org/versions/r2.15/api_docs/python/tf/keras/regularizers/L1L2
Incidentally, the operations in the Apply()
methods in one of the regularizers and one of the default values another are wrong. They're a straightforward fixs and I've done them on my side.
Oh, sorry, you're right. I forgot that the class is required in the json converter. Then please put it in Tensorflow.Operations
is fine. :)
Thanks! Seems to work now!
Would you like to make a PR for your fix? That will help others who have the same problem in the future.
For sure! I put something together tomorrow.
BTW are coded unit tests required for PR to this project? If not, then : https://github.com/SciSharp/TensorFlow.NET/pull/1248
Yes, but a simple one is enough. You could either add your model files to this asset and add a simple unit test like this one https://github.com/SciSharp/TensorFlow.NET/blob/master/test/TensorFlowNET.Keras.UnitTest/Model/ModelLoadTest.cs#L68
I modded ModelSaveTest to write out the bias_regularizer which ModelLoadTest read in. It passes.
Messed something on my machine and had to redo everything. Please see PR at https://github.com/SciSharp/TensorFlow.NET/pull/1250
Description
Hi, I recently started using TensorFlow.NET and was trying to load my saved Keras model, but I get an exception thrown during model deserialization.
Specifically:
var model = tf.keras.models.load_model("TestModel", false);
However, I get this error:
Stepping through the source (cloned from the project branch at commit 8775b0b), the exception seem to be thrown on Line 40 of
I've tried to step further in TensorFlow.Keras and TensorFlow.Binding but I cannot find the cause.
ConvolutionalArgs.cs
during deserialization of config for my model'sbias_regularizer
object (of classL1L2
) from its second layer (of classConv2D
):The model I used is here: TestModel.zip
Is there something I need to specify when I save to the SavedModel in my Python script to avoid this exception when loading in C#?
Or is this something I need to do while using the Tensorflow.NET bindings to let it ingest this model without issues?
Any help for this would be greatly appreciated. Thank you!