SciSharp / TensorFlow.NET

.NET Standard bindings for Google's TensorFlow for developing, training and deploying Machine Learning models in C# and F#.
https://scisharp.github.io/tensorflow-net-docs
Apache License 2.0
3.25k stars 523 forks source link

Tensorflow.NET version of set_weights() #1025

Closed FrancescoRusticali closed 1 year ago

FrancescoRusticali commented 1 year ago

Description

I am trying to find a way to set weights of an individual neuron or layer manually without training. Is there any corresponding in Tensorflow.NET to python function set_weights? In version 100.4 I couldn't find any.

Alternatives

No response

AsakusaRinne commented 1 year ago

What if just using the setter of the property Weights of an Layer object?

FrancescoRusticali commented 1 year ago

I'm not sure if this is the right way to do it. Currently it's throwing a NullReferenceException.

The following code snippet is an example:

        var layers = new LayersApi();

        var sequential = keras.Sequential();
        var inputs = keras.Input(shape: new Shape(8));
        sequential.add(inputs);
        sequential.add(layers.Dense(8, "relu"));

        sequential.compile(loss: keras.losses.SparseCategoricalCrossentropy(from_logits: true),
                            optimizer: keras.optimizers.Adam(),
                            metrics: new[] { "accuracy" });

        float[,] myArray = new float[8, 8]
        {
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
            { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f },
        };

        Tensor myTensor = new Tensor(myArray);
        sequential.Weights[0] = new ResourceVariable(myTensor);

It's maybe wrong to use the ResourceVariable constructor?

AsakusaRinne commented 1 year ago

Please use Tensor myTensor = tf.convert_to_tensor(myArray); because directly using constructor of Tensor won't produce an EagerTensor.

I'm not sure if this is the right way to do it.

I agree and we'll add the set_weights API. If you met any other problem when using the setter of Weights, please tell us and we'll help you.

AsakusaRinne commented 1 year ago

BTW, tf.Variable is recommended compared to using constructor of ResourceVariable.

Wanglongzhi2001 commented 1 year ago

It works well when use sequential.Weights[0].assign(myTensor);

FrancescoRusticali commented 1 year ago

Thank you all for the useful suggestions. The following works fine:

Tensor myTensor = tf.convert_to_tensor(myArray);
sequential.Weights[0].assign(myTensor);

Instead with:

Tensor myTensor = new Tensor (myArray);
sequential.Weights[0].assign(myTensor);

I get the following exception:

Tensorflow.RuntimeError: 'Attempting to capture an EagerTensor without building a function.'

The tf.convert_to_tensor function seems to be mandatory. Provided you're using it, other formulations of the second row (like tf.Variable, or ResourseVariable constructor) seem not to throw exceptions, but weights are actually not updated.

AsakusaRinne commented 1 year ago

The set_weights API has already been added, close this issue as completed. You can reopen this issue if there's any problem with it.