pytorch实现图像分类代码实例

图像多标签分类例子

import os
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from tensorboardX import SummaryWriter

import seaborn as sns
from sklearn.metrics import confusion_matrix

'''数据加载'''
#选择设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#对三种数据集进行不同预处理,对训练数据进行加强
data_transforms = {
    'train': transforms.Compose([
        transforms.RandomRotation(30),
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'valid': 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/wanghongzhi/17flowers"
 
#获取两个数据集
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),  #要习惯python这种语法
                 data_transforms[x]) for x in ['train', 'valid']} 
traindataset = image_datasets['train']
validdataset = image_datasets['valid']
 
batch_size = 8
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size,
             shuffle=True, num_workers=4) for x in ['train', 'valid']}
print(dataloaders)
traindataloader = dataloaders['train']
validdataloader = dataloaders['valid']
 
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'valid']}

'''定义网络结构'''
class Net(nn.Module):
    def __init__(self,model):
        super(Net,self).__init__()
        self.features = model.features
        # for p in self.parameters():
        #     p.requires_grad = False
        self.classifier = nn.Sequential(
            nn.Linear(25088, 4096,bias=True),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5,inplace=False),
            nn.Linear(4096, 4096,bias=True),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5,inplace=False),
            nn.Linear(4096, 102,bias=True)
        )
 
    def forward(self,x):
        x = self.features(x)
        x = x.view(x.shape[0], -1)
        x = self.classifier(x)
        return x
 
net = models.resnet50().to(device)

net.load_state_dict(torch.load('/home/wanghongzhi/zuoye/resnet50.pth'))

'''参数设定'''
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad, net.parameters()),lr=0.0001,momentum=0.9)

'''定义根据loss列表绘制loss曲线函数'''
def hua_loss(loss):
    l=len(loss)
    #x=list(range(1,l+1))
    x=range(1,l+1)

    # 设置图片大小
    plt.figure(figsize=(20,8),dpi=80) # figsize设置图片大小,dpi设置清晰度
    plt.title("Train-Epoch-Loss",fontsize=25)
    plt.xlabel("Epoch",fontsize=20)
    plt.ylabel("Loss",fontsize=20)
    plt.plot(x,loss)
    x_major_locator=MultipleLocator(2)  #x轴刻度为1的倍数
    y_major_locator=MultipleLocator(0.15) #y轴刻度为0.01的倍数
    ax=plt.gca() #ax为两条坐标轴的实例
    ax.xaxis.set_major_locator(x_major_locator)
    ax.yaxis.set_major_locator(y_major_locator)
    #保存
    #plt.savefig("./t1.png")
    plt.show()

'''先定义验证集检验''' #测试集和验证集代码一模一样
def valid_model(model, criterion):
    best_acc = 0.0
    print('-' * 10)
 
    running_loss = 0.0
    running_corrects = 0
    model = model.to(device)
    for inputs, labels in validdataloader:
        inputs = inputs.to(device)
        labels = labels.to(device)
        model.eval()
        with torch.no_grad():
            outputs = model(inputs)
        loss = criterion(outputs, labels)
        print('outputs:',outputs)
        print('labels:',labels)
        _, preds = torch.max(outputs, 1)
        running_loss += loss.item()
        running_corrects += torch.sum(preds == labels).item()
    epoch_loss = running_loss / dataset_sizes['valid']
    print(running_corrects)
    epoch_acc = running_corrects / dataset_sizes['valid']
    print('{} Loss: {:.4f} Acc: {:.4f}'.format(
            'valid', epoch_loss, epoch_acc))
    print('-' * 10)
    print()
    #val_loss.append(epoch_loss)

'''训练模型'''
def train_model(model, criterion, optimizer, num_epochs=5):
    #since = time.time()
    best_acc = 0.0
    train_loss=[]
    #val_loss=[]

    for epoch in range(num_epochs):
        if (epoch+1)%5==0:       #每五个epoch就用该模型验证一次结果          
            valid_model(model, criterion)
        print('-' * 10)
        print('Epoch {}/{}'.format(epoch+1, num_epochs))
 
        running_loss = 0.0
        running_corrects = 0
        model = model.to(device)
        for inputs, labels in traindataloader:
            inputs = inputs.to(device)
            labels = labels.to(device)
            model.train()
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
 
            _, preds = torch.max(outputs, 1)
            running_loss += loss.item()  #加起来用来计算每个epoch的loss
            running_corrects += torch.sum(preds == labels).item() #item()取出张量中的值,或者(predicted==labels).sum().item()
        epoch_loss = running_loss / dataset_sizes['train']
        print(dataset_sizes['train'])  #训练集总数
        print(running_corrects) #正确预测个数
        epoch_acc = running_corrects / dataset_sizes['train']
        best_acc = max(best_acc,epoch_acc)
        print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                'train', epoch_loss, epoch_acc)) 
        print()
        train_loss.append(epoch_loss)

    hua_loss(train_loss)

 
    print('Best val Acc: {:4f}'.format(best_acc)) 
    return model



'''开始训练'''
epochs = 5
model = train_model(net, criterion, optimizer, epochs)

参考了博客:Pytorch实现鲜花分类(102 Category Flower Dataset)

PyTorch 是一个基于 Python 的机器学习库,它提供了丰富的工具和接口,可以帮助用户快速构建和训练深度学习模型。下面是一个使用 PyTorch 实现图像分类的简单示例。 1. 准备数据 首先,需要准备数据集。常见的图像分类数据集有 MNIST、CIFAR-10、ImageNet 等。这里以 MNIST 数据集为例,它包含了 60000 张 28x28 像素的手写数字图片,以及相应的标签。 ``` import torch from torchvision import datasets, transforms # 定义数据预处理 transform = transforms.Compose([ transforms.ToTensor(), # 将图像转换为张量 transforms.Normalize((0.1307,), (0.3081,)) # 标准化 ]) # 加载数据集 train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform) test_dataset = datasets.MNIST('./data', train=False, download=True, transform=transform) # 定义数据加载器 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False) ``` 2. 构建模型 接下来,需要构建一个 CNN 模型,用于对图像进行分类。这里使用了两个卷积层、两个池化层和三个全连接层。 ``` import torch.nn as nn class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, kernel_size=3) self.conv2 = nn.Conv2d(32, 64, kernel_size=3) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(64 * 5 * 5, 512) self.fc2 = nn.Linear(512, 10) def forward(self, x): x = self.pool(nn.functional.relu(self.conv1(x))) x = self.pool(nn.functional.relu(self.conv2(x))) x = x.view(-1, 64 * 5 * 5) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return x # 实例化模型 model = Net() ``` 3. 训练模型 定义好模型后,可以开始训练。这里使用交叉熵损失函数和随机梯度下降优化器进行训练。 ``` import torch.optim as optim # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) # 训练模型 for epoch in range(10): for i, (inputs, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() if i % 100 == 0: print('Epoch: {}, Batch: {}, Loss: {:.4f}'.format(epoch+1, i+1, loss.item())) ``` 4. 评估模型 最后,使用测试集对模型进行评估。 ``` # 在测试集上验证模型 correct = 0 total = 0 with torch.no_grad(): for inputs, labels in test_loader: outputs = model(inputs) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy: {:.2f}%'.format(100 * correct / total)) ``` 完整代码如下: ``` import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms # 准备数据 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform) test_dataset = datasets.MNIST('./data', train=False, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False) # 构建模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, kernel_size=3) self.conv2 = nn.Conv2d(32, 64, kernel_size=3) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(64 * 5 * 5, 512) self.fc2 = nn.Linear(512, 10) def forward(self, x): x = self.pool(nn.functional.relu(self.conv1(x))) x = self.pool(nn.functional.relu(self.conv2(x))) x = x.view(-1, 64 * 5 * 5) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return x model = Net() # 训练模型 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) for epoch in range(10): for i, (inputs, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() if i % 100 == 0: print('Epoch: {}, Batch: {}, Loss: {:.4f}'.format(epoch+1, i+1, loss.item())) # 评估模型 correct = 0 total = 0 with torch.no_grad(): for inputs, labels in test_loader: outputs = model(inputs) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy: {:.2f}%'.format(100 * correct / total)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值