当前位置 : 主页 > 编程语言 > python >

Python+pytorch实现天气识别

来源:互联网 收集:自由互联 发布时间:2023-01-30
目录 一、前期工作 1.设置GPU或者cpu 2.导入数据 二、数据预处理 三、搭建网络 四、训练模型 1.设置学习率 2.模型训练 五、模型评估 1.Loss和Accuracy图 2.对结果进行预测 3.总结 一、前期工
目录
  • 一、前期工作
    • 1.设置GPU或者cpu
    • 2.导入数据
  • 二、数据预处理
    • 三、搭建网络
      • 四、训练模型
        • 1.设置学习率
        • 2.模型训练
      • 五、模型评估
        • 1.Loss和Accuracy图
        • 2.对结果进行预测
        • 3.总结

      一、前期工作

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

      1.设置GPU或者cpu

      import torch
      import torch.nn as nn
      import matplotlib.pyplot as plt
      import torchvision
       
      device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
       
      device
      

      2.导入数据

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

      二、数据预处理

      数据格式设置

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

      数据集划分

      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])
      train_dataset, test_dataset
      

      设置dataset

      batch_size = 32
       
      train_dl = torch.utils.data.DataLoader(train_dataset,
                                                 batch_size=batch_size,
                                                 shuffle=True,
                                                 num_workers=1)
      test_dl = torch.utils.data.DataLoader(test_dataset,
                                                batch_size=batch_size,
                                                shuffle=True,
                                                num_workers=1)
      

      检查数据格式 

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

      三、搭建网络

      import torch
      from torch import nn
      from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential,ReLU
       
      num_classes = 4
       
      class Model(nn.Module):
          def __init__(self):
              super(Model,self).__init__()
              # 卷积层
              self.layers = Sequential(
                  # 第一层
                  nn.Conv2d(3, 24, kernel_size=5),
                  nn.BatchNorm2d(24),
                  nn.ReLU(),
                  # 第二层
                  nn.Conv2d(24,64 , kernel_size=5),
                  nn.BatchNorm2d(64),
                  nn.ReLU(),
                  nn.MaxPool2d(2,2),
                  nn.Conv2d(64, 128, kernel_size=5),
                  nn.BatchNorm2d(128),
                  nn.ReLU(),
                  nn.Conv2d(128, 24, kernel_size=5),
                  nn.BatchNorm2d(24),
                  nn.ReLU(),
                  nn.MaxPool2d(2,2),
                  nn.Flatten(),
                  nn.Linear(24*50*50, 516,bias=True),
                  nn.ReLU(),
                  nn.Dropout(0.5),
                  nn.Linear(516, 215,bias=True),
                  nn.ReLU(),
                  nn.Dropout(0.5),
                  nn.Linear(215, num_classes,bias=True),
              )
       
          def forward(self, x):
       
              x = self.layers(x)
              return x    
       
       
      device = "cuda" if torch.cuda.is_available() else "cpu"
      print("Using {} device".format(device))
       
      model = Model().to(device)
      model

      打印网络结构

      四、训练模型

      1.设置学习率

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

      2.模型训练

      训练函数

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

      测试函数 

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

      具体训练代码 

      epochs     = 30
      train_loss = []
      train_acc  = []
      test_loss  = []
      test_acc   = []
       
      for epoch in range(epochs):
          model.train()
          epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
          
          model.eval()
          epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
          
          train_acc.append(epoch_train_acc)
          train_loss.append(epoch_train_loss)
          test_acc.append(epoch_test_acc)
          test_loss.append(epoch_test_loss)
          
          template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')
          print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
      print('Done')

      五、模型评估

      1.Loss和Accuracy图

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

      2.对结果进行预测

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

      预测结果如下:

      3.总结

      1.本次能主要对以下函数进行了学习

      transforms.Compose针对数据转换,例如尺寸,类型datasets.ImageFolder结合上面这个对某文件夹下数据处理torch.utils.data.DataLoader设置dataset

      以上就是Python+pytorch实现天气识别的详细内容,更多关于Python pytorch天气识别的资料请关注自由互联其它相关文章!

      上一篇:Python标准库re的使用举例(正则化匹配)
      下一篇:没有了
      网友评论