Kaggle-狗种类的识别(Pytorch框架)基本图像识别流程

news2024/12/23 2:34:59

请添加图片描述

狗类别实现过程

一. 将数据集按标签分类,将标签转换为数字表示,并制作数据集
二. 搭建网络框架,inception,或者ResNet
三. 选择优化函数,训练模型

数据集制作

首先分析数据集,题中已经很明确告诉有120 种狗,那么就有120种标签值,分别为0-119。
给了一个训练集,和一个csv文件,图像在训练集中,图像的标签在csv文件里,那么如何将图片和它的标签去捆绑,因为训练图像的流程就是拿图像训练得出预测值,和它标签进行损失计算。
首先观察csv文件:

在这里插入图片描述

训练集:
在这里插入图片描述

csv文件中给出了每张图片的标签值,那么要做的就是按照csv文件里的标签值,将图片复制到另一个文件夹中,进行分类,属于同一品中的狗放到同一文件夹中,然后用内置API ImageFolder 去自动设置标签。具体原理如下

在这里插入图片描述
左面是已经将训练集分类好的新训练集,将同一种类的图片归置到一起,那么ImageFolder会将每个文件夹中的照片赋值为相同的标签值,从0开始,例如第一个文件夹kuvasz 里的照片的标签全部赋值为0,下一个文件夹kerry_blue_terrier 标签赋值为1 ,它这种标签是自动生成的,不需要人为的加

那么要做的第一步,读取csv文件,创建一个字典,保证每张图片能够准确划分到属于它的类(文件夹)中,因为训练集中的图片要按照字典查找它的标签才能复制到它对应的文件夹中。

import pandas as pd 
def read_train_csv():
    df=pd.read_csv("/kaggle/input/dog-breed-identification/labels.csv")    
    id=df.iloc[0:,0].values         #读取每张图片的id,也就是训练集图片名称,从第一行开始到最后一行,第一列,想要从pandas数据转化为列表,必须后缀.values
    breed=df.iloc[0:,1].values      #读取第二行标签值
    return dict(zip(id,breed))      #将图片id和其对应的标签值捆绑,这里并不是图片,而是图片名称,图片要通过这个字典查询它应该放哪个文件夹中

定义复制函数

import shutil
import os
def copy_dir(data_dir,target_dir):       #源地址和目标地址
    os.makedirs(target_dir,exist_ok=True)        #如果目标地址不存在,先创建
    shutil.copy(data_dir,target_dir)             #复制
    

定义分类函数,将训练集分类,将图片按照上面的字典进行分类

#这里源文件地址是 /kaggle/input/dog-breed-identification/train
#目的文件地址是output中 :/kaggle/working/train

def train_to_data(data_dir,target_dir):    #训练集的地址,目标地址
    dict=read_train_csv()                  #用上面的读取csv文件函数返回训练集的字典
    for data in os.listdir(data_dir):      #将放训练集图片的文件夹迭代一张一张拿出来读
        label=dict.get(data.split('.')[0])  #因为我们用os读取出来是照片名称,格式为000bec180eb18c7604dcecc8fe0dba07.jpg,我们要前半部分作为value,去字典中查找key,那么查出来该img的label
        fname=os.path.join(data_dir,data)   #获取该图片的地址
        copy_dir(fname,os.path.join(target_dir,label))   #将图片复制到对应的文件夹中,文件名称就是label
train_to_data("/kaggle/input/dog-breed-identification/train","/kaggle/working/train")  #进行数据分类

#转移测试集,因为我们最后要预测测试集,所以也要把测试集封装成数据集,才能放到神经网络里面训练,否则光秃秃的测试集没法放进网络框架,和上面的一样
#但是将测试集都放到unknow文件中,这样ImageFolder会将其直接封装为标签值为0的数据集,因为我们要预测它标签值,所以这里赋值为多少都无所谓
for test_data in os.listdir("/kaggle/input/dog-breed-identification/test/"):
    copy_dir(os.path.join("/kaggle/input/dog-breed-identification/test",test_data),"/kaggle/working/test/unknow")

训练集图片分类完成后,那么就开始制作训练数据集了

#首先进行图像处理,数据增强,所有图像识别必须要做的,因为该数据集每张的图片大小不同,所以要统一图片像素大小

import torchvision
train_transform=torchvision.transforms.Compose([torchvision.transforms.RandomResizedCrop(224,scale=(0.08,1.0),ratio=(3.0/4.0,4.0/3.0)),       #设置裁剪出来的像素大小为224
                                                torchvision.transforms.RandomHorizontalFlip(),    #随机进行水平翻转
                                                torchvision.transforms.ColorJitter(
                                                        brightness=0.4,
                                                        contrast=0.4,
                                                        saturation=0.4
                                                ),                              #调图像的色彩度                                                
                                                torchvision.transforms.ToTensor(),               #必须有,将图像变为tensor向量,否则没法放进网络中运行,将维度[224,224,3] 变为 [3,224,224]
                                                torchvision.transforms.Normalize([0.485,0.456,0.406],  [0.229,0.224,0.225])     #将图像数据标准化,减小计算量
])

#对测试集进行图像处理  ,只需要改变尺寸,标准化数据就够了,因为只需预测
test_transform=torchvision.transforms.Compose([     torchvision.transforms.Resize(256),
                                                    torchvision.transforms.CenterCrop(224),
                                                    torchvision.transforms.ToTensor(),
                                                    torchvision.transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])])


#制作数据集,ImageFolder的原理上面已经说过,但是切记ImageFolder的文件地址必须是你分类数据集的上一级!,例如分好类后在文件夹/train/下
#那么ImageFolder的文件地址就只能到train/为止,因为ImageFolder是按照文件夹的名称赋值标签值的,它要看文件夹的名称,不能直接定位到具体某一类的文件夹上
from torch.utils.data import DataLoader
train_mid_data=torchvision.datasets.ImageFolder('/kaggle/working/train/',transform=train_transform)       #ImageFolder可以自动将对应文件夹中的图片进行标签赋值  但是切记,文件地址必须为上一级,否则会出错!
train_data=DataLoader(train_mid_data,batch_size=32,drop_last=True,shuffle=True)               #数据集制作,32个为一组,打乱数据集顺序,不能让网络挨次训练某一类型数据

#制作测试集数据,方便后面直接扔到网络模型中预测
test_mid_data=torchvision.datasets.ImageFolder('/kaggle/working/test/',transform=test_transform)
test_data=DataLoader(test_mid_data,batch_size=32)    

以上就是完整的数据集制作流程,具体的图像数据集制作可以看下面这篇文章

PyTorch数据集制作

网络模型搭建

这里做了三种网络的对比,第一种是 ResNet残差网络,第二种是LeNet网络
,第三种GoolgeNet网络,对比了性能,第三种最好
第三种使用的是inception模块 ,inception具体的原理是用不同的卷积维度,对同一张图片进行卷积,然后将不同卷积后的结果结合起来形成完整的一个结果。
在这里插入图片描述

完整的一个GoogleNet模型如下图:
在这里插入图片描述

实现很简单:

from torch import nn
from torch.nn import functional as F
class inception(nn.Module):
    def __init__(self,inchannels,c1,c2,c3,c4):
        super().__init__()
        self.p1_1=nn.Conv2d(inchannels,c1,kernel_size=1)
        self.p2_1=nn.Conv2d(inchannels,c2[0],kernel_size=1)
        self.p2_2=nn.Conv2d(c2[0],c2[1],kernel_size=3,padding=1)
        self.p3_1=nn.Conv2d(inchannels,c3[0],kernel_size=1)
        self.p3_2=nn.Conv2d(c3[0],c3[1],kernel_size=5,padding=2)
        self.p4_1=nn.MaxPool2d(kernel_size=3,padding=1,stride=1)
        self.p4_2=nn.Conv2d(inchannels,c4,kernel_size=1)
    def forward(self,x):
        x1=F.relu(self.p1_1(x))
        x2=F.relu(self.p2_2(F.relu(self.p2_1(x))))
        x3=F.relu(self.p3_2(F.relu(self.p3_1(x))))
        x4=F.relu(self.p4_2(F.relu(self.p4_1(x))))
        return torch.cat((x1,x2,x3,x4),dim=1)
    
b1=nn.Sequential(nn.Conv2d(in_channels=3,out_channels=64,kernel_size=7,stride=2,padding=3),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=3,stride=2,padding=1))
b2=nn.Sequential(nn.Conv2d(64,64,kernel_size=1),nn.ReLU(),
                nn.Conv2d(64,192,kernel_size=3,padding=1),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=3,stride=2,padding=1))
b3=nn.Sequential(inception(192,64,(96,128),(16,32),32),
                 inception(256,128,(128,192),(32,96),64),
                 nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
                )
b4=nn.Sequential(inception(480,192,(96,208),(16,48),64),
                inception(512,160,(112,224),(24,64),64),
                inception(512,128,(128,256),(24,64),64),
                inception(512,112,(144,288),(32,64),64),
                inception(528,256,(160,320),(32,128),128),
                nn.MaxPool2d(kernel_size=3,stride=2,padding=1))
b5=nn.Sequential(inception(832,256,(160,320),(32,128),128),
                inception(832,384,(192,384),(48,128),128),
                nn.AdaptiveAvgPool2d((1,1)),
                nn.Flatten())

#得到神经网络模型,上面模型是可以直接复制用的
def get_net():
    net=nn.Sequential(b1,b2,b3,b4,b5,nn.Linear(1024,120))
    return net

下面是一个简单模型框架也可以选择:

from torch import nn
from torch.nn import functional as F
class net(nn.Module):
    def __init__(self):
        super().__init__()
        #224 224 3
        self.conv1=nn.Conv2d(in_channels=3,out_channels=64,kernel_size=3,padding=1)
        self.bn1=nn.BatchNorm2d(64)
        self.pool1=nn.MaxPool2d(kernel_size=2,stride=2)
        #112 112 64
        self.conv2=nn.Conv2d(in_channels=64,out_channels=128,kernel_size=3,padding=1)
        self.bn2=nn.BatchNorm2d(128)
        self.pool2=nn.MaxPool2d(kernel_size=2,stride=2)
        #56 56 128
        self.conv3=nn.Conv2d(in_channels=128,out_channels=256,kernel_size=3,padding=1)
        self.bn3=nn.BatchNorm2d(256)
        self.pool3=nn.MaxPool2d(kernel_size=2,stride=2)
        #28 28 256
        self.conv4=nn.Conv2d(in_channels=256,out_channels=512,kernel_size=3,padding=1)
        self.bn4=nn.BatchNorm2d(512)
        self.pool4=nn.MaxPool2d(kernel_size=2,stride=2)
        #14 14 512
        self.conv5=nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,padding=1)
        self.bn5=nn.BatchNorm2d(512)
        self.pool5=nn.MaxPool2d(kernel_size=2,stride=2)
        #7 7 512

        self.Linear1=nn.Linear(in_features=7*7*512,out_features=240)
        self.Linear2=nn.Linear(in_features=240,out_features=120)
        
    def forward(self,x):
        x=F.relu(self.pool1(self.bn1(self.conv1(x))))
        x=F.relu(self.pool2(self.bn2(self.conv2(x))))
        x=F.relu(self.pool3(self.bn3(self.conv3(x))))
        x=F.relu(self.pool4(self.bn4(self.conv4(x))))
        x=F.relu(self.pool5(self.bn5(self.conv5(x))))
        x=x.flatten(start_dim=1)
        x=F.relu(self.Linear1(x))
        x=self.Linear2(x)
        return x
 
def get_net():
    net=net()
    return net

做训练函数

import matplotlib.pyplot as plt
# 将程序放到GPU上跑,否则默认cpu会卡死
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')             

net=get_net().to(device)     #将模型放到GPU上,必须把数据也放到相同GPU上才能运行


def train(net,train_data,epoch_num,lr,wd):
    #这里只是用了一个简单的Adam梯度下降算法,这篇文章只是一个基础构建,可以在此基础上改进
    optimer=torch.optim.Adamax(net.parameters(),
                lr=lr,
                weight_decay=wd)     
    num_batches=len(train_data)     #用来后面的损失函数计算,得到单个图片的损失值
    loss_function=nn.CrossEntropyLoss()   #损失函数
    loss_value=[]                         #记录损失值,用来画图,将该列表直接放到plt中就能画
    for epoch in range(epoch_num):       #进行大循环
        epoch_loss=0                     #每一次大循环都要重置损失值
        for img,label in train_data:   
            img=img.to(device)           #将数据都放在GPU上
            label=label.to(device)
            optimer.zero_grad()          #一系列训练模板
            y=net(img)
            loss=loss_function(y,label)
            epoch_loss+=loss.item()
            loss.backward()
            optimer.step()
        loss_value.append(epoch_loss/(num_batches*32))
    #画损失函数的图
    plt.plot(np.squeeze(loss_value))
    plt.ylabel('cost')
    plt.xlabel('iterations (per tens)')
    plt.show()
train(net,train_data,50,6e-5,5e-4)    #开始训练,后面俩参数都可以自己调

在这里插入图片描述

其实训练的结果不是太好,损失值还是太大,可以通过调学习率去调节,这里只是用的一个最基本的参数值

进行预测测试集

前面已经将测试集数据已经做好了,直接放模型里预测,去观察题中给的需要提交的csv文件格式,可以知道需要提交的并不是你要预测这张图片属于哪种狗子,而是这张图片属于每一类狗子的概率,这里就必须要用softmax函数了,具体原理可以上网差,他会将所有情况的概率总和变为1,然后每一类的概率就是看其在这1中占比多少。

preds=[]
for i,_ in test_data:
    out_put=torch.nn.functional.softmax(net(i.to(device)),dim=1)    #将预测值进行softmax处理
    preds.extend(out_put.cpu().detach().numpy())    #将得到的预测值变为numpy数组,因为只有numpy才能存到pandas文件中 
ids=sorted(os.listdir("/kaggle/working/test/unknow"))    #将测试集的顺序按id排序,因为提交的格式id就是按大小排序的
with open("/kaggle/working/submission.csv",'w') as f:     #制作csv文件
    f.write('id,'+','.join(train_mid_data.classes)+'\n')     #先将标题标签做好
    for i,output in zip(ids,preds):   
        f.write(i.split('.')[0]+','+','.join([str(num) for num in output])+'\n')    #将每一个对应的id和预测的结果加入到文件中,其实这里逗号,csv文件都会识别,将其作为分割符号,所以在csv文件中也不会看见逗号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

头晕,脖子酸痛?颈椎有问题,人就废了一半!颈椎病分3级,不同阶段治疗方法不一样!

每天下午快下班时,在办公室就会看到一种现象: 大家纷纷扭脖子、抬头、耸肩膀......诶,脖子太难受了! 毕竟每天长时间的面对电脑,我们的脖子在承受着巨大的压力。尤其,低头 45 度时,脖子甚至承受…

Fyne ( go跨平台GUI )中文文档- 扩展Fyne (七)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

图像处理软件,常用于照片编辑和修饰

一、简介 1、一款功能强大的图像处理软件,常用于照片编辑和修饰。它提供多种工具和特效,允许用户调整照片的亮度、对比度、色彩、锐化等 二、下载 1、文末有下载链接,不明白可以私聊我哈(麻烦咚咚咚,动动小手给个关注收藏小三连&a…

【掘金量化使用技巧】用日线合成长周期k线

掘金API中的接口最长的周期是‘1d’的,因此周线/月线/年线等数据需要自己进行合成。 基本思路 用日线合成长周期的k线只需要确定好合成的周期以及需要的数据即可。 周期: 一般行情软件上提供年k、月k、周k,我也选择年、月、周再加一个季度频率。 数据:…

图纸加密防泄密软件 | 从设计到交付,2024年值得关注的图纸加密软件大盘点!

图纸者,匠心之凝聚,智慧之结晶。然,信息之海浩瀚无垠,暗流涌动,图纸之安全,实乃企业之头等大事。 故,择一良器,以密护图纸,实为当务之急。 以下,七款图纸加密…

Linux之实战命令01:xargs应用实例(三十五)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…

高刷显示器哪个好?540Hz才有资格称高刷

高刷显示器哪个好?说实话,540Hz这些才能成为高刷显示器,什么200,240的,都不够高,什么是从容,有我不用才叫从容。下面我们一起来看看540Hz的高刷显示器都有哪些吧! 1.高刷显示器哪个好 - 蚂蚁电…

2024风湿免疫科常用评估量表汇总,附操作步骤与评定标准!

常笑医学整理了5个风湿免疫科常用的评估量表,包括类风湿关节炎患者病情评价(DAS28)、系统性狼疮活动性测定(SLAM)等。这些量表在常笑医学网均支持在线评估、下载和创建项目使用。 01 类风湿关节炎患者病情评价 &#x…

实践中如何选择o1或sonnet3-5?

简述 AI更新太快导致我们不知选择什么使用更好?本文对比了新模型o1系列和Claude-3.5-sonnet的一些特点,针对不同开发场景提供了选择建议,希望能为你提供一些模型选择的参考。 模型对比 o1系列: 优势: 推理能力非常强&#xff0…

【动态规划】两个数组的 dp 问题二

两个数组的 dp 问题 1.正则表达式匹配2.交错字符串3.两个字符串的最小ASCII删除和4.最长重复子数组 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&#x1…

高德地图自定义点标记

const markerContent <div class"custom-content-marker"> <span>摄像机<span> <img src"//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png"> </div> marker.value new AMap.Marker({position:…

Ubuntu搭建java开发环境

一&#xff1a;Ubuntu安装 1、下载Ubuntu 24.04.1 LTS 官网下载地址&#xff1a;https://releases.ubuntu.com/24.04.1/ubuntu-24.04.1-desktop-amd64.iso 可以直接点击这里下载 2、使用VMware安装 新建虚拟机 之后一直下一步&#xff0c;到如下界面&#xff0c;选择 刚刚…

【MYSQL】聚合查询、分组查询、联合查询

目录 聚合查询聚合函数count()sum()avg()max()和min()总结 分组查询group by 子句having 子句 联合查询笛卡尔积内连接外连接自连接子查询单行子查询多行子查询from子句使用子查询 合并查询 聚合查询 聚合查询就是针对表中行与行之间的查询。 聚合函数 count() count(列名)&a…

战神5/战神:诸神黄昏/God of War Ragnarok(容量175GB)百度网盘下载

版本介绍 v1.0.612.4312|容量175GB|官方简体中文|支持键盘.鼠标.手柄|赠单板学习补丁 配置要求 战神5/战神&#xff1a;诸神黄昏/God of War Ragnarok 游戏介绍 不灭的北欧传奇 由Santa Monica Studio出品、Jetpack Interactive负责PC移植的佳作《God of War Ragnark》将带您…

python实现语音唤醒

1. 环境 python版本&#xff1a;3.11.9 2.完整代码 import sqlite3 import timefrom funasr import AutoModel import sounddevice as sd import numpy as np from pypinyin import lazy_pinyin# 模型参数设置 chunk_size [0, 10, 5] encoder_chunk_look_back 7 decoder_c…

气膜体育馆:低成本、高效益的体育空间解决方案—轻空间

随着全民健身和健康生活理念的兴起&#xff0c;各类体育场馆需求日益增加。在这样的市场背景下&#xff0c;气膜体育馆凭借其低成本、快速建造以及灵活多变的空间设计&#xff0c;成为现代体育场馆建设的新趋势。气膜技术为体育场馆提供了一种全新的解决方案&#xff0c;让运营…

Tomcat 漏洞复现

1、CVE-2017-12615 1、环境开启 2、首页抓包&#xff0c;修改为 PUT 方式提交 Tomcat允许适用put方法上传任意文件类型&#xff0c;但不允许isp后缀文件上传&#xff0c;因此需要配合 windows的解析漏洞 3、访问上传的jsp文件 4、使用工具进行连接 2、后台弱⼝令部署war包 1…

新建flask项目,配置入口文件,启动项目

pycharm新建flask项目时&#xff0c;会提供一个创建flask项目的导向&#xff0c;自动设置虚拟环境&#xff0c;并且安装flask及其依赖而vscode新建flask项目时&#xff0c;需要手动设置虚拟环境并安装flask&#xff0c;需要在终端使用pip install flask命令来安装flask及其依赖…

一文了解什么是大模型?到底大模型有什么用呢?

党中央、国务院面向未来准确把握时代大势&#xff0c;已于十三五期间部署推进数字中国建设&#xff0c;《国民经济和社会发展第十四个五年规划和2035年远景目标纲要》更是将“加快数字化发展&#xff0c;建设数字中国”单列成篇&#xff0c;要求“提高数字政府建设水平”&#…

Kettle的实战练习指南:从数据导入到ETL自动化

在数据集成和数据仓库建设中&#xff0c;Kettle作为一个强大的开源ETL工具&#xff0c;提供了灵活的数据抽取、转换和加载功能。本文将通过实战案例&#xff0c;详细介绍Kettle在数据导入、ETL流程设计、自动化任务调度等方面的应用。 一、数据导入 1. SQL语句导入 导入sql语…