预训练模型PaddleHub
PaddleHub 飞桨的预训练模型应用工具,帮助开发者使用简单的代码快速开发复杂的深度学习任务。还提供 Fine-tune Api,帮助快速完成模型迁移部署。
# 安装paddlehub
pip install paddlehub==2.1
PaddleHub支持的预训练模型涵盖了图像分类、关键点检测、目标检测、文字识别、图像生成、人脸检测、图像编辑、图像分割、视频分类、视频修复、词法分析、语义模型、情感分析、文本审核、文本生成、语音合成、工业质检等300多个主流模型。
使用PaddleHub
在使用PaddleHub之前,需完成以下任务:
- 安装python,对应Linux或MAC系统版本要求3.5及以上版本,windows系统要求3.6及以上版本。
- 安装飞桨最新版框架
- 安装PaddleHub最新版
通过python调用PaddleHub
以计算机视觉为例:
- 人像抠图(deeplabv3p_xception65_humanseg)
- 人体部位分割(ace2p)
- 人脸检测(ultra_light_fast_generic_face_detector_1mb_640)
- 关键点检测(human_pose_estimation_resnet50_mpii)
人像抠图
# 安装预训练模型
hub install deeplabv3p_xception65_humanseg==1.1.2
import paddlehub as hub
import matplotlib.image as mping
import matplotlib.pyplot as plt
module = hub.Module(name="deeplabv3p_xception65_humanseg")
res = module.segmentation(paths=["./test.jpg"],visualization=True,output_dir="humanseg_output")
res_img_path = "humanseg_output/test.jpg"
img = mping.imread(res_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis("off")
plt.show()
人体部位分割
#安装预训练模型
hub install ace2p==1.1.0
import paddlehub as hub
import matplotlib.image as mping
import matplotlib.pyplot as plt
module = hub.Module(name="ace2p")
res = module.segmentation(paths=["./test.jpg"],visualization=True,output_dir="ace2p_output")
res_img_path = "ace2p_output/test.jpg"
img = mping.imread(res_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis("off")
plt.show()
人脸检测
#安装预训练模型
hub install ultra_light_fast_generic_face_detector_1mb_640==1.1.2
import paddlehub as hub
import matplotlib.image as mping
import matplotlib.pyplot as plt
module = hub.Module(name="ultra_light_fast_generic_face_detector_1mb_640")
res = module.segmentation(paths=["./test.jpg"],visualization=True,output_dir="face_detection_output")
res_img_path = "face_detection_output/test.jpg"
img = mping.imread(res_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis("off")
plt.show()
关键点检测
#安装预训练模型
hub install human_pose_estimation_resnet50_mpii==1.1.0
import paddlehub as hub
import matplotlib.image as mping
import matplotlib.pyplot as plt
module = hub.Module(name="human_pose_estimation_resnet50_mpii")
res = module.segmentation(paths=["./test.jpg"],visualization=True,output_dir="keypoint_output")
res_img_path = "keypoint_output/test.jpg"
img = mping.imread(res_img_path)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis("off")
plt.show()
以自然语言为例:
对中文分词与情感分析任务为例子
中文分词
#安装预训练模型
hub install lac
import paddlehub as hub
lac = hub.Module(name="lac")
test_text = ["1996年,曾经是微软员工的加布·纽维尔和麦克·哈灵顿一同创建了Valve软件公司。他们在1996年下半年从id software取得了雷神之锤引擎的使用许可,用来开发半条命系列。"]
res = lac.lexical_analysis(texts = test_text)
print("中文词法分析结果:", res)
情感分析
#安装预训练模型
hub install senta_bilstm
import paddlehub as hub
senta = hub.Module(name="senta_bilstm")
test_text = ["味道不错,确实不算太辣,适合不能吃辣的人。就在长江边上,抬头就能看到长江的风景。鸭肠、黄鳝都比较新鲜。"]
res = senta.sentiment_classify(texts = test_text)
print("中文词法分析结果:", res)
通过命令行方式调用PaddleHub
hub run deeplabv3p_xception65_humanseg --input_path test.jpg
hub run lac --input_text "今天是个好日子"
上面命令分为四个部分:
hub:PaddleHub的命令
run:调用要执行的模型预测
deeplabv3p_xception65_humanseg、lac:要调用的算法模型
—input_path、—input_text:表示输入模型的数据,图像和文本的输入方式不同
使用自己的数据Fine-tune PaddleHub
实现迁移学习包括以下步骤:
- 安装PaddleHub
- 数据准备
- 模型准备
- 训练准备
安装PaddleHub
pip install paddlehub==2.1 -i https://mirror.baidu.com/pypi/simple
数据准备
利用PaddleHub迁移CV类任务使用自定义数据,需要自行切分数据集,将数据集切分为训练集、验证集和测试集。需要三个文本记录对应的图片路径和标签,还需一个标签文件记录标签的名称。自定义PaddleHub的数据格式
├─data: 数据目录
├─train_list.txt:训练集数据列表
├─test_list.txt:测试集数据列表
├─validate_list.txt:验证集数据列表
├─label_list.txt:标签列表
└─……
训练集、验证集和测试集的数据列表文件的格式如下,列与列之间以空格键分隔。
图片1路径 图片1标签
图片2路径 图片2标签
……
label_list.txt的格式如下
分类1名称
分类2名称
...
准备好数据后即可使用PaddleHub完成数据读取器的构建,实现方法如下所示:
- 构建数据读取Python类,并继承
paddle.io.Dataset
这个类完成数据读取器构建。 - 在定义数据集时,需要预先定义好对数据集的预处理操作,并且设置好数据模式。
- 在数据集定义中,需要重新定义
__init__
,__getitem__
和__len__
三个部分。
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" # 数据集存储位置
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 = "val_list.txt"
self.file = os.path.join(self.dataset_dir,self.file)
with open(self.file,'r') as file:
self.data = file.read().split("\n")[:-1]
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)
在将训练数据输入模型前需要对原始数据进行数据处理,比如数据格式的规范化或增加数据策略。
- 指定输入图片的尺寸,并将样本数据统一处理成该尺寸
- 对输入数据进行归一化处理
import paddlehub.vision.transform 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) # 是否将输入从BGR模式转换为RGB模式
peach_train = DemoDataset(transforms)
peach_val = DemoDataset(transforms,mode="val")
模型准备
在PaddleHub中选择合适的预训练模型来Fine-tune,由于桃子分类是一个图像分类任务,这里采用Resnet50模型,并且是采用ImageNet数据集Fine-tune过的版本。
这个预训练模型是在图像任务中的一个“万金油”模型,Resnet是目前较为有效的处理图像的网络结构,50层是一个精度和性能兼顾的选择,而ImageNet又是计算机视觉领域公开的最大的分类数据集。
#安装预训练模型
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"])
训练准备
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_val,save_interval=1)
其中Adam
:
learning_rate
:全局学习率。默认为1e-3parameters
:待优化模型参数
运行配置
Trainer
主要控制Fine-tune的训练
model
:被优化模型optimizer
:优化器选择use_gpu
:是否使用GPUuse_vdl
:是否使用vdl可视化训练过程checkpoint_dir
:保存模型参数地址compare_metrics
:保存最优模型的衡量指标
trainer.train
主要控制具体的训练过程
train_dataset
:训练所用的数据集epochs
:训练轮数batch_size
:训练批次大小num_workers
:works的数量eval_dataset
:验证集log_interval
:打印日志间隔,单位为执行训练批次次数save_interval
:保存模型的间隔频次,单位为执行训练轮数
当Fine-tune完成后,我们使用模型来进行预测,实现如下:
import paddle
import paddlehub as hub
result = model.predict(['./work/peach-classification/test/M2/0.png'])
print(result)
PaddleHub Serving 一键服务化部署
PaddleHub Serving是基于PaddleHub的一键模型服务部署工具,能够通过简单的Hub命令行工具轻松启动一个模型预测在线服务,前端通过Flask和Gunicorn完成网络请求的处理,后端直接调用PaddleHub预测接口,同时支持使用多进程方式利用多核提高并发能力,保证预测服务的性能。
部署方法
1.启动服务端部署
PaddleHub Serving有两种启动方式:
- 使用命令行启动
- 使用配置文件启动。
命令行启动
hub serving start --modules Module1==Version1 module2==Version2... --port xxx --use_gpu --use_multiprocess --workers --gpu
参数说明
参数 | 用途 |
---|---|
—modules / -m | PaddleHub Serving预安装模型,以多个Module==Version键值对的形式列出 |
—port / -p | 服务端口,默认为8866 |
—use_gpu | 使用GPU进行预测,必须安装paddlepaddle-gpu |
—use_multiprocess | 是否启用并发方式,默认为单进程方式,推荐多核CPU机器使用此方式 |
—workers | 在并发方式下指定的并发任务数,默认为2*cpu_count-1 ,其中cpu_count 为CPU核数 |
—gpu | 指定使用gpu的卡号,如1,2代表使用1号显卡和2号显卡,默认仅使用0号显卡 |
注意:—use_gpu不可与—use_multiprocess共用
配置文件启动
hub serving start --config config.json
config.json
格式如下:
{
"modules_info": {
"yolov3_darknet53_coco2017": {
"init_args": {
"version": "1.0.0"
},
"predict_args": {
"batch_size": 1,
"use_gpu": false
}
},
"lac": {
"init_args": {
"version": "1.1.0"
},
"predict_args": {
"batch_size": 1,
"use_gpu": false
}
}
},
"port": 8866,
"use_multiprocess": false,
"workers": 2,
"gpu": "0,1,2"
}
参数说明:
参数 | 用途 |
---|---|
modules_info | PaddleHub Serving预安装模型,以字典列表形式列出,key为模型名称。 |
port | 服务端口,默认为8866 |
use_multiprocess | 是否启用并发方式,默认为单进程方式,推荐多核CPU机器使用此方式 |
use_gpu | 使用GPU进行预测,必须安装paddlepaddle-gpu |
workers | 在并发方式下指定的并发任务数,默认为2*cpu_count-1 ,其中cpu_count 为CPU核数 |
gpu | 指定使用gpu的卡号,如1,2代表使用1号显卡和2号显卡,默认仅使用0号显卡 |
注意:use_gpu不可与use_multiprocess共用
2.访问服务端
客户端访问预测接口以获取结果了,接口url格式为:http://127.0.0.1:8866/predict/<MODULE>
其中,<MODULE>
为模型名。通过发送一个POST请求,即可获取预测结果。
3.关闭服务端
hub serving stop --prot xxx
--prot
:指定要关闭的服务端口,默认:8866
评论