我很难理解我的第一个卷积神经网络期望的输入形状是什么。
我的训练集包含500张50×50像素的灰度图像。
网络从一个Conv2D
层开始。关于input_shape
参数的文档说明如下:
输入形状:4D张量,形状为:`(samples, channels, rows, cols)` 如果data_format='channels_first';或者4D张量,形状为:`(samples, rows, cols, channels)` 如果data_format='channels_last'。
因此,我期望需要将我的图像(目前存储在一个pandas.DataFrame
的列中)提供为形状为(500, 1, 50, 50)
的numpy.array
,因为我的图像只有一个“颜色”通道。我按以下方式进行了重塑:
X = np.array([img for img in imgs["img_res"]])X = X.reshape(-1, 1, img_size, img_size)
现在X.shape
的形状是:(500, 1, 50, 50)。我将其作为参数提供给了Conv2D
。
model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3), input_shape=X.shape[1:], activation="relu"),])
这产生了以下错误。你能指出这里的问题是什么吗?
---------------------------------------------------------------------------InvalidArgumentError Traceback (most recent call last)/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs) 1566 try:-> 1567 c_op = c_api.TF_FinishOperation(op_desc) 1568 except errors.InvalidArgumentError as e:InvalidArgumentError: Negative dimension size caused by subtracting 3 from 1 for 'conv2d/Conv2D' (op: 'Conv2D') with input shapes: [?,1,50,50], [3,3,50,64].During handling of the above exception, another exception occurred:ValueError Traceback (most recent call last)<ipython-input-24-0b665136e60b> in <module>() 3 kernel_size=(3,3), 4 input_shape=X.shape[1:],----> 5 activation="relu"), 6 #tf.keras.layers.MaxPool2D(pool_size=(2,2)), 7 #tf.keras.layers.Conv2D(filters=64,/usr/local/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/sequential.py in __init__(self, layers, name) 99 if layers: 100 for layer in layers:--> 101 self.add(layer) 102 103 @property/usr/local/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/sequential.py in add(self, layer) 162 # and create the node connecting the current layer 163 # to the input layer we just created.--> 164 layer(x) 165 set_inputs = True 166 else:/usr/local/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs) 312 """ 313 # Actually call the layer (optionally building it).--> 314 output = super(Layer, self).__call__(inputs, *args, **kwargs) 315 316 if args and getattr(self, '_uses_inputs_arg', True):/usr/local/lib/python3.6/site-packages/tensorflow/python/layers/base.py in __call__(self, inputs, *args, **kwargs) 715 716 if not in_deferred_mode:--> 717 outputs = self.call(inputs, *args, **kwargs) 718 if outputs is None: 719 raise ValueError('A layer\'s `call` method should return a Tensor '/usr/local/lib/python3.6/site-packages/tensorflow/python/layers/convolutional.py in call(self, inputs) 166 167 def call(self, inputs):--> 168 outputs = self._convolution_op(inputs, self.kernel) 169 170 if self.use_bias:/usr/local/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py in __call__(self, inp, filter) 866 867 def __call__(self, inp, filter): # pylint: disable=redefined-builtin--> 868 return self.conv_op(inp, filter) 869 870 /usr/local/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py in __call__(self, inp, filter) 518 519 def __call__(self, inp, filter): # pylint: disable=redefined-builtin--> 520 return self.call(inp, filter) 521 522 /usr/local/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py in __call__(self, inp, filter) 202 padding=self.padding, 203 data_format=self.data_format,--> 204 name=self.name) 205 206 /usr/local/lib/python3.6/site-packages/tensorflow/python/ops/gen_nn_ops.py in conv2d(input, filter, strides, padding, use_cudnn_on_gpu, data_format, dilations, name) 954 "Conv2D", input=input, filter=filter, strides=strides, 955 padding=padding, use_cudnn_on_gpu=use_cudnn_on_gpu,--> 956 data_format=data_format, dilations=dilations, name=name) 957 _result = _op.outputs[:] 958 _inputs_flat = _op.inputs/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords) 785 op = g.create_op(op_type_name, inputs, output_types, name=scope, 786 input_types=input_types, attrs=attr_protos,--> 787 op_def=op_def) 788 return output_structure, op_def.is_stateful, op 789 /usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in create_op(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_shapes, compute_device) 3390 input_types=input_types, 3391 original_op=self._default_original_op,-> 3392 op_def=op_def) 3393 3394 # Note: shapes are lazily computed with the C API enabled./usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in __init__(self, node_def, g, inputs, output_types, control_inputs, input_types, original_op, op_def) 1732 op_def, inputs, node_def.attr) 1733 self._c_op = _create_c_op(self._graph, node_def, grouped_inputs,-> 1734 control_input_ops) 1735 else: 1736 self._c_op = None/usr/local/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs) 1568 except errors.InvalidArgumentError as e: 1569 # Convert to ValueError for backwards compatibility.-> 1570 raise ValueError(str(e)) 1571 1572 return c_opValueError: Negative dimension size caused by subtracting 3 from 1 for 'conv2d/Conv2D' (op: 'Conv2D') with input shapes: [?,1,50,50], [3,3,50,64].
回答:
通过向Conv2D传递data_format='channels_first'
来指定你不是使用默认的数据格式。
model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3), input_shape=X.shape[1:], activation="relu", data_format='channels_first'), ])