我有形状为 (100, 100, 3) 的图像,我想使用 keras 1D convolution对图像进行分类。 我想知道这是否可行,以及我需要使用的输入的形状是什么。
PS:我使用tf.data.Dataset
,并且我的数据集是批处理的(20, 100, 100, 3)。
最佳答案
我们应该使用一维卷积进行图像分类吗?
TLDR;不是单独的,但如果是组合的话也许可以。
图像中像素之间的相关性(无论是 2D 还是 3D,由于多 channel )具有空间性质:给定像素的值很大程度上受到垂直和水平方向上相邻像素的影响。 2D/3D 卷积(Conv2D
或 Conv3D
)的优点是它们能够在两个空间方向(垂直和水平)捕获这种影响。
相比之下,一维卷积或 Conv1D
仅捕获两种相关性(垂直或水平)之一,因此产生的信息更加有限。就其本身而言,单个 Conv1D
将遗漏大量信息。
尽管如此,由于 Conv2D 可以“分解”为两个 Conv1D
block (这类似于 MobileNet 架构中的 Pointwise 和 Depthwise 卷积),连接一个垂直Conv1D
和水平 Conv1D
捕获两个轴上的空间相关性。这是图像分类的有效方法,可以替代 Conv2D
。
我们可以使用一维卷积进行图像分类吗?怎么办?
是的,我们可以。
您不应该不 reshape 数据以减少尺寸:如果这样做,您将把图像的一端(如果垂直应用Conv1D,则为顶部)与另一端(说底部),这打破了空间连贯性。
这是一个关于如何(实现上面解释的串联)的可能示例:
import tensorflow as tf
x = tf.random.normal(input_shape = (20, 100, 100, 3)) # your input batch
# Horizontal Conv1D
y_h = tf.keras.layers.Conv1D(
filters=32, kernel_size=3, activation='relu', input_shape=x.shape[2:])(x)
# Vertical Conv1D
y_v = tf.transpose(x, perm=[0, 2, 1, 3]) # Image rows to columns
y_v = tf.keras.layers.Conv1D(
filters=32, kernel_size=3, activation='relu', input_shape=x.shape[2:])(x)
# y_v = tf.transpose(y_v, perm=[0, 2, 1, 3]) # Undo transpose, optional
# Concatenate results
y = tf.keras.layers.Concatenate(axis=3)([y_h, y_v]) # Concatenate on the feature_maps
请注意,您需要多次运算才能获得结果(垂直轴和水平轴上的卷积),通过直接应用 Conv2D
可以更轻松、更快地获得结果。
我们什么时候应该使用它?
如果您的图像数据在一个轴上信息量特别少,而在另一个空间轴上特别有趣,那么这可能是一个值得探索的想法。否则,最好采用标准 Conv2D
(大多数情况下,包括几乎所有公共(public)图像数据集)。
关于python - 我们可以使用一维卷积进行图像分类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64965741/