2017-03-09 79 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) –