Как связать обучаемые переменные TensorFlow с узлами, изменяемыми для чтения, на графике?

#tensorflow #keras

Вопрос:

Я хочу инициализировать обучаемые переменные на основе структуры графика тензорного потока. Я могу рекурсивно просматривать график по выходным данным и находить все операции ReadVariableOp. Но я не знаю, как найти связанную обучаемую переменную.

В функции recurse_init_vars я хочу назначить «инициализацию» всем переменным, связанным с операцией. Я бы хотел: tvar = associated_variable(op) . Самое близкое, что я мог сделать, — это перебрать все обучаемые переменные и посмотреть, соответствуют ли они операции. Но, если я раскомментирую строку if(tvar.op is op) , я получу сообщение: AttributeError: Tensor.op is meaningless when eager execution is enabled.

Как написано, код инициализирует все переменные до 0,5. Я хочу, чтобы переменные MatMul/ReadVariableOp были инициализированы до 0,25

Фактический Вывод Программы

 Identity init:1.0
  sequential/dense/BiasAdd init:1.0
    sequential/dense/MatMul init:0.5
      x init:0.25
      sequential/dense/MatMul/ReadVariableOp init:0.25
        sequential/dense/MatMul/ReadVariableOp/resource init:0.25
    sequential/dense/BiasAdd/ReadVariableOp init:0.5
      sequential/dense/BiasAdd/ReadVariableOp/resource init:0.5

----- Trainable Variable Initial Values -------
[[0.5]
 [0.5]]
[0.5]
 

Желаемый Вывод Программы

 Identity init:1.0
  sequential/dense/BiasAdd init:1.0
    sequential/dense/MatMul init:0.5
      x init:0.25
      sequential/dense/MatMul/ReadVariableOp init:0.25
        sequential/dense/MatMul/ReadVariableOp/resource init:0.25
    sequential/dense/BiasAdd/ReadVariableOp init:0.5
      sequential/dense/BiasAdd/ReadVariableOp/resource init:0.5

----- Trainable Variable Initial Values -------
[[0.25]
 [0.25]]
[0.5]
 

Программа

 def build_3pts_model():
    x_train  = np.array([[1,2],[2,3],[4,5],[6,7],[8,9],[9,10]],
                  dtype=np.dtype('float64'))
    y_train = np.array([[8], [11], [17], [23], [29], [32]],
                dtype=np.dtype('float64'))
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(1, input_shape=[2]))
    model.compile(loss='mean_squared_error', metrics=["mae"],
                  optimizer=tf.keras.optimizers.Adam(0.1))
    return(model, x_train, y_train)
    

def recurse_init_vars(model, graph, op, depth, init):
    print(f"{' ' * (depth*2)}{op.name} init:{init}")
    ########## NEED HELP HERE ###########################
    for tvar in model.trainable_variables:
        # if(tvar.op is op):
            tvar.assign(np.full_like(tvar.numpy(), init))
    #####################################################
    for input in op.inputs:
        input_op = input.op
        recurse_init_vars(model, graph, input_op, depth 1, init/len(op.inputs))


def init_vars(model):
    full_model = tf.function(lambda x: model(x))
    full_model = full_model.get_concrete_function(
        tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))
    full_model.graph.as_graph_def()
    for output in full_model.outputs:
        recurse_init_vars(model, full_model.graph, output.op, 0, 1.0)


def print_vars(model):
    print("")
    print("----- Trainable Variable Initial Values -------")
    for tvar in model.trainable_variables:
        print(tvar.numpy())


def main():
    (model, x_train, y_train) = build_3pts_model()
    init_vars(model)
    print_vars(model)
    # model.fit(x_train, y_train, epochs=3)

import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam
main()