Keras 一维CNN、二维CNN和三维CNN的输入形状之间的差异
我第一次为图像分类建立CNN模型,我对每种类型(1D CNN、2D CNN、3D CNN)的输入形状以及如何确定卷积层中的滤波器数量感到有点困惑。我的数据是100x100x30,其中30是功能。 以下是我使用函数式API Keras为1D CNN撰写的文章:Keras 一维CNN、二维CNN和三维CNN的输入形状之间的差异,keras,conv-neural-network,convolution,max-pooling,functional-api,Keras,Conv Neural Network,Convolution,Max Pooling,Functional Api,我第一次为图像分类建立CNN模型,我对每种类型(1D CNN、2D CNN、3D CNN)的输入形状以及如何确定卷积层中的滤波器数量感到有点困惑。我的数据是100x100x30,其中30是功能。 以下是我使用函数式API Keras为1D CNN撰写的文章: def create_CNN1D_model(pool_type='max',conv_activation='relu'): input_layer = (30,1) conv_layer1 = Conv1D(filter
def create_CNN1D_model(pool_type='max',conv_activation='relu'):
input_layer = (30,1)
conv_layer1 = Conv1D(filters=16, kernel_size=3, activation=conv_activation)(input_layer)
max_pooling_layer1 = MaxPooling1D(pool_size=2)(conv_layer1)
conv_layer2 = Conv1D(filters=32, kernel_size=3, activation=conv_activation)(max_pooling_layer1)
max_pooling_layer2 = MaxPooling1D(pool_size=2)(conv_layer2)
flatten_layer = Flatten()(max_pooling_layer2)
dense_layer = Dense(units=64, activation='relu')(flatten_layer)
output_layer = Dense(units=10, activation='softmax')(dense_layer)
CNN_model = Model(inputs=input_layer, outputs=output_layer)
return CNN_model
CNN1D = create_CNN1D_model()
CNN1D.compile(loss = 'categorical_crossentropy', optimizer = "adam",metrics = ['accuracy'])
Trace = CNN1D.fit(X, y, epochs=50, batch_size=100)
但是,在通过将Conv1D、maxpoolg1d更改为Conv2D和maxpoolg2d来尝试2D CNN模型时,我得到了以下错误:
ValueError: Input 0 of layer conv2d_1 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: (None, 30, 1)
谁能告诉我2D CNN和3D CNN的输入形状如何?输入数据预处理可以做什么?通过100x100x30输入形状,您是说批量大小为100?或者每个数据都是100x100x30的形状?在第二种情况下,必须改用
Conv2D
层。每层的输入形状应为:
Conv1D
:(尺寸1,频道号),Conv2D
:(尺寸1,尺寸2,频道号),Conv3D
:(尺寸1,尺寸2,尺寸3,频道号)
1DCNN
,2DCNN
,3DCNN
表示卷积层的每个内核和通道的尺寸。通过100x100x30输入形状,您是说批量大小为100吗?或者每个数据都是100x100x30的形状?在第二种情况下,必须改用Conv2D
层。每层的输入形状应为:
Conv1D
:(尺寸1,频道号),Conv2D
:(尺寸1,尺寸2,频道号),Conv3D
:(尺寸1,尺寸2,尺寸3,频道号)
1DCNN
,2DCNN
,3DCNN
表示卷积层的每个内核和通道的尺寸。TLDR您的X_列车
可以被视为(批量、空间DIM…、通道)。内核并行应用于所有通道的空间维度。因此,2D CNN需要两个空间维度(批次,尺寸1,尺寸2,通道)
因此,对于(100100,3)
形状的图像,您需要一个2D CNN,它在所有3个通道上卷积超过100个高度和100个宽度
让我们理解上面的陈述
首先,你需要了解CNN(通常)在做什么 内核在其特征映射/通道上卷积张量的空间维度,同时执行简单的矩阵运算(如点积)到相应的值 内核在空间维度上移动 现在,假设您有100个图像(称为批处理)。每个图像是28×28像素,有3个通道R、G、B(在CNN上下文中也称为特征映射)。如果我将这些数据存储为张量,形状将是
(100,28,28,3)
然而,我可以有一个没有任何高度的图像(可能像一个信号),或者,我可以有一个额外的空间维度的数据,比如视频(高度、宽度和时间)
一般来说,以下是基于CNN的神经网络的输入情况
同一内核,所有通道
您需要知道的第二个关键点是,2D内核将在2个空间维度上进行卷积,但同一个内核将在所有功能映射/通道上进行卷积。因此,如果我有一个(3,3)
内核。该内核将应用于R、G、B通道(并行),并在图像的高度和宽度上移动
操作是一个点积
最后,操作(对于单个特征映射/通道和单个卷积窗口)可以如下所示可视化
因此,简言之-
内核应用于数据的空间维度
内核形状等于空间维度的#
内核一次应用于所有功能映射/通道
该操作是内核和窗口之间的简单点积
让我们以具有单一特征贴图/通道的张量为例(因此,对于图像而言,它将是灰色缩放的)-
因此,凭直觉,我们可以看出,如果我想使用1D CNN,您的数据必须有一个空间维度,这意味着每个样本都需要是2D(空间维度和通道),这意味着X\u列
必须是3D张量(批次,空间维度,通道)
类似地,对于2D CNN,您将有两个空间维度(例如H,W),并且将是3D样本(H,W,通道)
,而X\U列
将是(样本,H,W,通道)
让我们用代码试试这个-
import tensorflow as tf
from tensorflow.keras import layers
X_2D = tf.random.normal((100,7,3)) #Samples, width/time, channels (feature maps)
X_3D = tf.random.normal((100,5,7,3)) #Samples, height, width, channels (feature maps)
X_4D = tf.random.normal((100,6,6,2,3)) #Samples, height, width, time, channels (feature maps)
用于应用一维CNN-
#With padding = same, the edge pixels are padded to not skip a few
#Out featuremaps = 10, kernel (3,)
cnn1d = layers.Conv1D(10, 3, padding='same')(X_2D)
print(X_2D.shape,'->',cnn1d.shape)
#(100, 7, 3) -> (100, 7, 10)
二维CNN的应用-
#Out featuremaps = 10, kernel (3,3)
cnn2d = layers.Conv2D(10, (3,3), padding='same')(X_3D)
print(X_3D.shape,'->',cnn2d.shape)
#(100, 5, 7, 3) -> (100, 5, 7, 10)
对于3D CNN-
#Out featuremaps = 10, kernel (3,3)
cnn3d = layers.Conv3D(10, (3,3,2), padding='same')(X_4D)
print(X_4D.shape,'->',cnn3d.shape)
#(100, 6, 6, 2, 3) -> (100, 6, 6, 2, 10)
TLDR您的X_列车
可以被视为(批量、空间DIM…、通道)。内核并行应用于所有通道的空间维度。因此,2D CNN需要两个空间维度(批次,尺寸1,尺寸2,通道)
因此,对于(100100,3)
形状的图像,您需要一个2D CNN,它在所有3个通道上卷积超过100个高度和100个宽度
让我们理解上面的陈述
首先,你需要了解CNN(通常)在做什么
内核在其特征映射/通道上卷积张量的空间维度,同时执行简单的矩阵运算(如点积)到相应的值
内核在空间维度上移动
现在,假设您有100个图像(称为批处理)。每个图像是28×28像素,有3个通道R、G、B(在CNN上下文中也称为特征映射)。如果我将这些数据存储为张量,形状将是(100,28,28,3)
然而,我可以有一个没有任何高度的图像(可能像一个信号),或者,我可以有这样的数据