当前位置:网站首页 > 今日头条 > 正文

蜻蜓,根底入门,怎样用PaddlePaddle高雅地写VGG与ResNet,南通市

admin 0

图画比较文字能够供给愈加生动、简略了解及更具艺术感的信息,图画分类是依据图画的语义信息将不同类别图画区别开来,是图画检测、图画切割、物体盯梢、行为剖析等其他高层视觉使命的基础。图画分类在安防、交通、互联网、医学等范畴有着广泛的运用。

一般来说,图画分类通过手艺提取特征或特征学习办法对整个图画进行悉数描绘,然后运用分类器判别物体类别,因而怎么提取图画的特征至关重要。根据深度学习的图画分类办法,能够通过有监督或无监督的办法学习层次化的特征描绘,然后替代了手艺规划或挑选图画特征的作业。

深度学习模型中的卷积神经网络(Convolution Neural Network, CNN) 直接运用图画像素信息作为输入,最大程度上保留了输入图画的一切信息,通过卷积操作进行特征的提取和高层笼统,模型输出直接是图画辨认的成果。这种根据"输入-输出"直接端到端的学习办法取得了非常好的作用。

本教程首要介绍图画分类的深度学习模型,以及怎么运用PaddlePaddle在CIFAR10数据集上快速完结CNN模型。

项目地址:

http://paddlepaddle.org/documentation/docs/zh/1.3/beginners_guide/basics/image_classification/index.html

夜色如澜

根据ImageNet数据集练习的更多图画分类模型,及对应的预练习模型、finetune操作详情请参照Github:

https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/image_classification/README_cn.md

图画分类包括通用图画分类、细粒度图画分类等。图1展现了通用图画分类作用,即模型能够正确辨认图画上的首要物体。

图1. 通用图画分类展现

图2展现了细粒度图画分类-花卉辨认的作用,要求模型能够正确辨认花的类别。

图2. 细粒度图画分类展现

一个好的模型既要对不同类别辨认正确,一起也应该六年级女孩能够对不同视角、光照、布景、变形或部分遮挡的图画正确辨认(这儿咱们共同称作图画扰动)。图3展现了一些图画的扰动,较好的模型会像聪明的人类相同能够正确辨认。

图3. 扰动图片展现[7]

传统CNN包括卷积层、全衔接层等组件,并选用softmax多类别分类器和多类穿插熵丢失函数,一个典型的卷积神经网络如图4所示,咱们先介绍用来结构CNN的常见组件。

图4. CNN网络示例[5]

• 卷积层(convolution layer): 履行卷积操作提取底层到高层的特征,发掘出图片部分相关性质和空间不变性质。

• 池化层(pooling layer): 履行降采样操作。通过取卷积输出特征图中部分区块的最大值(max-pooling)或许均值(avg-pooling)。降采样也是图画处理中常见的一种操作,能够过滤掉一些不重要的高频信息。

• 全衔接层(fully-connected layer,或许fc layer): 输入层到躲藏层的神经元是悉数衔接的。

• 非线性改变: 卷积层、全衔接层后边一般都会接非线性改变函数,例如Sigmoid、Tanh、ReLu等来增强网络的表达才能,在CNN里最常运用的为ReLu激活函数。

• Dropout [1] : 在模型练习阶段随机让一些隐层节点权重不作业,进步网络的泛化才能,必定程度上避免过拟合。

接下来咱们首要介绍VGG,ResNet网络结构。

1、VGG

牛津大学VGG(Visual Geometry Group)组在2014年ILSVRC提蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市出的模型被称作VGG模型[2] 。该模型比较以往模型进一步加宽和加深了网络结构,它的中心是五组卷积操作,每两组之间做Max-Pooling空间降维。同一组内选用屡次接连的3X3卷积,卷积核的数目由较浅组的64增多到最深组的512,同一组内的卷积核数目是相同的。卷积之后接两层全衔接层,之后是分类层。因为每组内卷积层的不同,有11、13、16、19层这几种模型,下图展现一个16层的网络结构。

VGG模型结构相对简练,提出之后也有许多文章根据此模型进行研究,如在ImageNet上初次揭露超过人眼辨认的模型[4]便是学习VGG模型的结构。

图5. 根据ImageNet的VGG16模型

2、ResNet

ResNet(Residual Network) [3] 是2015年ImageNet图画分类、图画物体定位和图画物体检测竞赛的冠军。针对跟着网络练习加深导致准确度下降的问题,ResNet提出了残差学习办法来减轻练习深层网络的困难。在已有规划思路(BN, 小卷积核,全卷积网络)的基础上,引进了残差模块。每个残差模块包括两条途径,其间一条途径是输入特征的直连通路,另一条途径对该特征做两到三次卷积操作得到该特征的残差,终究再将两条途径上的特征相加。

残差模块如图7所示,左面是根本模块衔接办法,由两个输出通道数相同的3x3卷积组成。右边是瓶颈模块(Bottleneck)衔接办法,之所以称为瓶颈,是因为上面的1x1卷积用来降维(图示例即256->64),下面的1x1卷积用来升维(图示例即64->256),这样中心3x3卷积的输入和输出通道数都较小(图示例即64->64)。

图7. 残差模块

3、数据预备

因为ImageNet数据集较大,下载和练习较慢,为了便利咱们学习,咱们运用CIFAR10数据集。CIFAR10数据集包括60,000张32x32的五颜六色图片,10个类别,每个类包括6,000张。其间50,000张图片作为练习集,10000张作为测验集。图11从每个类别中随机抽取了10张图片,展现了一切的类别。

图11. CIFAR10数据集[6]

Paddle API供给了主动加载cifar数据集模块paddle.dataset.cifar。

通过输入python train.py,就能够开端练习模型了,以下末节将具体介绍train.py的相关内容。

1、Paddle 初始化

让咱们从导入Paddle Fluid API 和辅佐模块开端。

from __future__ import print_function

import os

import paddle

import paddle.fluidas fluid

import numpy

import sys

from vgg import vgg_bn_drop

from resnet import resnet_cifar10

本教程中咱们供给了VGG和ResNet两个模型的装备。

2、VGG

首要介绍VGG模型结构,因为CIFAR10图片巨细和数量比较ImageNet数据小许多,因而这儿的模型针对CIFAR10数据做了必定的适配。卷积部分引进了BN和Dropout操作。VGG中心模块的输入是数据层,vgg_bn_drop界说了16层VGG结构,每层卷积后边引进BN层和Dropout层,具体的界说如下:

def vgg_bn_drop(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')

conv1= conv_block(input霍军慕安冉, 64, 2, [0.3, 0])

conv2= conv_block(conv1, 128, 2, [0.4, 0])

conv3= conv_block(conv2, 256, 3, [0.4, 0.4, 0])

conv4= conv_block(conv3, 512, 3, [0.4, 0.4, 0])

conv5= conv_block(conv4, 512, 3, [0.4, 0.4, 0])

drop= fluid.layers.dropout(x=conv5, dropout_prob=0.5)

fc1= fluid.layers.fc(input=drop, size=512, act=None)

bn= fluid.layers.batch_norm(input=fc1, act='relu')

drop2= fluid.layers.dropout(x=bn, dropout_prob=0.5)

fc2= fluid.layers.fc(input=drop2, size=512, act=None)

predict= fluid.layers.fc(input=fc2, size=10, act='softmax')

return predict

首要界说了一组卷积网络,即conv_block。卷积核巨细为3x3,池化窗口巨细为2x2,窗口滑动巨细为2,groups决议每组VGG模块是几回接连的卷积操作,dropouts指定Dropout操作的概率。所运用的img_conv_group是在paddle.fluit.net中预界说的模块,由若干组Conv->BN->ReLu->Dropout 和一组Pooling 组成。

五组卷积操作,即5个conv_block。榜首、二组选用两次接连的卷积操作。第三、四、五组选用三次接连的卷积操作。每组终究一个卷积后边Dropout概率为0,即不运用Dropout操作。

终究接两层512维的全衔接。

在这儿,VGG网络首要提取高层特征,随后在全衔接层中将其映射到和类别维度巨细共同的向量上,终究通过Softmax办法核算图片划为每个类其他概率。

3、ResNet

ResNet模型的第1、3、4步和VGG模型相同,这儿不再介绍。首要介绍第2步即CIFAR10数据集上ResNet中心模块。

先介绍resnet_cifar10中的一些根本函数,再介绍网络衔接进程。

• conv_bn_layer: 带BN的卷积层。

• shortcut: 残差模块的"直连k990"途径,"直连"实践分两种方式:残差模块输入和输出特征通道数不等时,选用1x1卷积的升维操作;残差模块输入和输出通道持平时,选用直连操作。

• basicblock: 一个基础残差模块,即图9左面所示,由两组3x3卷积组成的途径和一条"直连"途径组成。

• layer_warp: 一组残差模块,由若干个残差模块堆积而成。每组中榜首个残差模块滑动窗口巨细与其他能够不同,以用来削减特征图在笔直和水平方向的巨细。

def conv_bn_layer(input,

ch_out,

filter_size,

stride,

padding,

act='relu',

bias_attr=False):

tmp= fluid.layers.conv2d(

input=input,

filter_size=filter_size,

num_filters=ch_out,

stride=stride,

padding=padding,第九区ss账号

act=None,

bias_attr=bias_attr)

return fluid.layers.batch_norm(input=tmp, act=act)

def shortcut(input, ch_in, ch_out, stride):

if ch_in!= ch_out:

return conv_bn_layer(input, ch_out, 1, stride, 0, None)

else:

return input

def basicblock(input, ch_in, ch_out, stride):

tmp= conv_bn_layer(input, ch_out, 3, stride, 1)

tmp= conv_bn_layer(tmp, ch_out, 3, 1, 1, act=None, bias_attr=True)

short= shortcut(input, ch_in, ch_out, stride)

return fluid.layers.elementwise_add(x=tmp, y=short, act='relu')

def layer_warp(block_func, input, ch_in, ch_out, count, stride):

tmp= block_func(input, ch_in, ch_out, stride)

for iin range安染顾天俊免费全集(1, count):

tmp= block_func(tmp, ch_out, ch_out, 1)

return tmp

resnet_cifar10的衔接结构首要有以下几个进程。

底层输入衔接一层conv_bn_layer,即带BN的卷积层。

然后衔接3组残差模块即下面装备3组layer_warp,每组选用图10 左面残差模块组成。

终究对网络做均值池化并回来该层。

留意:除榜首层卷积层和终究一层全衔接层之外,要求三组layer_warp总的含参层数能够被6整除,即resnet_cifar10的depth 要满意(depth - 2) % 6 = 0

def resnet_cifar10(ipt, depth=32):

# depth should be one of 20, 32, 44, 56, 110, 1202

assert (depth- 2) % 6== 0

n= (depth- 2) // 6

nStages= {16, 64, 128}

conv1= conv_bn_layer(ipt, ch_out=16, filter_size=3, stride=1, padding=1)

res1= layer_warp(basicblock, conv1, 16, 16, n, 1)

res2= layer_warp(basicblock, res1, 16, 32, n, 2)

res3= layer_warp(basicblock, res2, 32, 64, n, 2)

pool= fluid.layers.pool2d(

input=res3, pool_size=8, pool_type='avg', pool_stride=1)

predict= fluid.layers.fc(input=pool, size=10, act='softmax')

return predict

4、Infererence装备

网络输入界说为data_layer(数据层),在图画分类中即为图画像素信息。CIFRAR10是RGB 3通道32x32巨细的五颜六色图,因而输入数据巨细为3072(3x32x32)。

def inference_network():

# The image is 32 * 32 with RGB representation.

data_shape = [3, 32, 32]

images = fluid.layers.data(name='pixel', shape=data_shape, dtype='float32')

predict = resnet_cifar10(images, 32)

# predict = vgg_bn_drop(images) # un-comment to use vgg net

return predict

5、Train 装备

然后咱们需求设置练习程序train_network。它首要从推理程序中进行猜测。钟二郎吃鬼在练习期间,它将从猜测中核算avg_cost。在有监督练习中需求输入图画对应的类别信息,相同通过fluid.layers.data来界说。练习中选用多类穿插熵作为丢失函数,并作为网络的输出,猜测阶段界说网络的输出为分类器得到的概率信息。

留意:练习程序应该回来一个数组,榜首个回来参数有必要是avg_cost。练习器运用它来核算梯度。

def train_network(predict):

label = fluid.layers.data(name='label', shape=[1], dtype='int64')

cost = fluid.layers.cross_entropy(input=predict, label=label)

avg_cost = fluid.layers.mean(cost)

accuracy = fluid.layers.accuracy(input=predict, label=label)

return [avg_cost, accuracy]

6、Optimizer 装备

鄙人面的Adam optimizer,learning_rate是学习率,与网络的练习收敛速度有联系。

def optimizer_program():

return fluid.optimizer.Adam(learning_rate=0.001)

7、练习模型

-1)Data Feeders 装备

cifar.train10()每次发生一条样本,在完结shuffle和batch之后,作为练习的输入。

# Each batch will yield 128 images

BATCH_SIZE= 128

# Reader for training

train_reader = paddle.batch(

paddle.reader.shuffle(

paddle.dataset.cifar.train10(), buf_size=128 * 100),

batch_size=BATCH_SIZE)

# Reader for test金三角雇佣兵ing. A separated data set for testing.

test_reader = paddle.batch(

paddle.dataset.cifar.test10(), batch_size=BATCH_SIZE)

-2)Trainer 程序的完结

咱们需求为练习进程拟定一个main_program, 相同的,还需求为测验程序装备一个test_progra蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市m。界说练习的place,并运用从前界说的优化器。

place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()

feed_order = ['pixel', 'label']

main_program =猩猩生殖器 fluid.default_main_program()

star_program = fluid.default_startup_program()

predict = inference_network()

avg_cost, acc = train_network(predict)

# Test program

test_program = main_program.clone(for_test=True)

optimizer = optimizer_program()

optimizer.minimize(avg_cost)

exe = fluid.Executor(蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市place)

EPOCH_大八粒NUM = 1

# For training test cost

def train_test(program, reader):

count = 0

feed_var_list = [

program.global_block().var(var_name) for var_name in feed_order

]

feeder_test = fluid.DataFeeder(feed_list=feed_var_list, place=place)

test_exe = fluid.Executor(place)

accumulated = len([avg_cost, acc]) * [0]

for tid, test_data in enumerate(reader()):

avg_cost_np = test_exe.run(

program=progratinglesm,

feed=feeder_test.feed(test_data),

fetch_list=[avg_cost, acc])

accumulated = [

x[0] + x[1][0] for x in zip(accumulated, avg_cost_np)

]

count += 1

return [x / count for x in accumulated]

-3)练习主循环以及进程输出

在接下来的主练习循环中,咱们将通过输出来来调查练习进程,或进行测验等。

# main train loop.

def train_loop():

feed_var_list_loop = [

main_program.global_block().var(var_name) for var_name in feed_order

]

feeder = 德古拉元年2不拍了fluid.DataFeeder(feed_list=feed_var_list_loop, place=place)

exe.run(star_program)

step = 0

for pass_id in range(EPOCH_NUM):

for step_id, data_train in enumerate(train_reader()):

avg_loss_value = exe.run(

main_program,

feed=feeder.feed(data_train),

fetch_list=[avg_cost, acc])

if step_id % 100 == 0:

print("

Pass %d, Batch %d, Cost %f, Acc %f" % (

step_id, pass_id, avg_loss_value[0], avg_loss_value[1])阑鬼坊)

else:

sys.stdout.write('.')

sys.stdout电影还魂砂.flush()

step += 1

avg_cost_test, accuracy_test = train_test(

test_program, reader=test_reader)

print('

Test with Pass {0}, Loss {1:2.2}, Acc {2:2.2}'.format(

pass_id, avg_蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市cost_test, accuracy_test))

if params_dirname is not None:

fluid.io.save_inference_model(params_dirname, ["pixel"],

[predict], exe)

train_loop()

-4)练习

通过trainer_loop函数练习, 这儿咱们只进行了2个Epoch赵人乞猫, 一般绝色引诱咱们在实践运用上会履行上百个以上Epoch

留意:CPU,每个Epoch 将花费大约15~20分钟。这部分或许需求一段时间。请随意修正代码,在GPU上运转测验,以进步练习速度。

train_loop()

一轮练习log示例如下所示,通过1个pass,练习集上均匀Accuracy 为0.59 ,测验集上均匀Accuracy 为0.6 。

Pass 0, Batch 0, Cost 3.869598, Acc 0.164062

...................................................................................................

Pass 100, Batch 0, Cost 1.481038, Acc 0.460938

...................................................................................................

Pass 200, Batch 0, Cost 1.340323, Acc 0.523438

...................................................................................................

Pass 300, Batch 0, Cost 1.223424, Acc 0.593750

..........................................................................................

Test with Pass 0, Loss 1.1, Acc 0.6

图13是练习的分类错误率曲线图,运转到第200个pass后根本收敛,终究得到测验集上分类错误率为8.54%。

图13. CIFAR10数据集上VGG模型的分类错误率

能够运用练习好的模型对图片进行分类,下面程序展现了怎么加载现已练习好的网络和参数进行揣度。

1、生成猜测输入数据

dog.png是一张小狗的图片. 咱们将它转换成numpy数组以满意feeder的格局.

from PIL import Image

def load_image(infer_file):

im = Image.open(infer_file)

im = im.resize((32, 32), Image.ANTIALIAS)

im = numpy.array(im).astype(numpy.float32)

# The storage order of the loaded image is W(width),

# H(height), C(channel). PaddlePaddle requires

# the CHW order, so transpose them.

im = im.tr杨伟中死了anspose((2, 0, 1)) # CHW

im = im / 255.0

# Add one dimension to mimic the list format.

im = numpy.expand_dims(im, axis=0)

return im

cur_dir = os.path.dirname(os.path.realpath(__file__))

img = load_image(cur_dir + '/image/dog.png')

2、Inferencer 装备和猜测

与练习进程相似,inferencer需求构建相应的进程。咱们从params_dirname加载网络和通过练习的参数。咱们能够简略地刺进前面界说的推理程序。现在咱们预备做猜测。

place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()

exe = fluid.Executor(place)

inference_scope = fluid.core.Scope()

with fluid.scope_guard(inference_scope):

# Use fluid.io.load_inference_model to obtain the inference program desc,

# the feed_target_names (the names of variables that will be feeded

# data using feed operators), and the fetch_targets (variables that

# we want to obtain data from using fetch operators).

[inference_program, feed_target_names,

fetch_targets] = fluid.io.富士山简笔画load_inference_model(params_dirname, exe)

# The input's dimension of conv should be 4-D or 5-D.

# Use inference_transpiler to speedup

inference_transpiler_program = inference_program.clone()

t = fluid.transpiler.InferenceTranspiler()

t.transpile(inference_transpiler_program, place)

# Construct feed as a dictionary of {feed_target_name: feed_target_data}

# and results will contain a list of data corresponding to fetch_targets.

results = exe.run(

inference_program,

feed={feed_target_names[0]: img},

fetch_list=fetch_targets)

transpiler_results = exe.run(

inference_transpiler_program,

feed={feed_target_names[0]: img},

fet蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市ch_list=fetch_targets)

assert len(results[0]) == len(transpiler_results[0])

for i in range(len(results[0])):

numpy.testing.assert_almost_equal(

results[0][i], transpiler_results[0][i], decimal=5)

# infer label

label_list = [

"airplane", "automobile", "bird", "cat", "deer", "dog", "frog",

"horse", "ship", "truck"

]

print("inf蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市er results: %s" % label_list[numpy.argmax(results[0])])

总结

传统图画分类办法由多个阶段构成,结构较为杂乱,而端到端的CNN模型结构可一步到位,并且大幅度提升了分类准确率。本文咱们首要介绍VGG、ResNet两个经典的模型;蜻蜓,基础入门,怎样用PaddlePaddle典雅地写VGG与ResNet,南通市然后根据CIFAR10数据集,介绍怎么运用PaddlePaddle装备和练习CNN模型;终究介绍怎么运用PaddlePaddle的API接口对图片进行猜测和特征提取。关于其他数据集比方ImageNet,装备和练习流程是相同的。请参照Github

https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/image_classification/README_cn.md。

参考文献

[1] G.E. Hinton, N. Srivastava, A. Krizhevsky, I. Sutskever, and R.R. Salakhutdinov. Improving neural networks by preventing co-adaptation of feature detectors. arXiv preprint arXiv:1207.0580, 2012.

[2] K. Chatfield, K. Simonyan, A. Vedaldi, A. Zisserman. Return of the Devil in the Details: Delving Deep into Convolutional Nets. BMVC, 2014。

[3] K. He, X. Zhang, S. Ren, J. Sun. Deep Residual Learning for Image Recognition. CVPR 2016.

[4] He, K., Zhang, X., Ren, S., and Sun, J. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification. ArXiv e-prints, February 2015.

[5] http://deeplearning.net/tutorial/lenet.html

[6] https://www.cs.toronto.edu/~kriz/cifar.html

[7] http://cs231n.github.io/classification/

声明:该文观念仅代表作者自己,搜狐号系信息发布渠道,搜狐仅供给信息存储空间效劳。