Advertisement

(深度学习记录)第P4周:猴痘病识别

阅读量:
我的环境
  • 电脑系统:Windows 11
  • 编译器:kaggle在线编译器
  • 深度学习环境:Pytorch

代码及结果:

复制代码
 import torch

    
 import torch.nn as nn
    
 import torchvision.transforms as transforms
    
 import torchvision
    
 from torchvision import transforms, datasets
    
  
    
 import os,PIL,pathlib
    
  
    
 device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
  
    
 device
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/TQu394CJsNWEYgn5kIrFvKzP8bUp.png)
复制代码
 import os,PIL,random,pathlib

    
  
    
 data_dir = '/kaggle/input/p4data'
    
 data_dir = pathlib.Path(data_dir)
    
  
    
 data_paths = list(data_dir.glob('*'))
    
 classeNames = [str(path).split("/")[1] for path in data_paths]
    
 classeNames
    
 total_datadir = '/kaggle/input/p4data'
    
 train_transforms = transforms.Compose([
    
     transforms.Resize([224, 224]), 
    
     transforms.ToTensor(),         
    
     transforms.Normalize(           
    
     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
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/wCE7iN6blVjrAxZJpMO4IkmeDsTR.png)
复制代码
    total_data.class_to_idx
    
复制代码
 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
    
    
    
    
复制代码
    train_size,test_size
    
复制代码
 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
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/AFzVK0lkoGEbcqXjQUBgTnuSND49.png)
复制代码
 import torch.nn.functional as F

    
  
    
 class Network_bn(nn.Module):
    
     def __init__(self):
    
     super(Network_bn, self).__init__()
    
     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, len(classeNames))
    
  
    
     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
    
  
    
 device = "cuda" if torch.cuda.is_available() else "cpu"
    
 print("Using {} device".format(device))
    
  
    
 model = Network_bn().to(device)
    
 model
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/vlBnSmyPJNrHps2W3MoAj4ITC0kg.png)
复制代码
 loss_fn    = nn.CrossEntropyLoss()

    
 learn_rate = 1e-4
    
 opt        = torch.optim.SGD(model.parameters(),lr=learn_rate)
    
 def train(dataloader, model, loss_fn, optimizer):
    
     size = len(dataloader.dataset)
    
     num_batches = len(dataloader)
    
     train_loss, train_acc = 0, 0
    
  
    
     for X, y in dataloader:
    
     X, y = X.to(device), y.to(device)
    
  
    
     # 调试信息
    
     #print("Batch labels:", y.min().item(), y.max().item())
    
     
    
     # 计算预测误差
    
     pred = model(X)
    
     loss = loss_fn(pred, y)
    
  
    
     # 反向传播
    
     optimizer.zero_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)
    
     num_batches = len(dataloader)
    
     test_loss, test_acc = 0, 0
    
  
    
     with torch.no_grad():
    
     for imgs, target in dataloader:
    
         imgs, target = imgs.to(device), target.to(device)
    
         
    
         # 调试信息
    
         #print("Batch labels:", target.min().item(), target.max().item())
    
  
    
         # 计算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 = 20
    
 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')
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/Et6WboAZulgpPRJxmaIFeYhk7O2L.png)
复制代码
 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()
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/TKHZNLO93zjmqkDA4iwd5y1sogtV.png)
复制代码
 from PIL import Image

    
  
    
 classes = list(total_data.class_to_idx)
    
  
    
 def predict_one_image(image_path, model, transform, classes):
    
     
    
     test_img = Image.open(image_path).convert('RGB')
    
     # plt.imshow(test_img)  # 展示预测的图片
    
  
    
     test_img = transform(test_img)
    
     img = test_img.to(device).unsqueeze(0)
    
     
    
     model.eval()
    
     output = model(img)
    
  
    
     _,pred = torch.max(output,1)
    
     pred_class = classes[pred]
    
     print(f'预测结果是:{pred_class}')
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/yWIlLE5HGmU1nkSfgqJ3xucwiAKo.png)
复制代码
 # 预测训练集中的某张照片

    
 predict_one_image(image_path='/kaggle/input/p4data/Monkeypox/M01_01_00.jpg', 
    
               model=model, 
    
               transform=train_transforms, 
    
               classes=classes)
    
    
    
    
复制代码
  
    
 PATH = './model.pth'  
    
 torch.save(model.state_dict(), PATH)
    
  
    
 model.load_state_dict(torch.load(PATH, map_location=device))
    
    
    
    

调整网络结构使测试集accuracy到达88%:

调整了学习率的大小,和优化器

结果:

个人总结:完成了猴痘病的预测,经过调节学习率和优化器函数,最后结果有了一定的改善,但是有一点点点过拟合,训练集的准确率接近100%,但测试集最高时88.8%,可以考虑dropout或者正则化参数。

全部评论 (0)

还没有任何评论哟~