第1关:数据集加载与预处理
本关主要带大家掌握如何进行数据的加载和预处理。
import warnings
warnings.filterwarnings("ignore")
import glob
import cv2
import numpy as np
import keras
from sklearn.model_selection import train_test_split
# 人物的Label-encoding,构造字典 map_characters 存储 label
# ********** Begin *********#
map_characters = {0:'A',1:'C',2:'D',3:'F',4:'G',5:'H',6:'I',7:'J',8:'K',9:'L', 10:'M',11:'P',12:'R',13:'S', 14:'T', 15:'V' }
# ********** End *********#
imgsPath = "/opt/train"
# 图片裁切大小
img_width = 42
img_height = 42
# 验证集比例
test_size = 0.15
num_classes = len(map_characters) # 要辨识的角色个数
# 加载图片
def load_pictures():
pics = []
labels = []
# ********** Begin *********#
for key, v in map_characters.items():
pictures = [k for k in glob.glob(imgsPath + "/" + v + "/*")]
for pic in pictures:
tmp_img = cv2.imread(pic)
tmp_img = cv2.cvtColor(tmp_img, cv2.COLOR_BGR2RGB)
tmp_img = cv2.resize(tmp_img, (img_width, img_height))
pics.append(tmp_img)
labels.append(key)
# ********** End *********#
return np.array(pics), np.array(labels)
# 取得训练集与验证集
def get_dataset():
# ********** Begin *********#
X, Y = load_pictures()
Y = keras.utils.to_categorical(Y, num_classes)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size = 0.15)
# ********** End *********#
return X_train, X_test, y_train, y_test
X_train, X_test, y_train, y_test = get_dataset()
第2关:构建网络模型
本关主要带大家掌握如何构建网络模型。
import warnings
warnings.filterwarnings("ignore")
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Activation, Flatten
img_width = 42
img_height = 42
map_characters = {0: 'A', 1: 'C', 2: 'D',
3: 'F', 4: 'G', 5: 'H', 6: 'I',
7: 'J', 8: 'K', 9: 'L', 10:'M',
11:'P', 12:'R', 13:'S', 14:'T', 15:'V'}
num_classes = len(map_characters) # 要辨识的角色个数
# 定义模型
# input_shape 由函数调用时传入,为(42,42,3)
def create_model_six_conv(input_shape):
# ********** Begin *********#
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=input_shape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
# ********** End **********#
return model;
#圖像的shape是 (42,42,3)
model = create_model_six_conv((img_height, img_width, 3)) # 初始化一個模型
第3关:训练模型
本关主要带大家掌握如何训练网络模型。
import warnings
warnings.filterwarnings("ignore")
import os
from keras.optimizers import SGD
from keras.callbacks import LearningRateScheduler, ModelCheckpoint
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
# Model Compile
# ********** Begin *********#
lr = 0.01
sgd = SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
# ********** End *********#
# Training
# ********** Begin *********#
def lr_schedule(epoch):
return lr*(0.1**int(epoch/10))
# ********** End *********#
# ********** Begin *********#
batch_size = 32
epochs = 30
# ********** End *********#
filepath = "model.h5"
# ********** Begin *********#
# 请不要删除参数 verbose,否则会影响评测
history = model.fit(X_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(X_test, y_test),
shuffle=True,
verbose = 0,
callbacks=[LearningRateScheduler(lr_schedule),
ModelCheckpoint(filepath, save_best_only=True)])
# ********** End *********#
第4关:验证评估
本关主要带大家掌握如何对训练过的模型进行评估。
import warnings
warnings.filterwarnings("ignore")
import glob
import cv2
import numpy as np
import keras
import os
import pandas as pd
from keras.models import load_model
import os
# 屏蔽系统信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
def load_test_set(path):
pics, labels = [], []
map_characters = {0: 'A', 1: 'C', 2: 'D',
3: 'F', 4: 'G', 5: 'H', 6: 'I',
7: 'J', 8: 'K', 9: 'L', 10:'M',
11:'P', 12:'R', 13:'S', 14:'T', 15:'V'}
num_classes = len(map_characters)
img_width = 42
img_height = 42
# ********** Begin *********#
# 一定要反转字典
reverse_dict = {v:k for k,v in map_characters.items()}
# 获取目录 "/opt/test/" 下的所有内容(所有图片的地址+图片名)
for pic in glob.glob(path+'*.*'):
# os.path.basename(pic):返回每张图片的名字
char_name = "".join(os.path.basename(pic).split('_')[0])
# 查找 人名 是否在 lable-value 里面
if char_name in reverse_dict:
temp = cv2.imread(pic)
temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)
temp = cv2.resize(temp, (img_height,img_width)).astype('float32') / 255.
pics.append(temp)
labels.append(reverse_dict[char_name]) # 得到的将是 int
X_test = np.array(pics)
y_test = np.array(labels)
y_test = keras.utils.to_categorical(y_test, num_classes) # one-hot编码
# ********** End *********#
return X_test, y_test
imgsPath = "/opt/test/"
X_valtest, y_valtest = load_test_set(imgsPath)
# 预测对比
def acc():
# 把训练时 val_loss 最小的模型载入
model = load_model("model.h5")
# 预测与对比
# ********** Begin *********#
y_pred = model.predict_classes(X_valtest)
acc = np.sum(y_pred==np.argmax(y_valtest, axis=1))/np.size(y_pred)
# ********** End *********#
return(acc)