深度学习第22讲:搭建一个基于keras的迁移学习花朵识别系统(附数据)

        在上一讲中,笔者和大家探讨了迁移学习的基本原理,并利用 keras 基于 VGG16 预训练模型简单了在 mnist 数据集上做了演示。鉴于大家对于迁移学习的兴趣,本节笔者将继续基于迁移学习利用一些花朵数据搭建一个花朵识别系统。因为是带有教学系统的演示,本节将尽量将试验过程完整详细的展示给大家,也会在文章末尾附上试验数据和代码,以供大家学习和复现试验内容。

        笔者使用的试验数据来自于罗大钧在 cos 统计之都上的分享,数据可于此处下载:https://pan.baidu.com/s/1jIMOc1S

        下载数据后解压可见共有五个文件夹,每个文件夹是一种花类,具体信息如下:

640?wx_fmt=png

        五种花种加起来不过是 3669 张图片,数据量不算小样本但也绝对算不上多。所以我们采取迁移学习的策略来搭建花朵识别系统。

        实际数据中玫瑰花存在着一张图片的重复,笔者直接对其进行了删除。花型图片大致如下:640?wx_fmt=jpeg

        需要导入的 package:

import os
import pandas as pd
import numpy as np
import cv2
import matplotlib.pyplot as plt
from PIL import Image
import time
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import kerasfrom keras.models import Model
from keras.layers import Dense, Activation, Flatten, Dropout
from keras.utils import np_utils
from keras.applications.resnet50 import ResNet50

提取数据标签

        数据没有单独给出标签文件,需要我们自行通过文件夹提取每张图片的标签,建立标签文件:

def tranverse_images(path):
    labels = pd.DataFrame()
    first_dir_file = [file for file in os.listdir(path)]    
    for item in first_dir_file:
        flower = [image for image in os.listdir(path+item)]
        labels_data = pd.DataFrame({'flower': flower, 'labels': item})
        labels = pd.concat((labels, labels_data))    
    return labels

labels = tranverse_images('./flower_photos/')
labels.head()

640?wx_fmt=png

        这样标签文件就顺利拿到了。

图片预处理(缩放)

       通过试验可知每张图片像素大小并不一致,所以在搭建模型之前,我们需要对图片进行整体缩放为统一尺寸。我们借助 opencv 的 python 库 cv2 可以轻松实现图片缩放,因为后面我们的迁移学习策略采用的是 ResNet50 作为预训练模型,所以我们这里将图片缩放大小为 224x224x3。单张图片的 resize 效果如下:

img = cv2.imread('./flower_photos/509239741_28e2cfe492_m.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img3)
print(img.shape)

640?wx_fmt=png

        缩放后的效果和尺寸:

img_1 = cv2.resize(img, (224, 224))
print(img_1.shape)
img3_1 = cv2.cvtColor(img3_1, cv2.COLOR_BGR2RGB)
plt.imshow(img_1)

640?wx_fmt=png

        批量缩放代码为:

# resize
def resize_image(path1, path2):
    images = [img for img in os.listdir(path1)]
    total = 0
    start_time = time.time()    
    for img in images:
        img1 = cv2.imread(path1 + img)
        img1 = cv2.resize(img1, (224, 224))
        total += 1
        print('now is resizing {} image.'.format(total))
        cv2.imwrite(path2+img, img1)
    print('all images are resized, all resized image is {}.'.format(total))
    end_time = time.time()
    print('the resize time is {}.'.format(end_time - start_time))

resize_image(path1='./flower_photos/', path2='./resize_flower_photos/')

640?wx_fmt=png

        原始图片并不复杂,所以除了对其进行缩放处理之外基本无需多做处理。下一步我们需要将图片转化为可以拿来进行训练的 numpy 数组。

准备训练数据

        处理好的图片无法直接拿来训练,我们需要将其转化为 numpy 数组的形式,另外标签也需要进一步的处理。

# image to array
def image2array(labels, path):
    lst_imgs = [l for l in labels['flower']]    
    return np.array([np.array(Image.open(path+img)) for img in lst_imgs])

X = image2array(labels, './resize_flower_photos/')
print(X.shape)
np.save('./X_train.npy', X)

        (3669, 224, 224, 3)

        可见转化后的数组大小为 3669x224x224x3,跟我们的实际数据一致。然后我们再来处理标签数据,标签变量都是分类值,我们先需要将其进行硬编码 LabelEncoder,然后借助 keras 将其 one-hot 处理。具体处理如下:

lbl = LabelEncoder().fit(list(labels['labels'].values))
labels['code_labels'] = pd.DataFrame(lbl.transform(list(labels['labels'].values)))
labels.head()

640?wx_fmt=png

        训练数据的预处理准备停当,下面我们用 sklearn 划分一下数据集:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

        (2568, 224, 224, 3) (2568,) (1101, 224, 224, 3) (1101,)

        训练集和测试集数据划分完毕,终于可以进入建模环节啦。

基于resnet50 的迁移学习模型

        试验模型的基本策略就是使用预训练模型的权重作为特征提取器,将预训练的权重进行冻结,只训练全连接层。在正式构建模型前,先将数据进行标准化以及标签数据进行 onehot 处理。

X_train /= 255
X_test /= 255
y_train = np_utils.to_categorical(y_train, 5)
y_test = np_utils.to_categorical(y_test, 5)

        构建模型如下:

def flower_model(X_train, y_train):
    base_model = ResNet50(include_top=False, weights='imagenet', input_shape=(224, 224, 3))    
    for layers in base_model.layers:
        layers.trainable = False

    model = Flatten()(base_model.output)
    model = Dense(128, activation='relu')(model)
    model = Dropout(0.5)(model)
    model = Dense(5, activation='softmax')(model)

    model = Model(inputs=base_model.input, outputs=model)
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.fit(X_train, y_train, batch_size=128, epochs=50)   
     
    return model

        模型训练和测试集评估:

model = flower_model(X_train, y_train)
model.evaluate(X_test, y_test, verbose=0)

        训练过程:

640?wx_fmt=png     

        限于计算资源,笔者的笔记本训练了一轮后就已热的发烫,果断停止了训练。大家若是有 gpu 计算资源的话可尝试将模型训练完。一两轮后模型的识别准确率就达到 70%,相信继续训练下去会有一个较高的识别率。(数据也可阅读原文下载)

参考资料:

https://cosx.org/2017/10/transfer-learning/

往期精彩:


一个数据科学从业者的学习历程

640?
640?wx_fmt=jpeg
长按二维码.关注数据科学家养成记

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python深度学习实战是一本基于TensorFlow和Keras的书籍,主要介绍了如何使用Python进行深度学习的实践。其中,包含了聊天机器人、人脸识别、物体识别和语音识别等不同应用领域的实例。 聊天机器人是一种人工智能应用,可以模拟人类的对话交流,通过使用Python深度学习模型,可以训练出一个能够自动回答用户问题的机器人。这本书可以教会读者如何构建一个聊天机器人,并且基于TensorFlow和Keras进行深度学习训练。 人脸识别是近年来非常热门的研究方向,它可以通过对人脸图像进行分析和识别,实现人脸的自动识别功能。本书介绍了如何使用Python深度学习模型,结合TensorFlow和Keras,进行人脸识别的训练和应用。 物体识别是指通过对图像中的物体进行分析和识别,将物体与其他物品、场景进行区分。通过本书的学习,读者可以学习如何使用Python深度学习技术,借助TensorFlow和Keras,构建物体识别模型,并实现准确的物体识别功能。 语音识别是将语音信号转化为文字的过程,可以应用于语音助手、语音指令控制等场景。在本书中,作者将通过Python深度学习技术,利用TensorFlow和Keras,教会读者如何训练一个语音识别模型,并实现准确的语音识别功能。 综上所述,Python深度学习实战:基于TensorFlow和Keras的聊天机器人以及人脸、物体和语音识别,为读者提供了使用深度学习模型,结合不同应用场景的实例,帮助读者更好地理解和应用深度学习技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值