1D CNN、2D CNN 和 3D CNN 输入形状的区别
Difference between the input shape for a 1D CNN, 2D CNN and 3D CNN
我是第一次构建用于图像分类的 CNN 模型,我对每种类型(1D CNN、2D CNN、3D CNN)的输入形状以及如何修复有点困惑卷积层中过滤器的数量。我的数据是 100x100x30,其中 30 个是特征。
这是我使用 Functional API Keras 的 1D CNN 论文:
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、Maxpooling1D 更改为 Conv2D 和 Maxpooling2D 来尝试 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
: (size1, channel_number), Conv2D
: (size1, size2, channel_number), Conv3D
: (size1, size2, size3, channel_number)
1DCNN
、2DCNN
、3DCNN
分别表示卷积层每个kernel和channel的维度
TLDR; 您的 X_train
可以看作(批处理、空间暗淡...、通道)。内核并行应用于所有通道的空间维度。因此,二维 CNN 需要两个空间维度 (batch, dim 1, dim 2, channels)
.
因此对于 (100,100,3)
形状的图像,您将需要一个 2D CNN,它在所有 3 个通道上卷积超过 100 的高度和 100 的宽度。
让我们理解上面的说法。
首先,您需要了解 CNN(通常)在做什么。
A kernel is convolving through the spatial dimensions of a tensor across its feature maps/channels while performing a simple matrix operation (like dot product) to the corresponding values.
内核在空间维度上移动
现在,假设您有 100 张图像(称为 批次 )。每幅图像为 28 x 28 像素,具有 3 个通道 R、G、B(在 CNN 的上下文中也称为 特征图 )。如果我将此数据存储为张量,则形状将为 (100,28,28,3)
.
但是,我可以只拥有一个没有任何高度的图像(可能像一个信号),或者,我可以拥有具有额外空间维度的数据,例如视频(高度、宽度和时间) .
一般来说,基于 CNN 的神经网络的输入是这样的。
相同内核,所有通道
您需要知道的第二个关键点是,二维内核将在 2 个空间维度上进行卷积,但同一个内核将在所有特征上执行此操作 maps/channels。所以,如果我有一个 (3,3)
内核。这个相同的内核将应用于 R、G、B 通道(并行)并移动到图像的 Height
和 Width
。
运算是点积
最后,操作(对于单个特征 map/channel 和单个卷积 window)可以像下面这样可视化。
因此,简而言之-
- 内核应用于数据的空间维度
- 核形状等于空间维度的#
- 内核一次应用所有功能maps/channels
- 运算是内核与window
之间的简单点积
让我们以具有单一特征的张量为例 maps/channels(因此,对于图像,它会被灰度化)-
So, with that intuition, we see that if I want to use a 1D CNN, your data must have 1 spatial dimension, which means each sample needs to be 2D (spatial dimension and channels), which means the X_train
must be a 3D tensor (batch, spatial dimensions, channels)
.
Similarly, for a 2D CNN, you would have 2 spatial dimensions (H, W for example) and would be 3D samples (H, W, Channels)
and X_train
would be (Samples, H, W, Channels)
让我们用代码试试这个 -
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)
用于应用 1D 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)
用于应用 2D 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)
我是第一次构建用于图像分类的 CNN 模型,我对每种类型(1D CNN、2D CNN、3D CNN)的输入形状以及如何修复有点困惑卷积层中过滤器的数量。我的数据是 100x100x30,其中 30 个是特征。 这是我使用 Functional API Keras 的 1D CNN 论文:
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、Maxpooling1D 更改为 Conv2D 和 Maxpooling2D 来尝试 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
: (size1, channel_number), Conv2D
: (size1, size2, channel_number), Conv3D
: (size1, size2, size3, channel_number)
1DCNN
、2DCNN
、3DCNN
分别表示卷积层每个kernel和channel的维度
TLDR; 您的 X_train
可以看作(批处理、空间暗淡...、通道)。内核并行应用于所有通道的空间维度。因此,二维 CNN 需要两个空间维度 (batch, dim 1, dim 2, channels)
.
因此对于 (100,100,3)
形状的图像,您将需要一个 2D CNN,它在所有 3 个通道上卷积超过 100 的高度和 100 的宽度。
让我们理解上面的说法。
首先,您需要了解 CNN(通常)在做什么。
A kernel is convolving through the spatial dimensions of a tensor across its feature maps/channels while performing a simple matrix operation (like dot product) to the corresponding values.
内核在空间维度上移动
现在,假设您有 100 张图像(称为 批次 )。每幅图像为 28 x 28 像素,具有 3 个通道 R、G、B(在 CNN 的上下文中也称为 特征图 )。如果我将此数据存储为张量,则形状将为 (100,28,28,3)
.
但是,我可以只拥有一个没有任何高度的图像(可能像一个信号),或者,我可以拥有具有额外空间维度的数据,例如视频(高度、宽度和时间) .
一般来说,基于 CNN 的神经网络的输入是这样的。
相同内核,所有通道
您需要知道的第二个关键点是,二维内核将在 2 个空间维度上进行卷积,但同一个内核将在所有特征上执行此操作 maps/channels。所以,如果我有一个 (3,3)
内核。这个相同的内核将应用于 R、G、B 通道(并行)并移动到图像的 Height
和 Width
。
运算是点积
最后,操作(对于单个特征 map/channel 和单个卷积 window)可以像下面这样可视化。
因此,简而言之-
- 内核应用于数据的空间维度
- 核形状等于空间维度的#
- 内核一次应用所有功能maps/channels
- 运算是内核与window 之间的简单点积
让我们以具有单一特征的张量为例 maps/channels(因此,对于图像,它会被灰度化)-
So, with that intuition, we see that if I want to use a 1D CNN, your data must have 1 spatial dimension, which means each sample needs to be 2D (spatial dimension and channels), which means the
X_train
must be a 3D tensor(batch, spatial dimensions, channels)
.Similarly, for a 2D CNN, you would have 2 spatial dimensions (H, W for example) and would be 3D samples
(H, W, Channels)
andX_train
would be(Samples, H, W, Channels)
让我们用代码试试这个 -
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)
用于应用 1D 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)
用于应用 2D 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)