CNN人脸识别(误)低配版:辛普森一家

看动画也不忘机器学习✌( •̀ ω •́ )y:

这个项目在Keras(后端为Tensorflow)上实现用神经网络根据动画片截图对辛普森一家的成员进行分类,使用的是目前最复杂和艰深的神经网络之一:卷积神经网络(Convolutional Neural Network,CNN)。
数据集为11个辛普森家族的成员的动画片截图,存放在11个文件夹中,每个成员有大约1000张图片。
这些图片有不一样的尺寸,在进过归一化后和标签一起输入神经网络进行训练

由于这次图像识别训练直接用的图片,因此该程序实际上可以用来做很多事情(验证码识别,智能交通领域的机器视觉,行人和车辆识别),只需更换文件夹路径,指向新的数据集即可。

《CNN人脸识别(误)低配版:辛普森一家》
《CNN人脸识别(误)低配版:辛普森一家》

直接上代码:

导入依赖库:

from PIL import Image
import numpy as np
import os
import glob
import re
import keras
from keras.optimizers import SGD, Adam
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import np_utils
from keras import backend as K

*定义函数:从数据集中导入图片,归一化后再转化为特征矩阵:
每个文件夹中取前100张图片的数据放到测试集,剩余的样本全都作为训练集。*

def read_img(location):
    x_train = [] 
    y_train = [] 
    x_test = [] 
    y_test = [] 
    label_name = [] 
    dirs = os.listdir(location) 
    label = 0 
    count = 0
    for i in dirs: #loop all directory
        print(i)
        n = 0 
        label_name.append(i) #save folder name in var label_name
        x_s = 200
        y_s = 200
        for pic in glob.glob(location+'\\'+i+'\*.jpg'): 
            im = Image.open(pic) #open data
            im = im.resize((x_s, y_s), Image.ANTIALIAS)
            im = np.array(im) #store im as numpy array
            if(im.shape[0]==200 and im.shape[1]==200): 
                r = im[:,:,0]
                g = im[:,:,1]
                b = im[:,:,2]
                if(n<100): 
                    x_test.append([r,g,b]) #save in x_test
                    y_test.append([label]) #save in y_test
                else: #remaining data set as training data
                    x_train.append([r,g,b]) #save in x_train
                    y_train.append([label]) #save in y_train
                n = n + 1 
                count = count + 1 
        label = label + 1 #increment label
    print(label_name)
    print(dirs)
    return np.array(x_train),np.array(y_train),np.array(x_test),np.array(y_test)

将图片经过归一化处理,变为200p200p的尺寸:*
原图:
《CNN人脸识别(误)低配版:辛普森一家》

归一化的图片:
《CNN人脸识别(误)低配版:辛普森一家》

通过定义的函数生成训练数据、训练标签、测试数据、测试标签:

path='E:\\JLD\\desktop\\the-simpsons-characters-dataset\\simpsons_dataset'
img_rows = 200 #num of image height
img_cols = 200 #num of image width
num_class = 11 #num of classes/labels
x_train,y_train,x_test,y_test = read_img(path) 

输出的结果:完成对11个文件夹的遍历,并输出训练标签向量和测试标签向量:

《CNN人脸识别(误)低配版:辛普森一家》

对训练数据和测试数据的值做线性变化,提高机器学习的速率,并将标签转化为向量,以便用交叉熵计算loss值:

x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 3) 
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 3) 
input_shape = (img_rows, img_cols, 3)
x_train = x_train.astype('float32') 
x_test = x_test.astype('float32') 
x_train /= 255 
x_test /= 255 
y_train = keras.utils.to_categorical(y_train, num_class) 
y_test = keras.utils.to_categorical(y_test, num_class) 

输出训练训练特征矩阵、训练标签向量、测试特征矩阵、测试标签向量的维度:

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

运行结果:

《CNN人脸识别(误)低配版:辛普森一家》

定义CNN神经网络模型:

model = Sequential()
model.add(Conv2D(64, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(num_class, activation='softmax'))

编译模型:用交叉熵作为损失值,随机梯度下降作为优化器,预测的准确率用以定义模型的好坏。

model.compile(loss='categorical_crossentropy',
              optimizer=SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True),
              metrics=['accuracy'])

训一次模型并保存:模型一个批次处理64个样本,迭代1次,用测试集数据做验证。

model.fit(x_train, y_train, batch_size=64, epochs=1, verbose=1, validation_data=(x_test, y_test))
model.save('Simpson.h5')

循环进行模型训练,每一次循环迭代一次训练,保存并读取模型,循环十次,这样写是因为避免显存溢出导致之前所有训练结果丢失。该语句可重复运行。机器学习,俗称“炼丹”:

for i in range(0,10):
    print('The '+str(i)+' th Iteration')
    model=load_model('Simpson.h5')
    model.fit(x_train, y_train, batch_size=64, epochs=1, verbose=1, validation_data=(x_test, y_test))
    model.save('Simpson.h5')
    K.clear_session()

运行结果:该模型在测试集上最终达到了99.09%的准确率。
《CNN人脸识别(误)低配版:辛普森一家》

若要用该模型进行识别应用,只需调用model.predict()函数就行。

    原文作者:JackieFang
    原文地址: https://segmentfault.com/a/1190000010895519
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞