Как расширить тензор мульти дим матриц с помощью ряда Тейлора в тензорном потоке? - PullRequest
4 голосов
/ 19 апреля 2020

Я пытаюсь передать вектор пикселей в сверточную нейронную сеть (CNN), где вектор пикселей поступил из данных изображения, таких как набор данных cifar-10. Прежде чем подать вектор пикселей в CNN, мне нужно расширить вектор пикселей с помощью расширения Тейлора. Дело в том, что я разобрался, как расширить тензор с одним димом, но не смог получить его правильно для тензора с дим> 2. Кто-нибудь может дать мне представление о том, как применить разложение Тейлора одного dim-тензора к тензорному dim больше, чем 1? Есть ли эвристический подход для реализации этого либо в TensorFlow или Keras? любая возможная мысль?

расширение Тейлора на CNN :

математическая формулировка расширения Тейлора на CNN :

Вот heuristi c математическая формулировка расширения Тейлора CNN:

enter image description here

, где y - выход, w - вес, s - Разложение входного тензора по Тейлору (также известный как пиксельный вектор). Я хочу использовать пиксельный вектор из набора данных изображения cifar-10. Я изначально придумал способ расширения тензора на 1 дим, используя расширение Тейлора. Вот как выглядит реализация с нуля:

def cnn_taylor(input_dim, approx_order=2):
    x = Input((input_dim,))
    def pwr(x, approx_order):
        x = x[..., None] 
        x = tf.tile(x, multiples=[1, 1, approx_order + 1])
        pw = tf.range(0, approx_order + 1, dtype=tf.float32) 
        x_p = tf.pow(x, pw) 
        x_p = x_p[..., None]
        return x_p

    x_p = Lambda(lambda x: pwr(x, approx_order))(x)
    h = Dense(1, use_bias=False)(x_p)  
    def cumu_sum(h):
        h = tf.squeeze(h, axis=-1)  
        s = tf.cumsum(h, axis=-1) 
        s = s[..., None] 
        return s
    S = Lambda(cumu_sum)(h)

, поэтому приведенная выше реализация - это попытка наброска кода для расширения CNN с расширением Тейлора с использованием 1 тусклого тензора. Мне интересно, как сделать то же самое для тензора с множеством массивов dim (т.е. dim = 3).

графическая иллюстрация

вот графическая иллюстрация попытки расширения CNN с расширением Тейлора, где в качестве входных данных используется тензор с 3-мя тусклыми массивами. Я хочу сделать простую классификацию пикселей, выполняя это, я надеюсь, что кто-то может дать мне возможное направление. Тензор реализован на любом из каналов RGB. Если я хочу расширить CNN с приближением порядка 2 с расширением Тейлора, где входной сигнал представляет собой пиксельный вектор из RGB изображения, как я собираюсь выполнить sh это легко в TensorFlow? есть мысли? Спасибо

1 Ответ

3 голосов
/ 20 апреля 2020

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

  1. Свести входной сигнал 4D (b, h, w, c), поступающий от сверточного слоя, в тензор формы (b, h*w*c).
  2. Примените преобразование к результирующему тензору.
  3. Отмените изменение формы, чтобы получить 4-мерный тензор формы (b, h, w, c) `назад, для которого было применено" расширение Тейлора " поэлементно.

Этого можно достичь следующим образом:

shape_cnn = h.shape  # Shape=(bs, h, w, c)
flat_dim = h.shape[1] * h.shape[2] * h.shape[3]
h = tf.reshape(h, (-1, flat_dim))
taylor_model = taylor_expansion_network(input_dim=flat_dim, max_pow=approx_order)
h = taylor_model(h)
h = tf.reshape(h, (-1, shape_cnn[1], shape_cnn[2], shape_cnn[3]))

ПРИМЕЧАНИЕ: Я заимствую функцию taylor_expansion_network у this ответ .


ОБНОВЛЕНИЕ: Я все еще не совсем понимаю конечную цель, но, возможно, это обновление приблизит нас к желаемому результату. Я изменил taylor_expansion_network, чтобы применить первую часть конвейера к RGB-изображениям формы (width, height, nb_channels=3), возвращая тензор формы (width, height, nb_channels=3, max_pow+1):

def taylor_expansion_network_2(width, height, nb_channels=3, max_pow=2):
    input_dim = width * height * nb_channels

    x = Input((width, height, nb_channels,))
    h = tf.reshape(x, (-1, input_dim))

    # Raise input x_i to power p_i for each i in [0, max_pow].
    def raise_power(x, max_pow):
        x_ = x[..., None]  # Shape=(batch_size, input_dim, 1)
        x_ = tf.tile(x_, multiples=[1, 1, max_pow + 1])  # Shape=(batch_size, input_dim, max_pow+1)
        pows = tf.range(0, max_pow + 1, dtype=tf.float32)  # Shape=(max_pow+1,)
        x_p = tf.pow(x_, pows)  # Shape=(batch_size, input_dim, max_pow+1)
        return x_p

    h = raise_power(h, max_pow)

    # Compute s_i for each i in [0, max_pow]
    h = tf.cumsum(h, axis=-1)  # Shape=(batch_size, input_dim, max_pow+1)

    # Get the input format back
    h = tf.reshape(h, (-1, width, height, nb_channels, max_pow+1))  # Shape=(batch_size, w, h, nb_channels, max_pow+1)

    # Return Taylor expansion model
    model = Model(inputs=x, outputs=h)
    model.summary()
    return model

В этой модифицированной модели последний шаг конвейер, а именно сумма w_i * s_i для каждого i, не применяется. Теперь вы можете использовать полученный тензор формы (width, height, nb_channels=3, max_pow+1) любым удобным для вас способом.

...