簡體   English   中英

'Conv2D' 從 1 中減去 3 導致的負尺寸大小

[英]Negative dimension size caused by subtracting 3 from 1 for 'Conv2D'

我使用KerasTensorflow作為后端,這里是我的代碼:

import numpy as np
np.random.seed(1373) 
import tensorflow as tf
tf.python.control_flow_ops = tf

import os
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils

batch_size = 128
nb_classes = 10
nb_epoch = 12


img_rows, img_cols = 28, 28

nb_filters = 32

nb_pool = 2

nb_conv = 3


(X_train, y_train), (X_test, y_test) = mnist.load_data()

print(X_train.shape[0])

X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)


X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255


print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')


Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

model = Sequential()

model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='valid',
input_shape=(1, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
model.add(Activation('relu'))

model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) 

model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=["accuracy"])


model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=1, validation_data=(X_test, Y_test))

score = model.evaluate(X_test, Y_test, verbose=0)

print('Test score:', score[0])
print('Test accuracy:', score[1])

和引用錯誤:

Using TensorFlow backend.
60000
('X_train shape:', (60000, 1, 28, 28))
(60000, 'train samples')
(10000, 'test samples')
Traceback (most recent call last):
  File "mnist.py", line 154, in <module>
    input_shape=(1, img_rows, img_cols)))
  File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 276, in add
    layer.create_input_layer(batch_input_shape, input_dtype)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 370, in create_input_layer
    self(x)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 514, in __call__
    self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 572, in add_inbound_node
    Node.create_node(self, inbound_layers, node_indices, tensor_indices)
  File "/usr/local/lib/python2.7/dist-packages/keras/engine/topology.py", line 149, in create_node
    output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
  File "/usr/local/lib/python2.7/dist-packages/keras/layers/convolutional.py", line 466, in call
    filter_shape=self.W_shape)
  File "/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.py", line 1579, in conv2d
    x = tf.nn.conv2d(x, kernel, strides, padding=padding)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_nn_ops.py", line 396, in conv2d
    data_format=data_format, name=name)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py", line 759, in apply_op
    op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2242, in create_op
    set_shapes_for_outputs(ret)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1617, in set_shapes_for_outputs
    shapes = shape_func(op)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1568, in call_with_requiring
    return call_cpp_shape_fn(op, require_shape_fn=True)
  File "/usr/local/lib/python2.7/dist-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/python2.7/dist-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 3 from 1 for 'Conv2D' (op: 'Conv2D') with input shapes: [?,1,28,28], [3,3,28,32].

首先,我看到一些答案是Tensorflow版本有問題,所以我將Tensorflow升級到0.12.0 ,但仍然存在,是網絡問題還是我遺漏了什么, input_shape應該是什么樣子?

更新這里是./keras/keras.json

{
    "image_dim_ordering": "tf", 
    "epsilon": 1e-07, 
    "floatx": "float32", 
    "backend": "tensorflow"
}

您的問題來自image_ordering_dim中的keras.json

來自Keras 圖像處理文檔

dim_ordering:{"th", "tf"} 之一。 “tf”模式意味着圖像應該具有形狀(樣本、高度、寬度、通道),“th”模式意味着圖像應該具有形狀(樣本、通道、高度、寬度)。 它默認為在 ~/.keras/keras.json 的 Keras 配置文件中找到的 image_dim_ordering 值。 如果您從未設置它,那么它將是“tf”。

Keras 將卷積操作映射到選定的后端(theano 或 tensorflow)。 但是,兩個后端對維度的排序做出了不同的選擇。 如果您的圖像批次是 N 個 HxW 大小的圖像和 C 通道,theano 使用 NCHW 排序,而 tensorflow 使用 NHWC 排序。

Keras 允許您選擇您喜歡的順序,並將進行轉換以映射到后面的后端。 但是如果你選擇image_ordering_dim="th"它需要 Theano 風格的排序(NCHW,你的代碼中的image_ordering_dim="tf" ),如果image_ordering_dim="tf"它需要張量流風格的排序 (NHWC)。

由於您的image_ordering_dim設置為"tf" ,如果您將數據重塑為張量流樣式,它應該可以工作:

X_train = X_train.reshape(X_train.shape[0], img_cols, img_rows, 1)
X_test = X_test.reshape(X_test.shape[0], img_cols, img_rows, 1)

input_shape=(img_cols, img_rows, 1)

FWIW,我用一些 strides 或 kernel_size 但不是全部的值反復得到這個錯誤,后端和 image_ordering 已經設置為張量流,當我添加padding="same"時它們都消失了

只需添加這個:

from keras import backend as K
K.set_image_dim_ordering('th')

我也有同樣的問題。 但是,我使用的每個 Conv3D 層都在減少輸入的大小。 因此,在聲明 Conv2D/3D 層時包含一個參數 padding='same' 解決了這個問題。 這是演示代碼

model.add(Conv3D(32,kernel_size=(3,3,3),activation='relu',padding='same'))

減小過濾器的尺寸也可以解決問題。

實際上,Conv3D 或 Conv2D 層減少了輸入數據。 但是,當您的下一層沒有收到任何輸入或大小不適合該層的輸入時,就會發生此錯誤。 通過填充,我們使 Conv3Dor2D 的輸出保持與輸入相同的大小,以便下一層獲得所需的輸入

我遇到了同樣的問題,但通過更改 conv2d 函數解決了:

if K.image_data_format=='channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1,img_cols,img_rows)
    x_test = x_test.reshape(x_test.shape[0], 1,img_cols,img_rows)
    input_shape = (1,img_cols,img_rows)
else:
    x_train = x_train.reshape(x_train.shape[0],img_cols,img_rows,1)
    x_test = x_test.reshape(x_test.shape[0],img_cols,img_rows,1)
    input_shape = (img_cols,img_rows,1)
model.add(Convolution2D(32,(3, 3), input_shape = input_shape, activation="relu"))

使用括號提供過濾器的大小,例如:

model.add(Convolution2D(nb_filters,( nb_conv, nb_conv) ,border_mode='valid',
input_shape=(1, img_rows, img_cols)))

它適用於我的情況,並且還將 X_train 、 X_test 更改為:

X_train = X_train.reshape(X_train.shape[0], img_cols, img_rows, 1)
X_test = X_test.reshape(X_test.shape[0], img_cols, img_rows, 1)

另一個解決方案可以幫助改變:

from keras.layers import Convolution2D, MaxPooling2D

from keras.layers import Conv2D, MaxPooling2D

之后,為了運行預處理輸入數據,我更改:

X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)

X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test.reshape(X_test.shape[0], 28, 28, 1)

最后,我改變:

model.add(Convolution2D(32, 3, 3, activation='relu',input_shape=(1,28,28))) 
model.add(Convolution2D(32, 3, 3,activation='relu'))

model.add(Conv2D(32, (3, 3), activation='relu',input_shape=(28,28,1)))
model.add(Conv2D(32, (3, 3), activation='relu'))

剛遇到這個問題。 下面是使用新 API 的解決方案。

K.set_image_dim_ordering('tf') --> K.set_image_data_format('channels_last')
K.set_image_dim_ordering('th') --> K.set_image_data_format('channels_first')
K.image_dim_ordering() == 'tf' --> K.image_data_format() == 'channels_last'
K.image_dim_ordering() == 'th' --> K.image_data_format() == 'channels_first'

在這里查看更多

   %store -r le
   %store -r x_train 
   %store -r x_test 
   %store -r y_train 
   %store -r y_test 
   %store -r yy 
    import numpy as np
    import keras
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Activation, Flatten
    from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
    from keras.optimizers import Adam
    from keras.utils import np_utils
    from sklearn import metrics
    num_rows = 40
    num_columns = 174
    num_channels = 1
    x_train = x_train.reshape(x_train.shape[0],num_rows , num_columns, num_channels)
    x_test = x_test.reshape(x_test.shape[0], num_rows, num_columns,num_channels )
num_labels = yy.shape[1]
filter_size = 2
# Construct model 
model = Sequential()

model.add(Conv2D(filters=16, kernel_size=2, activation='relu',input_shape=( 
40,174,1)))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))

model.add(Conv2D(filters=32, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))

model.add(Conv2D(filters=64, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))

model.add(Conv2D(filters=128, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(GlobalAveragePooling2D())

model.add(Dense(num_labels, activation='softmax')) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM