简体   繁体   中英

InvalidArgumentError: Negative dimension size caused by subtracting 3 from 1 '{{node conv2d_28/Conv2D}}

import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dropout, Dense, MaxPool2D, Conv2D, BatchNormalization, Flatten, Activation
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.utils import to_categorical
import os
import time
import matplotlib.pyplot as plt
import seaborn
import pickle

This "icml_face_data.csv" contain training,validation and test data of facial expression

df = pd.read_csv("icml_face_data.csv")

def prepare_data(data):
  """
  This function separates array and label(target)
  :param data: data( it can be train,test,val)
  :return: image_array and labels(target)
  """
  image_array = np.zeros(shape=(len(data),48,48))
  image_label = np.array(data["emotion"])
  for i, row in enumerate(data.index):
    image = np.fromstring(data.loc[row, " pixels"], dtype=int, sep=" ")
    image = np.reshape(image, (48, 48))
    image_array[i] = image
  return image_array, image_label

training_data, training_label = prepare_data(df[df[" Usage"]=="Training"])
validation_data, validation_label = prepare_data(df[df[" Usage"]=="PublicTest"])
test_data, test_label = prepare_data(df[df[" Usage"]=="PrivateTest"])

train_data = training_data.reshape((training_data.shape[0],48,48,1))
train_data = train_data.astype("float32")/255

valid_data = validation_data.reshape((validation_data.shape[0],48,48,1))
valid_data = valid_data.astype("float32")/255

test_data = test_data.reshape((test_data.shape[0],48,48,1))
test_data = test_data.astype("float32")/255

training_label = to_categorical(training_label)
validation_label = to_categorical(validation_label)
test_label = to_categorical(test_label)

i was training convolutional model using deferent combination of dense layers,convolutional layers, and layers size when i trained on combination dense_layers = [1,2,3],layer_sizes = [32,64,128],conv_layers = [1,2,3]

It worked fine with no error and when i tried dense_layers = [1],layer_sizes = [32],conv_layers = [3,4] It still worked fine.

But when i used dense_layers = [1],layer_sizes = [32],conv_layers = [5] this combination it raise error

dense_layers = [1]
layer_sizes=[32]
conv_layers = [5]

for dense_layer in dense_layers:
  for layer_size in layer_sizes:
    for conv_layer in conv_layers:

      NAME = f"{conv_layer}-conv-{layer_size}-layer-{dense_layer}-Dense-{int(time.time())}"
      tensorboard = TensorBoard(log_dir=f"logs/{NAME}")

      model = Sequential()
      model.add(Conv2D(layer_size, (3,3),activation="relu",input_shape=(48,48,1)))
      model.add(MaxPool2D((2,2)))
      model.add(Dropout(0.2))

      for _ in range(conv_layer-1):
        model.add(Conv2D(layer_size, (3,3),activation="relu"))
        model.add(MaxPool2D((2,2)))
        model.add(Dropout(0.2))

      model.add(Flatten())
      for _ in range(dense_layer):
        model.add(Dense(layer_size, activation="relu"))
        model.add(Dropout(0.2))

      model.add(Dense(7, activation="softmax"))

      model.compile(loss='categorical_crossentropy',optimizer=tf.keras.optimizers.Adam(lr=1e-3),metrics=["accuracy"])

      model.fit(train_data, training_label,
                        validation_data=(valid_data,validation_label),
                        epochs=20,
                        batch_size=32,
                        callbacks=[tensorboard])

error:

---------------------------------------------------------------------------

InvalidArgumentError                      Traceback (most recent call last)

/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs, op_def)
   1879   try:
-> 1880     c_op = pywrap_tf_session.TF_FinishOperation(op_desc)
   1881   except errors.InvalidArgumentError as e:

InvalidArgumentError: Negative dimension size caused by subtracting 3 from 1 for '{{node conv2d_28/Conv2D}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](Placeholder, conv2d_28/Conv2D/ReadVariableOp)' with input shapes: [?,1,1,32], [3,3,32,32].


During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)

17 frames

/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs, op_def)
   1881   except errors.InvalidArgumentError as e:
   1882     # Convert to ValueError for backwards compatibility.
-> 1883     raise ValueError(str(e))
   1884 
   1885   return c_op

ValueError: Negative dimension size caused by subtracting 3 from 1 for '{{node conv2d_28/Conv2D}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](Placeholder, conv2d_28/Conv2D/ReadVariableOp)' with input shapes: [?,1,1,32], [3,3,32,32].

Why this code raising error for that combination only i used google colab (runtime type = "gpu") i tried restart runtime and run all but it just raise error on that combination only i don't know why its happening? please help

Your problem probably is, that the size of your feature maps becomes smaller and smaller with every additional layer due to your use of strides in your convolutional and max pooling layers. Your original input has shape (48, 48, 1), so if you use a conv layer on it (in your case without strides, but with padding="valid", which is the standard option) then your output will have shape (46, 46, x). The same is true for the max pooling layers, but the effect is even worse because you did not specify a stride, and by default tensorflow assumes that the stride is supposed to be equal to your kernel size. This means that the output of your max pooling layer for an input with shape (48, 48, 1) would be just (24, 24, 1).

So as a summary: With every additional layer you reduce the size of your feature maps, and at some point they will be smaller than the kernel size of your layer, which results in the error.

I assume that you want your image shape to stay the same all the time. If this is the case, then you should alter your code in the following ways:

  1. add padding = "same" to both your max pooling and your convolutional layers.
  2. add strides = (1, 1) to your max pooling layers.

For most convolutional.networks, it often makes sense for the feature map to become smaller and smaller while passing through the.network. So you should consider implementing my suggestions only for some layers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM