pytorch学习之路——07

本文详细介绍了如何在PyTorch中构建卷积神经网络(CNN)模型,从搭建网络结构到训练和验证过程,是PyTorch初学者的实践指南。
摘要由CSDN通过智能技术生成

建立cnn模型

import torch
from torch import nn,optim
import torch.nn.functional as F
from torchvision import datasets,transforms
from torch.utils.data.dataloader import DataLoader
from torch.utils.data.sampler import SubsetRandomSampler

import numpy as np



def get_dataloader(batch_size,valid_size):
    transform = transforms.Compose([transforms.ToTensor(),
                                    transforms.Normalize([0.5,],
                                                         [0.5,])])
    trainset = datasets.MNIST('MNIST_data/',train=True,transform=transform)
    testset = datasets.MNIST('MNIST_data/',train=False,transform=transform)

    num_train = len(trainset)
    indexs = list(range(num_train))
    np.random.shuffle(indexs)
    split = int(np.floor(valid_size*num_train))
    train_idx,valid_idx = indexs[split:],indexs[:split]

    train_sampler = SubsetRandomSampler(train_idx)
    valid_sampler = SubsetRandomSampler(valid_idx)
    train_loader = DataLoader(trainset,batch_size=batch_size,sampler=train_sampler)
    valid_loader = DataLoader(trainset,batch_size=batch_size,sampler=valid_sampler)
    test_loader = DataLoader(testset,batch_size=batch_size)

    return train_loader,valid_loader,test_loader


class Network(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1,8,3,padding=1)
        self.conv2 = nn.Conv2d(8,16,3,padding=1)
        self.conv3 = nn.Conv2d(16,32,3,padding=1)
        self.pool = nn.MaxPool2d(2,2)
        self.fc1 = nn.Linear(32*3*3,64)
        self.fc2 = nn.Linear(64,10)
        self.drop = nn.Dropout(p=0.3)

    def forward(self,x):
        x = self.pool(self.conv1(x))
        x = self.pool(self.conv2(x))
        x = self.pool(self.conv3(x))
        x = x.view(-1,32*3*3)
        x = F.relu(self.fc1(x))
        x = self.drop(x)
        x = F.log_softmax(self.fc2(x),dim=1)

        return x


def train(train_loader,valid_loader,epoch,device):
    model = Network()
    model.to(device)
    costFunc = nn.NLLLoss()
    optimizer = optim.SGD(model.parameters(),lr=0.03)

    min_valid_loss = np.Inf
    for e in range(epoch):
        train_loss = 0
        for imgs,labs in train_loader:
            imgs,labs = imgs.to(device),labs.to(device)
            optimizer.zero_grad()
            logps = model.forward(imgs)
            loss = costFunc(logps,labs)
            loss.backward()
            optimizer.step()
            train_loss += loss

        valid_loss = 0
        with torch.no_grad():
            for imgs,labs in valid_loader:
                imgs,labs = imgs.to(device),labs.to(device)
                logps = model.forward(imgs)
                loss = costFunc(logps,labs)
                valid_loss += loss

        train_loss /= len(train_loader)
        valid_loss /= len(valid_loader)
        print("Epoch :{}/{},".format(e,epoch),
              "Train Loss:{:.3f}".format(train_loss),
              "Valid Loss:{:.3f}".format(valid_loss))
        if valid_loss <= min_valid_loss:
            print("Epoch: {}".format(e),
                  "Valid Loss Decrease {:.3f} -> {:.3f}".format(min_valid_loss,valid_loss))
            min_valid_loss = valid_loss
            torch.save(model.state_dict(),"minst_cnn.pth")
            best_model = model

    return best_model


def predict(path,test_loader,device):
    model = Network()
    costFunc = nn.NLLLoss()
    state_dict = torch.load(path)
    model.load_state_dict(state_dict)
    model.to(device)
    model.eval()

    test_loss = 0
    class_correct = np.zeros(10)
    class_total = np.zeros(10)
    accuracy = 0
    for imgs,labs in test_loader:
        imgs,labs = imgs.to(device),labs.to(device)
        logps = model.forward(imgs)
        loss = costFunc(logps,labs)
        test_loss += loss

        ps = torch.exp(logps)
        top_k,top_class = ps.topk(1,dim=1)
        equal_tensor = top_class == labs.view(*top_class.shape)
        equal = np.squeeze(equal_tensor.numpy()) if device is not "gpu" else np.squeeze(equal_tensor.cpu().numpy())
        accuracy += np.mean(equal)
        for i in range(min(batch_size,labs.shape[0])):
            lab = labs[i]
            class_correct[lab] += equal[i]
            class_total[lab] += 1

    for i in range(10):
        if class_total[i] > 0:
            print("Accuracy:{:.3f} ({}/{})".format(class_correct[i]/class_total[i],class_correct[i],class_total[i]))

    print("Test Accuracy (Overall):",np.sum(class_correct)/np.sum(class_total))
    print(accuracy/len(test_loader))
    print(test_loss/len(test_loader))


if __name__ == "__main__":
    batch_size = 64
    valid_size = 0.2
    epoch = 5
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    train_loader,valid_loader,test_loader = get_dataloader(batch_size,valid_size)
    # model = train(train_loader,valid_loader,epoch,device)
    predict('minst_cnn.pth',test_loader,device)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值