В чем разница между conv2d и Conv2D в Керасе? - PullRequest
5 голосов
/ 30 апреля 2019

Я запутался с Conv2D и conv2d в Керасе. какая разница между ними? Я думаю, что первый - это слой, а второй - бэкэнд-функция, но что это значит? в Conv2D мы отправляем количество фильтров, размер фильтров и шаг (Conv2D(64,(3,3),stride=(8,8))(input)), но в conv2d мы используем conv2d(input, kernel, stride=(8,8)) что такое ядро ​​(64,3,3) и мы соединяем число фильтров и размер вместе? где я должен ввести количество ядер? Не могли бы вы помочь мне с этим вопросом? Спасибо.

код в pytorch

def apply_conv(self, image, filter_type: str):

        if filter_type == 'dct':
            filters = self.dct_conv_weights
        elif filter_type == 'idct':
            filters = self.idct_conv_weights
        else:
            raise('Unknown filter_type value.')

        image_conv_channels = []
        for channel in range(image.shape[1]):
            image_yuv_ch = image[:, channel, :, :].unsqueeze_(1)
            image_conv = F.conv2d(image_yuv_ch, filters, stride=8)
            image_conv = image_conv.permute(0, 2, 3, 1)
            image_conv = image_conv.view(image_conv.shape[0], image_conv.shape[1], image_conv.shape[2], 8, 8)
            image_conv = image_conv.permute(0, 1, 3, 2, 4)
            image_conv = image_conv.contiguous().view(image_conv.shape[0],
                                                  image_conv.shape[1]*image_conv.shape[2],
                                                  image_conv.shape[3]*image_conv.shape[4])

            image_conv.unsqueeze_(1)

            # image_conv = F.conv2d()
            image_conv_channels.append(image_conv)

        image_conv_stacked = torch.cat(image_conv_channels, dim=1)

        return image_conv_stacked

измененный код в Керасе

def apply_conv(self, image, filter_type: str):

        if filter_type == 'dct':
            filters = self.dct_conv_weights
        elif filter_type == 'idct':
            filters = self.idct_conv_weights
        else:
            raise('Unknown filter_type value.')
        print(image.shape)

        image_conv_channels = []
        for channel in range(image.shape[1]):
            print(image.shape)
            print(channel)
            image_yuv_ch = K.expand_dims(image[:, channel, :, :],1)
            print( image_yuv_ch.shape)
            print(filters.shape)
            image_conv = Kr.backend.conv2d(image_yuv_ch,filters,strides=(8,8),data_format='channels_first')
           image_conv = Kr.backend.permute_dimensions(image_conv,(0, 2, 3, 1))
            image_conv = Kr.backend.reshape(image_conv,(image_conv.shape[0], image_conv.shape[1], image_conv.shape[2], 8, 8))
            image_conv =  Kr.backend.permute_dimensions(image_conv,(0, 1, 3, 2, 4))
            image_conv = Kr.backend.reshape(image_conv,(image_conv.shape[0],
                                                  image_conv.shape[1]*image_conv.shape[2],
                                                  image_conv.shape[3]*image_conv.shape[4]))

            Kr.backend.expand_dims(image_conv,1)

            # image_conv = F.conv2d()
            image_conv_channels.append(image_conv)

        image_conv_stacked = Kr.backend.concatenate(image_conv_channels, axis=1)

        return image_conv_stacked

но когда я выполняю код, он выдает следующую ошибку:

Traceback (последний вызов был последним):

Файл "", строка 383, в decoded_noise = JpegCompression () (act11) # 16

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ keras \ двигатель \ base_layer.py", линия 457, вызов output = self.call (входные данные, ** кваргс)

Файл "", строка 169, в вызове image_dct = self.apply_conv (noised_image, 'dct')

Файл "", строка 132, в apply_conv image_conv = Kr.backend.conv2d (image_yuv_ch, фильтры, шаги = (8,8), data_format = 'channel_first')

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ keras \ бэкэнд \ tensorflow_backend.py", линия 3650, в conv2d data_format = tf_data_format)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ OPS \ nn_ops.py", линия 779, в свертке data_format = data_format)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ OPS \ nn_ops.py", строка 839, в init filter_shape [num_spatial_dims]))

ValueError: количество входных каналов не совпадает с соответствующим размер фильтра, 1! = 8

новый код

for channel in range(image.shape[1]):
            image_yuv_ch = K.expand_dims(image[:, channel, :, :],axis=1)
            image_yuv_ch = K.permute_dimensions(image_yuv_ch, (0, 2, 3, 1))
            image_conv = tf.keras.backend.conv2d(image_yuv_ch,kernel=filters,strides=(8,8),padding='same')
            image_conv = tf.keras.backend.reshape(image_conv,(image_conv.shape[0],image_conv.shape[1], image_conv.shape[2],8,8))

ошибка:

Traceback (последний последний вызов):

Файл "", строка 263, в decoded_noise = JpegCompression () (act11) # 16 * * тысяча пятьдесят пять

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ keras \ двигатель \ base_layer.py", линия 457, вызов output = self.call (входные данные, ** кваргс)

Файл "", строка 166, в вызове image_dct = self.apply_conv (noised_image, 'dct')

Файл "", строка 128, в apply_conv image_conv = tf.keras.backend.reshape (image_conv, (image_conv.shape [0], image_conv.shape [1], image_conv.shape [2], 8,8)) * * тысяча шестьдесят-три

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ keras \ backend.py", строка 2281, в форме return array_ops.reshape (x, shape)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ OPS \ gen_array_ops.py", строка 6482, в форме «Изменить форму», тензор = тензор, форма = форма, имя = имя)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ рамки \ op_def_library.py", строка 513, в _apply_op_helper поднять ошибку

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ рамки \ op_def_library.py", строка 510 в _apply_op_helper preferred_dtype = default_dtype)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ рамки \ ops.py", строка 1146, в internal_convert_to_tensor ret = translation_func (значение, dtype = dtype, имя = имя, as_ref = as_ref)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ рамки \ constant_op.py", строка 229, в _constant_tensor_conversion_function возвращаемая константа (v, dtype = dtype, name = name)

Файл "D: \ Software \ Anaconda3 \ envs \ py36 \ Lib \ сайт-пакеты \ tensorflow \ питон \ рамки \ constant_op.py", строка 208, в постоянном значение, dtype = dtype, shape = shape, verify_shape = verify_shape))

Файл«D: \ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ensorflow \ python \ framework \ensor_util.py», строка 531, в make_tensor_proto «поддерживаемый тип».% (тип (значения), значения))

TypeError: Не удалось преобразовать объект типа в Tensor.Содержание: (Размер (Нет), Размер (4), Размер (4), 8, 8).Рассмотрим приведение элементов к поддерживаемому типу.

1 Ответ

5 голосов
/ 01 мая 2019

Tensorflow и Keras теперь используют соглашение channel_last. Итак, сначала вы должны переставьте тусклый канал до последнего, используя K.permute_dimension. Вы можете попробовать этот код в colab.research.google.com, чтобы выяснить сами.

Первый вопрос:

  • conv2d - функция для выполнения двумерной свертки документы
  • keras.layers.Conv2D() вернет экземпляр класса Conv2D, который выполняет функцию свертки. Подробнее здесь
# The second 
import keras
conv_layer = keras.layers.Conv2D(filters=64, kernel_size=8, strides=(4, 4), padding='same')

В основном они отличаются от способа определения и способа использования. K.conv2d используется внутри keras.layers.Conv2D, когда conv_layer применяет свертку к некоторому входу x, например conv_layer.

Приведенный ниже пример может помочь вам легче понять разницу между say_hello и SayHello.

def say_hello(word, name):
    print(word, name)


class SayHello():

    def __init__(self, word='Hello'):
        self.word = word
        pass

    def __call__(self, name):
        say_hello(self.word, name)


say_hello('Hello', 'Nadia') #Hello Nadia

sayhello = SayHello(word='Hello') # you will get an instance `sayhello` from class SayHello

sayhello('Nadia') # Hello Nadia

Второй вопрос:

  • kernel вот тензор формы (kernel_size, kernel_size, in_channels, out_channels)
  • Если вы хотите получить image_conv формы (8, 8, 64), тогда strides=(4,4).
import tensorflow as tf
import tensorflow.keras.backend as K

image = tf.random_normal((10,3, 32, 32))
print(image.shape) # shape=(10, 3, 32, 32)

channel = 1
image_yuv_ch = K.expand_dims(image[:, channel,:,:], axis=1) # shape=(10, 1, 32, 32)
image_yuv_ch = K.permute_dimensions(image_yuv_ch, (0, 2, 3, 1)) # shape=(10, 32, 32, 1)

# The first K.conv2d
in_channels = 1
out_channels = 64 # same as filters
kernel = tf.random_normal((8, 8, in_channels, out_channels)) # shape=(8, 8, 1, 64)

image_conv = tf.keras.backend.conv2d(image_yuv_ch, kernel=kernel, strides=(4, 4), padding='same')
print(image_conv.shape) #shape=(10, 8, 8, 64)


# The second 
import keras
conv_layer = keras.layers.Conv2D(filters=64, kernel_size=8, strides=(4, 4), padding='same')
image_conv = conv_layer(image_yuv_ch)
print(image_conv.shape) #shape=(10, 8, 8, 64)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...