[python]飞桨python小白逆袭课程day4——PaddleHub之《青春有你2》作业:五人识别

一、任务简介

图像分类是计算机视觉的重要领域,它的目标是将图像分类到预定义的标签。近期,许多研究者提出很多不同种类的神经网络,并且极大的提升了分类算法的性能。本文以自己创建的数据集:青春有你2中选手识别为例子,介绍如何使用PaddleHub进行图像分类任务。

#CPU环境启动请务必执行该指令
%set_env CPU_NUM=1 


#安装paddlehub
!pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

二、任务实践

Step1、基础工作

加载数据文件

导入python包

 

利用前天的爬虫案例爬取五位选手照片。我是在本地pycharm环境爬取的,随后把数据打包上传到平台

import re
import requests
from urllib import error
from bs4 import BeautifulSoup
import os
## name:选手名称 basepath:图片下载目录 pn: 百度图片分页参数 pic_num:下载图片数量
def crawl_pic_urls(name,basepath,pn,pic_num):
    pic_urls=[]
    # 数据源主要是通过百度
    url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + name+' 青春有你 高清' + '&pn='
    tmp = url
    num = 0
    while num < pic_num:
        try:
            url = tmp + str(pn)
            print(url)
            result = requests.get(url, timeout=10)
            pic_url = re.findall('"objURL":"(.*?)",', result.text, re.S)  # 先利用正则表达式找到图片url
            if len(pic_url)>pic_num:
                pic_url=pic_url[0:pic_num]
            down_pic(name,pic_url,basepath)
            num+=len(pic_url)
            pn+=60
        except error.HTTPError as e:
            print('网络错误,请调整网络后重试')

def down_pic(name,pic_urls,basepath):
    '''
    根据图片链接列表pic_urls, 下载所有图片,保存在以name命名的文件夹中,
    '''
    path = basepath + name + '/'

    if not os.path.exists(path):
        os.makedirs(path)

    # print("正在下载:%s" %(str(name)))

    for i, pic_url in enumerate(pic_urls):
        try:
            pic = requests.get(pic_url, timeout=15)
            string = str(i + 1) + '.jpg'
            with open(path+string, 'wb') as f:
                f.write(pic.content)
                # 生成训练集
                print('成功下载第%s张图片: %s' % (str(i + 1), str(pic_url)))
        except Exception as e:
            print('下载第%s张图片时失败: %s' % (str(i + 1), str(pic_url)))
            print(e)
            continue

label_list = ['yushuxin', 'xujiaqi', 'zhaoxiaotang', 'anqi', 'wangchengxuan']
for name in label_list:
    crawl_pic_urls(name, 'dataset/train/', 0, 50)
    crawl_pic_urls(name, 'dataset/validate/', 0, 5)

上传数据集,然后解压。可以根据自己创建的路径修改下面的解压命令。

!unzip -o /home/aistudio/dataset/dataset.zip -d /home/aistudio/dataset/

这样数据集就导入了,下面导入python包

import paddlehub as hub

到这一步基本没有什么问题报错

下面是填写txt文件,主要是test_list.txt 和 validate_list.txt 

为了防止粗心出错,遍些了程序写入内容,然后粘贴复制即可。

下面是验证集validate_list.txt ,

file_object = open('yushuxin.txt', 'w')
for i in range(1, 6):
    file_object.write('validate/yushuxin/'+ str(i) + '.jpg 0\n')

file_object = open('xujiaqi.txt', 'w')
for i in range(1, 6):
    file_object.write('validate/xujiaqi/'+ str(i) + '.jpg 1\n')

file_object = open('zhaoxiaotang.txt', 'w')
for i in range(1, 6):
    file_object.write('validate/zhaoxiaotang/'+ str(i) + '.jpg 2\n')

file_object = open('anqi.txt', 'w')
for i in range(1, 6):
    file_object.write('validate/anqi/'+ str(i) + '.jpg 3\n')

file_object = open('wangchengxuan.txt', 'w')
for i in range(1, 6):
    file_object.write('validate/wangchengxuan/'+ str(i) + '.jpg 4\n')

复制写好内容的文件到平台文件上,如下图所示。

需要注意的是: !!!

写入后不要有空行多余的行!!!踩过这样的坑,特此提醒。

相应的测试集train_list.txt,讲上面程序里面的validate改成train, range改成(0,51)

做相应调整后,按照上面的要求复制粘贴即可,同样!!!不要有空行和多余行!!!

 

Step2、加载预训练模型

接下来我们要在PaddleHub中选择合适的预训练模型来Finetune,由于是图像分类任务,因此我们使用经典的ResNet-50作为预训练模型。PaddleHub提供了丰富的图像分类预训练模型,包括了最新的神经网络架构搜索类的PNASNet,我们推荐您尝试不同的预训练模型来获得更好的性能。

module = hub.Module(name="resnet_v2_50_imagenet")

Step3、数据准备

接着需要加载图片数据集。我们使用自定义的数据进行体验,请查看适配自定义数据

from paddlehub.dataset.base_cv_dataset import BaseCVDataset
   
class DemoDataset(BaseCVDataset):	
   def __init__(self):	
       # 数据集存放位置
       
       self.dataset_dir = "dataset"
       super(DemoDataset, self).__init__(
           base_path=self.dataset_dir,
           train_list_file="train_list.txt",
           validate_list_file="validate_list.txt",
           test_list_file="test_list.txt",
           label_list_file="label_list.txt",
           )
dataset = DemoDataset()

到这里应该还是也没有什么报错

Step5、配置策略

在进行Finetune前,我们可以设置一些运行时的配置,例如如下代码中的配置,表示:

  • use_cuda:设置为False表示使用CPU进行训练。如果您本机支持GPU,且安装的是GPU版本的PaddlePaddle,我们建议您将这个选项设置为True;

  • epoch:迭代轮数;

  • batch_size:每次训练的时候,给模型输入的每批数据大小为32,模型训练时能够并行处理批数据,因此batch_size越大,训练的效率越高,但是同时带来了内存的负荷,过大的batch_size可能导致内存不足而无法训练,因此选择一个合适的batch_size是很重要的一步;

  • log_interval:每隔10 step打印一次训练日志;

  • eval_interval:每隔50 step在验证集上进行一次性能评估;

  • checkpoint_dir:将训练的参数和数据保存到cv_finetune_turtorial_demo目录中;

  • strategy:使用DefaultFinetuneStrategy策略进行finetune;

更多运行配置,请查看RunConfig

同时PaddleHub提供了许多优化策略,如AdamWeightDecayStrategyULMFiTStrategyDefaultFinetuneStrategy等,详细信息参见策略

config = hub.RunConfig(
    use_cuda=False,                              #是否使用GPU训练,默认为False;
    num_epoch=3,                                #Fine-tune的轮数;
    checkpoint_dir="cv_finetune_turtorial_demo",#模型checkpoint保存路径, 若用户没有指定,程序会自动生成;
    batch_size=3,                              #训练的批大小,如果使用GPU,请根据实际情况调整batch_size;
    eval_interval=10,                           #模型评估的间隔,默认每100个step评估一次验证集;
    strategy=hub.finetune.strategy.DefaultFinetuneStrategy())  #Fine-tune优化策略;

Step6、组建Finetune Task

有了合适的预训练模型和准备要迁移的数据集后,我们开始组建一个Task。

由于该数据设置是一个二分类的任务,而我们下载的分类module是在ImageNet数据集上训练的千分类模型,所以我们需要对模型进行简单的微调,把模型改造为一个二分类模型:

  1. 获取module的上下文环境,包括输入和输出的变量,以及Paddle Program;
  2. 从输出变量中找到特征图提取层feature_map;
  3. 在feature_map后面接入一个全连接层,生成Task;
    input_dict, output_dict, program = module.context(trainable=True)
    img = input_dict["image"]
    feature_map = output_dict["feature_map"]
    feed_list = [img.name]
    
    task = hub.ImageClassifierTask(
        data_reader=data_reader,
        feed_list=feed_list,
        feature=feature_map,
        num_classes=dataset.num_labels,
        config=config)
    

这是很重要的一个步骤,检验前面的步骤是否正确完成。

在这里有几个需要注意的地方

可能会报错说一个文件找不到,或者说文件找不到,原因可能是下载的照片有问题,或者是路径不正确,或者前面填写的文件里有空行等等,这些是常见的,而且也很容易忽略,需要特别注意。

当然也有可能出现其他错,认真解决吧!谁没踩过那么些个神奇搞怪的坑呢

当运行成功后,你的loss值从大到越来越小,acc值从小到越来越大的时候说明数据训练效果不错。

如果有些波动可能是数据集的问题,比如照片特征差异较大等等。

 

Step6、预测

当Finetune完成后,我们使用模型来进行预测,先通过以下命令来获取测试的图片

 

import numpy as np
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg

with open("dataset/test.txt","r") as f:
    filepath = f.readlines()

data = [filepath[0].split(" ")[0], filepath[1].split(" ")[0],filepath[2].split(" ")[0],filepath[3].split(" ")[0],filepath[4].split(" ")[0]]

label_map = dataset.label_dict()
index = 0
run_states = task.predict(data=data)
results = [run_state.run_results for run_state in run_states]

for batch_result in results:
    print(batch_result)
    batch_result = np.argmax(batch_result, axis=2)[0]
    print(batch_result)
    for result in batch_result:
        index += 1
        result = label_map[result]
        print("input %i is %s, and the predict result is %s" %
              (index, data[index - 1], result))

不能不说,走到这一步已经挺难了。如果一次运行成功了,那么恭喜你,真是幸运儿!

当然我要说的是,在这一步还是会报错的,信息如下:

直接来说就是,在测试时没有找到路径里的照片。

 因此,创建了一个test.txt,如下

最后保存运行一下

 至此任务就完成了,接下来就可以总结啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值