我已经建立了CNN模型来预测数字,并由MNIST数据进行训练。使用keras包装器进行张量流。我在预测自己的输入数据时遇到了麻烦。我已经用纪元= 100训练了模型,并使用MNIST的测试集测试了模型,该模型可以正常工作,精度约为97%。我已将此模型另存为“ my_model_conv2d.h5”。

第一个代码:



# importing modules
import numpy as np
import keras
import matplotlib.pyplot as plt
from keras.optimizers import SGD
from keras.models import Sequential
from keras.layers import Dense,Activation,  Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.datasets import mnist
from keras.utils import np_utils


plt.rcParams['figure.figsize'] = (7,7)

#reading MNIST data
(X_train,y_train),(X_test,y_test)=mnist.load_data('mnist.npz')
print X_train.shape, " train datad shape"
print y_train.shape, " labels shape"

#copying data for plotting
test=X_test.copy()

#reshaping data type according to the tensorflow param.
X_train=X_train.reshape(X_train.shape[0],X_train.shape[1],X_train.shape[2],1)
X_test=X_test.reshape(X_test.shape[0],X_test.shape[1],X_test.shape[2],1)
input_shape=(X_train.shape[1],X_train.shape[2],1)


X_train=X_train.astype('float32')
X_test=X_test.astype('float32')

X_train/=255
X_test/=255

# one_hot vector
Y_train=np_utils.to_categorical(y_train,10)
Y_test=np_utils.to_categorical(y_test,10)



print X_train.shape, " train datad shape"
print y_train.shape, " labels shape"

#building CNN model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))

#optimizer type initialization
sgd=SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

#compiling model
model.compile(loss='categorical_crossentropy', optimizer='sgd')

#training model
model.fit(X_train,Y_train, batch_size=128,epochs=100, verbose=1,validation_data=(X_test,Y_test))

#evaluating
score=model.evaluate(X_test,Y_test,verbose=1)
print score,  "score"

#predicting classes using MNIST test data
predicted_classes=model.predict_classes(X_test)
print predicted_classes.shape, "predicted_classes.shape"
correct_indices = np.nonzero(predicted_classes == y_test)[0]
incorrect_indices = np.nonzero(predicted_classes != y_test)[0]

#saving model for future use
model.save('my_model_conv2d.h5')


print len(correct_indices), "no . of correct samples"
print len(incorrect_indices), "no . of incorrect samples"
print str((len(incorrect_indices)/float(len(y_test)))*100)+'%', "error percentage"

#plotting graph of predicted test data
plt.figure()
for i, correct in enumerate(correct_indices[:9]):
    plt.subplot(3,3,i+1)
    plt.imshow(test[correct], cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[correct], y_test[correct]))
plt.show()

plt.figure()
for i, incorrect in enumerate(incorrect_indices[:9]):

    plt.subplot(3,3,i+1)
    plt.imshow(test[incorrect], cmap='gray', interpolation='none')
    plt.title("Predicted {}, Class {}".format(predicted_classes[incorrect], y_test[incorrect]))
plt.show()


我做了第二个python代码,打开了模型“ my_model_conv2d.h5”。在此代码中,我还创建了一个交互式窗口以绘制数字,该数字用作预测的输入图像。我已照顾的背景和图像的字体颜色,也是大小(28,28)的,大约是类似MNIST数据。

第二个代码:

import cv2
import numpy as np

from keras.models import Sequential,load_model



drawing=False
mode=True

#function for mouse events
def interactive_drawing(event,x,y,flags,param):
    global ix,iy,drawing, mode

    if event==cv2.EVENT_LBUTTONDOWN:
        drawing=True
        ix,iy=x,y
        print "EVENT_LBUTTONDOWN"

    elif event==cv2.EVENT_MOUSEMOVE:
        if drawing==True:
            print "EVENT_MOUSEMOVE"

            if mode==True:
                print "EVENT_MOUSEMOVE"
                cv2.line(img,(ix,iy),(x,y),1,1)
                ix=x
                iy=y
    elif event==cv2.EVENT_LBUTTONUP:
        drawing=False
        print "EVENT_LBUTTONUP"
        if mode==True:
            print "EVENT_LBUTTONUP"
            cv2.line(img,(ix,iy),(x,y),1,1)
            ix=x
            iy=y
    return x,y
#function for predicting number
def cnn(img):
    im=img.copy()

    #loading cnn model
    model = load_model('my_model_conv2d.h5')
    img=img.reshape(1,28,28,1).astype('float32')

    #prediction of class using drawn image as an input
    predicted_class=model.predict_classes(img)
    print predicted_class, "class"

    cv2.imwrite('actual=9:predicted='+str(predicted_class)+'.jpg',im*255)



#image same as mnist image
img = np.zeros((28,28), 'float32')
cv2.namedWindow('Drawing_window')
cv2.setMouseCallback('Drawing_window',interactive_drawing)
while(1):
    cv2.imshow('Drawing_window',img*255)
    k=cv2.waitKey(1)&0xFF
    if k==27:
        break
cv2.destroyAllWindows()
#calling cnn function for prediction
cnn(img)


我的输入数据大部分预测都是错误的。另外,我已经实现CNN之前进行完全连接层,但结果却是一样的。因此,我尝试了CNN,但问题是相同的。我已经在第二个代码中检查了MNIST的测试数据,它工作正常。您可以在https://drive.google.com/open?id=1E26zinOLrMw7XKhsHd9vnSYoHXzadiJ3处检查结果。请检查图像名称,图像名称会提示实际和预测值。
我哪里做错了,请建议。

最佳答案

在训练过程中对推理过程中的图像使用与图像完全相同的预处理。

这就是为什么您的程序以相同的方式标准化训练和测试数据的原因。

X_train/=255
X_test/=255


这对于您可能要执行的任何其他预处理(例如PCA或z分数归一化)也是如此。

因此,请确保您的输入图像被255除(如果该opencv调用期望在0到255之间),则它在(0,1)范围内

编辑:

我只是继续训练模型并尝试了您的程序。事实上,它似乎犯错误的很多(更多的是什么,因为它得到了1个%验证错误可以预料的)。

machine-learning - 在经过训练的CNN模型中,具有类似MNIST的图像数据的错误预测-LMLPHP

我的猜测是,由于mnist已经有点preprocessed


  这些数字已进行尺寸规格化,并以固定尺寸居中
  图片。


您的模型可能希望你的测试图像进​​行预处理为好。

我建议然后使用带有更多噪声/旋转的mnist变体来缓解问题。例如:mnist-rot,mnist-back-rand。

关于machine-learning - 在经过训练的CNN模型中,具有类似MNIST的图像数据的错误预测,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47815401/

10-12 23:17