# 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%。
该怎么做,以使其一定不能预测出类别之外的图像。

最佳答案

但是当我为house.jpg或laptop.jpg或图像预测它时
  除了这些3类,它还能预测
  3班。


这是正常行为,因为最后一层的神经网络

model.add(Dense(3, activation="softmax"))


它从您的问题返回每个班级的概率。

因此,如果您使用的是laptop.jpg图像,则它可能会返回三个小概率,而最大的概率会为您提供输出。

由于您没有在laptop集中使用training图像,因此neural network没有任何想法。

一种方法是设置阈值概率,例如50%,如果这些3概率中没有一个超过此阈值,则打印Unknown

换句话说,如果您在分类中使用softmax分布,则可以确定正确分类的样本的基线最大值probability是什么,然后推断新样本是否不属于您的任何已知类别,如果其最大概率低于某种threshold

这个想法来自解释这种情况的研究论文:A Baseline for Detecting Misclassified and Out-of-Distribution Examples in Neural Networks

关于python - 深度学习和神经网络,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59980932/

10-09 08:22
查看更多