pytorch实现简单的神经网络并训练

引用情况

import numpy as np
import pandas as pd
import os
import gzip


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

from torchvision import datasets
from torchvision import transforms
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

上面的引用中,torch.nn是用来构建神经网络每个层的,例如卷积层,全连接层等。torch.nn.functional用以引用各种数学函数,例如激活函数等。torch.optim是各种优化方法,例如SGD,ADAM等。
torchvisiontorch.utils.data等就不重要了

数据集

首先需要数据集,这里使用MNIST手写数字数据集,该数据集既可以用来训练全连接,也可以训练卷积神经网络。强烈不建议从官网下载该数据集,因为网速奇慢无比,而且还总是error断开连接。首先手动下载链接MNIST,密码3no7。将该压缩包文件解压后有四个文件,放在同一个文件夹中,记住路径。然后直接copy下面这段代码即可。下面这段代码是我在CSDN中一个大佬中抄过来的,代替读取数据集的,对以后的学习工作并没有什么价值,copy即可。

class DealDataset(Dataset):
    """
        读取数据、初始化数据
    """
    def __init__(self, folder, data_name, label_name,transform=None):
        (train_set, train_labels) = load_data(folder, data_name, label_name) # 其实也可以直接使用torch.load(),读取之后的结果为torch.Tensor形式
        self.train_set = train_set
        self.train_labels = train_labels
        self.transform = transform

    def __getitem__(self, index):

        img, target = self.train_set[index], int(self.train_labels[index])
        if self.transform is not None:
            img = self.transform(img)
        return img, target

    def __len__(self):
        return len(self.train_set)
def load_data(data_folder, data_name, label_name):
    with gzip.open(os.path.join(data_folder,label_name), 'rb') as lbpath: # rb表示的是读取二进制数据
        y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)

    with gzip.open(os.path.join(data_folder,data_name), 'rb') as imgpath:
        x_train = np.frombuffer(
        imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
    return (x_train, y_train)
trainDataset = DealDataset('./data/MNIST/', "train-images-idx3-ubyte.gz","train-labels-idx1-ubyte.gz",transform=transforms.ToTensor())
testDataset = DealDataset('./data/MNIST/', "t10k-images-idx3-ubyte.gz","t10k-labels-idx1-ubyte.gz",transform=transforms.ToTensor())

# 训练数据和测试数据的装载
train_loader = DataLoader(
    dataset=trainDataset,
    batch_size=100, # 一个批次可以认为是一个包,每个包中含有100张图片
    shuffle=False,
)

test_loader = DataLoader(
    dataset=testDataset,
    batch_size=100,
    shuffle=False,
)

注意上面代码中的路径’./data/MNIST/’,我的notebook的路径是home/notebook,数据集文件夹是home/notebook/data/MNIST,所以路径是这样,注意修改路径。

全连接神经网络

这里构建一个十分简单基础的包含一个隐含层的全连接神经网络。

#需要继承nn.Module,不要忘了
class NN(nn.Module):
    def __init__(self):
    	#super(NN,self).__init__()如果不理解就背下来,不懂python的super可以百度一下
        super(NN,self).__init__()
        #self.fc1构建第一个全连接层(full connect),nn.Linear是torch的全连接层方法,两个参数是左右的神经元个数
        self.fc1 = nn.Linear(28*28,500)
        self.fc2 = nn.Linear(500,10)
        
    def forward(self,x):
        x = self.fc1(x)
        #F.relu是torch的relu激活函数,还有其他激活函数,可以参考官网
        x = F.relu(x)
        x = self.fc2(x)
        return x

使用pytorch构建神经网络的步骤就这么简单,首先定义一个类,类里面包含两种方法,init和forward,网络的层定义在init中,前向方法定义在forward中就可以了。
实例化类,这里默认都是有GPU的,没有GPU。。。。。。买一个吧。

net_NN = NN().cuda()

卷积神经网络

class CNN(nn.Module):
    def __init__(self):
        super(CNN,self).__init__()
        #定义卷积和全连接层
        self.c1 = nn.Conv2d(1,6,(5,5))
        self.c2 = nn.Conv2d(6,16,(5,5))
        self.fc1 = nn.Linear(256,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)
        
        
    def forward(self,x):
    	#全向方法
        #x = F.max_pool2d(F.relu(self.c1(x)),2)
        x = self.c1(x)
        x = F.relu(x)
        x = F.max_pool2d(x,2)
        x = self.c2(x)
        x = F.relu(x)
        x = F.max_pool2d(x,2)
        
        x = x.view(-1,self.num_flat_feature(x))
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        x = F.relu(x)
        x = self.fc3(x)
        return x
    
    def num_flat_feature(self,x):
        size = x.size()[1:]
        
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

损失函数&优化方法&学习率

#损失函数,也可以选择其他损失函数
criterion = nn.CrossEntropyLoss()
#学习率
lr = 0.01
#优化方法,也可以选择其他优化方法
#net_NN.parameters(),将实例的参数传递给优化函数,优化函数自动计算导数
optimizer = optim.SGD(net_NN.parameters(),lr = lr,momentum = 0.9)

训练函数

def train(model, criterion, optimizer, epochs):
    loss = 0.0
    for epoch in range(epochs):
        for i, data in enumerate(train_loader):
            (inputs, labels) =  data
            #step1,获取inputs,计算outputs
            #因为是全连接网络,所以需要reshape到一维,卷积不需要
            inputs = inputs.reshape(-1, 28*28).to(device)
            labels = labels.to(device)
            outputs = model(inputs)
			
			#step2,清零梯度,计算loss,反向传播
            optimizer.zero_grad()
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            
            if i%100 == 0:
                print('Epoch [{}/{}], Loss: {:.4f}'
                      .format(epoch + 1, epochs, loss.item())) 

所以使用pytorch构建一个神经网络总共就四步。
第一步,把训练数据拿来。
第二步,把神经网络搭上。
第三步,确定loss_function,lr和优化方法。
第四步,构建训练函数。1.获取inputs,计算outputs。2.清零梯度,计算loss,反向传播。
你学废了吗?

保存与加载模型

torch.save(net_NN,'parh/name.pkl')
net = torch.load('parh/name.pkl')

测试函数

def test(test_loader,model):
    correct = 0
    total = 0
    for data in test_loader:
        inputs, labels = data
        inputs = inputs.cuda()
        labels = labels.cuda()
        outputs = model(inputs)
        #torch.max并不是np.max一个意思,是用以计算sofamax的分类类别的,建议CSDN查一下
        _, predict = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predict == labels).sum()
    print(total,correct)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值