Keras Custom Layer ValueError: у операции есть `None` для градиента - PullRequest
1 голос
/ 13 февраля 2020

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

ValueError: Операция имеет None для градиента. Пожалуйста, убедитесь, что все ваши операции имеют определенный градиент (то есть являются дифференцируемыми). Обычные операции без градиента: K.argmax, K.round, K.eval.

Есть ли ошибки реализации в моем пользовательском слое?

class SpatialLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(SpatialLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.bias = None
        self.built = True
        self.kernelA = self.add_weight(name='kernelA', shape=(input_shape[1]-2, self.output_dim), initializer='uniform', trainable=True)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], input_shape[1]-2, input_shape[1]-2, self.output_dim)


    def call(self, inputs):
        x_shape = tf.shape(inputs)
        top_values, top_indices = tf.nn.top_k(tf.reshape(inputs, (-1,)), 10, sorted=True,)
        top_indices = tf.stack(((top_indices // x_shape[1]), (top_indices % x_shape[1])), -1)
        top_indices = tf.cast(top_indices, dtype=tf.float32)
        t1 = tf.reshape(top_indices, (1,10,2))
        t2 = tf.reshape(top_indices, (10,1,2))
        result = tf.norm(t1-t2, ord='euclidean', axis=2)
        x = tf.placeholder(tf.float32, shape=[None, 10, 10, 1])
        tensor_zeros = tf.zeros_like(x)
        matrix = tensor_zeros + result
        return K.dot(matrix, self.kernelA)


    model = applications.VGG16(weights = "imagenet", include_top=False, input_shape = (img_width, img_height, 3))
    model.layers.pop()
    new_custom_layers = model.layers[-1].output
    model.layers[-1].trainable = False

    new_custom_layers = Conv2D(filters=1, kernel_size=(3, 3))(new_custom_layers)
    new_custom_layers = SpatialLayer(output_dim=1)(new_custom_layers)
    new_custom_layers = Flatten()(new_custom_layers)
    new_custom_layers = Dense(1024, activation="relu")(new_custom_layers)
    new_custom_layers = Dropout(0.5)(new_custom_layers)
    new_custom_layers = Dense(1024, activation="relu")(new_custom_layers)

Буду признателен за любую помощь.

Пояснение

Вход в мой пользовательский слой Keras является тензорным (?, 12,12 , 1) которая представляет карту объектов из данного изображения. Например:

[[147.00  20.14 ... 0 34.2  0   ]
 [ 12.00  10.14 ... 0 45.2  0   ]
 ...
 [100.00  60.14 ... 0 34.2  99.1]
 [ 90.00  65.14 ... 0 12.2  00.1]]

Я хочу получить координаты верхних 10 значений из этого тензора, например: (0,0), (10,0) ...., (10,11 ), т. е. 10 координат.

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

       coord1 coord2 ... coord9 cood10
coord1   0     12.3       13.1   2.3
coord2  1.3      0        3.2    9.1
  .
  .
  .
coord9  4.2     5.2        0     4.2
coor10  1.1     5.6       9.1     0

Эта матрица (?, 10,10,1) будет выводом слоя.

1 Ответ

2 голосов
/ 13 февраля 2020

Вы не можете осуществлять обратное распространение через функции, которые нельзя дифференцировать. И ваша функция не дифференцируема.

Вы отбросили значения top_values и оставили только целочисленные константы top_indices.

Единственный способ использовать этот слой в модели, если все до него не обучаемо. (Или, если вы найдете другой способ вычисления того, что вы хотите дифференцируемым способом - это означает: операции, которые должны включать входные значения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...