我制作了一个CNN模型来预测由MNIST数据训练的数字。使用keras包装器进行张量流。我在预测自己的输入数据方面遇到了麻烦。我用epochs = 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查看结果。请检查图像名称,图像名称将建议实际值和预测值。 如果我做错了,请建议。
答案 0 :(得分:1)
在推理期间,您需要在训练期间对图像应用完全相同的预处理。
这就是您的程序以相同的方式规范化列车和测试数据的原因。
X_train/=255
X_test/=255
对于您可能想要执行的任何其他预处理(例如PCA或通过z-score进行标准化)也是如此。
因此,在您的情况下,确保您的输入图像在范围(0,1)中除以255(如果从opencv调用预期范围为0到255)
编辑:
我只是继续训练模型并尝试了你的程序。事实上它似乎犯了很多错误(更多的是因为它得到1%的验证错误所预期的错误)。
我的猜测是,因为mnist已经有点preprocessed,
数字已经过尺寸标注,并以固定尺寸为中心 图像。
您的模型可能也希望您的测试图像也经过预处理。
我建议然后使用一些具有更多噪音/旋转的mnist变体来缓解这个问题。例如:mnist-rot,mnist-back-rand。