#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)))