Операции вне кода построения функции передается тензор «Graph»

#python #tensorflow #keras #tensorflow2.0

#python #tensorflow #keras #tensorflow2.0

Вопрос:

Я реализовал слой Keras Tf2, но когда я тренируюсь, я получаю следующую ошибку:

 TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: ada_cos_layer_1/truediv:0
  

Я видел несколько похожих сообщений, но их проблема заключалась в Lambda слое, который я не использую. Я считаю, что в моем случае это связано с присвоением атрибута, который не является tf.Variable ( self.s ). Однако я уже пытался установить его как таковой или использовать add_weight без какой-либо помощи. Мой уровень следующий:

 class AdaCos(tf.keras.layers.Layer):
    def __init__(self, n_classes, margin=None, logit_scale=None, **kwargs):
        super().__init__(**kwargs)
        self.n_classes = n_classes
        self.s = math.sqrt(2)*math.log(n_classes-1)

    def build(self, input_shape):
        super().build(input_shape[0])
        self.w = self.add_weight(name='weights',
                                shape=(input_shape[0][-1], self.n_classes),
                                initializer='glorot_uniform',
                                trainable=True)
    
    @staticmethod
    def get_median(v):
        v = tf.reshape(v, [-1])
        mid = v.get_shape()[0]//2   1
        return tf.nn.top_k(v, mid).values[-1]

    def call(self, inputs):
        x, y = inputs
        # normalize feature
        x = tf.nn.l2_normalize(x, axis=1, name='normed_embd')
        # normalize weights
        w = tf.nn.l2_normalize(self.w, axis=0, name='normed_weights')
        # dot product
        logits = tf.matmul(x, w, name='cos_t')
        # add margin
        # clip logits to prevent zero division when backward
        theta = tf.acos(tf.clip_by_value(logits, -1.0   1e-5, 1.0 - 1e-5))

        B_avg = tf.where(tf.expand_dims(y, 1) < 1, tf.exp(self.s*logits), tf.zeros_like(logits))
        B_avg = tf.reduce_mean(tf.reduce_sum(B_avg, axis=1), name='B_avg')

        theta_class = tf.gather_nd(theta, tf.expand_dims(tf.cast(y, tf.int32), 1), 1, name='theta_class')
        theta_med = self.get_median(theta_class)
        
        with tf.control_dependencies([theta_med, B_avg]):
            self.s = tf.math.log(B_avg) / tf.cos(tf.minimum(math.pi/4, theta_med))
            out = tf.multiply(logits, self.s, 'arcface_logist')
        return out

    def compute_output_shape(self, input_shape):
        return (None, self.n_classes)
  

Комментарии:

1. The graph tensor has name: arc_face_layer_1/truediv:0 кажется, что он принадлежит другому слою вашей модели, и вы должны искать его там.

2. Извините, это потому, что когда я запускал и получал ошибку, у слоя было другое имя. Я изменю это

3. Я прокомментировал строку self.s = tf.math.log(B_avg) ... и не получил никаких ошибок. Таким образом, кажется, что атрибуция действительно является проблемой

4. Затем попробуйте self.s = tf.Variable(math.sqrt(2)*math.log(n_classes-1)) и self.s.assign(tf.math.log(B_avg) / tf.cos(tf.minimum(math.pi/4, theta_med)))