PaddlePaddle基本用法详解(二)、PaddelPaddle训练分类模型

  • 1、基本用法
  • 2、训练水果分类模型

1、基本用法

2、训练水果分类模型


1、数据集预处理与模型定义代码:

import os###################################第一部分:水果预处理部分#################################
# 定义一组变量
name_dict = {"apple": 0, "banana": 1, "grape": 2, "orange": 3, "pear": 4}  # 水果名称和数组对应字典
data_root_path = "data/fruits/"  # 数据样本所在目录
test_file_path = data_root_path + "test.txt"  # 测试集文件路径
train_file_path = data_root_path + "train.txt"  # 训练集文件路径name_data_list = {}  # 记录每个类别的图片路径
# 将文件路径存入临时字典
def save_train_test_file(path, name):if name not in name_data_list:  # 当前水果没有在字典中,新增img_list = []img_list.append(path)  # 将图片添加到列表name_data_list[name] = img_list  # 将“名称-图片列表”键值对插入字典else:  # 当前水果已经在字典中,添加到相应的列表name_data_list[name].append(path)# 遍历所有子目录,读取出所有图片文件,并插入字典、保存到测试集、训练集
dirs = os.listdir(data_root_path)
for d in dirs:full_path = data_root_path + d  # 目录名称 + 子目录名称if os.path.isdir(full_path):  # 目录imgs = os.listdir(full_path)  # 列出子目录中的文件for img in imgs:save_train_test_file(full_path + "/" + img,  # 图片文件完整路径d)  # 子目录名称(类别名称)else:  # 文件pass# 将字典中的内容保存文件中
with open(test_file_path, "w") as f:  # 清空测试集文件pass
with open(train_file_path, "w") as f:  # 清空训练集文件pass# 遍历字典,将内容写入文件
for name, img_list in name_data_list.items():i = 0num = len(img_list)  # 每个类别图片数量print("%s: %d张图像" % (name, num))for img in img_list:  # 遍历每个列表,将图片路径存入文件if i % 10 == 0:  # 每10张写一张到测试集with open(test_file_path, "a") as f:line = "%s\t%d\n" % (img, name_dict[name])f.write(line)  # 写入文件else:  # 其它写入训练集with open(train_file_path, "a") as f:line = "%s\t%d\n" % (img, name_dict[name])f.write(line)  # 写入文件i += 1print("数据预处理完成.")###################################第二部分:水果预处理部分################################
import paddle
import paddle.fluid as fluid
import numpy as np
import sys
import os
from multiprocessing import cpu_count
import matplotlib.pyplot as plt# 数据准备
## 定义reader
## train_mapper函数:对传入的图片路径进行读取,返回图像数据(多通道矩阵)、标签
def train_mapper(sample):img, label = sample  # 将sample中值赋给img, labelif not os.path.exists(img):print(img, "图片文件不存在")# 读取图片文件img = paddle.dataset.image.load_image(img)  # 读取图片# 对图像进行简单变换:修剪、设置大小,输出(3, 100, 100)张量img = paddle.dataset.image.simple_transform(im=img, # 原图像数据resize_size=100, # 重设图像大小为100*100crop_size=100, # 裁剪成100*100is_color=True, # 彩色图像is_train=True) # 是否用于训练,影响裁剪策略# 对图像数据进行归一化处理,像素的值全部计算压缩到0~1之间img = img.astype("float32") / 255.0return img, label   # 返回图像数据、标签# 读取训练集文件,将路径、标签作为参数调用train_mapper函数
def train_r(train_list, buffered_size=1024):def reader():with open(train_list, "r") as f: # 打开训练集lines = [line.strip() for line in f]  # 读取出所有样本行for line in lines:# 去掉每行的换行符,并根据tab字符进行拆分,得到两个字段img_path, lab = line.replace("\n", "").split("\t")yield img_path, int(lab)# xmap_readers高阶函数,作用是将reader产生的数据穿个train_mapper函数进行下一步处理return paddle.reader.xmap_readers(train_mapper, # 二次处理函数reader, # 原始readercpu_count(), # 线程数(和cpu数量一致)buffered_size) # 缓冲区大小BATCH_SIZE = 32  # 批次大小# 定义reader
train_reader = train_r(train_list=train_file_path)# train_file_path为训练集文件路径
random_train_reader = paddle.reader.shuffle(reader=train_reader, # 原始readerbuf_size=1300) # 缓冲区大小
batch_train_reader = paddle.batch(random_train_reader,batch_size=BATCH_SIZE)  # 批量读取器
# 定义变量
image = fluid.layers.data(name="image", shape=[3, 100, 100], dtype="float32")
label = fluid.layers.data(name="label", shape=[1], dtype="int64")# 创建VGG模型
def vgg_bn_drop(image, type_size):  # 其包含批归一化层与丢弃层def conv_bn_block(ipt, num_filter, groups, dropout):# 创建Convolution2d,BatchNorm,Dropout,Pool2d组return fluid.nets.img_conv_group(input=ipt,  # 输入图像数据,【N,C,H,W】格式pool_stride=2,  # 池化步长值pool_size=2,  # 池化区域大小conv_num_filter=[num_filter] * groups,  # 卷积核的数量(即组的数量*每一组卷积核的数量)conv_filter_size=3,  # 卷积核大小conv_act="relu",  # 激活函数conv_with_batchnorm=True,  # 即卷积完成后是否要进行批量归一化操作pool_type="max"  # 池化的类型)# VGG前面的5组卷积池化conv1 = conv_bn_block(image, 64, 2, [0.0, 0.0])  # 表示卷积核数量;2表示组数;[0.0,0.0]表示每组卷积的丢弃率conv2 = conv_bn_block(conv1, 128, 2, [0.0, 0.0])conv3 = conv_bn_block(conv2, 256, 3, [0.0, 0.0, 0.0])conv4 = conv_bn_block(conv3, 512, 3, [0.0, 0.0, 0.0])conv5 = conv_bn_block(conv4, 512, 3, [0.0, 0.0, 0.0])drop = fluid.layers.dropout(x=conv5, dropout_prob=0.2)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.0)fc2 = fluid.layers.fc(input=drop2, size=512, act=None)predict = fluid.layers.fc(input=fc2,size=type_size,act="softmax")return predict# 调用上面的函数创建VGG
predict = vgg_bn_drop(image=image, type_size=5)  # type_size和水果类别一致
# 损失函数
cost = fluid.layers.cross_entropy(input=predict,  # 预测值label=label)  # 真实值
avg_cost = fluid.layers.mean(cost)
# 计算准确率
accuracy = fluid.layers.accuracy(input=predict,  # 预测值label=label)  # 真实值
# 优化器
optimizer = fluid.optimizer.Adam(learning_rate=0.00001)  # 自适应梯度下降优化器
optimizer.minimize(avg_cost)# 创建Executor
place = fluid.CUDAPlace(0)  # GPU上执行
exe = fluid.Executor(place)  # 执行器
exe.run(fluid.default_startup_program())  # 初始化变量# 定义feeder
feeder = fluid.DataFeeder(feed_list=[image, label], place=place)costs = []  # 记录损失值
accs = []  # 记录准确率
times = 0
batches = []  # 记录批次for pass_id in range(15):train_cost = 0for batch_id, data in enumerate(batch_train_reader()):times += 1train_cost, train_acc = exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),  # 喂入一个batch数据fetch_list=[avg_cost, accuracy])  # 获取结果if batch_id % 20 == 0:print("pass_id:%d, bat_id:%d, cost:%f, acc:%f" %(pass_id, batch_id, train_cost[0], train_acc[0]))accs.append(train_acc[0])  # 记录准确率costs.append(train_cost[0])  # 记录损失值batches.append(times)  # 记录训练批次数# 保存模型
model_save_dir = "model/fruits/"  # 模型保存路径
if not os.path.exists(model_save_dir):  # 如果模型路径不存在则创建os.makedirs(model_save_dir)
fluid.io.save_inference_model(dirname=model_save_dir,  # 保存路径feeded_var_names=["image"],  # 使用模型需传入的参数target_vars=[predict],  # 模型结果executor=exe)  # 模型
print("模型保存完成.")# 训练过程可视化
plt.figure('training', facecolor='lightgray')
plt.title("training", fontsize=24)
plt.xlabel("iter", fontsize=20)
plt.ylabel("cost/acc", fontsize=20)
plt.plot(batches, costs, color='red', label="Training Cost")
plt.plot(batches, accs, color='green', label="Training Acc")
plt.legend()
plt.grid()
plt.savefig("train.png")
plt.show()

2、加载模型,预测图像

############################# 第三部分:加载模型,使用模型执行预测 ################################
from PIL import Imageimport paddle.fluid as fluid
import paddle
import numpy
import matplotlib.pyplot as pltdef load_img(path):  # 从指定路径读取图片数据img = paddle.dataset.image.load_and_transform(path,  # 图片路径100, 100,  # resize图像大小、裁剪大小False  # 是否用于训练)# 因为需要对图像进行归一化,所以需要将图像转变为float32的格式img = (img.astype("float32")) / 255.0  # 进行归一化return img# 定义执行器
place = fluid.CPUPlace()  # 在预测时,计算量不大,所以没有必要在cuda上计算
infer_exe = fluid.Executor(place)  # 创建执行器
model_save_dir= "model/fruits/"  # 模型的保存路径infer_imgs = []  # 用来存放待预测图像数据
test_img = "putao.png"  # 待预测图片路径
infer_imgs.append(load_img(test_img))  # 读取图像数据,添加到待预测的列表中
# 因为神经网络无法读取列表数据,所以需要将列表数据转换为数组数据输入神经网络
infer_imgs = numpy.array(infer_imgs)  # 转换为数组# 加载保存的模型
infer_program,feed_target_names,fetch_targets= \fluid.io.load_inference_model(model_save_dir,   # 模型保存路径infer_exe)        # 要执行模型的Executor
# 使用模型执行预测
result = infer_exe.run(infer_program,  # 预测的programfeed={feed_target_names[0]: infer_imgs},  # 喂入待预测的数据fetch_list=fetch_targets  # 取得操作结果并返回)print(result)   # 得到的result是一个各个分类概率的二维数组
"""
[array([[9.9999964e-01, 5.7820136e-24, 2.9262706e-10, 3.9078353e-07,1.4152669e-19]], dtype=float32)]
"""index=numpy.argmax(result[0])
name_dict = {"apple": 0, "banana": 1, "grape": 2, "orange": 3, "pear": 4}
# 遍历字典
for k,v in name_dict.items():       # 对分类字典进行迭代返回的是字典的键,值if index==v:print("预测结果为:",k)# 显示待预测的图片
img = Image.open(test_img)
plt.imshow(img)
plt.show()

PaddlePaddle基本用法详解(二)、PaddelPaddle训练水果分类模型相关推荐

  1. PaddlePaddle基本用法详解(一)、PaddelPaddle进行波士顿房价预测

    PaddlePaddle基本用法详解(一).PaddelPaddle进行波士顿房价预测 # helloworld示例 import paddle.fluid as fluid # 创建两个类型为int ...

  2. 语音自训练平台技术详解,快速训练专属语音识别模型

    语音自训练平台4月份公测以来,有1000多名用户创建了1600+模型,涉及医疗.金融.农业.教育.餐饮.物流.建筑.地产等多个行业,模型上线后应用到业务数据采集录入.音频关键词质检.智能语音助手.呼叫 ...

  3. java typedef的用法_Java 枚举用法详解(二)

    枚举可以添加方法 在概念章节提到了,枚举值默认为从0开始的有序数值 .那么问题来了:如何为枚举显示的赋值. Java 不允许使用 = 为枚举常量赋值 如果你接触过C/C++,你肯定会很自然的想到赋值符 ...

  4. this指针的用法详解

    C++中this指针的用法详解 2010-11-12 20:40:45 分类: C/C++ this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果.th ...

  5. this指针用法详解

    C++中this指针的用法详解 2010-11-12 20:40:45 分类: C/C++ 1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果 ...

  6. Python中self用法详解

    Python中self用法详解 https://blog.csdn.net/CLHugh/article/details/75000104 首页 博客 学院 下载 图文课 论坛 APP 问答 商城 V ...

  7. python中permute_PyTorch中permute的用法详解

    PyTorch中permute的用法详解 permute(dims) 将tensor的维度换位. 参数:参数是一系列的整数,代表原来张量的维度.比如三维就有0,1,2这些dimension. 例: i ...

  8. ios开发读取剪切板的内容_iOS中管理剪切板的UIPasteboard粘贴板类用法详解

    一.自带剪切板操作的原生UI控件在iOS的UI系统中,有3个控件自带剪切板操作,分别是UITextField.UITextView与UIWebView.在这些控件的文字交互处进行长按手势可以在屏幕视图 ...

  9. RxJava flatMap操作符用法详解

    RxJava系列文章目录导读: 一.RxJava create操作符的用法和源码分析 二.RxJava map操作符用法详解 三.RxJava flatMap操作符用法详解 四.RxJava conc ...

最新文章

  1. 权限提升 T1548.002 绕过UAC
  2. GDB怎么调试使用.sh(shell脚本)启动的程序?(未完成,待测试)
  3. java继承类型的用法_详解Java中使用externds关键字继承类的用法
  4. JDK8新特性之重复注解
  5. 帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载
  6. 模板引擎工作原理_广州seo了解下搜索引擎的工作原理是什么
  7. 不定宽高的div如何垂直居中
  8. node 更新_更新应用时,如何实现 K8s 零中断滚动更新?
  9. RMS数据采集分布式架构
  10. python绘制复杂表格_Matplotlib绘制表格
  11. CSS伪元素(以:after为例)插入图片
  12. Windows10视频文件没有预览图的解决办法
  13. 湖南省工信厅党组书记、厅长雷绍业一行莅临麒麟信安调研
  14. 秀和vs太田雄藏(依田纪基讲定式,欺骗感情)
  15. 如何利用Vue3管理系统实现动态路由和动态侧边菜单栏
  16. python中base64库用法详解
  17. 游戏开发者必须是骨灰级玩家吗?
  18. 寻找孪生素数 (20 分)
  19. IBM获5896项专利连续18年蝉联年度冠军
  20. Win10运行程序提示不受信任的解决方法【系统天地】

热门文章

  1. OLA音频变速算法的仿真与剖析
  2. android控制手机拍照代码,Android开发之手机拍照功能的实现(源代码分享)
  3. 详解eNSP中Trunk端口和Access端口收发数据的区别
  4. 先序遍历 中序遍历 后序遍历 层序遍历
  5. 2020年 ICLR 国际会议最终接受论文(poster-paper)列表(二)
  6. A*寻路算法讲解+源码DEMO演示
  7. Webapck 体系基础
  8. 量化对冲:智能对冲策略解析
  9. 2015.7.15(千股跌停,开盘及时出货。10:49由于绘制通道错误,错误加仓)
  10. electron 打包后启动应用报错:Error: ENOENT: no such file or directory, open ‘xxx/manifest.json‘‘