第一个PyTorch程序训练测试流程

流程说明:

1、数据预处理:transform
2、数据库载入数据:重载Dateset
3、获取训练或者测试的数据流:DateLoader
4、定义网络:重载nn.Module,也有其它更复杂的方法;
5、定义loss:根据自己的问题进行定义;
6、训练流程:定义网络,获取数据流;定义循环,在循环中清空梯度,网络前向传播,计算loss,网络反向传播,梯度更新,并为了监视训练效果,在一定轮数打印出loss的情况;
7、测试流程:定义网络,获取数据流;对每一个数据,传入网络进行网络的前向传播,然后对网络结果进行处理后得到我们想要的结果,计算测试集的loss和准确率,并对相关信息进行打印;



import torch

from torch import nn
from torch import optim
import torch.nn.functional as F
import torchvision


from torch.utils.data import DataLoader, Dataset
import torchvision.transforms as transforms
import cv2
# 数据预处理
def gettransform():
    # img_path = "./ori.jpg"

    train_transformer = transforms.Compose([
        transforms.ToPILImage(),
        transforms.Resize([5,1]),
        #transforms.RandomResizedCrop(224,scale=(0.5,1.0)),
        #transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        #transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
        #transforms.ToTensor()
        #transforms.ToPILImage()
    ])

    ##numpy.ndarray
    # img = cv2.imread(img_path)  # 读取图像
    # img1 = train_transformer(img)
    #
    # img1.show()
    return  train_transformer


# 重载 Dataset 以便获取dataloader,用于训练
class MyDataset(Dataset):
    # TensorDataset继承Dataset, 重载了__init__, __getitem__, __len__
    # 实现将一组Tensor数据对封装成Tensor数据集
    # 能够通过index得到数据集的数据,能够通过len,得到数据集大小

    def __init__(self, imagepath,mytransformer):
        self.imagepath = imagepath
        self.transformer = mytransformer
        self.testy = 1

    def __getitem__(self,index):
        img = cv2.imread(self.imagepath)  # 读取图像
        img1 = self.transformer(img)
        return img1

    def __len__(self):
        return len(self.imagepath)

train_batch_size = 64
test_batch_size = 1000
img_size = 28


def get_dataloader(train=True):
    assert isinstance(train, bool), "train 必须是bool类型"

    # 准备数据集,其中0.1307,0.3081为MNIST数据的均值和标准差,这样操作能够对其进行标准化
    # 因为MNIST只有一个通道(黑白图片),所以元组中只有一个值
    dataset = torchvision.datasets.MNIST('/data', train=train, download=True,
                                         transform=torchvision.transforms.Compose([
                                             torchvision.transforms.ToTensor(),
                                             torchvision.transforms.Normalize((0.1307,), (0.3081,)), ]))
    # 准备数据迭代器
    batch_size = train_batch_size if train else test_batch_size
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)
    return dataloader


class MnistNet(nn.Module):
    def __init__(self):
        super(MnistNet, self).__init__()
        self.fc1 = nn.Linear(28 * 28 * 1, 28)
        self.fc2 = nn.Linear(28, 10)

    def forward(self, x):
        x = x.view(-1, 28 * 28 * 1)
        x = self.fc1(x)  # [batch_size,28]
        x = F.relu(x)  # [batch_size,28]
        x = self.fc2(x)  # [batch_size,10]
        # return x
        return F.log_softmax(x, dim=-1)


mnist_net = MnistNet()
optimizer = optim.Adam(mnist_net.parameters(), lr=0.001)

train_loss_list = []
train_count_list = []

def train(epoch):
    mode = True
    mnist_net.train(mode=mode)
    train_dataloader = get_dataloader(train=mode)
    print(len(train_dataloader.dataset))
    print(len(train_dataloader))
    for idx, (data, target) in enumerate(train_dataloader):
        optimizer.zero_grad()
        output = mnist_net(data)
        loss = F.nll_loss(output, target)  # 对数似然损失
        loss.backward()
        optimizer.step()
        if idx % 10 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, idx * len(data), len(train_dataloader.dataset),
                       100. * idx / len(train_dataloader), loss.item()))

            train_loss_list.append(loss.item())
            train_count_list.append(idx * train_batch_size + (epoch - 1) * len(train_dataloader))
            torch.save(mnist_net.state_dict(), "model/mnist_net.pkl")
            torch.save(optimizer.state_dict(), 'results/mnist_optimizer.pkl')


def test():
    test_loss = 0
    correct = 0
    mnist_net.eval()
    test_dataloader = get_dataloader(train=False)
    with torch.no_grad():
        for data, target in test_dataloader:
            output = mnist_net(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.data.max(1, keepdim=True)[1]  # 获取最大值的位置,[batch_size,1]
            correct += pred.eq(target.data.view_as(pred)).sum()
    test_loss /= len(test_dataloader.dataset)
    print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(
        test_loss, correct, len(test_dataloader.dataset),
        100. * correct / len(test_dataloader.dataset)))


# train and test
if __name__ == '__main__':

    test()
    for i in range(5):  # 模型训练5轮
        train(i)
        test()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值