有了前面的积累,我们可以开始用一些实际的例子结合着Keras提供的Example进行学习了,后续的例子会使用EnglishFnt这个印刷体数据集进行训练和识别,这个数据集里面存放了从0-9的数字和A-Z的英文字符。

比起手写字符集MNIST,EnglishFnt长得还是很中规中矩的。 为了不需要后续每次都重新加载一次数据做预处理,接下来先把这个数据集处理下,变成npy存起来
1 def loadEnglishFntData(self): 2 labels = [] 3 datasets = [] 4 base_path = '../datasets/English/Fnt' 5 train_dir = os.listdir(base_path) 6 train_dir.sort() 7 for dir in train_dir: 8 if dir.startswith('.'): 9 continue 10 11 print('处理文件夹:[%s]' % dir) 12 for root, dirs, files in os.walk(os.path.join(base_path, dir)): 13 for file in files: 14 if dir.startswith('.'): 15 continue 16 img = cv2.imread(os.path.join(root, file), cv2.COLOR_BGR2GRAY) 17 img = cv2.resize(img, (28, 28), interpolation=cv2.INTER_CUBIC) 18 labels.append(dir) 19 datasets.append(img) 20 21 datasets = np.array(datasets) 22 labels = np.array(labels) 23 24 # 处理数据集 25 datasets = datasets.astype('float32') 26 27 # 数据归一化 28 datasets /= 255 29 datasets = datasets.reshape(datasets.shape[0], 28, 28, 1) 30 31 prepare_labels = [] 32 for obj in labels: 33 prepare_labels.append(int(re.sub("\D", "", obj)) - 1) 34 35 labels = keras.utils.to_categorical(prepare_labels, 62) 36 return datasets, labels
这里把图片数据转成了28*28的代销,归一化后塞到了datasets里面,至于labels,我们按照文件夹的名称把数字做成了label,然后再借助了keras的to_categorical 把一维数组拉成了二维数组,接着保存下
1dataloader = DataLoader() 2datasets, labels = dataloader.loadEnglishFntData() 3np.save('fnt_datasets.npy', datasets) 4np.save('fnt_labels.npy', labels)
接下来就可以开始训练了,先试一下双层DNN训练的效果
1import numpy as np 2from keras import Sequential 3from keras.callbacks import TensorBoard 4from keras.layers import Dense, Dropout, Flatten 5from keras.optimizers import RMSprop 6 7X_Train = np.load('../fnt_datasets.npy') 8Y_Train = np.load('../fnt_labels.npy') 9 10model = Sequential() 11model.add(Dense(512, activation='relu', input_shape=X_Train.shape[1:])) 12model.add(Dropout(0.2)) 13model.add(Dense(512, activation='relu')) 14model.add(Dropout(0.2)) 15model.add(Flatten()) 16model.add(Dense(62, activation='softmax')) 17 18model.summary() 19 20model.compile(loss='categorical_crossentropy', 21 optimizer=RMSprop(), 22 metrics=['accuracy']) 23model.fit(X_Train, Y_Train, 24 batch_size=128, 25 epochs=10, 26 verbose=1, 27 validation_split=0.3, 28 callbacks=[TensorBoard(log_dir='./logs', histogram_freq=1)]) 29model.save('./model.h5')
接下来加载训练好的模型来进行检验,实验图片我们用着三张数字图片进行
1import cv2 2import keras 3import numpy as np 4 5model = keras.models.load_model('./model.h5') 6img = cv2.imread('../datasets/22.png', cv2.IMREAD_GRAYSCALE) 7img_resize = cv2.resize(img, (28, 28), interpolation=cv2.INTER_CUBIC) 8result = model.predict(img_resize.reshape(1, 28, 28, 1)) 9print(np.argmax(result))
不得不说两层建议的DNN训练10次,效果还是挺不好的....,那我们再做个小实验,用训练出来的模型重新跑一会训练的数据集咧?随手挑一个
1import os 2 3import cv2 4import keras 5import numpy as np 6 7model = keras.models.load_model('./model.h5') 8 9success = 0 10failed = 0 11 12for root, dirs, files in os.walk('../../../datasets/English/Fnt/Sample006'): 13 for file in files: 14 print(file) 15 img = cv2.imread(os.path.join(root, file), cv2.COLOR_BGR2GRAY) 16 img = cv2.resize(img, (28, 28), interpolation=cv2.INTER_CUBIC) 17 result = model.predict(img.reshape(1, 28, 28, 1)) 18 if np.argmax(result) == 5: 19 success += 1 20 else: 21 failed += 1 22print(success) 23print(failed)
成功判断出92个,判断失败了924个.....这简直没法用啊,哈哈哈。PS:用MacBookPro来炼丹真是挺费劲的...两层简易的DNN,一个epoch要跑200s=。=