ValueError: Ошибка при проверке цели: ожидается, что Activation_1 будет иметь форму (158,), но получил массив с формой (121,) - PullRequest
0 голосов
/ 08 июля 2019

Получил следующую ошибку при обучении моей CNN:

Traceback (последний вызов был последним): Файл "train_and_test.py", строка 66, в H = model.fit (trainX, trainY, validation_data = (testX, testY), batch_size = 32, эпох = 100, многословно = 1) Файл "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", строка 972, в форме batch_size = batch_size) Файл "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", строка 789, в _standardize_user_data exception_prefix = 'целевая') Файл "/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py", строка 138, в standardize_input_data ул (data_shape)) ValueError: Ошибка при проверке цели: ожидается, что Activation_1 будет иметь форму (158,), но получил массив с формой (121,)

Activation_1 - последний уровень моей сети, в качестве входного файла он должен иметь массив размером 158, потому что в моей задаче 158 классов. Я строю модель так:

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

Теперь есть странная вещь: если я поставлю число X в аргументе классов, который отличается от 158, ошибка говорит:

ValueError: Ошибка при проверке цели: ожидается, что Activation_1 будет иметь форму (X,), но получил массив с формой (158,)

Таким образом, входной массив имеет правильные размеры! Но каждый раз, когда я использую правильное значение, входной массив никогда не имеет (158) формы.

Где я не прав? Какие-либо предложения?

РЕДАКТИРОВАТЬ - Вот мой код:

Это для обучения и тестирования 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"])

Это структура 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 Ответ

0 голосов
/ 10 июля 2019

Я не пытался запустить код, но, возможно, понял вашу проблему.

Имейте в виду, что LabelBinarizer дает вам столько столбцов, сколько существует разных классов. Например:

from sklearn import preprocessing

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

lb.transform(y)

даст вам:

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

Так как есть только 4 уникальных класса.

У вас может быть 158 разных классов, но, возможно, у вас нет образца для каждого, поэтому в итоге вы получите только 121 столбец в trainY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...