HelloPaddle01-从头搭建图像识别模型教程
Posted Charlotte数据挖掘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HelloPaddle01-从头搭建图像识别模型教程相关的知识,希望对你有一定的参考价值。
关注&置顶“Charlotte数据挖掘”
每日9:00,干货速递!
By Charlotte77
前言:本文属于付费征稿,作者为HelloGitHub组织,每两周更新一篇PaddlePaddle教程,写的非常详细,可以直接按照教程操作~有对PaddlePaddle感兴趣的同学们也可以投稿哦~
一、图像识别、Cifar-10、PaddlePaddle 简介
1.1 图像识别
计算机视觉领域最基础也是最简单的一项任务,目的就是识别一张图中的目标属于什么种类。
1.2 Cifar-10 数据集
Cifar-10 数据集,一个小型的公开的图像分类的数据集,是从一个数量较多的无标注的数据集TinyImage(小图) 标注而来,共分为10类,下图可以直观的看到图像和种类:
既然是从 TinyImage 而来,Cifar 数据集的图像尺寸是比较小的,高宽的尺寸为 32x32。从上图中也可以看出来,有些图肉眼已经很难分辨是什么。但是今天我们要让程序自己来识别每张图是什么。肉眼不易识别的图片通过程序来识别,听起来还是挺酷的。但是实现起来很简单,原理也通俗易懂,只要你对数学有一定的了解、会一些 Python 的编程基础,跟着我一步步编写和运行就可以实现了。
继续说 Cifar-10 数据集,整个数据集分为训练集和测试集:
训练集 50000 张图,每类 10000 张
测试集 10000张图,每类1000张
Python版本数据点击下载 来下载,下载好了解压,在数据文件夹 cifar-10-batches-py 可以看到训练集分为 5 个批次,分别为 data_batch[1-5],详细的信息可以通过 readme.html 来看到。
1.3 PaddlePaddle
百度研发并开源的一个深度学习框架,我上手后使用的整体感觉较 TensorFlow 好用、方便一些。但上手难度要高于 PyTorch。在官方介绍中 Paddle 对于大规模工业生产、大数据集环境具有较大优势。由于我们本系列的教程主要以上手 Paddle 为主,而且本机环境也不是多机多卡的环境,所以还没体验过大规模多机多卡的并行训练,就不再着重介绍这一块了。
在百度近些年的积累和开发迭代 Paddle的进程中, Paddle在各个人工智能方向提供的预训练资源相对比较丰富。尤其是 NLP 领域,其中ERNIE 在中文NLP 各项任务中更是超越Google 1 8年网红模型BERT,具体信息可以去 Paddle 官方仓库 查看。
Paddle 文档全面清晰,同时对新手还有一定的福利 —— “PaddlePaddle 用户可领取免费 Tesla V100 在线算力资源、高效训练模型,每日登陆即送 12 小时,连续 5 天运行再加送 48小时。”对于刚进入深度学习没有 GPU 资源的同学来说,可以说是十分人性化了。我出机器让你用 Paddle 也是看到了百度要把 Paddle 做好的决心。
总的来说 PaddlePaddle 作为百度官方主推和维护的深度学习框架,在项目维护、资源更新、框架升级等方面具有强大的保障。在此基础上 Paddle 在易用上、工业生产上、用户量等方面一定会更上一层楼。那么就让我们“笨鸟先飞”,跟随HelloPaddle 系列教程,体验下 Paddle 的魅力吧!
二、PaddlePaddle图像分类
OK.下面我们开始进入正题,使用Paddle搭建一个深度学习模型来实现图像分类。
图像分类一直是人工智能和模型识别领域重要的一项任务,那么该如何让机器自己能图像分类呢?
首先,我们需要对数字图像有一定的了解,数字图像本质上是由大量数字组成的像素矩阵,比如我们上面说的Cifar-10的每张图其实对机器来说便是一个(32,32,3)的矩阵,这个矩阵中并非所有数字都对机器有用,存在大量的冗余,那么我们可以对这个矩阵进行抽取关键信息,假设我们这是一个简单的分类任务,分类所需的变换只是线性的,即 *y=a1*x1+a2*x2..+b*,这里的x1,x2..是我们抽取的关键信息,而对于同一类图像,我们认为抽取到的关键信息是相似的,不同类的图像抽取的信息是不同的,极端一点,我们假设同一类图像抽取的关键信息都是相同的,那么对于同一映射关系*y=a1*x1+a2*x2..+b*,同一类的图得到的结果是相同的,不同类的图得到的结果是不同的,由此,机器便可以通过一个函数得到分类的结果。
从本质上来说,图像分类的原理就是如此简单,只不过关键信息提取不像我们说的这么简单,函数也并不是线性的变换关系而是更复杂,但是这并不妨碍我们这样理解。
接下来,我们进入实战,首先导入我们所需的一些python包:
import numpy as np
import cv2
import matplotlib.pyplot as plt
import pickle
import os
import sys
import paddle.fluid as fluid
from PIL import Image
接下来,我们定义刚刚下载并解压的Cifar-10的目录路径:
1data_dir ='/home/meteo/xibin.yue/paddle/data/cifar-10-batches-py'
接下来,要多说几句了,对于一个深度学习模型的实现,大概可以分为几个步骤:
准备数据并对数据做一些预处理,写一个可以将数据传入模型的模块,一般情况下各个框架都封装了数据加载以及预处理模块,Paddle也有,但我们今天要自己写一个数据加载模块来加深理解。
搭建模型,各个框架也有现成的各种模型和预训练参数
定义优化目标函数,通常在机器学习里叫做“损失函数” ,loss function或者cost
定义优化器。优化器的定义这方面,每个框架都进行了封装,我们只要调用就可以了,但是具体的超参数的设置和参数调整需要我们根据训练情况来定,同时大家需要去理解和掌握一些概念,最基础的包括学习率、正则化、优化方法(包括SGD,Adadelta,Adam等)
训练和应用。训练的过程便是机器学习的过程,机器学习好了会将这部分记忆存储下来,再应用的时候调取这部分记忆就可以进行处理各种问题了。
首先是数据加载模块:Paddle中定义了几种数据读取方式,最基础的为reader,在reader之上,Paddle封装了readercreator和reader decorator。readercreator给我们返回一个reader,readerdecorator可以组合多个reader,这个功能在做数据或者特征组合的时候应该很有用,后面如果用到会讲到。重点在这个reader,Paddle的reader本质上是一个迭代器,使用yield实现,python的yield不是特别了解的可以去看一下,我基本理解为是一个迭代的return。
接下来我们来定义一个CifarDataReader,它本质上类似于Paddle的reader creator。
数据加载模块
class CifarDataReader(object):
"""Cifar-10 Data Reader.
Provide a reader to read cifar 10 data iterable.
Attributes:
root_dir: root dir for cifar-10 data
data_property: data for train or for validation or test
cycle: if return data cyclic
"""
def __init__(self, root_dir, data_property='train', cycle=True):
self.root_dir = root_dir
self.data_property = data_property
self.cycle = cycle
def _load_cifar(self, data_path):
try:
data_dict = pickle.load(open(data_path, 'rb')) # cifar python data 是二进制格式,可以用pickle加载
raw_data = data_dict['data']
label_data = data_dict['labels']
batch_anno = data_dict['batch_label']
raw_data = raw_data.reshape(10000,3,32,32).astype(np.float32) / 255.
return raw_data, label_data, batch_anno
except Exception as e:
print e
def reader(self):
while True:
if self.data_property == 'train':
for batch_id in range(1, 6): # 训练集共5个批次
file_path = os.path.join(self.root_dir, 'data_batch_%d' % batch_id)
raw_data, label_data, batch_anno = self._load_cifar(file_path)
# print 'BATCH INFO - %s' % batch_anno.upper()
length = raw_data.shape[0]
for i in range(length):
yield raw_data[i], label_data[i]
if not self.cycle: #如果不使用cycle 读完一遍跳出
break
else:
file_path = os.path.join(self.root_dir, 'test_batch')
print file_path
raw_data, label_data, batch_anno = self._load_cifar(file_path)
# print 'BATCH INFO - %s' % batch_anno.upper()
length = raw_data.shape[0]
for i in range(length):
yield raw_data[i], label_data[i]
if not self.cycle:
break
下面我们其实可以测试一下我们定义的CifarDataReader:
1In [28]:
2
3demo_reader = CifarDataReader('/home/meteo/xibin.yue/paddle/data/cifar-10-batches-py',cycle=False)
4
5for item in demo_reader.reader():
6img = (item[0]* 255).transpose(1,2,0).astype(np.uint8)
7im = Image.fromarray(img)
8im.save('test_cv_channel.png') # 存一张备用
9print im.size
10plt.imshow(im)
11plt.show()
12break
output:
可以看到,可以成功迭代的获取到数据,你能看出这是张青蛙么[汗]。但是这里感觉需要讲下图像的通道顺序问题,由于cifar-10原始数据是以二进制数据存储,我们读进来直接进行了reshape,这里的reshape之后的通道顺序其实为RGB,所以我们在训练的过程中其实是按照RGB的顺序训练的,这一点与Caffe不
同,caffe的用户这里需要注意一下,因为caffe底层其实是用的cv2,cv2加载图像的通道顺序为BGR,而PIL的Image库中直接open的图像的顺序为RGB,因此在训练好模型之后进行inference的时候,如果用到cv2进行图像加载,需要将BGR转化为RGB,而如果用Image读取的话,不需要这一步操作。
下面展示了Image和cv2读取图像的不同之处:
1In [27]:
2
3img = cv2.imread('test_cv_channel.png')
4
5im = Image.fromarray(img)
6
7plt.imshow(im)
8
9plt.show()
10
11im2 = Image.open('test_cv_channel.png')
12
13plt.imshow(im2)
接下来我们用Paddle定义一个卷积神级网络,卷积神经网络-Convolutional NeuralNetwork,本质上是我们上面说的信息抽取模块,最早由两位生物学家提出,是一种一定意义上具有仿生学机理的网络,最初被用在视觉上,目前在语音以及NLP领域均有应用。卷积的概念也很早,在没有深度学习之前,做图像处理用到的各种算子、滤波器很多都是卷积操作。自Lecun提出Lenet之后,以及Hinton提出逐层初始化和训练,伴随着GPU和数据量的发展,深度学习飞速发展,因此也引领了这一波人工智能智能的浪潮。
卷积神经网络在前几年得到了长足的发展,包括网络结构的不断迭代优化、训练方法的优化、各种训练技巧等等,这里不再深入细讲了,讲起来就太多了。
在图像识别领域,由于早年ILSVRC比赛中ImageNet数据集,吸引了一批又一批的人提出了一个又一个经典的网络模型,如AlexNet、VGG、GoogleNet、ResNet、Densenet等等,识别准确率也一再被刷新。
今天我们用Paddle自己搭一个简单的网络,基本会用到卷积神经网络的主要操作,包括卷积、Pooling、Batch Noramlization、Dropout、FC、softmax等。
网络结构模块
def paddlenet(input):
def conv_block(ipt, num_filter, groups, dropouts):
return fluid.nets.img_conv_group(
input=ipt,
pool_size=2,
pool_stride=2,
conv_num_filter=[num_filter] * groups,
conv_filter_size=3,
conv_act='relu',
conv_with_batchnorm=True,
conv_batchnorm_drop_rate=dropouts,
pool_type='max') # 这里是Paddle官方封装的一个组合层,可以定义卷积参数,包括分组卷积、pooling参数、是否使用BN和Dropout 我们直接拿来用
conv1 = conv_block(input, 32, 1, [0.3])
conv2 = conv_block(conv1, 64, 1, [0.4])
conv3 = conv_block(conv2, 128, 1, [0.4]) # 这里不分组,只许设定一个drop比例 如果用分组的话 需要设置多个
fc1 = fluid.layers.fc(input=conv3, size=256, act=None)
fc2 = fluid.layers.fc(input=fc1, size=512, act=None)
predict = fluid.layers.fc(input=fc2, size=10, act='softmax')
return predict
上面我们没有用分组卷积,分组卷积或者channel之间的信息融合,大家可以去参考shufflenet以及后面的轻量化模型MobileNet等。其实分组卷积最早在AlexNet的时候就出现了,当时只是因为一块GPU无法完成训练,所以分在了两块GPU上,后面大家觉得channel之间需要进行信息共享和交换,便研究了各种分组卷积的模型。
下面是官网提供的vgg模型,大家可以作为参考。VGG模型大家也可以去网络学习一下。
1def vgg_bn_drop(input):
2 def conv_block(ipt, num_filter, groups, dropouts):
3 return fluid.nets.img_conv_group(
4 input=ipt,
5 pool_size=2,
6 pool_stride=2,
7 conv_num_filter=[num_filter] * groups,
8 conv_filter_size=3,
9 conv_act='relu',
10 conv_with_batchnorm=True,
11 conv_batchnorm_drop_rate=dropouts,
12 pool_type='max')
13
14conv1 = conv_block(input, 64, 2, [0.3, 0])
15conv2 = conv_block(conv1, 128, 2, [0.4, 0])
16conv3 = conv_block(conv2, 256, 3, [0.4, 0.4, 0])
17conv4 = conv_block(conv3, 512, 3, [0.4, 0.4, 0])
18conv5 = conv_block(conv4, 512, 3, [0.4, 0.4, 0])
19
20drop = fluid.layers.dropout(x=conv5, dropout_prob=0.5)
21fc1 = fluid.layers.fc(input=drop, size=512, act=None)
22bn = fluid.layers.batch_norm(input=fc1, act='relu')
23drop2 = fluid.layers.dropout(x=bn, dropout_prob=0.5)
24fc2 = fluid.layers.fc(input=drop2, size=512, act=None)
25predict = fluid.layers.fc(input=fc2, size=10, act='softmax')
26return predict
定义好了网络模型,我们定义一个前馈过程得到网络输出结果:
1def inference_network():
2data_shape = [3, 32, 32] #顺序为C-H-W
3images = fluid.layers.data(name='pixel', shape=data_shape, dtype='float32')
4predict = paddlenet(images)
5return predict
然后定义我们的优化目标,一般分类任务的优化目标都为最小化交叉熵损失(交叉熵损失不熟的同学,需要自行去了解),下面是代码:
1def train_network(predict):
2label = fluid.layers.data(name='label', shape=[1], dtype='int64')
3cost = fluid.layers.cross_entropy(input=predict, label=label)
4avg_cost = fluid.layers.mean(cost)
5accuracy = fluid.layers.accuracy(input=predict, label=label)
6return [avg_cost, accuracy]
接下来,我们定义优化器,包括优化方式、学习率、权重衰减等参数,Paddle官方给的是Adam方式,同时官网支持很多其他的方式,如Adadelta等,具体可以在Paddle优化方式查看。个人常用SGD,包含一些正则化项(weight decay),Paddle里面也支持加入一些正则化项,这里就不加了,优化器定义如下:
1def optimizer_program():
2 return fluid.optimizer.SGD(learning_rate=0.01)
上面我们定义了简单固定的学习率learning_rate=0.01,其实在训练过程中,固定学习率的方式无法寻找到最优点,因此会有很多学习率变化策略,Paddle里也给我们封装了一些,在learning_rate_schedule模块,后面我们可以讨论下这块。至此,我们的数据加载模块、模型、目标函数、优化器均已定义好,下面需要将他们串在一起,就可以训练了。
首先,我们定义使用GPU还是CPU,Paddle里这个变量基本都被命名为Place,意思大概是在哪里训练吧,但总感觉不如device更契合
1use_cuda = True
2place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
3BATCH_SIZE = 128下面我们来生成训练和测试用的data reader对象:
1train_cifar = CifarDataReader('/home/meteo/xibin.yue/paddle /data/cifar-10-batches-py',cycle=False)
2test_cifar = CifarDataReader('/home/meteo/xibin.yue/paddle/data/cifar-10-batches-py',data_property='test',cycle=False)
3
4# 这里的paddle.batch和paddle.reader.shuffle是在reader上层包装了一下 batch返回一批数据 shuffle是随机顺序
5train_reader = paddle.batch(paddle.reader.shuffle(train_cifar.reader,buf_size=10000),batch_size = BATCH_SIZE)
6test_reader = paddle.batch(test_cifar.reader,batch_size = BATCH_SIZE)
1feed_order = ['pixel', 'label']
2
3main_program = fluid.default_main_program()
4start_program = fluid.default_startup_program()# 这里类似于 TensorFlow里的Graph 具体的还没有深入看
5
6main_program.random_seed = 90
7start_program.random_seed = 90
8
9# 前馈
10predict = inference_network()
11avg_cost, acc = train_network(predict)
12
13test_program = main_program.clone(for_test=True)
14
15optimizer = optimizer_program()
16optimizer.minimize(avg_cost)
17
18exe = fluid.Executor(place)
19
20# 训练轮数
21EPOCH_NUM = 10
1# 这里定义一个在训练过程中测试集准确率的模块
2def train_test(program, reader):
3count = 0
4feed_var_list = [program.global_block().var(var_name) for var_name in feed_order]
5feeder_test = fluid.DataFeeder(feed_list=feed_var_list, place=place)
6test_exe = fluid.Executor(place)
7accumulated = len([avg_cost, acc]) * [0]
8for tid, test_data in enumerate(reader()):
9 avg_cost_np = test_exe.run(program=program,feed=feeder_test.feed(test_data),fetch_list=[avg_cost, acc])
10 accumulated = [x[0] + x[1][0] for x in zip(accumulated, avg_cost_np)]
11 count += 1
12return [x / count for x in accumulated]
2def train_loop():
3feed_var_list_loop = [main_program.global_block().var(var_name) for var_name in feed_order]
4feeder = fluid.DataFeeder(feed_list=feed_var_list_loop, place=place)
5exe.run(start_program)
6
7step = 0
8for pass_id in range(EPOCH_NUM): # 这里的pass_id 便是epoch
9 for step_id, data_train in enumerate(train_reader()):
10 avg_loss_value = exe.run(main_program,feed=feeder.feed(data_train),fetch_list=[avg_cost, acc])
11 if step_id % 100 == 0:
12 print("
Pass %d, Batch %d, Cost %f, Acc %f" %
13 (pass_id, step_id,avg_loss_value[0], avg_loss_value[1]))
14 else:
15 sys.stdout.write('.')
16 sys.stdout.flush()
17 step += 1
18
19 avg_cost_test, accuracy_test = train_test(test_program, reader=test_reader)
20 print('
Test with Pass {0}, Loss {1:2.2}, Acc {2:2.2}'.format(pass_id, avg_cost_test, accuracy_test))
21
22
23 fluid.io.save_inference_model('../weights', ["pixel"],[predict], exe) # 保存参数
24
25 if pass_id == EPOCH_NUM - 1:
26 print("kpis train_cost %f" % avg_loss_value[0])
27 print("kpis train_acc %f" % avg_loss_value[1])
28 print("kpis test_cost %f" % avg_cost_test)
29 print("kpis test_acc %f" % accuracy_test)
下面是输出结果:
1train_loop()
2
3Pass 0, Batch 0, Cost 3.474087, Acc 0.140625
4...................................................................................................
5Pass 100, Batch 0, Cost 1.813744, Acc 0.421875
6...................................................................................................
7Pass 200, Batch 0, Cost 1.573293, Acc 0.367188
8...................................................................................................
9Pass 300, Batch 0, Cost 1.641935, Acc 0.351562
10........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
11
12Test with Pass 0, Loss 1.9, Acc 0.28
13
14Pass 0, Batch 1, Cost 1.620478, Acc 0.398438
15...................................................................................................
16Pass 100, Batch 1, Cost 1.602701, Acc 0.421875
17...................................................................................................
18Pass 200, Batch 1, Cost 1.376074, Acc 0.492188
19...................................................................................................
20Pass 300, Batch 1, Cost 1.400322, Acc 0.507812
21........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
22
23Test with Pass 1, Loss 1.8, Acc 0.35
24
25Pass 0, Batch 2, Cost 1.518327, Acc 0.453125
26...................................................................................................
27Pass 100, Batch 2, Cost 1.464380, Acc 0.507812
28 ..................................................................................................
29Pass 200, Batch 2, Cost 1.274296, Acc 0.523438
30 ...................................................................................................
31Pass 300, Batch 2, Cost 1.457271, Acc 0.437500
32........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
33
34Test with Pass 2, Loss 1.7, Acc 0.39
35
36Pass 0, Batch 3, Cost 1.388974, Acc 0.484375
37...................................................................................................
38Pass 100, Batch 3, Cost 1.184492, Acc 0.593750
39...................................................................................................
40Pass 200, Batch 3, Cost 1.370192, Acc 0.476562
41...................................................................................................
42Pass 300, Batch 3, Cost 1.327766, Acc 0.609375
43........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
44
45 Test with Pass 3, Loss 1.8, Acc 0.34
46
47 Pass 0, Batch 4, Cost 1.470855, Acc 0.500000
48...................................................................................................
49Pass 100, Batch 4, Cost 1.296775, Acc 0.562500
50...................................................................................................
51Pass 200, Batch 4, Cost 1.268556, Acc 0.531250
52...................................................................................................
53Pass 300, Batch 4, Cost 1.146190, Acc 0.593750
54........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
55
56Test with Pass 4, Loss 1.6, Acc 0.44
57
58Pass 0, Batch 5, Cost 1.108460, Acc 0.656250
59...................................................................................................
60Pass 100, Batch 5, Cost 1.362371, Acc 0.492188
61...................................................................................................
62Pass 200, Batch 5, Cost 1.284810, Acc 0.515625
63...................................................................................................
64Pass 300, Batch 5, Cost 1.169709, Acc 0.601562
65........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
66
67Test with Pass 5, Loss 1.6, Acc 0.46
68
69Pass 0, Batch 6, Cost 1.276461, Acc 0.523438
70...................................................................................................
71Pass 100, Batch 6, Cost 1.149449, Acc 0.546875
72...................................................................................................
73Pass 200, Batch 6, Cost 1.262985, Acc 0.507812
74...................................................................................................
75 Pass 300, Batch 6, Cost 1.390151, Acc 0.539062
76........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
77
78Test with Pass 6, Loss 1.6, Acc 0.39
79
80Pass 0, Batch 7, Cost 1.289596, Acc 0.546875
81...................................................................................................
82Pass 100, Batch 7, Cost 1.213763, Acc 0.507812
83...................................................................................................
84Pass 200, Batch 7, Cost 1.081227, Acc 0.656250
85...................................................................................................
86Pass 300, Batch 7, Cost 0.916016, Acc 0.710938
87........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
88
89Test with Pass 7, Loss 1.6, Acc 0.46
90
91Pass 0, Batch 8, Cost 1.269660, Acc 0.554688
92...................................................................................................
93Pass 100, Batch 8, Cost 1.135844, Acc 0.609375
94...................................................................................................
95Pass 200, Batch 8, Cost 1.377947, Acc 0.562500
96...................................................................................................
97Pass 300, Batch 8, Cost 1.230803, Acc 0.523438
98........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
99
100Test with Pass 8, Loss 1.6, Acc 0.45
101
102Pass 0, Batch 9, Cost 1.196927, Acc 0.546875
103...................................................................................................
104Pass 100, Batch 9, Cost 1.078637, Acc 0.671875
105...................................................................................................
106Pass 200, Batch 9, Cost 1.040397, Acc 0.625000
107...................................................................................................
108Pass 300, Batch 9, Cost 1.370309, Acc 0.468750
109........................................................................................../home/meteo/xibin.yue/paddle/data/cifar-10-batches-py/test_batch
110
111Test with Pass 9, Loss 1.6, Acc 0.4
112kpis train_cost 1.278773
113kpis train_acc 0.587500
114kpis test_cost 1.620999
115kpis test_acc 0.399328
训练完毕后,我们就要看下训练的效果了,由于上面模型是我们随意搭建的,所以准确率不是特别高,这不重要,重要的是大家一起走完整个流程。好的,下面我们来写inference阶段代码,也就是给一张图,让机器识别这张图属于什么种类,当然给的图最好是我们训练的10类之中的图,如果不是的话就涉及到另外一个问题了无样本学习,这里我们不进行讨论。
1def load_image(infer_file):
2im = Image.open(infer_file)
3im = im.resize((32, 32), Image.ANTIALIAS)
4
5im = np.array(im).astype(np.float32)
6im = im.transpose((2, 0, 1)) # CHW
7im = im / 255.0
8im = np.expand_dims(im, axis=0)
9return im
1def infer(params_dirname=None):
2from PIL import Image
3place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
4exe = fluid.Executor(place)
5inference_scope = fluid.core.Scope()
6
7img = load_image('test_cv_channel.png')
8
9with fluid.scope_guard(inference_scope):
10 [inference_program, feed_target_names,fetch_targets] = fluid.io.load_inference_model(params_dirname, exe)
11 inference_transpiler_program = inference_program.clone()
12
13 # 这里我感觉我要多说一点,因为我在官方文档没有看到对这一块的讲解。这一块其实是Paddle对前馈过程的一个转译,包括将卷积层和BN层的融合,
14 # BN层和relu层的融合,提前对卷积参数做BN操作的处理,在前馈过程中就不再需要进行BN,主要目的是为了加速,我之前测过caffe的,提前将
15 # BN融合到卷积参数可以大幅提高速度,但是caffe需要自己做一步操作merge bn,而Paddle官方进行了封装,这一点很赞。
16 t = fluid.transpiler.InferenceTranspiler()
17 t.transpile(inference_transpiler_program, place)
18
19
20 results = exe.run(
21 inference_program,
22 feed={feed_target_names[0]: img},
23 fetch_list=fetch_targets)
24
25 transpiler_results = exe.run(
26 inference_transpiler_program,
27 feed={feed_target_names[0]: img},
28 fetch_list=fetch_targets)
29
30 # 这里做了个比较 证明转译前和转译后结果一致
31 assert len(results[0]) == len(transpiler_results[0])
32 for i in range(len(results[0])):
33 np.testing.assert_almost_equal(results[0][i], transpiler_results[0][i], decimal=5)
34
35 # infer label
36 label_list = [
37 "airplane", "automobile", "bird", "cat", "deer", "dog", "frog",
38 "horse", "ship", "truck"
39 ]
40
41 print("infer results: %s" % label_list[numpy.argmax(results[0])])
好了,上面定义好了我们的推断模块,下面我们运行一下,用到的图就是我们上面存下来的那只青蛙,让我们来看下结果:
1import numpy
2infer('../weights')!output:
infer results: frog
好的,机器已经识别出这是只青蛙了,哈哈,朋友们,下期再会!
-点击右下角 告诉大家你“在看”-
以上是关于HelloPaddle01-从头搭建图像识别模型教程的主要内容,如果未能解决你的问题,请参考以下文章