2017-03-09 81 views
2

我在使用Keras和Python对3D形状进行分类时会出现喂养3D CNN的问题。我有一些JSON格式的文件夹。我将这些模型读入Numpy Array。这些模型是25 * 25 * 25,代表体素化模型的占用网格(每个位置代表位置(i,j,k)中的体素是否有点或没有),所以我只有1个输入通道,像二维图像中的灰度图像。那我的代码如下:3D卷积神经网络输入形状

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) 

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

Using TensorFlow backend. Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", line 670, in _call_cpp_shape_fn_impl status) File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py", line 89, in exit next(self.gen) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 469, in raise_exception_on_not_ok_status pywrap_tensorflow.TF_GetCode(status)) tensorflow.python.framework.errors_impl.InvalidArgumentError: Negative dimension size caused by subtracting 5 from 1 for 'Conv3D' (op: 'Conv3D') with input shapes: [?,1,25,25,25], [5,5,5,25,32].

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "CNN_3D.py", line 76, in activation='relu')) File "/usr/local/lib/python3.6/site-packages/keras/models.py", line 299, in add layer.create_input_layer(batch_input_shape, input_dtype) File "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", line 401, in create_input_layer self(x) File "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", line 572, in call self.add_inbound_node(inbound_layers, node_indices, tensor_indices) File "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", line 635, in add_inbound_node Node.create_node(self, inbound_layers, node_indices, tensor_indices) File "/usr/local/lib/python3.6/site-packages/keras/engine/topology.py", line 166, in create_node output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0])) File "/usr/local/lib/python3.6/site-packages/keras/layers/convolutional.py", line 1234, in call filter_shape=self.W_shape) File "/usr/local/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 2831, in conv3d x = tf.nn.conv3d(x, kernel, strides, padding) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 522, in conv3d strides=strides, padding=padding, name=name) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", line 763, in apply_op op_def=op_def) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 2397, in create_op set_shapes_for_outputs(ret) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1757, in set_shapes_for_outputs shapes = shape_func(op) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1707, in call_with_requiring return call_cpp_shape_fn(op, require_shape_fn=True) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", line 610, in call_cpp_shape_fn debug_python_shape_fn, require_shape_fn) File "/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", line 675, in _call_cpp_shape_fn_impl raise ValueError(err.message) ValueError: Negative dimension size caused by subtracting 5 from 1 for 'Conv3D' (op: 'Conv3D') with input shapes: [?,1,25,25,25], [5,5,5,25,32].

我在做什么错得到这个错误?

+0

我认为你的训练数据的形状是错误的。 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)'。 – Matt

+0

我仍然得到相同的错误。当我添加更多通道('input_shape =(5,img_rows,img_cols,img_depth)')时,我可以通过创建图层来克服或等于卷积滤镜的大小。但我只有一个输入渠道。我认为问题在于Conv3D层的定义 –

回答

4

我认为问题在于您在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) 

添加此行应该修复它。

+0

使用这两个代码几乎都有它。但是现在我得到一个新的错误:'使用TensorFlow后端。 Traceback(最近一次调用的最后一个):文件“CNN_3D_2.py”,第86行,在 verbose = 1)... ValueError:检查模型输入时出错:期望convolution3d_input_1具有形状(无,25,25,25,1 ),但得到了阵列形状(1,25,25,25,2)' –

+0

你能告诉我你的原形(重塑前)X_train.shape? –

+0

(2,25,25,25) –