pytorch处理图片的机器学习

设计方案

本次机器学习项目的目标是使用PyTorch来训练一个模型,能够根据本地提供的图片库判断输入的图片是否为库里所有的人物。具体的实现步骤如下:

  1. 数据预处理:将本地的图片库进行处理,将其划分为训练集和测试集,同时进行数据增强操作,增加数据的多样性和数量。
  2. 模型设计:使用PyTorch构建卷积神经网络模型,包括卷积层、池化层、全连接层等,以及相应的激活函数和损失函数。
  3. 模型训练:使用训练集对模型进行训练,并在测试集上进行验证,调整模型参数,提高模型的准确率。
  4. 模型评估:使用测试集对模型进行评估,计算模型的准确率、精确率、召回率等指标。
  5. 模型应用:使用训练好的模型对输入的图片进行判断,输出是否为库里所有的人物。

Python代码

1. 数据预处理

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模块对数据进行批量处理。

2. 模型设计

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优化器。

3. 模型训练

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来加速训练过程。

4. 模型评估

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等。

5. 模型应用

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是用于预测图片的脚本。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值