用Pytorch实现水果分类,训练+测试(内附数据集下载,完整代码)

一.数据集下载

链接: https://pan.baidu.com/s/1_7blbYJc0ouCGmqe8kBnTw 提取码: c6ex 复制这段内容后打开百度网盘手机App,操作更方便哦

二.训练模型

1.定义数据初始化
import torchvision.transforms as transforms
image_size=(224,224) #
data_transforms=transforms.Compose([
    transforms.RandomHorizontalFlip(), #依概率(默认0.5)水平翻转
    transforms.Resize(image_size ),    #图像大小变换,统一处理成224*224
    transforms.ToTensor(),             #将图像转化成Tensor类型
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), #图像正则化

])

一、 裁剪——Crop

1.随机裁剪:transforms.RandomCrop
2.中心裁剪:transforms.CenterCrop
3.随机长宽比裁剪 transforms.RandomResizedCrop
4.上下左右中心裁剪:transforms.FiveCrop
5.上下左右中心裁剪后翻转: transforms.TenCrop
二、翻转和旋转——Flip and Rotation

6.依概率p水平翻转transforms.RandomHorizontalFlip
7.依概率p垂直翻转transforms.RandomVerticalFlip
8.随机旋转:transforms.RandomRotation
三、图像变换

9.resize:transforms.Resize
10.标准化:transforms.Normalize
11.转为tensor:transforms.ToTensor
12.填充:transforms.Pad
13.修改亮度、对比度和饱和度:transforms.ColorJitter
14.转灰度图:transforms.Grayscale
15.线性变换:transforms.LinearTransformation()
16.仿射变换:transforms.RandomAffine
17.依概率p转为灰度图:transforms.RandomGrayscale
18.将数据转换为PILImage:transforms.ToPILImage
19.transforms.Lambda
四、对transforms操作,使数据增强更灵活

20.transforms.RandomChoice(transforms)
21.transforms.RandomApply(transforms, p=0.5)
22.transforms.RandomOrder

二.导入数据集

import torchvision.datasets as datasets
train_data=datasets .ImageFolder (root='fruits-360-original-size/fruits-360-original-size/Training',transform=data_transforms  )    #双引号里面加上数据集的地址
print(train_data.classes)  #输出train_data里面的文件夹名称

输出为:
在这里插入图片描述注意:
ImageForder函数只能导入文件夹,不能导入文件。
Classes函数作用是根据分的文件夹的名字来确定的类别。

三.用DataLoader函数处理数据集
from torch.utils.data import DataLoader
batchsize=16
train_loader=DataLoader(train_data,batch_size=batchsize,shuffle=True,num_workers=1)

注意:
1.“batch_size= “一次训练所选取的样本数。
2."shuffle="输入一个布尔值来决定是否打乱数据
3.“num_workers= ”是服务于多进程(multiprocessing)数据加载的, 用于设置有多少个子进程负责数据加载. num_workers并不是越大越好, 因为过多的子进程会占据 CPU 计算资源, 使得程序中其他在CPU上的计算部分变慢, 导致整体运行时间增加.
一般来说是通过逐步增加尝试来进行设置, 比如当GPU计算利用率已经很饱和时, 说明数据读取足够满足计算需求, 则不必再增加worker数量.

四.导入模型
import torchvision.models as models
AlexNet=models.AlexNet()
model=AlexNet

注意:
torchvision.models里面内置了许多预训练的模型,比如:
AlexNet
VGG
ResNet
SqueezeNet
DenseNet
Inception v3
其中ResNet18和AlexNet可以流畅运行。除了用Pytorch自带的模型也可以从本地导入模型,也可以自己定义模型。

五.权重初始化
import torch.nn.init as init
for name,module in model._modules.items() :
    if (name=='fc'):
        init.kaiming_uniform_(module.weight,a=0,mode='fan_in')

1.均匀分布 torch.nn.init.uniform_(tensor, a=0, b=1) 服从~U(a,b)
2.正太分布 torch.nn.init.normal_(tensor, mean=0, std=1) 服从~ N(mean,std)
3.初始化为常数 torch.nn.init.constant_(tensor, val) 初始化整个矩阵为常数val
4.Xavier
5.kaiming

六.定义优化器
import torch
optimizer=torch.optim .SGD(model.parameters(),lr=0.01 )
StepLR=torch.optim.lr_scheduler .StepLR (optimizer ,step_size= 3,gamma=1 )  #每隔三次调整一下LR

注意:
StepLR()作用是等间隔的调整学习率,调整倍数为gamma倍,调整间隔为step_size。

七.调用GPU
# device=torch.device("cuda:0" if torch.cuda.is_available() else"cpu")  #采用一个GPU训练时的代码
if torch.cuda.device_count()>1: #判断cuda里面GPU数量是否大于一
    model=nn.DataParallel(model) #如果大于一就并行调用GPU,同时训练
print(device)

注意:
用GPU训练的模型,测试时只能用GPU测试

八.训练模型

import torch.nn.functional as F

def get_num_correct(outs, label):
    pass

model.to(device)  #调用GPU训练

for epoch in range(10):
    total_loss=0
    print("epoch",epoch,":***************************")

    for batch in train_loader:
        images,labels=batch
        
        images=images.to(device) #将图片传入GPU
        labels=labels.to(device)  #将标签传入GPU
        
        outs=model(images)
        loss=F.cross_entropy(outs,labels)  #正向传播
        optimizer.zero_grad()  #用过的梯度一定要清零,不然会占内存
        loss.backward()          #反向传播
        optimizer .step()        #参数优化
        total_loss +=loss.item()
    print('loss',total_loss )
九.保存模型
torch.save(model,'FruitModelGPU.pth')

三.测试模型

1.定义数据初始化
import torchvision.transforms as transforms
image_size=(224,224)
data_transforms=transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Resize(image_size ),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),

])
2.导入模型
import torch
model=torch.load('/home/ilab/FruitModelCpu4.pth',map_location='cpu')
model=model.module
model.eval()

注意:
因为使用GPU训练的模型,此时我们用CPU来进行测试,因此需要加上map_location=‘cpu’,以及另起一行加上model=model.module

3.导入测试集(测试集为文件夹时)
import torchvision.datasets as datasets
test_data=datasets .ImageFolder (root='fruits-360-original-size/fruits-360-original-size/test',transform=data_transforms  )
4.进行测试
batch = next(iter(test_data))
images, labels = batch 
out = model(images)
print(out)

注意:当测试集为打乱的文件时,前面的方法就行不通了,可以用下列方法:

1.定义数据初始化
import torchvision.transforms as transforms
image_size=(224,224)
data_transforms=transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Resize(image_size ),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),

])
2.导入训练集
import torchvision.datasets as datasets
train_data=datasets .ImageFolder (root='/ilab/datasets/local/fruits/train',transform=data_transforms )

3.导入模型
import torch
model=torch.load('/home/ilab/FruitModelCpu4.pth',map_location='cpu')
model=model.module
4.进行测试
from PIL import Image
import os
i=1
sum=22688
root='/ilab/datasets/local/fruits/test'  #将测试集的地址赋值给Root
file_list=os.listdir(root)  #返回当前文件夹里包含的文件或者文件夹的列表
model.eval()
with open('/home/ilab/submission','w') as f:
        for filename in file_list:
            filepath = os.path.join(root,filename)
            img=Image.open(filepath)
            x=data_transforms(img).reshape((1,3,224,224))
            y= model(x)
            re=filename+' '+train_data.classes[int(y.argmax(dim=1))]+'\n'
            f.write(re)
            print(re)


5.FruitModelCpu4.pth下载地址:

链接: https://pan.baidu.com/s/17sa4Rda9jLhNRzKVkfsBMA 提取码: 2xv8 复制这段内容后打开百度网盘手机App,操作更方便哦

四.完整代码

"""""""""""""""""""""""定义数据初始化方法"""""""""""""""""""""""
import torch
import torch.nn
import torchvision
import torchvision.transforms as transforms
image_size=(224,224)
data_transforms=transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Resize(image_size ),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),

])
"""""""""""""""""""""""导入数据集"""""""""""""""""""""""
import torchvision.datasets as datasets
train_data=datasets .ImageFolder (root='fruits-360-original-size/fruits-360-original-size/Training',transform=data_transforms  )
print(train_data.classes)
"""""""""""""""""""""制作DataLoader"""""""""""""""""""""""
from torch.utils.data import DataLoader
batchsize=500
train_loader=DataLoader(train_data,batch_size=batchsize,shuffle=True,num_workers=1)
""""""""""""""""""""""制作模型"""""""""""""""""""""""""""""
import torchvision.models as models
AlexNet=models.AlexNet()#(pretrained= True)
model=AlexNet
"""""""""""""""""""""权重初始化"""""""""""""""""""""""
import torch.nn.init as init
for name,module in model._modules.items() :
    if (name=='fc'):
        init.kaiming_uniform_(module.weight,a=0,mode='fan_in')
"""""""""""""""""""""""定义优化器"""""""""""""""""""""
import torch
optimizer=torch.optim .SGD(model.parameters(),lr=0.01 )
StepLR=torch.optim.lr_scheduler .StepLR (optimizer ,step_size= 3,gamma=1 )  #每隔三次调整一下LR
""""""""""""""""""""""调用GPU"""""""""""""""""""""""""""""
# device=torch.device("cuda:0" if torch.cuda.is_available() else"cpu")
if torch.cuda.device_count()>1:
    model=nn.DataParallel(model)
print(device)
"""""""""""""""""""""""""""""""训练"""""""""""""""""""""""""""""""""
import torch.nn.functional as F

def get_num_correct(outs, label):
    pass

model.to(device)

for epoch in range(10):
    total_loss=0
    print("epoch",epoch,":***************************")

    for batch in train_loader:
        images,labels=batch
        
        images=images.to(device)
        labels=labels.to(device)
        
        outs=model(images)
        loss=F.cross_entropy(outs,labels)
        optimizer.zero_grad()
        loss.backward()
        optimizer .step()
        total_loss +=loss.item()
    print('loss',total_loss )

""""""""""""""""""""""测试"""""""""""""""""""""""""
""""""""""""""""""""""权重初始化"""""""""""""""""""""""""
import torchvision.transforms as transforms
image_size=(224,224)
data_transforms=transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Resize(image_size ),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
"""""""""""""""""""""""导入数据集"""""""""""""""""""""""
import os
import torchvision.datasets as datasets
train_data=datasets .ImageFolder (root='/ilab/datasets/local/fruits/train',transform=data_transforms )
"""""""""""""""""""""""导入模型"""""""""""""""""""""""
import torch
model=torch.load('/home/ilab/FruitModelCpu4.pth',map_location='cpu')
model=model.module
"""""""""""""""""""""""测试"""""""""""""""""""""""
 from PIL import Image
import os
i=1
sum=22688
root='/ilab/datasets/local/fruits/test'
file_list=os.listdir(root)  #返回当前文件夹里包含的文件或者文件夹的列表
model.eval()
with open('/home/ilab/submission','w') as f:
        for filename in file_list:
            filepath = os.path.join(root,filename)
            img=Image.open(filepath)
            x=data_transforms(img).reshape((1,3,224,224))
            y= model(x)
            re=filename+' '+train_data.classes[int(y.argmax(dim=1))]+'\n'
            f.write(re)
            print(re)   

])

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tomorrow;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值