首页 > 其他分享 >百度飞桨paddle paddle实现蝴蝶分类

百度飞桨paddle paddle实现蝴蝶分类

时间:2024-01-29 19:01:14浏览次数:28  
标签:img self list paddle label 飞桨 data 百度

一、实验背景

近年来,随着人工智能的发展,其在语音识别、自然语言处理、图像与视频分析等诸多领域取得了巨大成功。如何将人工智能技术应用到更广泛的领域成为了重要目标,本次竞赛将聚焦蝴蝶图片的细粒度图像分类,利用人工智能技术,对蝴蝶的类别、属性进行识别分类,以便相关工作者快速识别蝴蝶种类,进行科学研究,提高效率和精度。


二、实验内容:

要求参赛者给出一个算法或模型,对于给定的图片,检测出图片中的蝴蝶类别和属。给定图片数据,选手据此训练模型,为每张测试数据预测出最正确的类别。

数据文件包括训练集(有标注)和测试集(无标注),训练集和验证集的所有图片分别保存在Butterfly20文件夹下面的20个文件夹中,文件名即属-物种标签,测试集共有200张待分类的蝴蝶图片在test文件夹下,名称为:图片ID.jpg。

【数据说明】

本竞赛所用训练和测试图片均来自网络(和鲸社区)。总共有9个属,20个物种,文件genus.txt中描述了9个属名,species.txt描述了20个物种名。

百度飞桨paddle paddle实现蝴蝶分类_蝴蝶分类

百度飞桨paddle paddle实现蝴蝶分类_人工智能_02

数据文件包括训练集(有标注)和测试集(无标注),训练集和验证集的所有图片分别保存在Butterfly20文件夹下面的20个文件夹中,文件名即属-物种标签,测试集共有200张待分类的蝴蝶图片在test文件夹下,名称为:图片ID.jpg。

三、实验步骤及结果

1. 解压文件夹

百度飞桨paddle paddle实现蝴蝶分类_蝴蝶分类_03

!cd data && unzip -oq /home/aistudio/data/data126285/Butterfly20_test.zip && rm -r __MACOSX
!cd data && unzip -oq /home/aistudio/data/data126285/Butterfly20.zip && rm -r __MACOSX

2. 查看数据集中的图片

import matplotlib.pyplot as plt
import PIL.Image as Image
path='/home/aistudio/data/Butterfly20/001.Atrophaneura_horishanus/006.jpg'
img = Image.open(path)
plt.imshow(img)          #根据数组绘制图像
plt.show()               #显示图像
print(img.size)

百度飞桨paddle paddle实现蝴蝶分类_paddle_04

3. 数据类别分布统计

import pandas as pd
import cv2
import numpy as np
import glob
data_path='/home/aistudio/data/Butterfly20/*/*.jpg'
test_path='/home/aistudio/data/Butterfly20_test/*.jpg'
but_files =glob.glob(data_path)
data_list = [] #用个列表保存每个样本的读取路径、标签
#由于属种名称本身是字符串,而输入模型的是数字。需要构造一个字典,把某个数字代表该属种名称。键是属种名称,值是整数。
label_list=[]
with open("/home/aistudio/data/species.txt") as f:
    for line in f:
        a,b = line.strip("\n").split(" ")
        label_list.append([b, int(a)-1])
label_dic = dict(label_list)
df = pd.DataFrame(but_files,columns=['filepath'])            #生成数据框。
df['name'] = df.filepath.apply(lambda x:x.split('/')[-2])    #按要求产生相对路径。只要工作目录下的相对路径 。
df['label']=df.name.map(label_dic)                           #用映射生成标签   
df['shape']=df.filepath.apply(lambda x:cv2.imread(x).shape)  #数据形状 
df['height']=df['shape'].apply(lambda x:x[0])
df['width']=df['shape'].apply(lambda x:x[1])
df_dataset=df[['filepath','label']]
dataset=np.array(df_dataset).tolist()
group=df.name.value_counts()                                 #查看样品分布情况
plt.figure(figsize=(8,4),dpi=100)
group.plot(kind='bar',color='red')

百度飞桨paddle paddle实现蝴蝶分类_人工智能_05

百度飞桨paddle paddle实现蝴蝶分类_Image_06

4. 数据准备

#建立样本数据读取路径与样本标签之间的关系
import os
import random

data_list = [] #用个列表保存每个样本的读取路径、标签

#由于属种名称本身是字符串,而输入模型的是数字。需要构造一个字典,把某个数字代表该属种名称。键是属种名称,值是整数。
label_list=[]
with open("/home/aistudio/data/species.txt") as f:
    for line in f:
        a,b = line.strip("\n").split(" ")
        label_list.append([b, int(a)-1])
label_dic = dict(label_list)

#获取Butterfly20目录下的所有子目录名称,保存进一个列表之中
class_list = os.listdir("/home/aistudio/data/Butterfly20")
class_list.remove('.DS_Store') #删掉列表中名为.DS_Store的元素,因为.DS_Store并没有样本。

for each in class_list:
    for f in os.listdir("/home/aistudio/data/Butterfly20/"+each):
        data_list.append(["/home/aistudio/data/Butterfly20/"+each+'/'+f,label_dic[each]])

#按文件顺序读取,可能造成很多属种图片存在序列相关,用random.shuffle方法把样本顺序彻底打乱。
random.shuffle(data_list)

#打印前十个,可以看出data_list列表中的每个元素是[样本读取路径, 样本标签]。
print(data_list[0:10])

#打印样本数量,一共有1866个样本。
print("样本数量是:{}".format(len(data_list)))

百度飞桨paddle paddle实现蝴蝶分类_paddle_07

百度飞桨paddle paddle实现蝴蝶分类_人工智能_08

百度飞桨paddle paddle实现蝴蝶分类_蝴蝶分类_09

#构造读取器与数据预处理
#首先需要导入相关的模块
import paddle
from paddle.vision.transforms import Compose, ColorJitter, Resize,Transpose, Normalize
import cv2
import numpy as np
from PIL import Image
from paddle.io import Dataset

#自定义的数据预处理函数,输入原始图像,输出处理后的图像,可以借用paddle.vision.transforms的数据处理功能
def preprocess(img):
    transform = Compose([
        Resize(size=(224, 224)), #把数据长宽像素调成224*224
        Normalize(mean=[127.5, 127.5, 127.5], std=[127.5, 127.5, 127.5], data_format='HWC'), #标准化
        Transpose(), #原始数据形状维度是HWC格式,经过Transpose,转换为CHW格式
        ])
    img = transform(img).astype("float32")
    return img

#自定义数据读取器
class Reader(Dataset):
    def __init__(self, data, is_val=False):
        super().__init__()
        #在初始化阶段,把数据集划分训练集和测试集。由于在读取前样本已经被打乱顺序,取20%的样本作为测试集,80%的样本作为训练集。
        self.samples = data[-int(len(data)*0.2):] if is_val else data[:-int(len(data)*0.2)]

    def __getitem__(self, idx):
        #处理图像
        img_path = self.samples[idx][0] #得到某样本的路径
        img = Image.open(img_path)
        if img.mode != 'RGB':
            img = img.convert('RGB')
        img = preprocess(img) #数据预处理--这里仅包括简单数据预处理,没有用到数据增强

        #处理标签
        label = self.samples[idx][1] #得到某样本的标签
        label = np.array([label], dtype="int64") #把标签数据类型转成int64
        return img, label

    def __len__(self):
        #返回每个Epoch中图片数量
        return len(self.samples)

#生成训练数据集实例
train_dataset = Reader(data_list, is_val=False)

#生成测试数据集实例
eval_dataset = Reader(data_list, is_val=True)

#打印一个训练样本
print(len(train_dataset)) #1866*0.8=1492.8
#print(train_dataset[1136][0])
print(train_dataset[1136][0].shape)
print(train_dataset[1136][1])

百度飞桨paddle paddle实现蝴蝶分类_数据_10

百度飞桨paddle paddle实现蝴蝶分类_人工智能_11

5. 定义模型

#定义模型
class MyNet(paddle.nn.Layer):
    def __init__(self):
        super(MyNet,self).__init__()
        self.layer=paddle.vision.models.resnet101(pretrained=True)
        self.fc = paddle.nn.Linear(1000, 20)
    #网络的前向计算过程
    def forward(self,x):
        x=self.layer(x)
        x=self.fc(x)
        return x

百度飞桨paddle paddle实现蝴蝶分类_paddle_12

#################查看网络结构(每层参数)################
input = paddle.static.InputSpec([None, 3, 224, 224], 'float32', 'x')
label = paddle.static.InputSpec([1], 'int64', 'label')
net = MyNet()
model = paddle.Model(net, input, label)
model.summary((-1, 3, 224, 224))

百度飞桨paddle paddle实现蝴蝶分类_数据_13

百度飞桨paddle paddle实现蝴蝶分类_Image_14

#定义输入
input_define = paddle.static.InputSpec(shape=[-1,3,224,224], dtype="float32", name="img")
label_define = paddle.static.InputSpec(shape=[-1,1], dtype="int64", name="label")

百度飞桨paddle paddle实现蝴蝶分类_人工智能_15

6. 模型训练

#实例化网络对象并定义优化器等训练逻辑
model = MyNet()
model = paddle.Model(model,inputs=input_define,labels=label_define) #用Paddle.Model()对模型进行封装
optimizer = paddle.optimizer.Adagrad(learning_rate=0.0003, weight_decay=0.01, parameters=model.parameters())
#上述优化器中的学习率(learning_rate)参数很重要。要是训练过程中得到的准确率呈震荡状态,忽大忽小,可以试试进一步把学习率调低。

model.prepare(optimizer=optimizer, #指定优化器
              loss=paddle.nn.CrossEntropyLoss(), #指定损失函数
              metrics=paddle.metric.Accuracy()) #指定评估方法

model.fit(train_data=train_dataset,     #训练数据集
          eval_data=eval_dataset,         #测试数据集
          batch_size=64,                  #一个批次的样本数量
          epochs=13,                      #迭代轮次
          save_dir="/home/aistudio/final", #把模型参数、优化器参数保存至自定义的文件夹
          save_freq=1,                    #设定每隔多少个epoch保存模型参数及优化器参数
          log_freq=100                     #打印日志的频率
)

百度飞桨paddle paddle实现蝴蝶分类_蝴蝶分类_16


7. 模型预测

class InferDataset(Dataset):
    def __init__(self, img_path=None):
        """
        数据读取Reader(推理)
        :param img_path: 推理单张图片
        """
        super().__init__()
        if img_path:
            self.img_paths = [img_path]
        else:
            raise Exception("请指定需要预测对应图片路径")

    def __getitem__(self, index):
        # 获取图像路径
        img_path = self.img_paths[index]
        # 使用Pillow来读取图像数据并转成Numpy格式
        img = Image.open(img_path)
        if img.mode != 'RGB': 
            img = img.convert('RGB') 
        img = preprocess(img) #数据预处理--这里仅包括简单数据预处理,没有用到数据增强
        return img

    def __len__(self):
        return len(self.img_paths)

#实例化推理模型
model = paddle.Model(MyNet(),inputs=input_define)

#读取刚刚训练好的参数
model.load('/home/aistudio/final/final')

#准备模型
model.prepare()

#得到待预测数据集中每个图像的读取路径
infer_list=[]
with open("/home/aistudio/data/testpath.txt") as file_pred:
    for line in file_pred:
        infer_list.append("/home/aistudio/data/"+line.strip())

#模型预测结果通常是个数,需要获得其对应的文字标签。这里需要建立一个字典。
def get_label_dict2():
    label_list2=[]
    with open("/home/aistudio/data/species.txt") as filess:
        for line in filess:
            a,b = line.strip("\n").split(" ")
            label_list2.append([int(a)-1, b])
    label_dic2 = dict(label_list2)
    return label_dic2

label_dict2 = get_label_dict2()
#print(label_dict2)

#利用训练好的模型进行预测
results=[]
for infer_path in infer_list:
    infer_data = InferDataset(infer_path)
    result = model.predict(test_data=infer_data)[0] #关键代码,实现预测功能
    result = paddle.to_tensor(result)
    result = np.argmax(result.numpy()) #获得最大值所在的序号
    results.append("{}".format(label_dict2[result])) #查找该序号所对应的标签名字

#把结果保存起来
with open("work/model_result.txt", "w") as f:
    for r in results:
        f.write("{}\n".format(r))

百度飞桨paddle paddle实现蝴蝶分类_paddle_17

百度飞桨paddle paddle实现蝴蝶分类_蝴蝶分类_18

百度飞桨paddle paddle实现蝴蝶分类_Image_19

百度飞桨paddle paddle实现蝴蝶分类_数据_20

8. 测试集精度验证


# 按行读取答案标签文件
import codecs
f = codecs.open('/home/aistudio/work/result.txt', mode='r', encoding='utf-8')  # 打开txt文件,以‘utf-8’编码读取
line = f.readline()   # 以行的形式进行读取文件
list1 = []
while line:
    a = line.split('.')
    b = a[0]       # 这是选取需要读取的位数
    list1.append(b)  # 将其添加在列表之中
    line = f.readline()
f.close()
# 将读取到的字符串列表转换为整型列表
list2 = []
for i in list1:
    x = int(i)
    list2.append(x)
# 读取模型预测标签文件
f = codecs.open('/home/aistudio/work/model_result.txt', mode='r', encoding='utf-8')  # 打开txt文件,以‘utf-8’编码读取
line = f.readline()   # 以行的形式进行读取文件
list1 = []
while line:
    a = line.split('.')
    b = a[0]       # 这是选取需要读取的位数
    list1.append(b)  # 将其添加在列表之中
    line = f.readline()
f.close()
list3 = []
for i in list1:
    x = int(i)
    list3.append(x)
# list2,list3转换为可以加减的格式
import numpy as np
list2new = np.array(list2)
list3new = np.array(list3)
list4 = list2new-list3new
# 记录预测正确的标签个数
count = 0
for number in list4:
    if number == 0:
        count = count + 1
# 输出百分比结果
result = count/2
print("模型预测正确率为:{:.2f}%".format(result))

百度飞桨paddle paddle实现蝴蝶分类_数据_21

百度飞桨paddle paddle实现蝴蝶分类_人工智能_22

最终结果预测正确率为90.5%.

标签:img,self,list,paddle,label,飞桨,data,百度
From: https://blog.51cto.com/u_16532251/9446123

相关文章

  • 人工智能||百度飞桨paddle paddle——CIFAR10数据集CNN实现猫狗分类
    猫狗分类一、实验背景图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题。猫狗分类属于图像分类中的粗粒度分类问题。(1)数据集介绍我们使用CIFAR10数据集。CIFAR10数据集包含60,000张32x32的彩色图片,10个类别,每个类包含6,000张。其中50,000张图片作......
  • 百度地图开发使用汇总
    地图开发使用汇总百度官网:https://map.baidu.com/开发平台:https://lbsyun.baidu.com/高德官网:https://www.amap.com/开发平台:https://lbs.amap.com/腾讯官网:https://map.qq.com/开放平台:https://lbs.qq.com/百度地图基本操作应用类型:浏览器javascriptapi应用......
  • 中国大模型迎来“95后” 百度奖学金发掘百位“未来AI技术领袖”
    在人工智能掀起的科技革命和产业变革浪潮下,大模型成为最受关注的研究领域。1月22日,第十一届百度奖学金颁奖典礼在北京举行,来自全球顶尖高校及科研机构的10位“未来AI技术领袖”脱颖而出,他们平均年龄仅27岁,其中8人聚焦大模型领域。百度首席技术官王海峰致辞并颁奖。百度首席技术......
  • java代码通过百度获取第一条搜索结果代码以及注意事项
    导入依赖:<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>4.4.3</version></dependency><de......
  • 有挑战才有收获!PaddleOCR算法模型挑战赛火热开启!
    在数字化时代,文本和表格识别在生活和工作中扮演着越来越重要的角色。从扫描件、图片中的文字提取,到自动化录入数据、分析报表,这些场景都需要高效准确的文本识别和表格识别技术。作为PaddleOCR开源项目背后的维护者,飞桨团队一直致力于提升光学字符识别(Opticalcharacterrecognition......
  • 百度网盘(百度云)SVIP超级会员共享账号每日更新(2024.01.23)
    一、百度网盘SVIP超级会员共享账号可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答。我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免了U盘的物理载体,直接在网上就实现文件传输。百度网盘SVIP会员可以让自己百度账......
  • 百度网盘(百度云)SVIP超级会员共享账号每日更新(2024.01.21)
    一、百度网盘SVIP超级会员共享账号可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答。我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免了U盘的物理载体,直接在网上就实现文件传输。百度网盘SVIP会员可以让自己百度账......
  • 百度面试,跪了!凉经分享
    前两天有位朋友去应聘百度测试开发工程师,面试完自我感觉还行,手撕算法、手撕SQL都写出来了,八股也回答的不错,但被通知没通过一面。所以朋友就有点不解,于是就跑来问我原因。从上面的聊天记录可以看出,面试官的反馈有两个未通过的原因:自我思考力一般。学习能力一般。题外话:这也太较真......
  • 花200块咨询费买的百度千帆大模型的流式数据解析方法
    EventSource只能使用GET方法,所以只能使用fetch或者xhr来实现,该示例使用的fetch来实现。//千帆流式接口js调用demofunctioncallWenXinWorkshopSSE(url,access_token,body,onMessage){body.stream=true;constdecoder=newTextDecoder("utf-8");letbuf......
  • 全流程机器视觉工程开发(一)环境准备,paddledetection和labelme
    前言我现在在准备做一个全流程的机器视觉的工程,之前做了很多理论相关的工作。大概理解了机器视觉的原理,然后大概了解了一下,我发现现在的库其实已经很发展了,完全不需要用到非常多的理论,只需要知道开发过程就可以了,甚至paddlex已经直接有了傻瓜式模型训练的软件,所以我现在准备来做......