Tensorflow 2: как я могу использовать форму тензора y_true в пользовательских потерях?

#python #tensorflow #keras

#python #tensorflow #keras

Вопрос:

Я передаю список a своей пользовательской функции, и я хочу tf.tile его преобразовать в постоянный тензор. Время, когда я разбиваю его на плитки, зависит от формы y_true . Я не знаю, как я могу получить форму y_true целых чисел. Вот код:

 def getloss(a):
    a = tf.constant(a, tf.float32)
    def loss(y_true, y_pred):
        a = tf.reshape(a, [1,1,-1])
        ytrue_shape = y_true.get_shape().as_list() #????
        multiples = tf.constant([ytrue_shape[0], ytrue_shape[1], 1], tf.int32)
        a = tf.tile(a, multiples)
        #...
    return loss
 

Я пробовал y_true.get_shape().as_list() , но он сообщает об ошибке, потому что первое измерение (размер пакета) задается None при компиляции модели. Есть ли какой-либо способ, которым я могу использовать форму y_true здесь?

Ответ №1:

При попытке получить доступ к форме тензора во время построения модели, когда известны не все формы, лучше всего использовать tf.shape . Он будет оценен при запуске модели, как указано в документе :

tf.shape и Tensor.shape должны быть идентичны в режиме ожидания. В tf.function или в контексте compat.v1 не все измерения могут быть известны до времени выполнения. Следовательно, при определении пользовательских слоев и моделей для графического режима отдавайте предпочтение динамическому tf.shape(x) над статическим x.shape.

 ytrue_shape = tf.shape(y_true)
 

Это даст тензор, поэтому используйте TF ops, чтобы получить то, что вы хотите :

 multiples = tf.concat((tf.shape(y_true_shape)[:2],[1]),axis=0)
 

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

1. Но tf.shape(y_true) дает тензор, что означает, что я не могу использовать ytrue_shape[0] или ytrue_shape[1] как целые числа в шестой строке. Если я использую tf.shape(y_true) его, он сообщит об ошибке типа: ожидаемый int32, вместо этого получил <tf.Tensor ‘loss/KPD_Output_loss/strided_slice:0’ shape=() dtype=int32> типа ‘Tensor’.

2. Да, мне казалось очевидным, что вам понадобятся операции tensorflow, чтобы получить то, что вы хотели. Я добавил быстрый комментарий. В следующий раз я постараюсь быть более тщательным.

3. Вау, я никогда не думал, что смогу реализовать это таким образом. Вы действительно просветили меня. Большое вам спасибо!