第二周天气识别

第二周天气识别

前言

这周学习天气识别项目,学会加载本地数据集进行训练,学会把数据集划分为·数据集和验证集,这是本周的学习重点。

数据预处理

数据准备

有四种天气需要识别,文件目录如下:
在这里插入图片描述
每一类图片数量在300-400之间

函数详解

1.数据处理函数
● pathlib.Path()
用于创建路径对象,方便对路径进行操作
● data_paths = list(data_dir.glob(‘‘))
data_dir.glob(’
’),该方法用于匹配指定模式的路径,并返回一个生成器。在代码片段中,data_dir.glob(‘*’) 是在指定的目录 (data_dir) 中查找所有条目(文件和目录),并生成一个列表。
● str(path).split(“\”) 是将路径字符串转换为字符串并使用反斜杠 () 作为分隔符进行拆分的操作。
如果 path 是 C:\Users\Username\Documents\file.txt,那么 str(path).split(“\”) 将返回以下列表:

['C:', 'Users', 'Username', 'Documents', 'file.txt']

● transforms.Compose
torchvision.transforms.Compose()类。这个类允许用户将多个图像转换按顺序组合在一起,以便在数据预处理中一次性应用这些转换。

torchvision.transforms.Compose(transforms)

from torchvision import transforms

# 定义一些图像转换
transform1 = transforms.Resize((256, 256))
transform2 = transforms.RandomCrop((224, 224))
transform3 = transforms.ToTensor()

# 使用Compose将转换组合在一起
data_transform = transforms.Compose([transform1, transform2, transform3])
# 使用创建的转换管道
transformed_image = data_transform(your_image)

注意:
● 转换的顺序很重要,因为它们按照列表中的顺序应用。
● Compose 对象的调用方式类似于一个函数,接受图像数据作为输入,返回转换后的图像数据。

  • torchvision.datasets.ImageFolder
torchvision.datasets.ImageFolder(root, transform=None, target_transform=None, loader=<function default_loader>, is_valid_file=None)

PyTorch 中 torchvision 库提供的一个类,用于加载包含图像数据的文件夹。这个类假设文件夹的组织结构是按类别划分的,每个子文件夹包含同一类别的图像。
● root(必需): 数据集的根目录路径,该目录下的子目录包含了不同类别的图像。
● transform(可选): 对图像进行的转换操作,可以使用 torchvision.transforms 中的转换函数或Compose 对象。
● target_transform(可选): 对目标标签进行的转换操作。
● loader(可选): 用于加载图像的函数,默认为 default_loader。
● is_valid_file(可选): 一个函数,用于确定文件是否为有效文件。
主要的返回值有:
● dataset.classes: 返回一个包含类别名称的列表。每个子文件夹的名称被认为是一个类别。
● dataset.class_to_idx: 返回一个将类别名称映射到类别索引的字典。
● dataset.imgs: 返回一个包含所有图像路径和标签的元组列表。

total_data = datasets.ImageFolder(total_datadir,transform=train_transforms)

# 访问返回值
classes = total_data.classes
class_to_idx = total_data.class_to_idx
imgs = total_data.imgs

# 打印返回值
print("Classes:", classes)
print("Class to Index Mapping:", class_to_idx)
print("Image Paths and Labels:", imgs)
Classes: ['cloudy', 'rain', 'shine', 'sunrise']
Class to Index Mapping: {'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3}
Image Paths and Labels: [('./data/cloudy\\cloudy1.jpg', 0), ]
len(total_data)##样本总数
  • torch.utils.data.random_split
torch.utils.data.random_split(dataset, lengths)

● dataset(必需): 要分割的数据集对象。
● lengths(必需): 一个包含两个整数的列表,表示分割后每个子数据集的长度。

功能实现

1.数据集划分

按照0.8:0.2划分数据集

train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])

2.数据加载和模型训练

这里在上周做了详细学习,不在赘述。

3.训练结果

在这里插入图片描述在这里插入图片描述

编写测试函数

网上随机下载图片
在这里插入图片描述

import torch
import torchvision
from PIL import Image
from torch import nn
import torch.nn.functional as F
image_path="./imgs/2.jpeg"
image=Image.open(image_path)
print(image)
image=image.convert('RGB')

transform=torchvision.transforms.Compose([torchvision.transforms.Resize((224,224)),torchvision.transforms.ToTensor()])
image=transform(image)
print(image.shape)

class Network_bn(nn.Module):
    def __init__(self):
        super(Network_bn, self).__init__()
        """
        nn.Conv2d()函数:
        第一个参数(in_channels)是输入的channel数量
        第二个参数(out_channels)是输出的channel数量
        第三个参数(kernel_size)是卷积核大小
        第四个参数(stride)是步长,默认为1
        第五个参数(padding)是填充大小,默认为0
        """
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(12)
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn2 = nn.BatchNorm2d(12)
        self.pool = nn.MaxPool2d(2,2)
        self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn4 = nn.BatchNorm2d(24)
        self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn5 = nn.BatchNorm2d(24)
        self.fc1 = nn.Linear(24*50*50, 4)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = self.pool(x)
        x = F.relu(self.bn4(self.conv4(x)))
        x = F.relu(self.bn5(self.conv5(x)))
        x = self.pool(x)
        x = x.view(-1, 24*50*50)
        x = self.fc1(x)

        return x

model = torch.load("model_19.pth", map_location=torch.device("cpu"))
model = Network_bn()
image = torch.reshape(image, (1, 3, 224, 224))

model.eval()#有dropout等使用
with torch.no_grad():
    output = model(image)
print(output)
print(output.argmax(1))

输出
在这里插入图片描述

总结

通过这周学习学会了加载本地数据,对数据集的划分,并进行模型训练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值