Python+pytorch实现天气识别

1. 介绍

天气识别是一种重要的应用,可以帮助人们及时了解天气情况,从而更好地安排生活。本文介绍如何使用Python和pytorch实现天气识别,主要涉及到以下内容:

数据集准备

构建模型

训练模型

测试模型

2. 数据集准备

数据集是机器学习领域非常重要的组成部分,数据的质量和数量直接影响到模型的性能。在天气识别任务中,我们需要构建一个数据集,包含不同天气的图片。

2.1 数据集来源

本文使用Weather Classification数据集,该数据集包含10种天气类型的图片,每种天气类型有2000张图片,共计20000张图片。

2.2 数据集预处理

为了使得模型更好地学习,我们需要进行数据集预处理。首先,我们将图片缩放到固定的大小,比如256x256;其次,我们需要将每张图片转换为模型可以接受的格式,比如RGB三通道的tensor。为了避免过拟合,我们还需要进行数据增强操作,比如随机旋转、平移、水平翻转等。

下面是对原始图片进行缩放和数据增强的代码:

import torch

from torchvision import transforms

from torchvision.datasets import ImageFolder

# 定义数据增强操作

train_transforms = transforms.Compose([

transforms.Resize(256),

transforms.RandomResizedCrop(224),

transforms.RandomRotation(30),

transforms.RandomHorizontalFlip(),

transforms.ToTensor(),

transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

])

# 加载数据集

train_dataset = ImageFolder('data/train', train_transforms)

3. 构建模型

构建模型是天气识别任务中的核心部分。在本文中,我们使用卷积神经网络(CNN)来完成天气识别任务,CNN是一种非常适合图像识别任务的深度学习模型。

3.1 模型架构

本文使用ResNet18作为模型骨干网络,在此基础上添加一个全连接层来进行分类。为了防止过拟合,我们还添加了一个Dropout层。

下面是模型的代码:

import torch.nn as nn

import torchvision.models as models

class WeatherNet(nn.Module):

def __init__(self, num_classes):

super(WeatherNet, self).__init__()

self.resnet = models.resnet18(pretrained=True)

num_features = self.resnet.fc.in_features

self.fc = nn.Linear(num_features, num_classes)

self.dropout = nn.Dropout(0.1)

def forward(self, x):

x = self.resnet(x)

x = self.dropout(x)

x = self.fc(x)

return x

model = WeatherNet(num_classes=10)

3.2 损失函数和优化器

在训练过程中,我们需要定义损失函数和优化器。对于多分类任务,常用的损失函数是交叉熵损失函数。优化器方面,我们可以选择Adam优化器。

下面是损失函数和优化器的代码:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(model.parameters(), lr=1e-3)

4. 训练模型

有了数据集和模型之后,我们就可以开始训练模型了。在训练过程中,我们需要定义一些超参数,比如batch_size、epoch等。另外,我们还需要定义一些辅助函数,如计算训练集上的准确率、记录训练过程中的损失值等。

4.1 超参数设置

在训练神经网络时,需要设置一些超参数,这些超参数会影响到模型的性能和训练速度。在本篇文章中,我们设置的超参数如下:

batch_size = 32

num_epochs = 10

learning_rate = 1e-3

4.2 训练函数

下面是训练函数的代码,主要包括训练代码和验证代码:

def train(model, criterion, optimizer, dataloader):

model.train()

running_loss = 0.0

running_corrects = 0

for inputs, labels in dataloader:

inputs = inputs.cuda()

labels = labels.cuda()

optimizer.zero_grad()

outputs = model(inputs)

loss = criterion(outputs, labels)

loss.backward()

optimizer.step()

running_loss += loss.item() * inputs.size(0)

_, preds = torch.max(outputs, 1)

running_corrects += torch.sum(preds == labels.data)

epoch_loss = running_loss / len(dataloader.dataset)

epoch_acc = running_corrects.double() / len(dataloader.dataset)

return epoch_loss, epoch_acc

def evaluate(model, criterion, dataloader):

model.eval()

running_loss = 0.0

running_corrects = 0

for inputs, labels in dataloader:

inputs = inputs.cuda()

labels = labels.cuda()

with torch.no_grad():

outputs = model(inputs)

loss = criterion(outputs, labels)

running_loss += loss.item() * inputs.size(0)

_, preds = torch.max(outputs, 1)

running_corrects += torch.sum(preds == labels.data)

epoch_loss = running_loss / len(dataloader.dataset)

epoch_acc = running_corrects.double() / len(dataloader.dataset)

return epoch_loss, epoch_acc

4.3 训练过程

下面是完整的训练过程:

import time

# 将数据集分为训练集和验证集

train_dataset, val_dataset = torch.utils.data.random_split(train_dataset, [16000, 4000])

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4)

val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, shuffle=False, num_workers=4)

# 使用GPU加速训练

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model = model.to(device)

# 开始训练

best_acc = 0.0

for epoch in range(num_epochs):

since = time.time()

print('Epoch {}/{}'.format(epoch + 1, num_epochs))

print('-' * 10)

train_loss, train_acc = train(model, criterion, optimizer, train_loader)

val_loss, val_acc = evaluate(model, criterion, val_loader)

print('Train Loss: {:.4f} Acc: {:.4f}'.format(train_loss, train_acc))

print('Val Loss: {:.4f} Acc: {:.4f}'.format(val_loss, val_acc))

time_elapsed = time.time() - since

print('Epoch complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))

if val_acc > best_acc:

best_acc = val_acc

torch.save(model.state_dict(), 'model.pt')

print('Training complete.')

5. 测试模型

有了训练好的模型后,我们就可以使用测试集来测试模型的性能了。在测试过程中,我们需要加载训练好的模型,并将测试集输入到模型中,得到模型的预测结果。

5.1 加载模型

在测试之前,我们需要加载训练好的模型。下面是加载模型的代码:

model.load_state_dict(torch.load('model.pt'))

model.eval()

5.2 测试函数

下面是测试函数的代码,包括将模型预测结果转换为标签、计算测试集上的准确率等:

def test(model, dataloader):

model.eval()

running_corrects = 0

predictions = []

for inputs, labels in dataloader:

inputs = inputs.cuda()

labels = labels.cuda()

with torch.no_grad():

outputs = model(inputs)

_, preds = torch.max(outputs, 1)

running_corrects += torch.sum(preds == labels.data)

predictions += preds.tolist()

acc = running_corrects.double() / len(dataloader.dataset)

labels = [dataset.classes[i] for i in predictions]

return acc, labels

5.3 测试过程

下面是完整的测试过程:

test_transforms = transforms.Compose([

transforms.Resize(256),

transforms.CenterCrop(224),

transforms.ToTensor(),

transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

])

test_dataset = ImageFolder('data/test', test_transforms)

test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=4)

# 使用GPU加速测试

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model = model.to(device)

test_acc, test_labels = test(model, test_loader)

print('Test Acc: {:.4f}'.format(test_acc))

6. 总结

本文介绍了如何使用Python和pytorch实现天气识别,主要涉及到了数据集准备、模型构建、模型训练和模型测试四个方面。最终,我们得到了一个准确率较高的天气识别模型,可以用于实际应用中。

后端开发标签