Keras中的conv2d和Conv2D有什么区别?

时间:2019-04-30 16:33:15

标签: python tensorflow 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行,在       encoded_noise = JpegCompression()(act11)#16

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ base_layer.py”,   第457行,致电       输出= self.call(输入,** kwargs)

     

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

     

apply_conv中的文件“”,第132行       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       data_format = data_format)

     

文件   “ 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行,在       encoded_noise = JpegCompression()(act11)#16

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ base_layer.py”,   第457行,致电       输出= self.call(输入,** kwargs)

     

通话中的文件“”,第166行       image_dct = self.apply_conv(noised_image,'dct')

     

apply_conv中的文件“”,第128行       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,重塑       返回array_ops.reshape(x,shape)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ tensorflow \ python \ ops \ gen_array_ops.py”,   线6482,重塑       “重塑”,张量=张量,形状=形状,名称=名称)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ tensorflow \ python \ framework \ op_def_library.py”,   _apply_op_helper中的第513行       提高错误

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ tensorflow \ python \ framework \ op_def_library.py”,   _apply_op_helper中的第510行       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”,   _constant_tensor_conversion_function中的第229行       返回常量(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”,   make_tensor_proto中的第531行       “支持的类型”。 %(类型(值),值))

     

TypeError:无法将类型的对象转换为Tensor。   内容:(Dimension(None),Dimension(4),Dimension(4),8,8)。   考虑将元素强制转换为受支持的类型。

1 个答案:

答案 0 :(得分:4)

Tensorflow和Keras现在正在使用channel_last约定。所以首先你应该 使用K.permute_dimension将通道暗淡调至最后一个。您可以在colab.research.google.com中尝试使用此代码来弄清楚自己。

第一个问题:

  • conv2d是执行2D卷积docs
  • 的功能
  • keras.layers.Conv2D()将返回执行卷积功能的类Conv2D的实例。查看更多here
# 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)上应用卷积时,xconv_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)
  • 如果要获得形状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)