看动画也不忘机器学习✌( •̀ ω •́ )y:
这个项目在Keras(后端为Tensorflow)上实现用神经网络根据动画片截图对辛普森一家的成员进行分类,使用的是目前最复杂和艰深的神经网络之一:卷积神经网络(Convolutional Neural Network,CNN)。
数据集为11个辛普森家族的成员的动画片截图,存放在11个文件夹中,每个成员有大约1000张图片。
这些图片有不一样的尺寸,在进过归一化后和标签一起输入神经网络进行训练
由于这次图像识别训练直接用的图片,因此该程序实际上可以用来做很多事情(验证码识别,智能交通领域的机器视觉,行人和车辆识别),只需更换文件夹路径,指向新的数据集即可。
直接上代码:
导入依赖库:
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的尺寸:*
原图:
归一化的图片:
通过定义的函数生成训练数据、训练标签、测试数据、测试标签:
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个文件夹的遍历,并输出训练标签向量和测试标签向量:
对训练数据和测试数据的值做线性变化,提高机器学习的速率,并将标签转化为向量,以便用交叉熵计算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神经网络模型:
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%的准确率。
若要用该模型进行识别应用,只需调用model.predict()函数就行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。