十行代码就能搞定深度学习?飞桨框架高层API,计算机视觉研究院带你一起轻松玩转AI(附源码)...

欢迎关注“

计算机视觉研究院

计算机视觉研究院专栏

作者:Edison_G

前言  向往深度学习技术,可是深度学习框架太难学怎么办?百度倾心打造飞桨框架高层API,零基础也能轻松上手深度学习,一起来看看吧?

另:文末有福利,一定要看完

高层API,What 

深度学习作为人工智能时代的核心技术,近年来无论学术、还是工业领域,均发挥着愈加重要的作用。然而,深度学习理论太难学,开发过程太复杂,又将许多人拒之于深度学习的门外。

为了简化深度学习的学习过程、降低深度学习的开发难度,百度飞桨框架历经近一年的打磨,不断地优化深度学习API,并针对开发者的使用场景进行封装,在飞桨框架的最新版本中,推出了高低融合、科学统一的飞桨全新 API 体系。

飞桨框架将API分为两种,基础API和高层API。用制作披萨举例,一般有两种方法:一种是我们准备好面粉、牛奶、火腿等食材,精心加工后,就能制作出美味的披萨;而第二种则是我们买商家预烤制的披萨饼,以及调好的馅料,直接加热就可以吃到披萨了。

那么这两种方法有什么区别呢?采用方法一,自己准备食材,可以随心所欲的搭配料理,制作酱料,从而满足我们的不同口味,但是,这更适合「老司机」,如果是新人朋友,很有可能翻车;而方法二,用商家预烤制的披萨饼与馅料,直接加热就可以非常快速的完成披萨的制作,而且味道会有保障;但是,相比于方法一,我们会少一些口味的选择。

用框架来类比,基础API对应方法一,高层API对应方法二。使用基础API,我们可以随心所欲的搭建自己的深度学习模型,不会受到任何限制;而使用方法二,我们可以很快的实现模型,但是可能会少一些自主性。

但是,与制作披萨不同的是,飞桨框架可以做到真正的「鱼与熊掌」可以兼得。因为高层API本身不是一个独立的体系,它完全可以和基础API互相配合使用,做到高低融合,使用起来会更加便捷。使我们在开发过程中,既可以享受到基础API的强大,又可以兼顾高层API的快捷。

高层API,All

飞桨框架高层API的全景图如下:

从图中可以看出,飞桨框架高层API由五个模块组成,分别是数据加载、模型组建、模型训练、模型可视化和高阶用法。针对不同的使用场景,飞桨框架提供了不同高层API,从而降低开发难度,让每个人都能轻松上手深度学习。

我们先通过一个深度学习中经典的手写数字分类任务,来简单了解飞桨高层 API。然后再详细的介绍每个模块中所包含的 API。

import paddle
from paddle.vision.transforms import Compose, Normalize
from paddle.vision.datasets import MNIST
import paddle.nn as nn 


# 数据预处理,这里用到了归一化
transform = Compose([Normalize(mean=[127.5],
                               std=[127.5],
                               data_format='CHW')])


# 数据加载,在训练集上应用数据预处理的操作
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)


# 模型组网
mnist = nn.Sequential(
        nn.Flatten(),
        nn.Linear(784, 512),
        nn.ReLU(),    
        nn.Dropout(0.2),    
        nn.Linear(512, 10))


# 模型封装,用 Model 类封装
model = paddle.Model(mnist)


# 模型配置:为模型训练做准备,设置优化器,损失函数和精度计算方式
model.prepare(optimizer=paddle.optimizer.Adam(parameters=model.parameters()),
              loss=nn.CrossEntropyLoss(),              
              metrics=paddle.metric.Accuracy())


# 模型训练,
model.fit(train_dataset,
          epochs=10,          
          batch_size=64,          
          verbose=1)


# 模型评估,
model.evaluate(test_dataset, verbose=1)


# 模型保存,
model.save('model_path')

从示例可以看出,在数据预处理、数据加载、模型组网、模型训练、模型评估、模型保存等场景,高层API均可以通过1~3 行代码实现。相比传统方法动辄几十行的代码量,高层API只需要十来行代码,就能轻松完成一个MNIST分类器的实现。以极少的代码就能达到与基础API同样的效果,大幅降低了深度学习的学习门槛。

如果是初次学习深度学习框架,使用飞桨高层API,可以「凡尔赛」说出「好烦哦,飞桨高层API怎么这么快就完成开发了,我还想多写几行代码呢!」

高层API,How

接下来以CV任务为例,简单介绍飞桨高层API在不同场景下的使用方法。

本示例的完整代码可以在AI Studio上获取,无需准备任何软硬件环境即可直接在线运行代码,https://aistudio.baidu.com/aistudio/projectdetail/1243085

一、数据预处理与数据加载

对于数据加载,在一些典型的任务中,我们完全可以使用飞桨框架内置的数据集,完成数据的加载。飞桨框架将常用的数据集作为领域API,集成在paddle.vision.datasets 目录中,包含了CV领域中常见的MNIST、Cifar、Flowers等数据集。

而在数据预处理场景中,飞桨框架提供了20多种常见的图像预处理 API,方便我们快速实现数据增强,如实现图像的色调、对比度、饱和度、大小等各种数字图像处理的方法。图像预处理API集成在paddle.vision.transforms目录中,使用起来非常方便。只需要先创建一个数据预处理的transform,在其中存入需要进行的数据预处理方法,然后在数据加载的过程中,将transform作为参数传入即可。

此外,如果我们需要加载自己的数据集,使用飞桨框架标准数据定义与数据加载API paddle.io.Dataset与paddle.io.DataLoader,就可以「一键」完成数据集的定义与数据的加载。这里通过一个案例来展示如何利用Dataset定义数据集,示例如下:

from paddle.io import Dataset


class MyDataset(Dataset):
    """
    步骤一:继承 paddle.io.Dataset 类
    """    
    def __init__(self):        
    """
    步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集
    """
    super(MyDataset, self).__init__()


        self.data = [
             ['traindata1', 'label1'],            
             ['traindata2', 'label2'],            
             ['traindata3', 'label3'],            
             ['traindata4', 'label4'],       
         ]


    def __getitem__(self, index):
    """
    步骤三:实现__getitem__方法,定义指定 index 时如何获取数据,并返回单条数据(训练数据,对应的标签)
    """        
    data = self.data[index][0]        
    label = self.data[index][1]


     return data, label


    def __len__(self):        
    """
    步骤四:实现__len__方法,返回数据集总数目
    """        
    return len(self.data)


# 测试定义的数据集
train_dataset = MyDataset()


print('=============train dataset=============')
for data, label in train_dataset:
    print(data, label)

只需要按照上述规范的四个步骤,我们就实现了一个自己的数据集。然后,将train_dataset作为参数,传入到DataLoader中,即可获得一个数据加载器,完成训练数据的加载。

【Tips:对于数据集的定义,飞桨框架同时支持 map-style 和 iterable-style 两种类型的数据集定义,只需要分别继承 paddle.io.Dataset 和 paddle.io.IterableDataset 即可。】

二、网络构建

在网络构建模块,飞桨高层API与基础API保持一致,统一使用paddle.nn下的API进行组网。paddle.nn目录下包含了所有与模型组网相关的API,如卷积相关的Conv1D、Conv2D、Conv3D,循环神经网络相关的RNN、LSTM、GRU等。

对于组网方式,飞桨框架支持Sequential或SubClass进行模型组建。Sequential可以帮助我们快速的组建线性的网络结构,而SubClass支持更丰富灵活的网络结构。我们可以根据实际的使用场景,来选择最合适的组网方式。如针对顺序的线性网络结构可以直接使用Sequential ,而如果是一些比较复杂的网络结构,我们使用SubClass的方式来进行模型的组建,在__init__构造函数中进行Layer的声明,在forward中使用声明的Layer变量进行前向计算。

下面就来分别看一下Sequential与SubClass的实例。

1、Sequential 

对于线性的网络模型,我们只需要按网络模型的结构顺序,一层一层的加到Sequential后面即可,具体实现如下:

# Sequential 形式组网
mnist = nn.Sequential(
    nn.Flatten(),    
    nn.Linear(784, 512),    
    nn.ReLU(),    
    nn.Dropout(0.2),    
    nn.Linear(512, 10)
)

2、SubClass

使用SubClass进行组网的实现如下:

# SubClass 方式组网
class Mnist(nn.Layer):
    def __init__(self):    
        super(Mnist, self).__init__()


        self.flatten = nn.Flatten()
        self.linear_1 = nn.Linear(784, 512)        
        self.linear_2 = nn.Linear(512, 10)        
        self.relu = nn.ReLU()        
        self.dropout = nn.Dropout(0.2)


    def forward(self, inputs):
        y = self.flatten(inputs)        
        y = self.linear_1(y)        
        y = self.relu(y)        
        y = self.dropout(y)        
        y = self.linear_2(y)


        return y

上述的SubClass组网的结果与Sequential组网的结果完全一致,可以明显看出,使用 SubClass 组网会比使用Sequential更复杂一些。不过,这带来的是网络模型结构的灵活性。我们可以设计不同的网络模型结构来应对不同的场景。

3、飞桨框架内置模型

除了自定义模型结构外,飞桨框架还「贴心」的内置了许多模型,真正的一行代码实现深度学习模型。目前,飞桨框架内置的模型都是CV领域领域的模型,都在paddle.vision.models目录下,包含了常见的vgg系列、resnet系列等模型。使用方式如下:

import paddle
from paddle.vision.models import resnet18


# 方式一: 一行代码直接使用 
resnetresnet = resnet18()


# 方式二: 作为主干网络进行二次开发
class FaceNet(paddle.nn.Layer):
    def __init__(self, num_keypoints=15, pretrained=False):
        super(FaceNet, self).__init__()


        self.backbone = resnet18(pretrained)        
        self.outLayer1 = paddle.nn.Linear(1000, 512)        
        self.outLayer2 = paddle.nn.Linear(512, num_keypoints*2)


    def forward(self, inputs):        
         out = self.backbone(inputs)        
         out = self.outLayer1(out)        
         out = self.outLayer2(out)        
         return out

三、模型可视化

在我们完成模型的构建后,有时还需要可视化模型的网络结构与参数,只要我们用Model进行模型的封装后,然后调用model.summary即可实现网络模型的可视化,具体如下:

mnist = nn.Sequential(
    nn.Flatten(),    
    nn.Linear(784, 512),    
    nn.ReLU(),    
    nn.Dropout(0.2),    
    nn.Linear(512, 10))


# 模型封装,用 Model 类封装
model = paddle.Model(mnist)
model.summary()

其输出如下:

---------------------------------------------------------------------------
 Layer (type)       Input Shape          Output Shape         Param #    
 ===========================================================================
   Flatten-795    [[32, 1, 28, 28]]        [32, 784]              0         
    Linear-5         [[32, 784]]           [32, 512]           401,920       
     ReLU-3          [[32, 512]]           [32, 512]              0        
    Dropout-3        [[32, 512]]           [32, 512]              0          
    Linear-6         [[32, 512]]            [32, 10]            5,130     
    ===========================================================================
    Total params: 407,050
    Trainable params: 407,050
    Non-trainable params: 0
---------------------------------------------------------------------------
Input size (MB): 0.10
Forward/backward pass size (MB): 0.57
Params size (MB): 1.55
Estimated Total Size (MB): 2.22
---------------------------------------------------------------------------
{'total_params': 407050, 'trainable_params': 407050}

Model.summary不仅会给出每一层网络的形状,还会给出每层网络的参数量与模型的总参数量,非常方便直观的就可以看到模型的全部信息。

四、模型训练

1、使用高层API在全部数据集上进行训练

过去常常困扰深度学习开发者的一个问题是,模型训练的代码过于复杂,常常要写好多步骤,才能使程序运行起来,冗长的代码使许多开发者望而却步。

现在,飞桨高层API将训练、评估与预测API都进行了封装,直接使用 Model.prepare()、Model.fit()、Model.evaluate()、Model.predict()就可以完成模型的训练、评估与预测。

对比传统框架动辄一大块的训练代码。使用飞桨高层API,可以在3-5行内,完成模型的训练,极大的简化了开发的代码量,对初学者开发者非常友好。具体代码如下:

# 将网络结构用 Model 类封装成为模型
model = paddle.Model(mnist)


# 为模型训练做准备,设置优化器,损失函数和精度计算方式
model.prepare(optimizer=paddle.optimizer.Adam(parameters=model.parameters()),
              loss=paddle.nn.CrossEntropyLoss(),              
              metrics=paddle.metric.Accuracy())


# 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式
model.fit(train_dataset, 
         epochs=10,          
         batch_size=64,          
         verbose=1)


# 启动模型评估,指定数据集,设置日志格式
model.evaluate(test_dataset, verbose=1)


# 启动模型测试,指定测试集 
Model.predict(test_dataset)

2、使用高层API 在一个批次的数据集上训练、验证与测试

有时我们需要对数据按batch进行取样,然后完成模型的训练与验证,这时,可以使用train_batch、eval_batch、predict_batch完成一个批次上的训练、验证与测试,具体如下:

# 模型封装,用 Model 类封装
model = paddle.Model(mnist)


# 模型配置:为模型训练做准备,设置优化器,损失函数和精度计算方式
model.prepare(optimizer=paddle.optimizer.Adam(parameters=model.parameters()),
              loss=nn.CrossEntropyLoss(),              
              metrics=paddle.metric.Accuracy())


# 构建训练集数据加载器
train_loader = paddle.io.DataLoader(train_dataset, batch_size=64, shuffle=True)


# 使用 train_batch 完成训练
for batch_id, data in enumerate(train_loader()):
    model.train_batch([data[0]],[data[1]])


# 构建测试集数据加载器
test_loader = paddle.io.DataLoader(test_dataset, places=paddle.CPUPlace(), batch_size=64, shuffle=True)


# 使用 eval_batch 完成验证
for batch_id, data in enumerate(test_loader()):
    model.eval_batch([data[0]],[data[1]])


# 使用 predict_batch 完成预测
for batch_id, data in enumerate(test_loader()):
    model.predict_batch([data[0]])

五、高阶用法

除此之外,飞桨高层API还支持一些高阶的玩法,如自定义Loss、自定义Metric、自定义Callback等等。

自定义Loss是指有时我们会遇到特定任务的Loss计算方式在框架既有的Loss接口中不存在,或算法不符合自己的需求,那么期望能够自己来进行Loss的自定义。

自定义Metric和自定义Loss的场景一样,如果遇到一些想要做个性化实现的操作时,我们也可以来通过框架完成自定义的评估计算方法。

自定义Callback则是可以帮助我们收集训练时的一些参数以及数据,由于Model.fit()封装了训练过程,如果我们需要保存训练时的loss、metric等信息,则需要通过callback 参数收集这部分信息。

更多更丰富的玩法,可以扫描关注文末的二维码获取

高层API,Next

上文以CV 任务为例,介绍了飞桨框架高层API的使用指南。后续,飞桨框架还计划推出NLP领域专用的数据预处理模块,如对数据进行padding、获取数据集词表等;在组网方面,也会实现NLP领域中组网专用的API,如组网相关的 sequence_mask,评估指标相关的BLEU等;最后,针对NLP领域中的神器transformer,我们也会对其进行特定的优化;待这些功能上线后,我们会第一时间告诉大家,敬请期待吧!

高层API,Where

看完前面飞桨高层API的使用介绍,是不是有种跃跃欲试的冲动呀?

体验方式一:在线体验

无需准备任何软硬件环境,直接访问以下地址,即可在线跑代码看效果:https://aistudio.baidu.com/aistudio/projectdetail/1243085

体验方式二:本地体验

如果你还想在自己本地电脑上体验,那需要确保本地电脑上已成功安装飞桨开源框架 2.0。

下面介绍飞桨开源框架2.0的安装方法,可以参考下面的命令,直接使用pip安装。安装后,就可以开始使用高层API。

# CPU 版
$ pip3 install paddlepaddle==2.0.0rc0 -i https://mirror.baidu.com/pypi/simple
# GPU 版
$ pip3 install paddlepaddle_gpu==2.0.0rc0 -i https://mirror.baidu.com/pypi/simple

/End.

我们开创“计算机视觉协会”知识星球一年有余,也得到很多同学的认可,我们定时会推送实践型内容与大家分享,在星球里的同学可以随时提问,随时提需求,我们都会及时给予回复及给出对应的答复。

如果想加入我们“计算机视觉研究院”,请扫二维码加入我们。我们会按照你的需求将你拉入对应的学习群!

计算机视觉研究院主要涉及深度学习领域,主要致力于人脸检测、人脸识别,多目标检测、目标跟踪、图像分割等研究方向。研究院接下来会不断分享最新的论文算法新框架,我们这次改革不同点就是,我们要着重”研究“。之后我们会针对相应领域分享实践过程,让大家真正体会摆脱理论的真实场景,培养爱动手编程爱动脑思考的习惯!

后台回复“飞桨代码”

获取源码下载地址

计算机视觉研究院

长按扫描二维码关注我们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值