0
votes

Got the following error when training my CNN:

Traceback (most recent call last): File "train_and_test.py", line 66, in H = model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=32, epochs=100, verbose=1) File "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", line 972, in fit batch_size=batch_size) File "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", line 789, in _standardize_user_data exception_prefix='target') File "/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py", line 138, in standardize_input_data str(data_shape)) ValueError: Error when checking target: expected activation_1 to have shape (158,) but got array with shape (121,)

Activation_1 is the Last layer of my network, it should have an array of size 158 as input, because my problem has 158 classes. I build the model like this:

model = DeepIrisNet_A.build(width=128, height=128, depth=1, classes=158)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

Now there's the Strange thing: if I put a number X in classes argument that is different from 158, the error says:

ValueError: Error when checking target: expected activation_1 to have shape (X,) but got array with shape (158,)

So the input array has the right dimensions! But everytime I use the correct value the input array has never (158,) shape.

Where am I wrong? Any suggestions?

EDIT - Here's some of my code:

This is for training and testing the CNN

from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from datasets import UtirisLoader
from models import DeepIrisNet_A
from utilities import ResizerPreprocessor
from utilities import ConvertColorSpacePreprocessor
from keras.optimizers import SGD
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import tensorflow as tf

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="path to input dataset")
ap.add_argument("-o", "--output", required=True, help="path to the output loss/accuracy plot")
args = vars(ap.parse_args())

# grab the list of images that we’ll be describing
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))

# initialize the image preprocessor
rp = ResizerPreprocessor(128, 128)
ccsp = ConvertColorSpacePreprocessor()

# load the dataset from disk then scale the raw pixel intensities to the range [0, 1]
utiris = UtirisLoader(preprocessors=[rp, ccsp])
(data, labels) = utiris.load_infrared(imagePaths, verbose=100)


# print some infos
print("DATA LENGTH: {}".format(len(data)))
print("LABELS LENGTH: {}".format(len(labels)))

unique = np.unique(labels, return_counts=False)
print("LABELS COUNT: {}".format(len(unique)))


# convert data to float
data = data.astype("float") / 255.0

# partition the data into training and testing splits using 75% of the data for training
# and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25, random_state=42)
#trainX = np.resize(trainX, (-1, 128, 128, 1))
trainX = trainX.reshape((trainX.shape[0], 128, 128, 1))
testX = testX.reshape((testX.shape[0], 128, 128, 1))

# convert the labels from integers to vectors
trainY = LabelBinarizer().fit_transform(trainY)
testY = LabelBinarizer().fit_transform(testY)

print("trainY: {}".format(trainY))

# initialize the optimizer and model_selection
print("[INFO] compiling model...")
opt = SGD(lr=0.01, momentum=0.9)
model = DeepIrisNet_A.build(width=128, height=128, depth=1, classes=158)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

#train the network
print("[INFO] training network...")
H = model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=32, epochs=100, verbose=1)

# evaluate the network
print("[INFO] evaluating network...")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=["cat", "dog", "panda"]))
# plot the training loss and accuracy
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, 100), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, 100), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, 100), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, 100), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["output"])

This is the structure of the CNN

from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K

class DeepIrisNet_A:
    @staticmethod
    def build(width, height, depth, classes):
        # initialize the models along with the input shape to be "channels last" and the channels dimension itself
        model = Sequential()
        inputShape = (height, width, depth)
        chanDim = -1 # the index of the channel dimension, needed for batch normalization. -1 indicates that channels is the last dimension in the input shape

        # if we are using "channel first", update the input shape
        if K.image_data_format() == "channels_first":
            inputShape = (depth, height, width)
            chanDim = 1
        # CONV 1
        model.add(Conv2D(32,(5,5), strides=(1,1), padding="same", input_shape=inputShape))
        # BN 1
        model.add(BatchNormalization(axis=chanDim))
        # CONV 2
        model.add(Conv2D(64, (3,3), strides=(1,1), padding ="valid"))
        # POOL 1
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        # BN 2
        model.add(BatchNormalization(axis=chanDim))
        # CONV 3
        model.add(Conv2D(128, (3,3), strides=(1,1), padding ="valid"))
        # BN 3
        model.add(BatchNormalization(axis=chanDim))
        # CONV 4
        model.add(Conv2D(192, (3,3), strides=(1,1), padding ="same"))
        # POOL 2
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        # BN 4
        model.add(BatchNormalization(axis=chanDim))
        # CONV 5
        model.add(Conv2D(256, (3,3), strides=(1,1), padding ="valid"))
        # BN 5
        model.add(BatchNormalization(axis=chanDim))
        # CONV 6
        model.add(Conv2D(320, (3,3), strides=(1,1), padding ="valid"))
        # POOL 3
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        # BN 6
        model.add(BatchNormalization(axis=chanDim))
        # CONV 7
        model.add(Conv2D(480, (3,3), strides=(1,1), padding ="valid"))
        # BN 7
        model.add(BatchNormalization(axis=chanDim))
        # CONV 8
        model.add(Conv2D(512, (3,3), strides=(1,1), padding ="valid"))
        # POOL 4
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        # BN 8
        model.add(BatchNormalization(axis=chanDim))
        # FC 9
        model.add(Flatten())
        model.add(Dense(4096))
        # DROP 10
        model.add(Dropout(0.5))
        # FC 11
        model.add(Dense(4096))
        # DROP 12
        model.add(Dropout(0.5))
        # FC 13
        model.add(Dense(classes))
        # COST 14
        model.add(Activation("softmax"))

        # return the constructed network architecture
        return model
1
Please also add a minimal example of your code! - ga97dil
Thank you for your answer! I edited the Question adding some code - Mauro Semproni

1 Answers

0
votes

I didn't try to run the code but i might have figured your problem.

Be aware that LabelBinarizeronly gives you as many columns as there are different classes. For example:

from sklearn import preprocessing

y = [1, 2, 6, 4, 2]
lb = preprocessing.LabelBinarizer()
lb.fit(y)

lb.transform(y)

will give you:

>>> array([[1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 1, 0, 0]])

Since there are only 4 unique classes.

You might have 158 different classes but maybe you dont have a sample for each one so you only get 121 columns in trainYin the end.