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