★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>>

一、数据集介绍

  • 水稻是世界上生产最广泛的谷物产品之一,具有许多遗传品种。这些品种由于其某些特征而彼此分离。这些通常是纹理、形状和颜色等特征。有了区分水稻品种的这些特征,就可以对种子的质量进行分类和评估。在这项研究中,使用了Arborio,Basmati,Ipsala,Jasmine和Karacadag,这是土耳其经常种植的五种不同品种的水稻。
  • 数据集中总共包含 75000 张颗粒图像,每个品种 15000 张。使用了具有106个特征的第二个数据集,包括从这些图像中获得的12个形态学特征,4个形状特征和90个颜色特征。


二、数据集准备

2.1 解压数据集

!unzip -oq /home/aistudio/data/data198754/Rice_Image_Dataset.zip

2.2生成数据列表

# 导入所需要的库
from sklearn.utils import shuffle
import os
import pandas as pd
import numpy as np
from PIL import Image
import 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 Accuracy
import random
  • 由于原数据集文件名格式不符合paddleclas的标准,我们需要把文件名重命名删除文件名中的空格。
import os

# 定义照片文件夹路径

# 获取照片文件夹中所有文件名
def F(dir_path):
    file_names = os.listdir(dir_path)

# 遍历文件名列表,进行重命名
    for file_name in file_names:
    # 对于每个文件名,将空格删除
        new_file_name = file_name.replace(" ", "")
    # 使用os.rename()函数进行重命名
        os.rename(os.path.join(dir_path, file_name), os.path.join(dir_path, new_file_name))
dir_path1 ="/home/aistudio/Rice_Image_Dataset/Arborio"
dir_path2 = "/home/aistudio/Rice_Image_Dataset/Basmati"
dir_path3 = "/home/aistudio/Rice_Image_Dataset/Ipsala"
dir_path4 = "/home/aistudio/Rice_Image_Dataset/Jasmine"
dir_path5 = "/home/aistudio/Rice_Image_Dataset/Karacadag"
F(dir_path1)
F(dir_path2)
F(dir_path3)
F(dir_path4)
F(dir_path5)
  • 经过脚本处理,原先文件名的空格就会被删除

  • 根据官方paddleclas的提示,我们需要把图像变为两个txt文件

  • 我们总共是75000张图片,按照经典的划分方式0.8:0.2

  • train_list.txt(训练集,60000张图)

  • val_list.txt(验证集,15000张图)

  • 先把路径搞定 比如:dataset/Rice_Image_Dataset/Arborio/Arborio(10468).jpg ,读取到并写入txt

# -*- coding: utf-8 -*-

dirpath = "Rice_Image_Dataset"
# 先得到总的txt后续再进行划分,因为要划分出验证集,所以要先打乱,因为原本是有序的
def get_all_txt():
    all_list = []
    i = 0
    for root,dirs,files in os.walk(dirpath): # 分别代表根目录、文件夹、文件
        for file in files:
            i = i + 1 
            # 文件中每行格式: 图像相对路径      图像的label_id(注意:中间有空格)。              
            #                Rice_Image_Dataset/Arborio/Arborio(10468).jpg    0
        
            if("Arborio" in root):
                all_list.append(os.path.join(root,file)+" 0\n")
            if("Basmati" in root):
                all_list.append(os.path.join(root,file)+" 1\n")
            if("Ipsala" in root):
                all_list.append(os.path.join(root,file)+" 2\n")
            if("Jasmine" in root):
                all_list.append(os.path.join(root,file)+" 3\n")
            if("Karacadag" in root):
                all_list.append(os.path.join(root,file)+" 4\n")
    allstr = ''.join(all_list)
    f = open('all_list.txt','w',encoding='utf-8')
    f.write(allstr)
    return all_list , i

all_list,all_lenth = get_all_txt()
print(all_lenth-1) # 有意者是预测的图片,得减去
74999
random.shuffle(all_list)
random.shuffle(all_list)
# 我们总共是75000张图片,按照经典的划分方式0.8:0.2
# train_list.txt(训练集,60000张图)
# val_list.txt(验证集,15000张图)

train_size = int(all_lenth * 0.8)
train_list = all_list[:train_size]
val_list = all_list[train_size:]

print(len(train_list))
print(len(val_list))
60000
15000
# 运行cell,生成txt 
train_txt = ''.join(train_list)
f_train = open('train_list.txt','w',encoding='utf-8')
f_train.write(train_txt)
f_train.close()
print("train_list.txt 生成成功!")
train_list.txt 生成成功!

# 运行cell,生成txt
val_txt = ''.join(val_list)
f_val = open('val_list.txt','w',encoding='utf-8')
f_val.write(val_txt)
f_val.close()
print("val_list.txt 生成成功!")
val_list.txt 生成成功!
  • 这是生成的数据集列表

三、环境准备

!unzip -oq /home/aistudio/data/data98136/PaddleClas-release-2.1.zip #解压套件
  • 由于使用的是相对路径,所以我们需要把生成的数据列表移动到“/home/aistudio/PaddleClas-release-2.1/dataset”
!mv Rice_Image_Dataset/ PaddleClas-release-2.1/dataset/
!mv all_list.txt PaddleClas-release-2.1/dataset/Rice_Image_Dataset
!mv train_list.txt PaddleClas-release-2.1/dataset/Rice_Image_Dataset
!mv val_list.txt PaddleClas-release-2.1/dataset/Rice_Image_Dataset

四、模型训练

  • 我们在使用套件脚本训练时,需要进去Paddle文件夹里
%cd PaddleClas-release-2.1
!ls
/home/aistudio/PaddleClas-release-2.1
all_list.txt  deploy	   LICENSE	paddleclas.py  README.md	 tools
configs       docs	   MANIFEST.in	ppcls	       requirements.txt
dataset       __init__.py  output	README_cn.md   setup.py

setup.py

4.1 修改配置文件

  • Paddleclas为我们提供了非常多模型,我们可以根据需求自行选择,"/home/aistudio/PaddleClas-release-2.1/configs"这是配置文件所在的路径

  • 主要修改以下几点

4.2 训练模型

我们使用的是ResNet152网络模型,简单的介绍一下ResNet模型

  • Residual Network (ResNet) 是著名的深度学习模型之一,由 Shaoqing Ren、Kaiming He、Jian Sun 和 Xiangyu Zhang 在他们的论文中提出。该论文在 2015 年被命名为“Deep Residual Learning for Image Recognition” 。ResNet 模型是迄今为止流行和最成功的深度学习模型之一。
  • 该网络架构中有一个 34 层的普通网络,其灵感来自 VGG-19,其中添加了快捷连接或跳过连接,这些跳过连接或残差块将架构转换为残差网络

    上图是ResNet不同层数的网络 结构图。
    可以看到,结构大差不差。不论是18层、34层、50层、还是101层、152层。
    上来都是一个7x7的卷积层,然后是一个3x3的最大池化下采样。
    然后就是按照图中的conv2_x、conv3_x、conv4_x、conv5_x中的残差结构。
    最后再跟一个平均池化下采样,和全连接层,sofmax输出。
  • 不同版本的ResNet网络区别在于创建的ResNet 层不同
    • 对于 ResNet50,层序列为 [3, 4, 6, 3]。
    • 对于 ResNet101,层序列为 [3, 4, 23, 3]。
    • 对于 ResNet152,层序列为 [3, 8, 36, 3]。
#我们使用提前准备好的配置文件
!python tools/train.py \
    -c /home/aistudio/ResNet152.yaml
  • 在跑完五个epoch时acc已经达到0.98

五、模型评估

  • 在训练的过程中,PaddleClas就可以进行边训练边评估,并根据评估的精度值将最优模型参数存储在output/xxx/best_model目录中。 在训练结束后,可以再单独使用eval.py文件进行评估操作。 然后就可以使用存盘的模型文件进行模型预测,一般在研究阶段和比赛阶段,就是这样操作的。 在实际工业落地的时候,对速度要求更高,一般需要将存盘文件转换为推理模型,然后进行推理和部署。
!python tools/eval.py \
    -c /home/aistudio/ResNet152.yaml \
    -o pretrained_model="/home/aistudio/PaddleClas-release-2.1/output/ResNet152/best_model"\
    -o load_static_weights=False
  • 模型训练完成之后,可以加载训练得到的预训练模型(就是存盘文件),进行模型预测。在模型库的 tools/infer/infer.py 中提供了完整的示例,只需执行下述命令即可完成模型预测:
!python tools/infer/infer.py \
    -i ~/work/test \
    --model ResNet152 \
    --pretrained_model "/home/aistudio/PaddleClas-release-2.1/output/ResNet152/best_models" \
    --load_static_weights False \
    --class_num=5 

总结

  • 原本打算自行组网实现,但奈何功力太差最后还是选择了套件。等后期功力深厚了,尝试重写一下此项目。
  • 使用ResNet152在第五个epoch时已经跑出来98%的正确率,我感觉是有可能跑出99%甚至100%欢迎小伙伴们fork尝试一下其他的模型。
最后感谢李导的辛苦指导

请点击此处查看本环境基本用法.

Please click here for more detailed instructions.

此文章为转载
原文链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐