随着时代的快速发展,人工智能已经融入我们生活的方方面面。中国的农业也因人工智能而受益进入高速发展阶段。现今,看庄稼长势有卫星遥感技术,水果分拣有智能分拣系统,灌溉施肥有自动化机械……

具体以水果分拣场景为例,大型的水果种植园每到丰收的季节,都会雇佣大量的分拣工人来分拣水果,这是一件人力成本很高的事情。另外,人工分拣水平层次不一还可能使得农场主收益受到很大影响。然而,如今智能水果分拣系统的出现,可以自动根据设置的水果等农作物的品级进行分拣,降低人力成本,提高处理效率,提升分拣的准确性,那么问题来了。

如何搭建一套完整的智能水果分拣系统?巧了,PaddleHub正好可以帮你搞定完整的系统建立!

今天我们带大家利用PaddleHub搭建ResNet50_vd网络,实现桃子分类,让大家亲自感受图像分类的魅力。
本实践旨在通过桃子分类来让大家对图像分类问题有一个初步了解,同时理解和掌握如何使用PaddleHub搭建一个经典的卷积神经网络。

如果您觉得本案例对您有帮助,欢迎Star收藏一下,不易走丢哦~,链接指路:https://github.com/PaddlePaddle/awesome-DeepLearning。

方案设计

本教程的设计方案如图2所示。对于一幅输入的桃子图像,首先使用ResNet50_vd网络提取特征,获取特征表示;然后使用分类器获取属于每个桃子类别的概率值。在训练阶段,通过模型输出的概率值与样本的真实标签构建损失函数,从而进行模型训练;在推理阶段,选出概率最大的类别作为最终的输出。

环境搭建与准备

安装PaddlePaddle:参考快速安装,aistudio已经预先安装好了PaddlePaddle。

安装PaddleHub:为了保证最新版本稳定,建议执行以下命令安装。

!pip install paddlehub==2.0.4 -i https://pypi.tuna.tsinghua.edu.cn/simple

数据处理

在本教程提供的数据文件中,已经提供了分割好的训练集、验证集、测试集的索引和标注文件。如果用户利用PaddleHub迁移CV类任务使用自定义数据,则需要自行切分数据集,将数据集切分为训练集、验证集和测试集。需要三个文本文件来记录对应的图片路径和标签,此外还需要一个标签文件用于记录标签的名称。相关方法可参考自定义数据集。该桃子分拣系统按照桃子品相分为4个等级。

其中:R0为最好:颜色鲜红且果实较大;B1为次优:果实较大,颜色较红;M2为中等:果实中等;S3为较差:果实个头比较小。

数据分为训练集、验证集和测试集,训练集为每种桃子各1500张,验证集每种桃子各100张,测试集每种桃子为15张。

├─data: 数据目录
├─train_list.txt:训练集数据列表
├─test_list.txt:测试集数据列表
├─validate_list.txt:验证集数据列表
├─label_list.txt:标签列表
└─……

训练集、验证集和测试集的数据列表文件的格式如下,列与列之间以空格键分隔。

图片1路径 图片1标签
图片2路径 图片2标签
...

label_list.txt的格式如下:

分类1名称
分类2名称
...

随后进行数据集的解压:

!unzip -q -o ./data/data67225/peach.zip -d ./work

准备好数据后即可使用PaddleHub完成数据读取器的构建,实现方法如下所示:构建数据读取Python类,并继承paddle.io.Dataset这个类完成数据读取器构建。在定义数据集时,需要预先定义好对数据集的预处理操作,并且设置好数据模式。在数据集定义中,需要重新定义__init____getitem____len__三个部分。示例如下:

#coding:utf-8
import os

import paddle
import paddlehub as hub

class DemoDataset(paddle.io.Dataset):
def __init__(self, transforms, num_classes=4, mode='train'):
# 数据集存放位置
self.dataset_dir = "./work/peach-classification" #dataset_dir为数据集实际路径,需要填写全路径
self.transforms = transforms
self.num_classes = num_classes
self.mode = mode

if self.mode == 'train':
self.file = 'train_list.txt'
elif self.mode == 'test':
self.file = 'test_list.txt'
else:
self.file = 'validate_list.txt'

self.file = os.path.join(self.dataset_dir , self.file)
self.data = []

with open(self.file, 'r') as f:
for line in f.readlines():
line = line.strip()
if line != '':
self.data.append(line)

def __getitem__(self, idx):
img_path, grt = self.data[idx].split(' ')
img_path = os.path.join(self.dataset_dir, img_path)
im = self.transforms(img_path)
return im, int(grt)

def __len__(self):
return len(self.data)

将训练数据输入模型之前,我们通常还需要对原始数据做一些数据处理的工作,比如数据格式的规范化处理,或增加一些数据增强策略。

构建图像分类模型的数据读取器,负责将桃子dataset的数据进行预处理,以特定格式组织并输入给模型进行训练。

如下数据处理策略,只做了三种操作:

1.指定输入图片的尺寸,并将所有样本数据统一处理成该尺寸。

2.对输入图像进行裁剪,并且保持图片中心点不变。

3.对所有输入图片数据进行归一化处理。

对数据预处理及加载数据集的示例如下:

import paddlehub.vision.transforms as T

transforms = T.Compose(
[T.Resize((256, 256)),
T.CenterCrop(224),
T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])],
to_rgb=True)

peach_train = DemoDataset(transforms)
peach_validate = DemoDataset(transforms, mode='val')
peach_test = DemoDataset(transforms, mode='test')

PaddleHub提供了丰富的数据预处理方式,具体可以参见预处理。

模型构建

我们要在PaddleHub中选择合适的预训练模型来Fine-tune,由于桃子分类是一个图像分类任务,这里采用Resnet50模型,并且是采用ImageNet数据集预训练过的版本。这个预训练模型是在图像任务中的一个“万金油”模型,Resnet是目前较为有效的处理图像的网络结构,50层是一个精度和性能兼顾的选择,而ImageNet又是计算机视觉领域公开的最大的分类数据集。所以,在不清楚选择什么模型好的时候,可以优先以这个模型作为baseline。

使用PaddleHub加载ResNet50模型,十分简单,只需一行代码即可实现。关于更多预训练模型信息参见PaddleHub模型介绍。

#安装预训练模型
!hub install resnet50_vd_imagenet_ssld==1.1.0
# 加载模型

import paddlehub as hub

model = hub.Module(name='resnet50_vd_imagenet_ssld', label_list=["R0", "B1", "M2", "S3"])

模型训练

本案例中,我们使用Adam优化器,2014年12月,Kingma和Lei Ba提出了Adam优化器。该优化器对梯度的均值,即一阶矩估计(First Moment Estimation)和梯度的未中心化的方差,即二阶矩估计(Second Moment Estimation)进行综合计算,获得更新步长。Adam优化器实现起来较为简单,且计算效率高,需要的内存更少,梯度的伸缩变换不会影响更新梯度的过程, 超参数的可解释性强,且通常超参数无需调整或仅需微调等优点。我们将学习率设置为0.001,训练10个epochs。

from paddlehub.finetune.trainer import Trainer

import paddle

optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
trainer = Trainer(model, optimizer, checkpoint_dir='img_classification_ckpt', use_gpu=True)
trainer.train(peach_train, epochs=10, batch_size=16, eval_dataset=peach_validate, save_interval=1)

其中 paddle.optimizer.Adam:

  • learning_rate:全局学习率。默认为1e-3;

  • parameters:待优化模型参数。

运行配置

Trainer 主要控制Fine-tune的训练,包含以下可控制的参数:

  • model:被优化模型;

  • optimizer:优化器选择;

  • use_vdl:是否使用vdl可视化训练过程;

  • checkpoint_dir:保存模型参数的地址;

  • compare_metrics:保存最优模型的衡量指标;

trainer.train 主要控制具体的训练过程,包含以下可控制的参数:

  • train_dataset:训练时所用的数据集;

  • epochs:训练轮数;

  • batch_size:训练的批大小,如果使用GPU,请根据实际情况调整batch_size;

  • num_workers:works的数量,默认为0;

  • eval_dataset:验证集;

  • log_interval:打印日志的间隔, 单位为执行批训练的次数。

  • save_interval:保存模型的间隔频次,单位为执行训练的轮数。

当Fine-tune完成后,我们使用模型来进行预测,实现如下:

模型评估

这里我们使用测试集来评估训练完成的模型。

# 模型评估
trainer.evaluate(peach_test, 16)

模型推理

这里我们使用训练完成的模型来预测测试集中的一张图片,观察预测结果与真实结果是否一致。

import paddle
import paddlehub as hub
from PIL import Image
import matplotlib.pyplot as plt

img_path = './work/test.jpg'
img = Image.open(img_path)
plt.imshow(img)
plt.axis('off')
plt.show()
result = model.predict([img_path])
print("桃子的类别被预测为:{}".format(result))

以上为加载模型后实际预测结果(这里只测试了一张图片),返回的是预测的实际效果,可以看到我们传入待预测的是M2类别的桃子照片,经过Fine-tune之后的模型预测的效果也是M2,由此成功完成了桃子分类的迁移学习。

模型部署

由于AIStudio不支持ip访问,以下代码仅做示例,如有需要,请在本地机器运行。

想用我们自己训练的分拣桃子的网络参数,先配置config.json文件:

{
"modules_info": {
"resnet50_vd_imagenet_ssld": {
"init_args": {
"version": "1.1.0",
"label_list":["R0", "B1", "M2", "S3"],
"load_checkpoint": "img_classification_ckpt/best_model/model.pdparams"
},
"predict_args": {
"batch_size": 1
}

}
},
"port": 8866,
"gpu": "0"
}

借助 PaddleHub,服务器端的部署也非常简单,直接用一条命令行在服务器启动resnet50分类模型就行了:

$ hub serving start --config config.json

是的,在服务器端这就完全没问题了。相比手动配置各种参数或者调用各种框架,PaddleHub 部署服务器实在是太好用了。

NOTE: 如使用GPU预测,则需要在启动服务之前,请设置CUDA_VISIBLE_DEVICES环境变量,否则不用设置。

在服务端发送请求,请求脚本如下:

import requests
import json
import cv2
import base64

import numpy as np

def cv2_to_base64(image):
data = cv2.imencode('.jpg', image)[1]
return base64.b64encode(data.tostring()).decode('utf8')

def base64_to_cv2(b64str):
data = base64.b64decode(b64str.encode('utf8'))
data = np.fromstring(data, np.uint8)
data = cv2.imdecode(data, cv2.IMREAD_COLOR)
return data

# 发送HTTP请求
org_im = cv2.imread('/PATH/TO/IMAGE')

data = {'images':[cv2_to_base64(org_im)], 'top_k':1}
headers = {"Content-type": "application/json"}
url = "http://127.0.0.1:8866/predict/resnet50_vd_imagenet_ssld"
r = requests.post(url=url, headers=headers, data=json.dumps(data))
data =r.json()["results"]['data']

相信只要有一些 Python 基础,在本地预测、以及部署到服务器端都是没问题的,飞桨的 PaddleHub 已经帮我们做好了各种处理过程。

数据来源:https://aistudio.baidu.com/aistudio/datasetdetail/67225

作者:快速实现AI想法

|关于深延科技|

深延科技成立于2018年,是深兰科技(DeepBlue)旗下的子公司,以“人工智能赋能企业与行业”为使命,助力合作伙伴降低成本、提升效率并挖掘更多商业机会,进一步开拓市场,服务民生。公司推出四款平台产品——深延智能数据标注平台、深延AI开发平台、深延自动化机器学习平台、深延AI开放平台,涵盖从数据标注及处理,到模型构建,再到行业应用和解决方案的全流程服务,一站式助力企业“AI”化。

分享 | 基于图像分类网络ResNet50_vd实现桃子分类相关推荐

  1. 基于图像分类网络ResNet50_vd实现桃子分类

    基于图像分类网络ResNet50_vd实现桃子分类 随着时代的快速发展,人工智能已经融入我们生活的方方面面.中国的农业也因人工智能而受益进入高速发展阶段.现今,看庄稼长势有卫星遥感技术,水果分拣有智能 ...

  2. 【计算机视觉(CV)】基于图像分类网络VGG实现中草药识别(二)

    [计算机视觉(CV)]基于图像分类网络VGG实现中草药识别(二) 作者简介:在校大学生一枚,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践 ...

  3. 【计算机视觉(CV)】基于图像分类网络VGG实现中草药识别(一)

    [计算机视觉(CV)]基于图像分类网络VGG实现中草药识别(一) 作者简介:在校大学生一枚,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践 ...

  4. 基于飞桨图像分类套件PaddleClas的柠檬分类竞赛实战

    前情提要   通过之前教程中的学习,相信大家对于如何搭建一个分类网络已经清晰了.那么我们不禁会想,有没有更快速的尝试模型及技巧的方法呢?因为我们在上一次课程中使用的代码都需要自己进行开发,自己写需要很 ...

  5. 基于语义规则的胶囊网络跨域情感分类:Cross-Domain Sentiment Classification by Capsule Network With Semantic Rules

    基于语义规则的胶囊网络跨域情感分类 论文 ABSTRACT I. INTRODUCTION II. RELATED WORK A. CROSS-DOMAIN SENTIMENT CLASSIFICAT ...

  6. 基于Keras搭建LSTM网络实现文本情感分类

    基于Keras搭建LSTM网络实现文本情感分类 一.语料概况 1.1 数据统计 1.1.1 查看样本均衡情况,对label进行统计 1.1.2 计句子长度及长度出现的频数 1.1.3 绘制句子长度累积 ...

  7. 朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战

    基于朴素贝叶斯的文本分类方法 一.朴素贝叶斯原理的介绍 二.朴素贝叶斯分类器的代码实现 分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同时会给出这个猜测的概率估计值.朴素贝叶 ...

  8. 有望替代卷积神经网络?微软最新研究提基于关系网络的视觉建模

    导语:最近两年,自注意力机制.图和关系网络等模型在NLP领域刮起了一阵旋风,基于这些模型的Transformer.BERT.MASS等框架已逐渐成为NLP的主流方法.这些模型在计算机视觉领域是否能同样 ...

  9. 计算机视觉算法——图像分类网络总结

    计算机视觉算法--图像分类网络总结 计算机视觉算法--图像分类网络总结 1. AlexNet 1.1 网络结构 1.2 关键知识点 1.2.1 卷积和池化特征尺寸计算公式 1.2.2 ReLU非线性激 ...

最新文章

  1. js如何让高度和宽度保持一致_如何实现一个下载进度条/播放进度条
  2. 《深入浅出iPhone/iPad开发(第2版)》——组件可以触发特定事件
  3. 动态规划-01背包问题详解
  4. asp 调用java文件上传_用asp实现文件浏览、上传、下载的程序
  5. laravel 模块化管理 插件 caffeinated
  6. ELK下es的分词器analyzer
  7. 锻造恒生O45:致广大而尽精微
  8. 获取桌面DC: GetDC(GetDesktopWindow())与GetDC(NULL)
  9. 突破Dr.com校园网客户端对于热点和路由器的限制
  10. Python爬虫工程师必备工具 Charles 的安装,以及爬取淘宝网+学UI网
  11. 利用磁共振成像数据估测脑年龄
  12. python把正整数翻译成英文_将Python整数转换为单词
  13. python chm模块_python3.7.0官方参考文档 最新api文档 chm
  14. ThinkPad E460如何进入bios
  15. 手机中的小金库被盗?手机支付安全如何保障
  16. oracle rebuild online,rebuild online 请慎用
  17. pycharm远程连接服务器完整教程
  18. 一些投资理财渠道(仅供参考)
  19. 中国发布域名系统基础软件 “红枫”
  20. mysql win10 msi下载_Windows10 MYSQL Installer 安装 (msi 安装)

热门文章

  1. 推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
  2. 解决导出excel文件名中文乱码的问题
  3. 自媒体平台做网赚不要指望着,平台广告分成!
  4. PowerManagerService分析(二)之updatePowerStateLocked()核心
  5. eclipse创建Javaweb项目
  6. 小红书流量红利词「0基础」实操手册
  7. 方法论:后台产品经理的前世今生(一)
  8. 记录一次飞猪杀熟的日常(买机票价格翻倍)
  9. 关于U盘烧录iso问题
  10. GAN_1——基础知识