【问题标题】:3D Convolutional Neural Network input shape3D 卷积神经网络输入形状
【发布时间】:2017-07-30 17:03:03
【问题描述】:

我在使用 Keras 和 Python 对 3D 形状进行分类时为 3D CNN 提供数据时遇到了问题。我有一个包含一些 JSON 格式模型的文件夹。我将这些模型读入 Numpy 数组。模型为 25*25*25,表示体素化模型的占用网格(每个位置表示位置 (i,j,k) 中的体素是否有点),所以我只有 1 个输入通道,就像二维图像中的灰度图像。我的代码如下:

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution3D, MaxPooling3D
from keras.optimizers import SGD
from keras.utils import np_utils
from keras import backend as K

# Number of Classes and Epochs of Training
nb_classes = 3 # cube, cone or sphere
nb_epoch = 100
batch_size = 2

# Input Image Dimensions
img_rows, img_cols, img_depth = 25, 25, 25

# Number of Convolutional Filters to use
nb_filters = 32

# Convolution Kernel Size
kernel_size = [5,5,5]

X_train, Y_train = [], []

# Read from File
import os
import json

i=0
for filename in os.listdir(os.path.join(os.getcwd(), 'models')):
    with open(os.path.join(os.getcwd(), 'models', filename)) as f:
        file = f.readlines()
        json_file = '\n'.join(file)
        content = json.loads(json_file)
        occupancy = content['model']['occupancy']
        form = []
        for value in occupancy:
            form.append(int(value))
        final_model = [ [ [ 0 for i in range(img_rows) ]
                              for j in range(img_cols) ]
                              for k in range(img_depth) ]
        a = 0
        for i in range(img_rows):
            for j in range(img_cols):
                for k in range(img_depth):
                    final_model[i][j][k] = form[a]
                    a = a + 1
        X_train.append(final_model)
        Y_train.append(content['model']['label'])

X_train = np.array(X_train)
Y_train = np.array(Y_train)

# (1 channel, 25 rows, 25 cols, 25 of depth)
input_shape = (1, img_rows, img_cols, img_depth)

# Init
model = Sequential()

# 3D Convolution layer
model.add(Convolution3D(nb_filters, kernel_size[0], kernel_size[1], kernel_size[2],
                        input_shape=input_shape,
                        activation='relu'))

# Fully Connected layer
model.add(Flatten())
model.add(Dense(128,
          init='normal',
          activation='relu'))
model.add(Dropout(0.5))

# Softmax Layer
model.add(Dense(nb_classes,
                init='normal'))
model.add(Activation('softmax'))

# Compile
model.compile(loss='categorical_crossentropy',
              optimizer=SGD())

# Fit network
model.fit(X_train, Y_train, nb_epoch=nb_epoch,
         verbose=1)

在此之后,我收到以下错误

使用 TensorFlow 后端。 Traceback(最近一次通话最后一次):文件 “/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py”, 第 670 行,在 _call_cpp_shape_fn_impl 状态)文件“/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py”, 第 89 行,在 退出 下一个(self.gen)文件“/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py”, 第 469 行,在 raise_exception_on_not_ok_status pywrap_tensorflow.TF_GetCode(status)) tensorflow.python.framework.errors_impl.InvalidArgumentError: Negative 'Conv3D' 的 1 减去 5 导致的尺寸大小(操作: 'Conv3D') 输入形状:[?,1,25,25,25], [5,5,5,25,32]。

在处理上述异常的过程中,又发生了一个异常:

Traceback(最近一次调用最后一次):文件“CNN_3D.py”,第 76 行,在 激活='relu')) 文件“/usr/local/lib/python3.6/site-packages/keras/models.py”,第 299 行,在 添加 layer.create_input_layer(batch_input_shape, input_dtype) 文件 "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", 第 401 行,在 create_input_layer 自我(x)文件“/usr/local/lib/python3.6/site-packages/keras/engine/topology.py”, 第 572 行,在 调用 self.add_inbound_node(inbound_layers, node_indices, tensor_indices) 文件 "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", 第 635 行,在 add_inbound_node Node.create_node(self, inbound_layers, node_indices, tensor_indices) 文件 "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", 第 166 行,在 create_node output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0])) 文件 “/usr/local/lib/python3.6/site-packages/keras/layers/convolutional.py”, 第 1234 行,通话中 filter_shape=self.W_shape) 文件 "/usr/local/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", 第 2831 行,在 conv3d 中 x = tf.nn.conv3d(x, kernel, strides, padding) 文件 "/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/gen_nn_ops.py", 第 522 行,在 conv3d 中 strides=strides, padding=padding, name=name) 文件 "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", 第 763 行,在 apply_op 中 op_def=op_def) 文件 "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", 第 2397 行,在 create_op 中 set_shapes_for_outputs(ret) 文件“/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py”, 第 1757 行,在 set_shapes_for_outputs 形状= shape_func(op)文件“/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py”, 第 1707 行,在 call_with_requiring 中 返回 call_cpp_shape_fn(op, require_shape_fn=True) 文件 "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", 第 610 行,在 call_cpp_shape_fn 中 debug_python_shape_fn,require_shape_fn)文件“/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py”, 第 675 行,在 _call_cpp_shape_fn_impl raise ValueError(err.message) ValueError: 负维度大小是由输入的“Conv3D”(操作:“Conv3D”)从 1 中减去 5 引起的 形状:[?,1,25,25,25], [5,5,5,25,32]。

我做错了什么来得到这个错误?

【问题讨论】:

  • 我认为你的训练数据的形状是错误的。 Tensorflow 期望数据采用 (sample, dim1, dim2, ..., channel) 的形式。给定一个常规 2D 图像列表,您可以像这样重塑:X_train.reshape((-1, WIDTH, HEIGHT, 1))。将此适应您的情况,您可以尝试X_train = X_train.reshape((-1, img_rows, img_cols, img_depth, 1))input_shape 应该是 (img_rows, img_cols, img_depth, 1)
  • 我仍然遇到同样的错误。当我添加更多通道(input_shape = (5, img_rows, img_cols, img_depth))时,我可以通过层的创建来克服或等于卷积滤波器的大小。但我只有一个输入通道。我认为问题出在 Conv3D 层的定义中
  • 我想做你正在做的事情,但我无法弄清楚如何将 3D 模型文件转换为占用网格。你是怎么做到的?谢谢!

标签: python numpy tensorflow keras conv-neural-network


【解决方案1】:

我认为问题在于您在 Theano 排序中设置输入形状,但您使用的是带有 Tensorflow 后端和 Tensorflow img 排序的 Keras。此外,y_train 数组必须转换为分类标签。

更新代码:

from keras.utils import np_utils
from keras import backend as K

if K.image_dim_ordering() == 'th':
    X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols, img_depth)
    input_shape = (1, img_rows, img_cols, img_depth)
else:
    X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, img_depth, 1)
    input_shape = (img_rows, img_cols, img_depth, 1)

Y_train = np_utils.to_categorical(Y_train, nb_classes)

添加这行应该可以解决它。

【讨论】:

  • 使用这两个代码几乎可以了。但现在我得到一个新错误:Using TensorFlow backend. Traceback (most recent call last): File "CNN_3D_2.py", line 86, in <module> verbose=1) ... ValueError: Error when checking model input: expected convolution3d_input_1 to have shape (None, 25, 25, 25, 1) but got array with shape (1, 25, 25, 25, 2)
  • 你能告诉我你原来的(重塑之前)X_train.shape 吗??
  • (2, 25, 25, 25)
  • 我用重塑 @JoãoPedroFontes 更新了代码。立即尝试
  • 大卫,它给出了错误ValueError: Input 0 is incompatible with layer convolution3d_1: expected ndim=5, found ndim=4。你给我的例子不是二维的吗?在输入形状中,您只给出行和列。我尝试添加 img_depths 它给了ValueError: Error when checking model target: expected activation_1 to have shape (None, 3) but got array with shape (2, 1)
猜你喜欢
  • 2017-08-31
  • 2020-05-26
  • 2020-10-07
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-24
  • 2021-10-08
  • 1970-01-01
相关资源
最近更新 更多