使用CNN(卷积神经网络)识别102个图片分类

python,机器学习,深度学习 2019-03-13

数据集只要是以文件夹分类的数据都适用于本文的代码哦。

数据集目录树格式:数据树

图像识别是一个很有意思的领域,本次文章为练习卷积神经网络(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)

输出:1.jpg

处理图片数据,划分训练集测试集

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)

输出:2.jpg

构建卷积神经网络

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)

输出:3.jpg
从图片可以知道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)

输出:4.jpg

将测试图片处理成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])

输出:5.jpg

❤❤❤预测准确啦,当然不是百分百的,下面继续预测几个案例❤❤❤

6.jpg

额,螃蟹预测成了小龙虾 = =、

7.jpg
8.jpg
9.jpg


10.jpg


本文由 白间 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论

0:00