关于第四次作业的柠檬实战中一些坑的心得体会。

在这过程中的问题大多为路径问题,但实则不然,一些小细节放面也需要警惕!下面我来讲讲我所踩到的坑。

##先是文件解压

!unzip -oq data/data72793/lemon_homework.zip -d data/
!unzip -oq data/lemon_homework/lemon_lesson.zip -d data/
!unzip -oq data/lemon_lesson/train_images.zip -d data/
!unzip -oq data/lemon_lesson/test_images.zip -d data/
# 导入所需要的库
from sklearn.utils import shuffle
import os
import pandas as pd
import numpy as np
from PIL import Imageimport paddle
import paddle.nn as nn
from paddle.io import Dataset
import paddle.vision.transforms as T
import paddle.nn.functional as F
from paddle.metric import Accuracyimport warnings
warnings.filterwarnings("ignore")

数据处理这里要看懂代码的思路,我们从解压后的数据集知道,里面有train的标注好的csv文件,而test是没有的,所以将train的数据集82开划分为训练集和验证集,csv文件里只有名称’id’和类别’class_num’的信息。下面开始着手代码。

数据处理的步骤:
1.读取全部train的名称’id’和类别’class_num’的信息

2.打乱顺序,要记住一件事,我们对图片的读取处理,都是通过路径加图片名称来获得的。

3.划分数据集,这里是82开。

4.数据预处理,也就是数据增广。

5.构建dataset。

# 读取数据
train_images = pd.read_csv('data/lemon_lesson/train_images.csv', usecols=['id','class_num'])
#这里读出的是全部训练集的'id','class_num'信息# labelshuffling 这里是打乱顺序,我们是对存放图片名称的文本进行内容的打乱。def labelShuffling(dataFrame, groupByName = 'class_num'):groupDataFrame = dataFrame.groupby(by=[groupByName])labels = groupDataFrame.size()print("length of label is ", len(labels))maxNum = max(labels)lst = pd.DataFrame()for i in range(len(labels)):print("Processing label  :", i)tmpGroupBy = groupDataFrame.get_group(i)createdShuffleLabels = np.random.permutation(np.array(range(maxNum))) % labels[i]print("Num of the label is : ", labels[i])lst=lst.append(tmpGroupBy.iloc[createdShuffleLabels], ignore_index=True)print("Done")# lst.to_csv('test1.csv', index=False)return lst

划分数据集可以看出是对全部训练集按照前80%划分为train,并得到train_images_list,后20%得到val_image_list,这两个list存放的是路径

这两个list都是从训练集划分出来的,一个仍作为训练集,另一个作为验证集。

why?

因为数据集中的test_images并没有给出标注信息,所以我们无法用test_images去验证。

还有就是我们要读取图片最后是要依赖list中的信息。

# 划分训练集和校验集
all_size = len(train_images)
# print(all_size)
train_size = int(all_size * 0.8)
train_image_list = train_images[:train_size]
val_image_list = train_images[train_size:]

注意,这个list存放的是

下面是进行乱序,还有就是得到存放label信息的list,前面已经得到路径的list,所以图片完整的信息都有了,即名称+标签,并分开存放。

最后定义一下数据预处理。

df = labelShuffling(train_image_list)
df = shuffle(df)train_image_path_list = df['id'].values
label_list = df['class_num'].values
label_list = paddle.to_tensor(label_list, dtype='int64')
train_label_list = paddle.nn.functional.one_hot(label_list, num_classes=4)val_image_path_list = val_image_list['id'].values
val_label_list = val_image_list['class_num'].values
val_label_list = paddle.to_tensor(val_label_list, dtype='int64')
val_label_list = paddle.nn.functional.one_hot(val_label_list, num_classes=4)# 定义数据预处理
data_transforms = T.Compose([T.Resize(size=(224)),T.ToTensor(), T.Normalize(     mean=[0.31169346, 0.25506335, 0.12432463],        std=[0.34042713, 0.29819837, 0.1375536])])
# 构建Dataset
class MyDataset(paddle.io.Dataset):"""步骤一:继承paddle.io.Dataset类"""def __init__(self, train_img_list, val_img_list,train_label_list,val_label_list, mode='train'):"""步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集"""super(MyDataset, self).__init__()self.img = []self.label = []# 借助pandas读csv的库,将前面得到的标签,名称list分别赋值self.train_images = train_img_listself.test_images = val_img_listself.train_label = train_label_listself.test_label = val_label_listif mode == 'train':# 读train_images的数据,这里是读训练的,所以括号里的是train的label和imagesfor img,la in zip(self.train_images, self.train_label):self.img.append('data/train_images/'+img)self.label.append(la)else:# 读test_images的数据,这里是读验证的,所以括号里的应该是是val的label和images。for img,la in zip(self.test_images, self.test_label):#注意这里,因为我们从头到这里处理的都是list文件,本质上的test是从train划分出来的,所以路径应该为train_imagesself.img.append('data/train_images/'+img)self.label.append(la)def load_img(self, image_path):# 实际使用时使用Pillow相关库进行图片读取即可,这里我们对数据先做个模拟image = Image.open(image_path).convert('RGB')return imagedef __getitem__(self, index):"""步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)"""image = self.load_img(self.img[index])label = self.label[index]# label = paddle.to_tensor(label)return data_transforms(image), paddle.nn.functional.label_smooth(label)def __len__(self):"""步骤四:实现__len__方法,返回数据集总数目"""return len(self.img)#train_loader
train_dataset = MyDataset(train_img_list=train_image_path_list, val_img_list=val_image_path_list, train_label_list=train_label_list, val_label_list=val_label_list, mode='train')
train_loader = paddle.io.DataLoader(train_dataset, places=paddle.CPUPlace(), batch_size=32, shuffle=True, num_workers=0)#val_loader
#注意括号里的参数和train_loader的区别
val_dataset = MyDataset(train_img_list=train_image_path_list, val_img_list=val_image_path_list, train_label_list=train_label_list, val_label_list=val_label_list, mode='test')
val_loader = paddle.io.DataLoader(val_dataset, places=paddle.CPUPlace(), batch_size=32, shuffle=True, num_workers=0)
  • 关于路径的问题,我们定义dataset是为了得到经过处理的 train_loader 和 val_loader ,从前面的代码看下来,

      我们一直在处理存放图片信息 label_list 和 images_list ,因为我们可以通过这些信息去读取图片并进行处理。在Dataset中如果读取test文件的标签没改,即for img,la in zip(self.train_images, self.train_label): #我们是通过这两个标签文件确定图片位置的那么我们读取到的将会仍是训练集的,这样等于我们在验证的时候用的是和训练一样的数据,这样看不出效果的,还有我们是根据list文件才能获取到图片的,如果list文件错了,那么读取到的图片也将错误。
    
  • 划分为验证集的数据本身就是训练集的,

      我们要读取里面的图片本质上还得去train_images里找,这就是为什么读取test的路径不用改。简单来说就是:我们把全部的train_images的list划分为train和test。但都是train_images的,所以路径都是train_images
    
from paddle.vision import MobileNetV2# 模型封装
model_res = MobileNetV2(num_classes=4)
model = paddle.Model(model_res)# 定义优化器scheduler = paddle.optimizer.lr.LinearWarmup(learning_rate=0.5, warmup_steps=20, start_lr=0, end_lr=0.5, verbose=True)
#optim = paddle.optimizer.SGD(learning_rate=scheduler, parameters=model.parameters())
optim = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())# 配置模型
model.prepare(optim,paddle.nn.CrossEntropyLoss(soft_label=True),Accuracy())# 模型训练与评估
model.fit(train_loader,val_loader,log_freq=1,epochs=10,# callbacks=Callbk(write=write, iters=iters),verbose=1,)
Epoch 0: LinearWarmup set learning rate to 0.0.
The loss value printed in the log is the current step, and the metric is the average value of previous step.
Epoch 1/10
step 41/41 [==============================] - loss: 0.5990 - acc: 0.7788 - 297ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 1.5692 - acc: 0.3575 - 274ms/step
Eval samples: 221
Epoch 2/10
step 41/41 [==============================] - loss: 1.2327 - acc: 0.9587 - 293ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 1.2749 - acc: 0.6244 - 273ms/step
Eval samples: 221
Epoch 3/10
step 41/41 [==============================] - loss: 0.8710 - acc: 0.9650 - 293ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.4261 - acc: 0.9683 - 273ms/step
Eval samples: 221
Epoch 4/10
step 41/41 [==============================] - loss: 0.7454 - acc: 0.9868 - 295ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.4035 - acc: 0.9910 - 274ms/step
Eval samples: 221
Epoch 5/10
step 41/41 [==============================] - loss: 0.4169 - acc: 0.9907 - 297ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3782 - acc: 1.0000 - 289ms/step
Eval samples: 221
Epoch 6/10
step 41/41 [==============================] - loss: 0.3601 - acc: 0.9984 - 297ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3653 - acc: 1.0000 - 273ms/step
Eval samples: 221
Epoch 7/10
step 41/41 [==============================] - loss: 0.5843 - acc: 1.0000 - 300ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3681 - acc: 1.0000 - 291ms/step
Eval samples: 221
Epoch 8/10
step 41/41 [==============================] - loss: 0.4045 - acc: 0.9930 - 310ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3647 - acc: 0.9955 - 280ms/step
Eval samples: 221
Epoch 9/10
step 41/41 [==============================] - loss: 0.4106 - acc: 1.0000 - 297ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3591 - acc: 1.0000 - 273ms/step
Eval samples: 221
Epoch 10/10
step 41/41 [==============================] - loss: 0.5667 - acc: 1.0000 - 369ms/step
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 7/7 [==============================] - loss: 0.3631 - acc: 1.0000 - 285ms/step
Eval samples: 221
model.save('MyCNN', False)

模型评估

model.evaluate(val_loader)

下面是模型的训练和验证,应该没什么问题。

模型预测

import os, time
import matplotlib.pyplot as plt
import paddle
from PIL import Image
import numpy as npdef load_image(img_path):'''预测图片预处理'''img = Image.open(img_path).convert('RGB')#plt.imshow(img)          #根据数组绘制图像#plt.show()               #显示图像#resizeimg = img.resize((224, 224), Image.BILINEAR) #Image.BILINEAR双线性插值img = np.array(img).astype('float32')# HWC to CHW img = img.transpose((2, 0, 1))#Normalizeimg = img / 255         #像素值归一化mean = [0.31169346, 0.25506335, 0.12432463]   std = [0.34042713, 0.29819837, 0.1375536]img[0] = (img[0] - mean[0]) / std[0]img[1] = (img[1] - mean[1]) / std[1]img[2] = (img[2] - mean[2]) / std[2]return imgdef infer_img(path, model_file_path, use_gpu):'''模型预测'''paddle.set_device('gpu:0') if use_gpu else paddle.set_device('cpu')model = paddle.jit.load(model_file_path)model.eval() #训练模式#对预测图片进行预处理infer_imgs = []infer_imgs.append(load_image(path))infer_imgs = np.array(infer_imgs)label_list = ['0:優良', '1:良', '2:加工品', '3:規格外']label_pre = []for i in range(len(infer_imgs)):data = infer_imgs[i]dy_x_data = np.array(data).astype('float32')dy_x_data = dy_x_data[np.newaxis,:, : ,:]img = paddle.to_tensor(dy_x_data)out = model(img)# print(out[0])# print(paddle.nn.functional.softmax(out)[0]) # 若模型中已经包含softmax则不用此行代码。lab = np.argmax(out.numpy())  #argmax():返回最大数的索引label_pre.append(lab)# print(lab)print("样本: {},被预测为:{}".format(path, label_list[lab]))return label_pre# print("*********************************************")
infer_img(path='data/test_images/test_1604.jpg',model_file_path='MyCNN',use_gpu=1)
样本: data/test_images/test_1604.jpg,被预测为:3:規格外[3]

将test_images文件夹里的图片全部预测后的结果生成csv文件

import os
import csv
zemax = []
def create_csv_2(dirname):path = 'data/'+ dirname +'/' name = os.listdir(path)with open (dirname+'.csv','w') as csvfile:writer = csv.writer(csvfile)writer.writerow(['id', 'label'])for n in name:if n[-4:] == '.jpg':#print(n)zemax = infer_img(path='data/test_images/'+ n,model_file_path='MyCNN',use_gpu=1)writer.writerow([str(n),zemax[0]])else:pass
create_csv_2('test_images')
样本: data/test_images/test_1110.jpg,被预测为:3:規格外

得到的csv文件是test_images 的预测文件,预测准确度应该得去官网提交看看。

如果有说得不好或者不对的,欢迎指正,欢迎交流。PS:我也是只小菜鸡**

基于paddle的柠檬实战相关推荐

  1. R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行、基于多数据列not in规则过滤数据行

    R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行.基于多数据列not in规则过滤数据行 目录

  2. 推荐一份基于Docker的DevOps实战培训教程

    01. 基于Docker的DevOps实战培训 微软工具链 基于Azure和Team Foundation Server 微软DevOps工具链是基于Visual Studio 应用生命周期管理(VS ...

  3. LEANSOFT领航员 – 基于Docker的DevOps实战培训

    2016年,LEANSOFT推出了一系列广受开发人员欢迎的培训,包括<构建高效DevOps团队>,<基于Azure的容器化DevOps数据中心>和<Docker基础培训& ...

  4. 基于MT策略的实战分析

    基于MT策略的实战分析 一.概述 1.1研究背景 量化投资是指通过数量化方式及计算机程序化发出买卖指令,以获取稳定收益为目的的交易方式.在海外的发展已有30多年的历史,其投资业绩稳定,市场规模和份额不 ...

  5. 基于Dubbox的微服实战学习3——使用Dubbox+SpringBoot实现微服架构

    基于Dubbox的微服实战学习3--使用Dubbox+SpringBoot实现微服架构 0.问题 1.依赖环境介绍 2.运行原理介绍 3.环境搭建补充 4.基础服务模块介绍 5.提供者服务实现 6.消 ...

  6. 基于Paddle的截图OCR文字识别的实现

    基于Paddle的截图&OCR文字识别的实现 一款截图识别文字的OCR工具主要涉及2个环境: 截图 OCR识别 前要 OCR的应用场景 根据OCR的应用场景而言,我们可以大致分成识别特定场景下 ...

  7. 第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密 java.lang.ClassNotFoundException 踩坑解决问题详细内幕版本

    第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密    /* * *王家林老师授课http://weibo.com/ilovepains */  每天晚上20: ...

  8. 【基于Paddle框架的行车环境下天气及时间分类】

    目录 一.项目简介 二.数据来源及分析 2.1 解压训练数据集 三.数据读取 3.1 ImageNet数据集格式说明 3.1.1 数据文件夹格式 3.1.2 训练集.验证集列表和类别标签列表 3.2 ...

  9. 基于Paddle的计算机视觉入门教程——第7讲 实战:手写数字识别

    B站教程地址 https://www.bilibili.com/video/BV18b4y1J7a6/ 任务介绍 手写数字识别是计算机视觉的一个经典项目,因为手写数字的随机性,使用传统的计算机视觉技术 ...

最新文章

  1. 新手看看如何发布一个网站
  2. 基于STM32F103ZET6 HC_SR04超声波测距模块
  3. Mercurial黄昏,Bitbucket宣布全面转向Git
  4. python从入门到爬虫_python爬虫从入门到放弃(一)之初识爬虫
  5. 简单几何(极角排序) POJ 2007 Scrambled Polygon
  6. C#读取文本数据(按行读取)
  7. 考上985能改变命运吗_2021艺考生:文化课成绩一般,有机会考上985、211吗?
  8. android工程换背景图片,android换肤功能 如何动态获取控件中背景图片的资源id?
  9. 关于《HTTP权威指南》
  10. matlab 流星雨,dijkstra算法及其matlab实现
  11. 文献管理三剑客之Noteexpress:更新一次文献后把文献自动插一次
  12. 【JAVA面试题整理】框架之Shiro
  13. 2022.08 VMware官网下载安装+配置Linux虚拟机,最新最全
  14. AD转换原理,器件与参数
  15. softice 常用操作
  16. snipaste如何滚动截图_Windows系统的几种屏幕截图方法
  17. 常用的软件工程相关技术标准
  18. 如何查询网站服务器类型
  19. 大天使黎明服务器维护,亲爱的玩家: 您好,为保证服务
  20. rollback方法java_java 之回调函数 rollback

热门文章

  1. 【易盾图像识别】文字点选识别 附带 模型+数据集 +识别代码+思路
  2. 投票的链接怎么做出来的网上那些投票链接怎么做的网上投票器
  3. adb的screenrecord录屏功能
  4. Linux正则表达式 --已整理
  5. 创业者对融资有哪些要求
  6. H5移动端记一次图片裁剪合成功能
  7. 苏宁易购收购万达百货:零售业加速深度整合
  8. css边框实现高度,CSS上的边框高度
  9. python量化投资-技术指标的计算
  10. 那些有趣的网站系列(八)