ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PyTorch 深度学习实践 第10讲:卷积 神经网络(基础篇)

2022-08-12 18:00:29  阅读:205  来源: 互联网

标签:10 loss 卷积 torch batch 300 PyTorch test


第10讲:卷积 神经网络(基础篇)

视频教程

1.卷积神经网络

image
说明:

  • 首先明确输入的张量维度多少,输出的张量维度多少,利用各种层(做特征提取),进行这个维度上或者是每个维度上尺寸大小的变化,最终把它映射到想要的输出的这个空间里面
  • Feature Extraction:特征提取包括卷积、下采样
  • Classification:全连接
2.n个输入通道与m个输出通道

image
说明:

  • 3通道的输入,需要3通道的卷积核,进行数乘相加,输出
  • 每一个卷积核它的通道数量要求和输入通道是一样的
    image
    说明;
  • 卷积核的总数有m个 = 输出通道的数目m个
  • 卷积核的总数有多少个和你输出通道的数量是一样的
    so~
    image
  • 卷积层要求输入输出是四维张量(B,C,W,H),全连接层的输入与输出都是二维张量(B,Input_feature)。
  • 卷积层:明确:1.输入输出通道C,2.卷积核的size
3.代码图解

image

image

Pytorch的nn.Conv2d()详解

4。代码
import torch
from torchvision import transforms#图像处理
from torchvision import datasets#加载数据
from torch.utils.data import DataLoader#为了构建Dataloader
import torch.nn.functional as F#为了使用relu激活函数
import torch.optim as optim#优化器的包

# 1.prepare dataset
batch_size = 64
#要使用dataset,dataloader所以要设置batch容量
transform = transforms.Compose([transforms.ToTensor(),
                               transforms.Normalize((0.1307,), (0.3081,))])
#ToTensor讲原始图片转成图像张量(维度1->3,像素值属于【0,1】
#Normalize(均值,标准差)像素值切换成0,1分布

#加载训练集
train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)

#加载测试集,都是pytorch看你需求自己下载的
test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)

#2.Design Model

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #定义卷积模型:
        # 第一个卷积层(图片channel是1所以第一个参数为输入通道1
        #第二个参数:输出通道10(即这个卷积层需要10个卷积核
        #第三个参数:卷积核尺寸:5*5)  
        self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)
        #第二层同上:输入通道=上一层的输出通道
        self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
        #需要一个池化层作用主要是通过下采样降低参数量
        self.pooling = torch.nn.MaxPool2d(2)
        #需要线性层做分类,通过view操作变成一维向量(图一:4*4*20=320)
        self.fc = torch.nn.Linear(320,10)
    
    
    def forward(self, x):
        # Flatten data from (n, 1, 28, 28) to (n, 784)
        batch_size = x.size(0)#batch大小是输入x的第0个维度:样本n
        #输入x经过第一个卷积层 + 池化层 + relu激活
        x = F.relu(self.pooling(self.conv1(x)))
        #重复经历
        x = F.relu(self.pooling(self.conv2(x)))
        #将处理后二维的图片20x4x4张量转成向量,作为全连接网络的输入
        x = x.view(batch_size,-1)
        #用全连接层做转换,最后要用交叉熵计算损失,注意不要激活
        x = self.fc(x)
        return x
    
model = Net()#实例化为model        

#把计算迁移到GPU
# device = torch.device("cuda:0" if torch.cuda.is_available()else"cpu")
# model.to(device)

#3.construct Loss and Optimizer

#损失函数,来计算我们模型输出的值和标准值的差距
criterion = torch.nn.CrossEntropyLoss()
#定义一个优化器,他会反向的更改相应层的权重来训练模型
optimizer = optim.SGD(model.parameters(),lr=0.01, momentum=0.5)

#4.Train and  Test
def train(epoch):#一轮循环封装函数
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader,0):
        inputs, target = data
        #输入x,输出y
        optimizer.zero_grad()
        #清空过往梯度
        
        #forward + backward + updata
        outputs = model(inputs)
        #forward 计算y^
        loss = criterion(outputs, target)
        #(y^,y)计算损失值
        loss.backward()
        #反向传播,计算当前梯度
        optimizer.step()
        #根据梯度更新网络参数
        
        running_loss += loss.item()
        #损失累计
        #!loss拿出的值,而非构建计算图
        #每300下输出一次数据
        if batch_idx % 300 ==299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1,running_loss / 300))
            running_loss = 0.0
        
#4.Train and  Test
def train(epoch):#一轮循环封装函数
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader,0):
        inputs, target = data
        #输入x,输出y
        optimizer.zero_grad()
        #清空过往梯度
        
        #forward + backward + updata
        outputs = model(inputs)
        #forward 计算y^
        loss = criterion(outputs, target)
        #(y^,y)计算损失值
        loss.backward()
        #反向传播,计算当前梯度
        optimizer.step()
        #根据梯度更新网络参数
        
        running_loss += loss.item()
        #损失累计
        #!loss拿出的值,而非构建计算图
        #每300下输出一次数据
        if batch_idx % 300 ==299:
            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():#以下不用计算梯度
        for data in test_loader:
            images, labels = data
            outputs = model(images)
            _, predicted  = torch.max(outputs.data, dim = 1)
            #输出数据,dim =1检索每行最大值,并输出下标
            #(不关心最大值是多少,所以用_,predicted是下标)
            #dim = 1横向降维,dim = 0纵向降维
            total += labels.size(0)
            #正确率:两个张量的比较
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set:%d %%' %(100 * correct / total))
	
if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()

结果:
[1, 300] loss: 0.661
[1, 600] loss: 0.178
[1, 900] loss: 0.141
Accuracy on test set:96 %
[2, 300] loss: 0.110
[2, 600] loss: 0.108
[2, 900] loss: 0.090
Accuracy on test set:97 %
[3, 300] loss: 0.087
[3, 600] loss: 0.075
[3, 900] loss: 0.075
Accuracy on test set:98 %
[4, 300] loss: 0.066
[4, 600] loss: 0.069
[4, 900] loss: 0.064
Accuracy on test set:98 %
[5, 300] loss: 0.061
[5, 600] loss: 0.054
[5, 900] loss: 0.059
Accuracy on test set:98 %
[6, 300] loss: 0.055
[6, 600] loss: 0.050
[6, 900] loss: 0.049
Accuracy on test set:98 %
[7, 300] loss: 0.042
[7, 600] loss: 0.051
[7, 900] loss: 0.048
Accuracy on test set:98 %
[8, 300] loss: 0.040
[8, 600] loss: 0.044
[8, 900] loss: 0.045
Accuracy on test set:98 %
[9, 300] loss: 0.041
[9, 600] loss: 0.041
[9, 900] loss: 0.039
Accuracy on test set:98 %
[10, 300] loss: 0.036
[10, 600] loss: 0.036
[10, 900] loss: 0.043
Accuracy on test set:98 %

标签:10,loss,卷积,torch,batch,300,PyTorch,test
来源: https://www.cnblogs.com/Ling-22/p/16579474.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有