【实验课程】花卉图像分类实验

转载地址:https://bbs.huaweicloud.com/forum/thread-80033-1-1.html

作者:yangyaqin

 实验介绍

随着电子技术的迅速发展,人们使用便携数码设备(如手机、相机等)获取花卉图像越来越方便,如何自动识别花卉种类受到了广泛的关注。由于花卉所处背景的复杂性,以及花卉自身的类间相似性和类内多样性,利用传统的手工提取特征进行图像分类的方法,并不能很好地解决花卉图像分类这一问题。

本实验基于卷积神经网络实现的花卉识别实验与传统图像分类方法不同,卷积神经网络无需人工提取特征,可以根据输入图像,自动学习包含丰富语义信息的特征,得到更为全面的花卉图像特征描述,可以很好地表达图像的不同类别信息。

实验过程

本节将详细介绍实验的设计与实现。导入实验环境;数据准备;介绍构建花卉识别模型;介绍如何进行模型的测试,以及相应测试结果的展示。

导入实验环境

步骤 1  导入相应的模块

glob包主要用于查找符合特定规则的文件路径名,跟使用windows下的文件搜索差不多; os模块主要用于处理文件和目录,比如:获取当前目录下文件,删除制定文件,改变目录,查看文件大小等;MindSpore是目前业界最流行的深度学习框架,在图像,语音,文本,目标检测等领域都有深入的应用,也是该实验的核心,主要用于定义占位符,定义变量,创建卷积神经网络模型;numpy是一个基于python的科学计算包,在该实验中主要用来处理数值运算;time模块主要用于处理时间系列的数据,在该实验主要用于返回当前时间戳,计算脚本每个epoch运行所需要的时间。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

# 导入模块

from easydict import EasyDict as edict

import glob

import os

  

import numpy as np

import matplotlib.pyplot as plt

  

import mindspore

import mindspore.dataset as ds

import mindspore.dataset.transforms.vision.c_transforms as CV

import mindspore.dataset.transforms.c_transforms as C

from mindspore.dataset.transforms.vision import Inter

from mindspore.common import dtype as mstype

from mindspore import context

from mindspore.common.initializer import TruncatedNormal

from mindspore import nn

from mindspore.train import Model

from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor

from mindspore import Tensor

  

context.set_context(mode=context.GRAPH_MODE,device_target="Ascend")

步骤 2  定义变量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

cfg = edict({

    'data_path''flower_photos',

    'data_size':3670,

    'image_width'100,  # 图片宽度

    'image_height'100,  # 图片高度

    'batch_size'32,

    'channel'3,  # 图片通道数

    'num_class':5,  # 分类类别

    'weight_decay'0.01,

    'lr':0.0001,  # 学习率

    'dropout_ratio'0.5,

    'epoch_size'400,  # 训练次数

    'sigma':0.01,

     

    'save_checkpoint_steps'1,  # 多少步保存一次模型

    'keep_checkpoint_max'3,  # 最多保存多少个模型

    'output_directory''./code/flowers//model',  # 保存模型路径

    'output_prefix'"checkpoint_classification"  # 保存模型文件名字

})

数据集准备

该数据集是开源数据集,总共包括5种花的类型:分别是daisy(雏菊,633张),dandelion(蒲公英,898张),roses(玫瑰,641张),sunflowers(向日葵,699张),tulips(郁金香,799张),保存在5个文件夹当中,总共3670张,大小大概在230M左右。为了在模型部署上线之后进行测试,数据集在这里分成了flower_train和flower_test两部分。

数据集下载地址:https://professional.obs.cn-north-4.myhuaweicloud.com/flower_photos.zip

步骤 1  读取图片数据集

数据读取并处理流程如下:

- MindSpore的mindspore.dataset提供了ImageFolderDatasetV2函数,可以直接读取文件 夹图片数据并映射文件夹名字为其标签(label)。这里我们使用ImageFolderDatasetV2函数 读取'daisy','dandelion','roses','sunflowers','tulips'数据。并将这五类标签映射为: {'daisy':0,'dandelion':1,'roses':2,'sunflowers':3,'tulips':4}

- 使用RandomCropDecodeResize、HWC2CHW、TypeCast、shuffle进行数据预处理

1

2

3

4

5

6

7

8

9

10

11

12

# 解压数据集,只需要第一次运行时解压,第二次无需再解压

#!unzip   ./code/flowers/flower_photos.zip

  

de_dataset = ds.ImageFolderDatasetV2(cfg.data_path,                                  class_indexing={'daisy':0,'dandelion':1,'roses':2,'sunflowers':3,'tulips':4})

  

transform_img = CV.RandomCropDecodeResize([cfg.image_width,cfg.image_height], scale=(0.081.0), ratio=(0.751.333))  #改变尺寸

hwc2chw_op = CV.HWC2CHW()

type_cast_op = C.TypeCast(mstype.float32)

de_dataset = de_dataset.map(input_columns="image", num_parallel_workers=8, operations=transform_img)

de_dataset = de_dataset.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=8)

de_dataset = de_dataset.map(input_columns="image", operations=type_cast_op, num_parallel_workers=8)

de_dataset = de_dataset.shuffle(buffer_size=cfg.data_size)

步骤 2  划分训练集与测试集

- 按照8:2的比列将数据划分为训练数据集和测试数据集

- 对训练数据和测试数据分批次(batch)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

(de_train,de_test)=de_dataset.split([0.8,0.2])

  

de_train=de_train.batch(cfg.batch_size, drop_remainder=True)

de_train=de_train.repeat(cfg.epoch_size)

de_test=de_test.batch(cfg.batch_size, drop_remainder=True)

de_test=de_test.repeat(cfg.epoch_size)

  

print('训练数据集数量:',de_train.get_dataset_size()*cfg.batch_size)

print('测试数据集数量:',de_test.get_dataset_size()*cfg.batch_size)

  

data_next=de_dataset.create_dict_iterator().get_next()

print('通道数/图像长/宽:', data_next['image'].shape)

print('一张图像的标签样式:', data_next['label'])  # 一共5类,用0-4的数字表达类别。

  

plt.figure()

plt.imshow(data_next['image'][0,...])

plt.colorbar()

plt.grid(False)

plt.show()

训练数据集数量: 2912
测试数据集数量: 704
通道数/图像长/宽: (3, 100, 100)
一张图像的标签样式: 0

 【实验课程】花卉图像分类实验_第1张图片

构建CNN图像识别模型

花卉图像数据集准备完成,接下来我们就需要构建训练模型,本实验采用的是CNN神经网络算法。

步骤 1  定义图像识别模型

# 定义CNN图像识别网络

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

class Identification_Net(nn.Cell):

    def __init__(self, num_class=5,channel=3,dropout_ratio=0.5,trun_sigma=0.01):  # 一共分五类,图片通道数是3

        super(Identification_Net, self).__init__()

        self.num_class = num_class

        self.channel = channel

        self.dropout_ratio=dropout_ratio

         

        self.conv1 = nn.Conv2d(self.channel, 32,

                               kernel_size=5, stride=1, padding=0,

                               has_bias=True, pad_mode="same",

                               weight_init=TruncatedNormal(sigma=trun_sigma),bias_init='zeros')

        self.relu = nn.ReLU()

        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2,pad_mode="valid")

        self.conv2 = nn.Conv2d(3264,

                               kernel_size=5, stride=1, padding=0,

                               has_bias=True, pad_mode="same",

                               weight_init=TruncatedNormal(sigma=trun_sigma),bias_init='zeros')

        self.conv3 = nn.Conv2d(64128,

                               kernel_size=3, stride=1, padding=0,

                               has_bias=True, pad_mode="same",

                               weight_init=TruncatedNormal(sigma=trun_sigma),bias_init='zeros')

        self.conv4 = nn.Conv2d(128128,

                               kernel_size=3, stride=1, padding=0,

                               has_bias=True, pad_mode="same",

                               weight_init=TruncatedNormal(sigma=trun_sigma), bias_init='zeros')

        self.flatten = nn.Flatten()

        self.fc1 = nn.Dense(6*6*1281024,weight_init =TruncatedNormal(sigma=trun_sigma),bias_init = 0.1)

        self.dropout = nn.Dropout(self.dropout_ratio)

        self.fc2 = nn.Dense(1024512, weight_init=TruncatedNormal(sigma=trun_sigma), bias_init=0.1)

        self.fc3 = nn.Dense(512self.num_class, weight_init=TruncatedNormal(sigma=trun_sigma), bias_init=0.1)

  

    def construct(self, x):

        = self.conv1(x)

        = self.relu(x)

        = self.max_pool2d(x)

        = self.conv2(x)

        = self.relu(x)

        = self.max_pool2d(x)

        = self.conv3(x)

        = self.max_pool2d(x)

        = self.conv4(x)

        = self.max_pool2d(x)

        = self.flatten(x)

        = self.fc1(x)

        = self.relu(x)

        = self.dropout(x)

        = self.fc2(x)

        = self.relu(x)

        = self.dropout(x)

        = self.fc3(x)

        return x

 步骤 2  模型训练

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

net=Identification_Net(num_class=cfg.num_class, channel=cfg.channel, dropout_ratio=cfg.dropout_ratio)

net_loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction="mean")

#opt

fc_weight_params = list(filter(lambda x: 'fc' in x.name and 'weight' in x.name, net.trainable_params()))

else_params=list(filter(lambda x: x not in fc_weight_params, net.trainable_params()))

group_params = [{'params': fc_weight_params, 'weight_decay': cfg.weight_decay},

                {'params': else_params}]

net_opt = nn.Adam(group_params, learning_rate=cfg.lr, weight_decay=0.0)

  

model = Model(net, loss_fn=net_loss, optimizer=net_opt, metrics={"acc"})

loss_cb = LossMonitor(per_print_times=de_train.get_dataset_size())

config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps,

                             keep_checkpoint_max=cfg.keep_checkpoint_max)

ckpoint_cb = ModelCheckpoint(prefix=cfg.output_prefix, directory=cfg.output_directory, config=config_ck)

print("============== Starting Training ==============")

model.train(cfg.epoch_size, de_train, callbacks=[loss_cb], dataset_sink_mode=True)

  

# 使用测试集评估模型,打印总体准确率

metric = model.eval(de_test)

print(metric)

输出结果:

============== Starting Training ==============

epoch: 1 step 91, loss is 1.3102010488510132

Epoch time: 14017.676, per step time: 154.040, avg loss: 1.310

************************************************************

epoch: 2 step 91, loss is 1.237145185470581

Epoch time: 758.372, per step time: 8.334, avg loss: 1.237

************************************************************

epoch: 3 step 91, loss is 1.3110840320587158

Epoch time: 757.112, per step time: 8.320, avg loss: 1.311

************************************************************

epoch: 4 step 91, loss is 1.3393423557281494

Epoch time: 763.801, per step time: 8.393, avg loss: 1.339

************************************************************

...

...

...

************************************************************

epoch: 397 step 91, loss is 0.18403360247612

Epoch time: 764.593, per step time: 8.402, avg loss: 0.184

************************************************************

epoch: 398 step 91, loss is 0.09277979284524918

Epoch time: 766.729, per step time: 8.426, avg loss: 0.093

************************************************************

epoch: 399 step 91, loss is 0.20462298393249512

Epoch time: 769.085, per step time: 8.451, avg loss: 0.205

************************************************************

epoch: 400 step 91, loss is 0.24984098970890045

Epoch time: 761.465, per step time: 8.368, avg loss: 0.250

************************************************************

{'acc': 0.9147727272727273}

图像分类模型验证实验

l * 掌握利图像识别模型验证方法。

步骤 1  加载训练模型

1

2

3

4

5

6

# 加载模型

#加载模型

CKPT = './code/flowers/model/checkpoint_classification-400_91.ckpt'

net = Identification_Net(num_class=cfg.num_class, channel=cfg.channel, dropout_ratio=cfg.dropout_ratio)

load_checkpoint(CKPT, net=net)

model = Model(net)

步骤 2  验证推理

1

2

3

4

5

6

7

8

9

10

# 预测

class_indexing={0:'daisy',1:'dandelion',2:'roses',3:'sunflowers',4:'tulips'}

test_ = de_test.create_dict_iterator().get_next()

test = Tensor(test_['image'], mindspore.float32)

predictions = model.predict(test)

predictions = predictions.asnumpy()

for in range(10):

    p_np = predictions[i, :]

    p_list = p_np.tolist()

    print('第' + str(i) + '个sample预测结果:', class_indexing[p_list.index(max(p_list))], '   真实结果:', class_indexing[test_['label']])

输出结果:

第0个sample预测结果: sunflowers    真实结果: sunflowers

第1个sample预测结果: dandelion    真实结果: dandelion

第2个sample预测结果: sunflowers    真实结果: sunflowers

第3个sample预测结果: sunflowers    真实结果: sunflowers

第4个sample预测结果: daisy    真实结果: daisy

第5个sample预测结果: dandelion    真实结果: dandelion

第6个sample预测结果: daisy    真实结果: daisy

第7个sample预测结果: sunflowers    真实结果: sunflowers

第8个sample预测结果: tulips    真实结果: tulips

第9个sample预测结果: dandelion    真实结果: dandelion

实验总结

本章提供了一个基于华为ModelArts平台的图像识别实验。该实验演示了如何利用华为云ModelArts完成图像识别任务。本章对实验实验做了详尽的剖析。阐明了整个实验功能、结构与流程是如何设计的,详细解释了如何解析数据、如何构建深度学习模型、如何保存模型等内容。部署后的实验多个类别图片下进行测试,结果表明实验实验具有较快的推断速度和较好的识别性能。读者可以在该实验实验的基础上开发更有针对性的应用实验。

创新设计

基于本实验的描述,请使用数据集CIFAR10完成图片识别任务并搭建一套自定义的图片识别实验。

你可能感兴趣的:(【实验课程】花卉图像分类实验)