数据集只要是以文件夹分类的数据都适用于本文的代码哦。
数据集目录树格式:
图像识别是一个很有意思的领域,本次文章为练习卷积神经网络(CNN)的一个小实例,用于巩固记忆所学。
处理不规则图片
import os
from PIL import Image
src_dir = '102_ObjectCategories/'
dest_dir_train = '102_oc_train/'
dest_dir_test = '102_oc_test/'
if not os.path.exists(dest_dir_train):
os.mkdir(dest_dir_train)
if not os.path.exists(dest_dir_test):
os.mkdir(dest_dir_test)
# 图形处理函数
def deal_image(filename, src_dir, dest_dir):
im = Image.open(src_dir + filename)
crpim = im.resize((64, 64))
crpim.save(dest_dir + filename)
# 构建训练集和测试集目录
def create_new_categories_dir(src_dir):
src_dir_list = os.listdir(src_dir)
for src_dir_one in src_dir_list:
dest_dic_one_test = dest_dir_test + src_dir_one + '/'
dest_dic_one_train = dest_dir_train + src_dir_one + '/'
if (not os.path.exists(dest_dic_one_test)) and (not os.path.exists(dest_dic_one_train)):
os.mkdir(dest_dic_one_test)
os.mkdir(dest_dic_one_train)
执行函数create_new_categories_dir(src_dir)
输出:
处理图片数据,划分训练集测试集
for one_dir in os.listdir(src_dir):
src_dir_one = src_dir + one_dir + '/'
for index,filename in enumerate(os.listdir(src_dir_one)):
dest_dir_one_train = dest_dir_train + one_dir + '/'
dest_dir_one_test = dest_dir_test + one_dir + '/'
file_num = len(os.listdir(src_dir_one))
try:
if index < file_num // 4:
deal_image(filename=filename, src_dir=src_dir_one, dest_dir=dest_dir_one_test)
else:
deal_image(filename=filename, src_dir=src_dir_one, dest_dir=dest_dir_one_train)
except Exception as e:
print(e)
print(src_dir_one, file_num)
输出:
构建卷积神经网络
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# initialising the CNN
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape=(64, 64, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Conv2D(32, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units=128, activation='relu'))
classifier.add(Dense(units=102, activation='softmax'))
classifier.compile(optimizer = 'adam',
loss ='categorical_crossentropy',
metrics = ['accuracy'])
图片增广技术
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True
)
test_datagen = ImageDataGenerator(rescale=1./255)
建立训练与测试数据集
train_set = train_datagen.flow_from_directory(
'102_oc_train/', target_size=(64, 64),
class_mode='categorical')
test_set = train_datagen.flow_from_directory(
'102_oc_test/', target_size=(64, 64),
class_mode='categorical')
训练神经网络
history = classifier.fit_generator(train_set,
steps_per_epoch=30,
epochs=100,
verbose=1,
validation_steps=5,
validation_data=test_set)
输出:
从图片可以知道100次迭代后准确度为 88%
预测单张图片
def print_class_name(number):
name = list(train_set.class_indices.keys())[list(train_set.class_indices.values()).index(number)]
print(name)
# test目录存放要预测的图片
prediction_dir = 'test/'
prediction_done_dir = 'test_done/'
if not os.path.exists(prediction_dir):
os.mkdir(prediction_dir)
if not os.path.exists(prediction_done_dir):
os.mkdir(prediction_done_dir)
for one in os.listdir('test/'):
deal_image(one, 'test/', 'test_done/')
os.listdir('test_done')
# 用公鸡来测试下,展示公鸡图
test_name = 'rooster_test.jpg'
Image.open('test/' + test_name)
输出:
将测试图片处理成numpy矩阵数据,为符合预测数据的输入
import numpy as np
from keras.preprocessing import image
test_image = image.img_to_array(image.load_img('test_done/' + test_name, target_size=(64, 64)))
test_image_plus = np.expand_dims(test_image, axis = 0)
运行函数 print_class_name(classifier.predict_classes(test_image_plus).tolist()[0])
输出:
❤❤❤预测准确啦,当然不是百分百的,下面继续预测几个案例❤❤❤
额,螃蟹预测成了小龙虾 = =、
555