簡體   English   中英

Keras 中的 conv2d 和 Conv2D 有什么區別?

[英]what is the difference between conv2d and Conv2D in Keras?

我對 Keras 中的Conv2Dconv2d感到困惑。 它們之間有什么區別? 我認為第一個是層,第二個是后端功能,但這是什么意思? 在 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

Keras 中更改的代碼

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

但是當我執行代碼時,它會產生以下錯誤:

追溯(最近一次通話):

文件“”,第 383 行,在 decoded_noise=JpegCompression()(act11)#16

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\base_layer.py”,第 457 行,在call output = self.call(inputs, **kwargs)

文件“”,第 169 行,調用 image_dct = self.apply_conv(noised_image, 'dct')

文件“”,第 132 行,在 apply_conv image_conv = Kr.backend.conv2d(image_yuv_ch,filters,strides=(8,8),data_format='channels_first')

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\keras\backend\tensorflow_backend.py”,第 3650 行,conv2d data_format=tf_data_format)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\ops\nn_ops.py”,第 779 行,卷積數據格式=數據格式)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\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))

錯誤:

追溯(最近一次通話):

文件“”,第 263 行,在 decoded_noise=JpegCompression()(act11)#16

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\base_layer.py”,第 457 行,在call output = self.call(inputs, **kwargs)

文件“”,第 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\site-packages\tensorflow\python\keras\backend.py”,第 2281 行,在 reshape return array_ops.reshape(x, shape)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\ops\gen_array_ops.py”,第6482行,在reshape“Reshape”中,tensor=tensor, shape=shape, name=name )

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\op_def_library.py”,第 513 行,在 _apply_op_helper 中引發錯誤

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\op_def_library.py”,第 510 行,在 _apply_op_helper preferred_dtype=default_dtype 中)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\ops.py”,第 1146 行,internal_convert_to_tensor ret = conversion_func(value, dtype=dtype, name=name, as_ref =as_ref)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\constant_op.py”,第 229 行,在 _constant_tensor_conversion_function 返回常量(v,dtype=dtype,name=name)

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\constant_op.py”,第208行,常數值,dtype=dtype,shape=shape,verify_shape=verify_shape))

文件“D:\software\Anaconda3\envs\py36\lib\site-packages\tensorflow\python\framework\tensor_util.py”,第 531 行,在 make_tensor_proto“支持的類型”中。 %(類型(值),值))

類型錯誤:無法將類型對象轉換為張量。 內容:(維度(無)、維度(4)、維度(4)、8、8)。 考慮將元素轉換為受支持的類型。

Tensorflow 和 Keras 現在使用channel_last約定。 因此,首先您應該使用K.permute_dimension將通道 dim 置換為最后一個。 您可以在 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.conv2dkeras.layers.Conv2D內部使用,當conv_layer對某些輸入x應用卷積時,例如conv_layer

下面的示例可以幫助您更容易地理解say_helloSayHello之間的區別。

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)
  • 如果您想獲得形狀為 (8, 8, 64) 的image_conv ,則 strides 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM