用ipad怎么写python,paddle怎么用
概述图像比文本更清晰、更容易理解,并提供更多的艺术信息。图像分类是指根据语义信息区分不同类别的图像。这包括图像检测、图像分割、对象跟踪、行为分析等。高层次视觉任务的基础知识。图像分类广泛应用于安全、交通、互联网、医学等领域。
一般来说,图像分类是通过手动特征提取或特征学习技术来完整地描述整个图像,并使用分类器来确定对象的类别,因此如何提取图像的特征很重要。基于深度学习的图像分类方法可以以有监督或无监督的方式学习层次特征描述,取代人工设计或选择图像特征。
深度学习模型卷积神经网络(CNN)直接使用图像像素信息作为输入,最大限度地保留输入图像的所有信息,通过卷积运算进行特征提取和高级抽象,输出模型。这是图像识别的直接结果。这种基于“输入-输出”的直接端到端学习方法取得了非常好的效果。
本教程主要介绍图像分类的深度学习模型以及如何使用PaddlePaddle在CIFAR10数据集上快速实现CNN模型。
项目地址:
http://paddlepaddle.org/documentation/docs/en/1.3/beginners_guide/basics/image_classification/index.html
有关在ImageNet 数据集上训练的其他图像分类模型、相应的预训练模型和微调操作的更多信息,请访问Github。
https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/image_classification/README_cn.md
效果图像分类包括一般图像分类、详细图像分类等。图1展示了典型的图像分类效果。这意味着该模型可以准确识别图像上的关键对象。
图1. 典型图像分类显示
图2 显示了花卉识别对于细粒度图像分类的有效性,其中模型必须准确识别花卉类别。
图2. 详细的图像分类显示
一个好的模型不仅必须正确识别不同的类别,还必须正确识别来自不同视角、光照、背景、变形或部分遮挡(这里称为图像扰动)的图像。但事实并非如此。图3 显示了一些图像扰动,更好的模型可以像聪明人一样正确识别这些扰动。
图3 干扰图像显示[7]
模型概述:CNN 传统的CNN包括卷积层和全连接层等组件,并使用softmax多类别分类器和多类别交叉熵损失函数。典型的卷积神经网络如图4 所示。构建CNN 的通用组件。
图4. CNN 网络示例[5]
-卷积层(卷积层):执行卷积运算以从下到上提取特征并发现图像的局部相关性和空间不变属性。 ·池化层:执行下采样操作。获取卷积输出特征图中局部块的最大值(max-pooling)或平均值(avg-pooling)。下采样也是图像处理中的常见操作,可以滤除不重要的高频信息。 • 全连接层(或fc 层) : 从输入层到隐藏层的所有神经元均已连接。 • 非线性变化: 卷积层和全连接层后面通常会跟随着Sigmoid、Tanh 和ReLu 等非线性变化函数,以增加网络的表达能力。 CNN 中最常用的是ReLu 激活函数。 • Dropout [1] : 在模型训练阶段随机禁用部分隐藏层节点的权重,提高网络的泛化能力并防止一定程度的过拟合。
接下来我们主要介绍VGG和ResNet的网络结构。
1.VGG
ILSVRC的牛津大学VGG(Visual Geometry Group)小组于2014年提出的模型称为VGG模型[2]。该模型相比之前的模型具有更广泛、更深的网络结构,其核心是五组卷积运算,每两组之间会进行Max-Pooling空间的降维。同一组内使用多个连续的3X3卷积,卷积核数量从浅层组的64个增加到最深组的512个。同一组中的卷积核数量相同。卷积之后是两个全连接层,然后是分类层。根据每组内卷积层数的不同,有11层、13层、16层、19层模型,下图为16层网络结构。
VGG模型的结构相对简单,在其提出后,很多论文都是基于该模型进行研究的,例如在ImageNet上首次发表了超越人类视觉识别的模型[4]。 VGG模型的结构。
图5. 基于ImageNet的VGG16模型
2. 重网
ResNet(残差网络)[3]是2015年ImageNet图像分类、图像对象定位和图像对象检测竞赛的冠军。针对随着网络训练深度加深而精度下降的问题,ResNet提出了残差学习方法,降低了深度网络训练的难度。基于现有的设计思想(BN、小规模卷积核、全卷积网络),引入残差模块。每个residual模块包含两个pass,一个是对输入特征的直接连接pass,另一个pass对特征进行两到三个卷积操作,以减少特征残差,得到差异,最后两条路径上的特征总结。向上。
其余模块如图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张图像作为训练集,10,000张图像作为测试集。图11 通过从每个类别中随机选择10 个图像来显示所有类别。
图11. CIFAR10 数据集[6]
Paddle API 提供了paddle.dataset.cifar 模块,可以自动加载cifar 数据集。
您可以通过输入“python train.py”开始训练模型。下一节将详细介绍train.py的相关内容。
模型结构1、paddle初始化
首先,导入Paddle Fluid API 和辅助模块。
from __future__ import print_functionimport osimport paddleimport paddle.fluidas Fluidimport numpyimport sysfrom vgg import vgg_bn_dropfrom resnet import resnet_cifar10本教程提供VGG 和ResNet 模型的配置。
2.VGG
首先,我们介绍VGG模型结构,这里的模型适用于CIFAR10数据,因为CIFAR10图像的大小和数量比ImageNet数据小得多。在卷积部分,引入了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 detector 首先定义了一组卷积网络,即conv_block。卷积核大小为3x3,池化窗口大小为2x2,窗口滑动大小为2。 Group决定了每组VGG模块执行的连续卷积操作的数量,Dropout指定了dropout操作的概率。使用的img_conv_group是paddle.fluit.net中预定义的模块,由几组Conv-BN-ReLu-Dropout和一组Pooling组成。
五组卷积运算,或五个conv_block。第一组和第二组使用两个连续的卷积运算。第三、第四、第五组使用三次连续的卷积运算。每组最后一次卷积后的dropout 概率为0。也就是说,不使用丢失操作。
最后,我们连接两个512 维的全连接层。
这里,VGG网络首先提取高层特征,然后在全连接层将其映射为与类别维度相同大小的向量,最后通过softmax方法将图像分类到各个类别,计算概率。
3. 重网
ResNet模型的步骤1、3、4与VGG模型相同,这里不再介绍。本文主要介绍第二步,针对CIFAR10数据集的ResNet核心模块。
首先介绍resnet_cifar10的一些基本特性,然后介绍网络连接过程。
• conv_bn_layer: 使用BN 的卷积层。
•shortcut: “直连”路径在残留模块中,“直连”实际上被拆分为两种形式。如果残差模块的输入和输出特征通道数不等,则1x1卷积的增维操作如下:当模块的输入和输出通道相等时,采用直耦工作方式。
• Basicblock: 基本残差模块如图9 左侧所示,由两组3x3 卷积路径和一组“直接连接”路径组成。
• Layer_warp: 是一组残差模块,由多个残差模块组成。每组的第一残差模块的滑动窗口大小可以与其他模块不同,以减小垂直和水平特征图的大小。
def conv_bn_layer(输入,ch_out,filter_size,步幅,填充,act='relu',bias_attr=False): tmp=Fluid.layers.conv2d(输入=输入,filter_size=filter_size,num_filters=ch_out,stride=stride,padding=填充,act=None,bias_attr=bias_attr)返回Fluid.layers.batch_norm(input=tmp,act=act)defshortcut(input,ch_in,ch_out,stride):如果ch_in!=ch_out:返回conv_bn_layer(input,ch_out,1, stride, 0, none) else: return inputdef 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=无,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 tmpresnet_cifar10的连接结构主要由以下处理组成。 变得。
底部输入连接到一层conv_bn_layer,该层是包含BN 的卷积层。
接下来,连接其余三组模块。也就是说,配置以下三组Layer_warp:每组由图10 左侧的其余模块组成。
最后,我们对网络进行平均池化并返回到这一层。
注意:layer_warp中包含三组参数的总层数必须能被6整除,不包括第一个卷积层和最后一个全连接层。也就是说,resnet_cifar10的深度必须满足(深度- 2)。 ) %6=0
def resnet_cifar10(ipt, Depth=32): # 深度必须是20, 32, 44, 56, 110, 1202 之一断言(深度- 2) % 6==0 n=(深度- 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') 返回detector4,参考配置
网络输入定义为data_layer,即图像分类中图像的像素信息。 CIFRAR10 是具有3 个RGB 通道的32x32 彩色图像,因此输入数据大小为3072 (3x32x32)。
def inference_network(): # 图像在RGB 表示中为32 * 32 data_shape=[3, 32, 32] Image=Fluid.layers.data(name='pixel',shape=data_shape, dtype='float32') detector=resnet_cifar10 (images, 32) # detector=vgg_bn_drop(images) # 取消注释并训练配置以使用vgg netreturn detector5
接下来,我们需要设置训练程序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) precision=Fluid.layers.accuracy(input=predict, label=label)return [avg_cost, precision]6. 优化器设置
下面的Adam优化器中,learning_rate是学习率,与网络的训练收敛速度有关。
def Optimizer_program(): return Fluid.optimizer.Adam(learning_rate=0.001)7. 训练模型
-1) 数据馈送器配置
cifar.train10()每次生成一个样本,经过shuffle和batching后作为训练的输入。
# 每批次生成128 张图像BATCH_SIZE=128# 训练阅读器train_reader=paddle.batch( paddle.reader.shuffle( paddle.dataset.cifar.train10(), buf_size=128 * 100),batch_size=BATCH_SIZE)# 测试阅读器。用于测试的数据集test_reader=paddle.batch( paddle.dataset.cifar.test10(), batch_size=BATCH_SIZE)-2) 训练器程序的实现
我们需要为训练过程开发一个main_program ,同样我们需要为测试程序配置一个test_program 。定义训练位置并使用之前定义的优化器。
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() Prediction=inference_network()avg_cost, acc=train_network(predict)# 测试程序test_program=main_program.clone(for_test=True) Optimizer=Optimizer_program() Optimizer.minimize(avg_cost) exe=Fluid.Executor(place) EPOCH_NUM=1# 训练测试成本def train_test(program, Reader ) ): count=0 feed_var_list=[feed_order.global_block().var(var_name) 中var_name 的程序] feeder_test=Fluid.DataFeeder(feed_list=feed_var_list, place=place) test_exe=Fluid.Executor(place) Cumulative=len( [ avg_cost, acc]) * [0] tid, test_data in enumerate(reader()): avg_cost_np=test_exe.run(program=program, feed=feeder_test.feed(test_data), fetch_list=[avg_cost, acc]) 累积=累积[ x[0] + x[1][0] for x in zip(accumulated, avg_cost_np) ] count +=1 return [x/count for x inAccumulated]-3) 训练主循环并处理输出
下一个主要训练循环是通过输出观察训练过程、执行测试等。
# 主列车循环def train_loop(): feed_var_list_loop=[ main_program.global_block().var(var_name) for var_name in feed_order ] feeder=Fluid.DataFeeder(feed_list=feed_var_list_loop, place=place) exe.run(star_program) step=范围(EPOCH_NUM) : for pass_id, 0 for step_id, for data_train for 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(\'\nPass %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() 步骤+=1 avg_cost_test, precision_test=train_test( test_program, Reader=test_reader) print('\nPass {0}, Loss {1:2.2}, Acc {2:2.2} test'.format( pass_id, avg_cost_test, precision_test)) 如果params_dirname 不是None : Fluid.io.save_inference_model(params_dirname, [\'pixel\'], [predict], exe)train_loop()-4) 训练
对于使用Trainer_loop 函数进行训练,这里我们只运行2 个epoch,但在实际应用中我们通常运行100 个或更多epoch。
请注意,对于:CPU,每个纪元大约需要15-20 分钟。这部分可能需要一些时间。请随意修改代码并在GPU 上运行测试以提高训练速度。
火车循环()
以下是一轮训练日志的示例:经过一轮后,训练集的平均准确度为0.59,测试集的平均准确度为0.6。
通过0,批次0,成本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.transpose((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}, fetch_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(\"infer results: %s\" % label_list[numpy.argmax(results[0])])总结 传统图像分类方法由多个阶段构成,框架较为复杂,而端到端的CNN模型结构可一步到位,而且大幅度提升了分类准确率。本文我们首先介绍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/天地劫幽城再临归真4-5攻略:第四章归真4-5八回合图文通关教学[多图],天地劫幽城再临归真4-5怎么样八回合内通
2024-04-09