ValueError:参数“target”和“output”必须具有相同的等级(ndim)

问题描述 投票:0回答:1

我最近一直在测试使用 CNN 模型进行图像分类的代码(“main.py”)(无论图片是猫还是狗),但我一直收到此错误:

File "c:\Users\UserPC\Downloads\image-classification-using-cnn-master\image-classification-using-cnn-master\Code\main.py", line 164, in <module>
    history = model.fit(
              ^^^^^^^^^^
  File "C:\Users\UserPC\AppData\Local\Programs\Python\Python311\Lib\site-packages\keras\src\utils\traceback_utils.py", line 122, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\UserPC\AppData\Local\Programs\Python\Python311\Lib\site-packages\keras\src\backend\tensorflow\nn.py", line 694, in binary_crossentropy
    raise ValueError(
ValueError: Arguments `target` and `output` must have the same rank (ndim). Received: target.shape=(50,), output.shape=(50, 2)

我不确定它是否与 get_model() 有任何关系:

import numpy as np
import math
from data_prep import prep_and_load_data
import constants as CONST
import pickle
import os
import cv2
from matplotlib import pyplot as plt
import copy
import tensorflow as tf
import keras as k
from keras._tf_keras.keras.models import Sequential
from keras._tf_keras.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from keras._tf_keras.keras.layers import Conv2D, MaxPooling2D
from keras._tf_keras.keras.callbacks import TensorBoard
import constants as CONST
# from keras._tf_keras.keras.utils import to_categorical

def get_model():
    # model = k.Sequential()
    model = Sequential()

    # Adding Convolutional, MaxPooling, and BatchNormalization layers
    model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(CONST.IMG_SIZE, CONST.IMG_SIZE, 3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(BatchNormalization())

    model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(BatchNormalization())

    model.add(Conv2D(96, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(BatchNormalization())

    model.add(Conv2D(96, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(BatchNormalization())
    model.add(Dropout(0.2))

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

    # Flatten and add Dense layers
    model.add(Flatten())
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.3))

    # Final Dense layer for binary classification (2 classes)
    model.add(Dense(2, activation='softmax'))  # Changed from 10 to 2 units

    # Compile the model with binary crossentropy loss
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    print('Model prepared...')
    return model



def plotter(history_file):
    with open(history_file, 'rb') as file:
        history = pickle.load(file)
    
    plt.plot(history['accuracy'])
    plt.plot(history['val_accuracy'])
    plt.title('model accuracy')
    plt.ylabel('accuracy')
    plt.xlabel('epoch')
    plt.legend(['train', 'val'], loc='upper left')
    plt.show()

    plt.savefig('18_000_15epoch_accuracy.png')

    plt.plot(history['loss'])
    plt.plot(history['val_loss'])
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train', 'val'], loc='upper left')
    plt.show()
    plt.savefig('18_000_15epoch_loss.png')


def video_write(model):
    # fourcc = cv2.VideoWriter.fourcc(*'DIVX')
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    out = cv2.VideoWriter("./prediction.mp4", fourcc, 1.0, (400,400))
    val_map = {1: 'Dog', 0: 'Cat'}

    font = cv2.FONT_HERSHEY_SIMPLEX
    location = (20,20)
    fontScale = 0.5
    fontColor = (255,255,255)
    lineType  = 2

    test_data = []
    image_test_data = []

    DIR = CONST.TEST_DIR2
    image_paths = os.listdir(DIR)
    image_paths = image_paths[:100]
    count = 0
    for img_path in image_paths:
        image, image_std = process_image(DIR, img_path)
        
        image_std = image_std.reshape(-1, CONST.IMG_SIZE, CONST.IMG_SIZE, 3)
        pred = model.predict([image_std])
        arg_max = np.argmax(pred, axis=1)
        max_val = np.max(pred, axis=1)
        s = val_map[arg_max[0]] + ' - ' + str(max_val[0]*100) + '%'
        cv2.putText(image, s, 
            location, 
            font, 
            fontScale,
            fontColor,
            lineType)
        
        frame = cv2.resize(frame, (400, 400))
        out.write(frame)
        
        count += 1
        print(count)
    out.release()

def process_image(directory, img_path):
    path = os.path.join(directory, img_path)
    image = cv2.imread(path)
    image_copy = copy.deepcopy(image)
    
    image = cv2.resize(image, (CONST.IMG_SIZE, CONST.IMG_SIZE))
    image_std = image.astype('float') / 255.0
    return image_copy, image_std


if __name__ == "__main__":
    data = np.array(prep_and_load_data(),dtype=object)
    # print(data)
    train_size = int(CONST.DATA_SIZE * CONST.SPLIT_RATIO)
    
    # print('data', len(data), train_size)

    train_data = data[:train_size]
    train_images = np.array([i[0] for i in train_data]).reshape(-1, CONST.IMG_SIZE, CONST.IMG_SIZE, 3)
    train_labels = np.array([i[1] for i in train_data])
    # print(train_data)
    print('Train data fetched...')

    test_data = data[train_size:]
    test_images = np.array([i[0] for i in test_data]).reshape(-1, CONST.IMG_SIZE, CONST.IMG_SIZE, 3)
    test_labels = np.array([i[1] for i in test_data])
    print('Test data fetched...')
    
    model = get_model()
    
    print('Training started...')
    
    history = model.fit(
        train_images, train_labels,
        batch_size=50,
        epochs=15,
        verbose=1,
        validation_data=(test_images, test_labels),
        callbacks=[k.callbacks.TensorBoard(log_dir='./logs', histogram_freq=1, write_graph=True, write_images=True)]  # Ensure the tensorboard callback is passed here
    )
    print('Training done...')
    model.save('TEST.h5')

    # history_file = 'TEST_history.pickle'
    # with open(history_file, 'wb') as file:
    #     pickle.dump(history.history, file)

    # plotter(history_file)
    # video_write(model)

我尝试使用分类导入,但仍然遇到同样的问题。

python tensorflow keras valueerror
1个回答
0
投票
from keras.utils import to_categorical

if __name__ == "__main__":
    data = np.array(prep_and_load_data(), dtype=object)

    train_size = int(CONST.DATA_SIZE * CONST.SPLIT_RATIO)

    train_data = data[:train_size]
    train_images = np.array([i[0] for i in train_data]).reshape(-1, CONST.IMG_SIZE, CONST.IMG_SIZE, 3)
    train_labels = np.array([i[1] for i in train_data])
    
    train_labels = to_categorical(train_labels, num_classes=2)

    test_data = data[train_size:]
    test_images = np.array([i[0] for i in test_data]).reshape(-1, CONST.IMG_SIZE, CONST.IMG_SIZE, 3)
    test_labels = np.array([i[1] for i in test_data])
    
    test_labels = to_categorical(test_labels, num_classes=2)
    
    model = get_model()
    
    history = model.fit(
        train_images, train_labels,
        batch_size=50,
        epochs=15,
        verbose=1,
        validation_data=(test_images, test_labels),
        callbacks=[k.callbacks.TensorBoard(log_dir='./logs', histogram_freq=1, write_graph=True, write_images=True)]
    )
    
    model.save('TEST.h5')

© www.soinside.com 2019 - 2024. All rights reserved.