我最近一直在测试使用 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)
我尝试使用分类导入,但仍然遇到同样的问题。
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')