【问题标题】:Input_shape in 3D CNN3D CNN 中的 Input_shape
【发布时间】:2021-08-28 17:48:37
【问题描述】:

我有一个包含 100000 个形状为 (6, 4, 4) 的二进制 3D 数组的数据集,因此我输入的形状是 (10000, 6, 4, 4)。我正在尝试使用 Keras 建立一个 3D 卷积神经网络(CNN);但是,我输入的 input_shape 似乎有问题。我的第一层是:

model.add(Conv3D(20, kernel_size=(2, 2, 2), strides=(1, 1, 1), activation='relu', kernel_initializer='he_uniform', input_shape=(None, 6, 4, 4, 1)))

我收到的错误是:

ValueError:应定义Dense 输入的最后一个维度。找到None

不过,当我用整数替换 None 并尝试将模型拟合到我的数据集时,我得到的错误是:

ValueError: 层序贯_13 的输入 0 与层不兼容: : 预期 min_ndim=5,发现 ndim=4。收到的完整形状:(10, 6, 4, 4)

这里应该修改什么?

【问题讨论】:

  • 是否有特定原因要使用 3D 卷积? (6,4,4) 对二维卷积有效。
  • @Frightera 由于我的输入数据是体积数据,我认为我应该使用 3D ConvNet。不对吗?
  • 那么你的通道大小是多少? 3D 图层将您的输入解释为6 x 4 x 4 x channels
  • @Frightera 让我看看我是否明白这一点。那么,您的意思是我应该使用 2D ConvNet 并将 6 的深度视为我的 4 x 4 二进制矩阵的通道数?而不是 3D ConvNet?
  • 除非你在卷积层设置data_format = channels_first,否则你的深度是4(对于2D conv来说OK)。或者您可以通过扩展 dims 将通道维度添加到第一个输入,然后它将具有 (6,4,4,1) 的形状。

标签: python machine-learning neural-network conv-neural-network


【解决方案1】:

虚拟数据示例:

import tensorflow as tf

x = tf.random.normal((100000, 6, 4, 4))
x.numpy().shape # (100000, 6, 4, 4) # 4 --> channel size by default

这不适用于 3D 卷积:

y = tf.keras.layers.Conv3D(2, 3, activation='relu', 
                           input_shape=(6, 4, 4, 1))(x)
print('After convolution', y.shape)

它会说expected min_ndim=5, found ndim=4 ...。您需要向该数据添加渠道维度。这可以简单地完成:

x_expanded = tf.expand_dims(x, axis = -1)
print('Expand_dims shape', x_expanded.numpy().shape) # (100000, 6, 4, 4, 1)

y = tf.keras.layers.Conv3D(2, 3, activation='relu', 
                           input_shape=(6, 4, 4, 1))(x_expanded)
print('After convolution', y.shape) # (100000, 4, 2, 2, 2)

或者第一次,你可以使用2D卷积的数据:

x = tf.random.normal((100000, 6, 4, 4))
y = tf.keras.layers.Conv2D(2, 3, activation='relu', 
                           input_shape=(6, 4, 4))(x)
print('After convolution', y.shape) # (100000, 4, 2, 2)

您还可以更改卷积层中通道的顺序:

y = tf.keras.layers.Conv2D(2, 3, activation='relu', 
                           input_shape=(6, 4, 4),
                           data_format="channels_first")(x) # --> 6 will be channels
print(y.shape) # (100000, 2, 2, 2)

编辑:

model.add(tf.keras.layers.Conv3D(2, 3, activation='relu', input_shape=(6, 4, 4, 1)))

model(x_expanded).shape # TensorShape([100000, 4, 2, 2, 2])

【讨论】:

  • 非常感谢您的帮助。另外,感谢您详细回答。我猜这里的语法有问题。我尝试了您的 3D ConvNet 代码,但出现错误。是否可以将其编写为 model.add(Conv3D 格式。这是我得到的错误: InvalidArgumentError: Value for attr 'T' of int64 is not in the list of allowed values: half, bfloat16, float, double 。 ..
  • 您可以尝试将数据转换为 int32 或 float32 吗?我没有任何错误。查看编辑。
  • 你试过了吗:your_arr = your_arr.astype(np.float32).
  • 在 input_shape 参数中不要包括样本大小(100000),如果你这样做了。 (6,4,4,1) 本身应该没问题。如果这不是问题,我需要使用您的数据形状查看模型定义。
  • 应该在Conv3D层中传递,可以在input_shape之后直接传递。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2020-01-22
  • 2020-04-01
  • 2018-10-13
  • 1970-01-01
  • 2021-04-27
相关资源
最近更新 更多