Ошибка в пользовательской функции потерь Keras - tenotflow - PullRequest
0 голосов
/ 04 мая 2019

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

Как отсортировать значения в пользовательской функции потери Keras / Tensorflow?

Однако, когда я пытаюсь скомпилировать мою модель, используя этот код, я получаю следующую ошибку о размерах

InvalidArgumentError: input must have last dimension >= k = 20 but is 1 for 'loss_21/dense_65_loss/TopKV2' (op: 'TopKV2') with input shapes: [?,1], [] and with computed input tensors: input[1] = <20>.

Упрощенная версия кода, который воспроизводит ошибку, заключается в следующем.

import tensorflow as tf    
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.optimizers import SGD

top = 20

def top_loss(y_true, y_pred):
    y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred, top)
    loss_per_sample = tf.reduce_mean(tf.reduce_sum(y_pred_top_k,
            axis=-1))

    return loss_per_sample

model = Sequential()
model.add(Dense(50, input_dim=201))
model.add(Dense(1))
sgd = SGD(lr=0.01, decay=0, momentum=0.9)
model.compile(loss=top_loss, optimizer=sgd)

и ошибка генерируется в следующей строке функции top_loss при компиляции модели.

y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred, top)

Похоже, что y_pred во время компиляции по умолчанию имеет форму [?,1], тогда как функция tf.nn.top_k ожидает размерность, по крайней мере, большую, чем 'k` (то есть 20).

Должен ли я привести y_pred к чему-либо, чтобы tf.nn.top_k знал, что оно имеет правильные размеры?

1 Ответ

1 голос
/ 04 мая 2019

Использование:

y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred[:,0], top)

y_pred[:,0] получает прогнозные значения полной партии как тензор ранга 1.

Другая проблема:

Однако у вас все равно останется проблема с последней партией.Скажем, размер вашей партии равен 32, а данные поезда имеют размер 100, тогда последняя партия будет иметь размер меньше 20, поэтому tf.nn.top_k приведет к ошибке времени выполнения для последней партии.Просто убедитесь, что размер последней партии> = 20, чтобы избежать этой проблемы.Однако гораздо лучший способ - проверить, меньше ли текущая партия, чем 20, и, если это так, скорректировать значение k, которое будет использоваться в top_k

Код

import tensorflow as tf    
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.optimizers import SGD

top = tf.constant(20)

def top_loss(y_true, y_pred):
    result = tf.cond(tf.math.greater(top_, tf.shape(y_true)[0]), 
                     lambda: tf.shape(y_true)[0], lambda: top)

    y_pred_top_k, y_pred_ind_k = tf.nn.top_k(y_pred[:,0], result)
    loss_per_sample = tf.reduce_mean(tf.reduce_sum(y_pred_top_k,
            axis=-1))

    return loss_per_sample

model = Sequential()
model.add(Dense(50, input_dim=201))
model.add(Dense(1))
sgd = SGD(lr=0.01, decay=0, momentum=0.9)
model.compile(loss=top_loss, optimizer=sgd)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...