我对Keras中的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
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)。 考虑将元素强制转换为受支持的类型。
答案 0 :(得分:4)
Tensorflow和Keras现在正在使用channel_last
约定。所以首先你应该
使用K.permute_dimension
将通道暗淡调至最后一个。您可以在colab.research.google.com中尝试使用此代码来弄清楚自己。
# 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)