第二周天气识别
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊 | 接辅导、项目定制
- 🚀 文章来源:K同学的学习圈子
前言
这周学习天气识别项目,学会加载本地数据集进行训练,学会把数据集划分为·数据集和验证集,这是本周的学习重点。
数据预处理
数据准备
有四种天气需要识别,文件目录如下:
每一类图片数量在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))
输出
总结
通过这周学习学会了加载本地数据,对数据集的划分,并进行模型训练。