# set the matplotlib backend so figures can be saved in the background
import matplotlib
matplotlib.use("Agg")
# import the necessary packages
from keras.layers.core import Dropout, Activation
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.optimizers import SGD
import matplotlib.pyplot as plt
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from keras.layers import Dense, Conv2D, Flatten
from keras.layers.convolutional import MaxPooling2D
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.25, random_state=42)
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)
#create model
model = Sequential()
#add model layers
model.add(Conv2D(32, kernel_size=3, activation="relu", input_shape=(32,32,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(32, kernel_size=3, activation="relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, kernel_size=3, activation="relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Dense(3, activation="softmax"))
# initialize our initial learning rate and # of epochs to train for
INIT_LR = 0.001
EPOCHS = 500
opt = SGD(lr=INIT_LR, clipvalue=0.5)
model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=200)
mc = ModelCheckpoint('best_model_500Epoch.h5', monitor='val_accuracy', mode='max', verbose=1, save_best_only=True)
H = model.fit(trainX, trainY, validation_data=(testX, testY),epochs=EPOCHS, batch_size=32,callbacks=[es, mc])
使用以下脚本进行预测。
from keras.models import load_model
import pickle
import cv2
import os
import matplotlib.pyplot as plt
from keras import backend as k
new_model = load_model('model_name.h5')
lb = pickle.loads(open("Label_Binarizer", "rb").read())
dirName = "Other_than_class"
listOfFile = os.listdir(dirName)
# Iterate over all the entries
for entry in listOfFile:
# Create full path
fullPath = os.path.join(dirName, entry)
# If entry is a directory then get the list of files in this
directory
image = cv2.imread(fullPath)
output = image.copy()
image = cv2.resize(image, (32, 32))
# scale the pixel values to [0, 1]
image = image.astype("float") / 255.0
# check to see if we should flatten the image and add a batch
# dimension
image = image.flatten()
image = image.reshape((1, image.shape[0]))
# preds = new_model.predict(image)
preds = new_model.predict(image.reshape(1, 32, 32, 3))
print(preds[0])
k.clear_session()
# find the class label index with the largest corresponding
probability
i = preds.argmax(axis=1)[0]
label = lb.classes_[i]
plt.grid(False)
plt.imshow(output)
plt.xlabel("Actual: " + str(entry))
plt.title("Prediction: " + str(preds[0][i] * 100)+" "+str(label))
plt.show()
我已经使用上述架构为3类猫,狗和花开发了模型。当我预测这些类的任何看不见的图像时,它会提供良好的结果。但是,当我针对house.jpg或laptop.jpg或除这3类以外的图像进行预测时,它也在这3类中进行预测,真是令人作呕。 我在做什么错了?
house.jpg或laptop.jpg的预测准确性也高于85%。 该怎么做,以免它不能预测出类别之外的图像。
答案 0 :(得分:1)
但是当我为house.jpg或laptop.jpg或图像预测它时 除了这些3类,它还能预测 3节课。
这是正常现象,因为神经网络位于最后一层
model.add(Dense(3, activation="softmax"))
对于问题中的每个类,它都会返回概率。
因此,如果您使用的是laptop.jpg
图片,则它可能会返回三个小概率,而最大的概率会为您提供输出。
由于您没有使用laptop
集中的training
张图片,因此neural network
对此没有任何想法。
一种方法可能是设置阈值概率,例如50%
,如果这些3
概率中没有一个超过此阈值,则打印Unknown
。
换句话说,如果您使用 softmax 分布进行分类,则可以确定正确分类的样本的基线 max probability
是什么,然后推断新样本的最大概率是否低于某种threshold
。
此想法来自研究论文,该论文解释了这种情况:A Baseline for Detecting Misclassified and Out-of-Distribution Examples in Neural Networks
答案 1 :(得分:0)
您的问题是您的网络只有三个选项(“猫”,“狗”或“花”)。
最好的方法是添加第四个选项(“未知”)。
因此,您需要将一些随机图片添加到标签为“未知”的训练数据中。这些图片当然不能包含猫,狗或花朵。
这样,您的网络不仅可以学会预测给定的对象,还可以学会判断图片中是否没有已知的对象。
通常所说的话:您应该对网络进行尽可能接近实际应用的培训。
以您的情况为例:您为什么拥有house.jpg但不将其用于培训?
答案 2 :(得分:0)
您一切都很好。如果您不让网络为您的laptop.jpg选择其他类别的模型,您的模型将尝试做的工作是了解该笔记本的图片是否与猫,狗或花有更多共同点。假设它带有花朵,您的网络可以为您提供的任何笔记本电脑图片预测类别花朵!
再见:)