0


pytorch-实现天气识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:[365天深度学习训练营-第P3周:天气识别](**365天深度学习训练营-第P3周:天气识别 · 语雀 (yuque.com))****
  • 🍖 原作者:K同学啊|接辅导、项目定制

我的环境

  • 语言环境:Python3.6
  • 编译器:jupyter lab
  • 深度学习环境:pytorch1.10
  • 参考文章:本人博客(60条消息) 机器学习之——tensorflow+pytorch_重邮研究森的博客-CSDN博客

🍺要求:

  1. 本地读取并加载数据。(✔)

  2. 测试集accuracy到达93%(✔)

🍻拔高:

  1. 测试集accuracy到达95%(✔)
  2. 调用模型识别一张本地图片(✔)


一 前期工作

环境:python3.6,1080ti,pytorch1.10(实验室服务器的环境😂😂)

1.设置GPU或者cpu

  1. import torch
  2. import torch.nn as nn
  3. import matplotlib.pyplot as plt
  4. import torchvision
  5. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  6. device

2.导入数据

  1. import os,PIL,random,pathlib
  2. data_dir = 'weather_photos/'
  3. data_dir = pathlib.Path(data_dir)
  4. print(data_dir)
  5. data_paths = list(data_dir.glob('*'))
  6. print(data_paths)
  7. classeNames = [str(path).split("/")[1] for path in data_paths]
  8. classeNames

二 数据预处理

数据格式设置

  1. total_datadir = 'weather_photos/'
  2. # 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
  3. train_transforms = transforms.Compose([
  4. transforms.Resize([224, 224]), # 将输入图片resize成统一尺寸
  5. transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
  6. transforms.Normalize( # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
  7. mean=[0.485, 0.456, 0.406],
  8. std=[0.229, 0.224, 0.225]) # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
  9. ])
  10. total_data = datasets.ImageFolder(total_datadir,transform=train_transforms)
  11. total_data

数据集划分

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

设置dataset

  1. batch_size = 32
  2. train_dl = torch.utils.data.DataLoader(train_dataset,
  3. batch_size=batch_size,
  4. shuffle=True,
  5. num_workers=1)
  6. test_dl = torch.utils.data.DataLoader(test_dataset,
  7. batch_size=batch_size,
  8. shuffle=True,
  9. num_workers=1)

检查数据格式

  1. for X, y in test_dl:
  2. print("Shape of X [N, C, H, W]: ", X.shape)
  3. print("Shape of y: ", y.shape, y.dtype)
  4. break

三 搭建网络

  1. import torch
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential,ReLU
  4. num_classes = 4
  5. class Model(nn.Module):
  6. def __init__(self):
  7. super(Model,self).__init__()
  8. # 卷积层
  9. self.layers = Sequential(
  10. # 第一层
  11. nn.Conv2d(3, 24, kernel_size=5),
  12. nn.BatchNorm2d(24),
  13. nn.ReLU(),
  14. # 第二层
  15. nn.Conv2d(24,64 , kernel_size=5),
  16. nn.BatchNorm2d(64),
  17. nn.ReLU(),
  18. nn.MaxPool2d(2,2),
  19. nn.Conv2d(64, 128, kernel_size=5),
  20. nn.BatchNorm2d(128),
  21. nn.ReLU(),
  22. nn.Conv2d(128, 24, kernel_size=5),
  23. nn.BatchNorm2d(24),
  24. nn.ReLU(),
  25. nn.MaxPool2d(2,2),
  26. nn.Flatten(),
  27. nn.Linear(24*50*50, 516,bias=True),
  28. nn.ReLU(),
  29. nn.Dropout(0.5),
  30. nn.Linear(516, 215,bias=True),
  31. nn.ReLU(),
  32. nn.Dropout(0.5),
  33. nn.Linear(215, num_classes,bias=True),
  34. )
  35. def forward(self, x):
  36. x = self.layers(x)
  37. return x
  38. device = "cuda" if torch.cuda.is_available() else "cpu"
  39. print("Using {} device".format(device))
  40. model = Model().to(device)
  41. model

打印网络结构

四 训练模型

1.设置学习率

  1. loss_fn = nn.CrossEntropyLoss() # 创建损失函数
  2. learn_rate = 1e-3 # 学习率
  3. opt = torch.optim.SGD(model.parameters(),lr=learn_rate)

2.模型训练

训练函数

  1. # 训练循环
  2. def train(dataloader, model, loss_fn, optimizer):
  3. size = len(dataloader.dataset) # 训练集的大小,一共60000张图片
  4. num_batches = len(dataloader) # 批次数目,1875(60000/32)
  5. train_loss, train_acc = 0, 0 # 初始化训练损失和正确率
  6. for X, y in dataloader: # 获取图片及其标签
  7. X, y = X.to(device), y.to(device)
  8. # 计算预测误差
  9. pred = model(X) # 网络输出
  10. loss = loss_fn(pred, y) # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失
  11. # 反向传播
  12. optimizer.zero_grad() # grad属性归零
  13. loss.backward() # 反向传播
  14. optimizer.step() # 每一步自动更新
  15. # 记录acc与loss
  16. train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
  17. train_loss += loss.item()
  18. train_acc /= size
  19. train_loss /= num_batches
  20. return train_acc, train_loss

测试函数

  1. def test (dataloader, model, loss_fn):
  2. size = len(dataloader.dataset) # 测试集的大小,一共10000张图片
  3. num_batches = len(dataloader) # 批次数目,313(10000/32=312.5,向上取整)
  4. test_loss, test_acc = 0, 0
  5. # 当不进行训练时,停止梯度更新,节省计算内存消耗
  6. with torch.no_grad():
  7. for imgs, target in dataloader:
  8. imgs, target = imgs.to(device), target.to(device)
  9. # 计算loss
  10. target_pred = model(imgs)
  11. loss = loss_fn(target_pred, target)
  12. test_loss += loss.item()
  13. test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()
  14. test_acc /= size
  15. test_loss /= num_batches
  16. return test_acc, test_loss

具体训练代码

  1. epochs = 30
  2. train_loss = []
  3. train_acc = []
  4. test_loss = []
  5. test_acc = []
  6. for epoch in range(epochs):
  7. model.train()
  8. epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
  9. model.eval()
  10. epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
  11. train_acc.append(epoch_train_acc)
  12. train_loss.append(epoch_train_loss)
  13. test_acc.append(epoch_test_acc)
  14. test_loss.append(epoch_test_loss)
  15. template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')
  16. print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
  17. print('Done')

五 模型评估

1.Loss和Accuracy图

  1. import matplotlib.pyplot as plt
  2. #隐藏警告
  3. import warnings
  4. warnings.filterwarnings("ignore") #忽略警告信息
  5. plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
  6. plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
  7. plt.rcParams['figure.dpi'] = 100 #分辨率
  8. epochs_range = range(epochs)
  9. plt.figure(figsize=(12, 3))
  10. plt.subplot(1, 2, 1)
  11. plt.plot(epochs_range, train_acc, label='Training Accuracy')
  12. plt.plot(epochs_range, test_acc, label='Test Accuracy')
  13. plt.legend(loc='lower right')
  14. plt.title('Training and Validation Accuracy')
  15. plt.subplot(1, 2, 2)
  16. plt.plot(epochs_range, train_loss, label='Training Loss')
  17. plt.plot(epochs_range, test_loss, label='Test Loss')
  18. plt.legend(loc='upper right')
  19. plt.title('Training and Validation Loss')
  20. plt.show()

2.对结果进行预测

  1. import os
  2. import json
  3. import torch
  4. from PIL import Image
  5. from torchvision import transforms
  6. import matplotlib.pyplot as plt
  7. img_path = "weather_photos/cloudy/cloudy1.jpg"
  8. classes = ['cloudy', 'rain', 'shine', 'sunrise']
  9. data_transform = transforms.Compose([
  10. transforms.Resize([224, 224]), # 将输入图片resize成统一尺寸
  11. transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
  12. transforms.Normalize( # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
  13. mean=[0.485, 0.456, 0.406],
  14. std=[0.229, 0.224, 0.225]) # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
  15. ])
  16. def main():
  17. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  18. img = Image.open(img_path)
  19. plt.imshow(img)
  20. # [N, C, H, W]
  21. img = data_transform(img)
  22. # expand batch dimension
  23. img = torch.unsqueeze(img, dim=0)
  24. model.eval()
  25. with torch.no_grad():
  26. # predict class
  27. output = torch.squeeze(model(img.to(device))).cpu()
  28. predict = torch.softmax(output, dim=0)
  29. predict_cla = torch.argmax(predict).numpy()
  30. print(classes[predict_cla])
  31. plt.show()
  32. if __name__ == '__main__':
  33. main()

预测结果如下:

3.总结

1.本次能主要对以下函数进行了学习
transforms.Compose针对数据转换,例如尺寸,类型datasets.ImageFolder结合上面这个对某文件夹下数据处理torch.utils.data.DataLoader设置dataset
详情文章参考如下:

torchvision.transforms.Compose()详解【Pytorch入门手册】_K同学啊的博客-CSDN博客_torchvision.transforms.compose

(10条消息) torchvision.datasets.ImageFolder_平凡的久月的博客-CSDN博客_datasets.imagefolder

2.对于pytorch下面进行预测感觉还添麻烦的,,,,,上文预测代码还是网上搜的。

3.准确率提高到了97


本文转载自: https://blog.csdn.net/m0_60524373/article/details/127195845
版权归原作者 重邮研究森 所有, 如有侵权,请联系我们删除。

“pytorch-实现天气识别”的评论:

还没有评论