【深度学习】Python深度学习实践-不同网络结构实现minist数据集分类(线性\CNN\inception)

课程传送门:B站,刘二大人,pytorch深度学习实践

这里贴一个作者: GDUT 小胖鱼,博客对课程的理解和代码都比较详细,可以搭配课程观看,链接:Pytorch_GDUT 小胖鱼的博客-CSDN博客

1.线性回归实现Minist数据集分类问题

可配合这篇博客进行理解:Pytorch实现多分类问题 样例解释 通俗易懂 新手必看,写的很详细,对代码部分也进行了详细分析。

网络模型结构图:

添加注释的详细代码:

import torch
from torchvision import transforms #针对图像处理的工具
from torch.utils.data import DataLoader
from torchvision import datasets
import torch.nn.functional as F #为了使用函数relu()
import torch.optim as optim #构建优化器

#prepare dataset(dataset and dataloader)

batch_size = 64
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307, ),(0.3081, ))])
#torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作,
#transforms.ToTensor() 将给定图像转为Tensor,
#transforms.Normalize(mean,std) 归一化处理
train_dataset = datasets.MNIST(root='../dataset/minist/',train=True,download=True,transform = transform)
#定义好transform之后放到数据集里边,将来读取样本的时候拿到的数据会直接用transform进行处理

train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root='../dataset/minist/',train=False,download=True,transform = transform)

test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

#desigen model using class(继承自nn.module)

class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__() 
        #super() 是调用Net的父类(超类)Module的一种方法,在Net中可以通过super()方法来调用父类Module的方法。
        self.l1 = torch.nn.Linear(784,512)  #输入784,输出512
        self.l2 = torch.nn.Linear(512,256)
        self.l3 = torch.nn.Linear(256,128)
        self.l4 = torch.nn.Linear(128,64)
        self.l5 = torch.nn.Linear(64,10)

    def forward(self, x):
        x = x.view(-1,784) ##ninist数据集每张图片大小为28*28=784,将1*28*28图像三阶张量变成一阶向量
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return self.l5(x)
#使用交叉熵损失注意神经网络最后一层无需做激活,因为将其变分布的softmax激活包含在交叉熵损失中
model = Net()

#构建损失和优化器

criterion = torch.nn.CrossEntropyLoss()  
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)  #momentum为冲量加快权值收敛

#训练循环
def train(epoch):
    running_loss = 0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs, target = data

        #优化器优化之前要清零
        optimizer.zero_grad()

        #forward + backward + update
        outputs = model(inputs)
        loss = criterion(outputs,target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()  ##取loss要用item()把值拿出来,不然会构建计算图
        if batch_idx % 300 == 299:  #每300输出一次
            print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0

def test():
    correct = 0
    total = 0
    with torch.no_grad():  #test不需要计算梯度
        for data in test_loader:
            images,labels=data
            outputs=model(images)
            _,predicted = torch.max(outputs.data, dim=1) #把每行最大值下标拿出来,dim=1表示沿列,沿着列(横着)找最大值
            total += labels.size(0) #labels大小为(N,1),size中第0个元素就是N,即样本个数
            correct += (predicted == labels).sum().item() #得到预则值与labels相同的个数,求和
    print('Accuracy on testset: %d %%' % (100*correct/total))

if __name__=='__main__':
     for epoch in range(10): #训练10轮,一轮训练,一轮测试
        train(epoch)
        #if epoch % 10 = 9 #加上这句可以每10轮测试一次
        test()

运行结果:

 2.CNN实现Minist数据集分类问题

可配合这篇博客进行理解:看了上百篇文章,我希望用我方式让大家通俗理解CNN

网络模型结构图:

 添加注释的详细代码(可配合上述博客进行理解):

(代码与模型结构图不太一致,图中先relu再池化,代码先池化再relu)

import torch
from torchvision import transforms #针对图像处理的工具
from torch.utils.data import DataLoader
from torchvision import datasets
import torch.nn.functional as F #为了使用函数relu()
import torch.optim as optim #构建优化器

#prepare dataset(dataset and dataloader)

batch_size = 64

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307, ),(0.3081, ))])
#torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作,
#transforms.ToTensor() 将给定图像转为Tensor,
#transforms.Normalize(mean,std) 归一化处理
train_dataset = datasets.MNIST(root='../dataset/minist/',train=True,download=False,transform = transform)
#定义好transform之后放到数据集里边,将来读取样本的时候拿到的数据会直接用transform进行处理

train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root='../dataset/minist/',train=False,download=False,transform = transform)

test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

#desigen model using class(继承自nn.module)

class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__() 
        self.conv1 = torch.nn.Conv2d(1,10,kernel_size=5) #输入通道1,输出通道10。(1,28,28)经过5*5卷积-->(10,24,24)
        self.conv2 = torch.nn.Conv2d(10,20,kernel_size=5) #输入通道10,输出通道20.
        self.pooling = torch.nn.MaxPool2d(2) #最大池化filter:2*2
        self.fc = torch.nn.Linear(320,10) #经过两层卷积和池化之后,转化为(20,4,4)一共320元素,将320个元素变成一个向量,经过一个全连接层映射成10
        #若有时不知道该处向量元素个数,可利用模型计算,然后输出一下维度即可
    def forward(self, x):
        batch_size = x.size(0)
        x = F.relu(self.pooling(self.conv1(x)))
        x = F.relu(self.pooling(self.conv2(x)))
        x = x.view(batch_size,-1) #将x由多维变成一个向量
        x = self.fc(x)
        return x

#使用torch.nn.Sequential定义模型实测也可行(李沐-动手学习深度学习)
#model = torch.nn.Sequential(
#    torch.nn.Conv2d(1,10,kernel_size=5),torch.nn.MaxPool2d(2),torch.nn.ReLU(),
#    torch.nn.Conv2d(10,20,kernel_size=5),torch.nn.MaxPool2d(2),torch.nn.ReLU(),
#    torch.nn.Flatten(),
#    torch.nn.Linear(320,10)
#)

model = Net()

####
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)#把模型的参数权重缓存等放到cuda里边
###

#构建损失和优化器

criterion = torch.nn.CrossEntropyLoss()  
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)  #momentum为冲量加快权值收敛

#训练循环

def train(epoch):
    running_loss = 0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs, target = data
        ###把这两个迁移到device上
        inputs,target = inputs.to(device),target.to(device)
        ###

        #优化器优化之前要清零
        optimizer.zero_grad()

        #forward + backward + update
        outputs = model(inputs)
        loss = criterion(outputs,target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()  ##取loss要用item()把值拿出来,不然会构建计算图
        if batch_idx % 300 == 299:  #每300输出一次
            print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0

def test():
    correct = 0
    total = 0
    with torch.no_grad():  #test不需要计算梯度
        for data in test_loader:
            inputs,target=data
            ###把这两个迁移到device上
            inputs,target = inputs.to(device),target.to(device)
            ###
            outputs=model(inputs)
            _,predicted = torch.max(outputs.data, dim=1) #把每行最大值下标拿出来,dim=1表示沿列,沿着列(横着)找最大值
            total += target.size(0) #labels大小为(N,1),size中第0个元素就是N,即样本个数
            correct += (predicted == target).sum().item() #得到预则值与labels相同的个数,求和
    print('Accuracy on testset: %d %% [%d/%d]' % (100*correct/total,correct, total))

if __name__=='__main__':
     for epoch in range(10): #训练10轮,一轮训练,一轮测试
        train(epoch)
        #if epoch % 10 = 9 #加上这句可以每10轮测试一次
        test()

运行结果:

要暑期实践了,剩下的Residual和RNN有空再敲吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值