赞
踩
本次机器学习项目的目标是使用PyTorch来训练一个模型,能够根据本地提供的图片库判断输入的图片是否为库里所有的人物。具体的实现步骤如下:
import os import torch from torchvision import transforms, datasets # 数据增强操作 data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } # 加载数据 data_dir = 'data' image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']} dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4, shuffle=True, num_workers=4) for x in ['train', 'val']}
上述代码中,我们使用了PyTorch中的transforms模块对数据进行增强操作,包括随机裁剪、随机水平翻转、数据归一化等。同时,我们使用datasets模块加载数据集,并使用DataLoader模块对数据进行批量处理。
import torch.nn as nn
import torch.optim as optim
from torchvision import models
# 加载预训练模型
model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
上述代码中,我们使用了PyTorch中的models模块加载了一个预训练的ResNet18模型,并将其最后一层的输出改为2,以适应我们的二分类任务。同时,我们定义了交叉熵损失函数和SGD优化器。
import time import copy # 训练模型 def train_model(model, criterion, optimizer, num_epochs=25): since = time.time() best_model_wts = copy.deepcopy(model.state_dict()) best_acc = 0.0 for epoch in range(num_epochs): print('Epoch {}/{}'.format(epoch, num_epochs - 1)) print('-' * 10) # 训练和验证 for phase in ['train', 'val']: if phase == 'train': model.train() # 训练模式 else: model.eval() # 验证模式 running_loss = 0.0 running_corrects = 0 # 迭代数据 for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) # 梯度清零 optimizer.zero_grad() # 前向传播 with torch.set_grad_enabled(phase == 'train'): outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) # 反向传播和优化 if phase == 'train': loss.backward() optimizer.step() # 统计数据 running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) # 计算损失和准确率 epoch_loss = running_loss / len(image_datasets[phase]) epoch_acc = running_corrects.double() / len(image_datasets[phase]) print('{} Loss: {:.4f} Acc: {:.4f}'.format( phase, epoch_loss, epoch_acc)) # 深度复制模型 if phase == 'val' and epoch_acc > best_acc: best_acc = epoch_acc best_model_wts = copy.deepcopy(model.state_dict()) print() time_elapsed = time.time() - since print('Training complete in {:.0f}m {:.0f}s'.format( time_elapsed // 60, time_elapsed % 60)) print('Best val Acc: {:4f}'.format(best_acc)) # 加载最佳模型权重 model.load_state_dict(best_model_wts) return model # 训练模型 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model_ft = model_ft.to(device) model_ft = train_model(model_ft, criterion, optimizer_ft, num_epochs=25)
上述代码中,我们定义了一个train_model函数,用于训练模型。在训练过程中,我们使用了交叉验证的方法,同时记录了最佳的模型权重和准确率。我们使用了GPU来加速训练过程。
import matplotlib.pyplot as plt import numpy as np # 计算混淆矩阵 def confusion_matrix(model, dataloader): model.eval() y_true = [] y_pred = [] for inputs, labels in dataloader: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) _, preds = torch.max(outputs, 1) y_true.extend(labels.cpu().numpy()) y_pred.extend(preds.cpu().numpy()) cm = confusion_matrix(y_true, y_pred) return cm # 计算模型评价指标 def evaluate_model(model, dataloader): model.eval() running_loss = 0.0 running_corrects = 0 y_true = [] y_pred = [] for inputs, labels in dataloader: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) y_true.extend(labels.cpu().numpy()) y_pred.extend(preds.cpu().numpy()) loss = running_loss / len(dataloader.dataset) acc = running_corrects.double() / len(dataloader.dataset) precision = precision_score(y_true, y_pred) recall = recall_score(y_true, y_pred) f1 = f1_score(y_true, y_pred) return loss, acc, precision, recall, f1 # 计算混淆矩阵和评价指标 from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score cm = confusion_matrix(model_ft, dataloaders['val']) loss, acc, precision, recall, f1 = evaluate_model(model_ft, dataloaders['val']) # 输出结果 print('Confusion Matrix:') print(cm) print('Loss: {:.4f} Acc: {:.4f} Precision: {:.4f} Recall: {:.4f} F1-score: {:.4f}'.format( loss, acc, precision, recall, f1))
上述代码中,我们使用了sklearn.metrics模块计算了混淆矩阵和评价指标,包括准确率、精确率、召回率和F1-score等。
import urllib.request from PIL import Image # 下载图片并进行预处理 url = 'https://source.unsplash.com/1280x720/?person' urllib.request.urlretrieve(url, 'test.jpg') image = Image.open('test.jpg') image_transforms = data_transforms['val'] image_tensor = image_transforms(image) image_tensor = image_tensor.unsqueeze(0) # 使用模型进行预测 model_ft.eval() image_tensor = image_tensor.to(device) outputs = model_ft(image_tensor) _, preds = torch.max(outputs, 1) # 输出结果 class_names = image_datasets['train'].classes print('Predicted class is: {}'.format(class_names[preds]))
上述代码中,我们使用了PIL库下载了一张图片,并使用了之前定义的数据增强操作对其进行预处理。然后,我们使用训练好的模型对其进行预测,并输出预测结果。
通过本次机器学习项目,我们使用PyTorch训练了一个模型,能够根据本地提供的图片库判断输入的图片是否为库里所有的人物。我们通过数据预处理、模型设计、模型训练、模型评估和模型应用等步骤,逐步完成了整个项目。同时,我们使用了sklearn.metrics模块计算了混淆矩阵和评价指标,对模型的性能进行了评估。最终,我们得到了一个准确率较高的模型,可以应用于实际场景中。
pytorch-image-classification ├── data │ ├── train │ │ ├── person1 │ │ │ ├── img1.jpg │ │ │ ├── img2.jpg │ │ │ └── ... │ │ ├── person2 │ │ │ ├── img1.jpg │ │ │ ├── img2.jpg │ │ │ └── ... │ │ └── ... │ └── val │ ├── person1 │ │ ├── img1.jpg │ │ ├── img2.jpg │ │ └── ... │ ├── person2 │ │ ├── img1.jpg │ │ ├── img2.jpg │ │ └── ... │ └── ... ├── model │ ├── model.pth │ └── ... ├── utils │ ├── data.py │ ├── model.py │ └── ... ├── train.py ├── predict.py └── ...
其中,data
文件夹存放训练和验证数据集,model
文件夹存放模型文件,utils
文件夹存放数据处理和模型定义的代码,train.py
是用于训练模型的脚本,predict.py
是用于预测图片的脚本。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。