十、CNN卷积神经网络实战

news2024/11/19 4:38:05

一、确定输入样本特征和输出特征

输入样本通道数4、期待输出样本通道数2、卷积核大小3×3
具体卷积层的构建可参考博文:八、卷积层
设定卷积层
torch.nn.Conv2d(in_channels=in_channel,out_channels=out_channel,kernel_size=kernel_size,padding=1,stride=1)
必要参数:输入样本通道数in_channels、输出样本通道数out_channels、卷积核大小kernel_size
padding是否加边,默认不加,这里为了保证输出图像的大小不变,加边数设为1
stride步长设置,默认为1
在这里插入图片描述

import torch
in_channel, out_channel = 4, 2
width, heigh = 512, 512
batch_size = 1
inputs = torch.randn(batch_size,in_channels,width,heigh)#[B,C,W,H]

kernel_size = 3

conv_layer = torch.nn.Conv2d(in_channels=in_channel,out_channels=out_channel,kernel_size=kernel_size,padding=1,stride=1)
outputs = conv_layer(inputs)

print(inputs.shape)
"""
torch.Size([1, 4, 512, 512])
"""
print(outputs.shape)
"""
torch.Size([1, 2, 512, 512])
"""
print(conv_layer.weight.shape)#看下卷积层核参数信息
# 卷积层权重参数大小,因为batch_size为1,故卷积核参数的B也为1;
# 因为输入样本的通道数是3,故卷积层传入参数的channel也为3;
# 因为输出样本的通道数是1,故卷积层传入参数的
"""
torch.Size([2, 4, 3, 3])
"""

二、确定卷积核内容进行卷积

在这里插入图片描述

import torch
inputs = [1,1,1,1,1,
          2,2,2,2,2,
          1,1,2,1,1,
          1,1,2,1,1,
          1,1,2,1,1]

inputs = torch.Tensor(inputs).view(1,1,5,5)

kernel_size = 3
padding = 0
stride = 1

kernel = torch.Tensor([1,2,1,
                       2,1,2,
                       1,2,1]).view(1,1,3,3)

conv_layer = torch.nn.Conv2d(1,1,kernel_size=kernel_size,padding=padding,stride=stride,bias=False)
conv_layer.weight.data = kernel.data

outputs = conv_layer(inputs)

print(outputs)
"""
tensor([[[[19., 20., 19.],
          [20., 20., 20.],
          [17., 18., 17.]]]], grad_fn=<SlowConv2DBackward0>)
"""

print(inputs)
"""
tensor([[[[1., 1., 1., 1., 1.],
          [2., 2., 2., 2., 2.],
          [1., 1., 1., 1., 1.],
          [2., 2., 2., 2., 2.],
          [1., 1., 1., 1., 1.]]]])
"""
print(kernel)
"""
tensor([[[[1., 2., 1.],
          [2., 1., 2.],
          [1., 2., 1.]]]])
"""
print(inputs.shape)
"""
torch.Size([1, 1, 5, 5])
"""
print(outputs.shape)
"""
torch.Size([1, 1, 3, 3])
"""
print(kernel.shape)
"""
torch.Size([1, 1, 3, 3])
"""
print(conv_layer.weight.shape)
"""
torch.Size([1, 1, 3, 3])
"""

三、根据需求进行网络模型搭建

①准备数据集

还是以MNIST手写数字数据集为例,数据集细节可参考博文:九、多分类问题

设置batch_size=64,每个batch中有64张样本,至于一共有多少个batch,取决于数据集的总数量
使用transforms.Compose(),组合操作,把数据集都转换为Tensor数据类型,并且全部都取均值和标准差,方便训练,强化训练效果,这里的值都是经过计算过的,直接用就行

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #为了使用relu激活函数
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把图片变成张量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和标准差进行数据标准化,这俩值都是经过整个样本集计算过的
])

②加载数据集

pytorch提供MNIST接口,直接调用相关函数即可

datasets
参数root表示数据集路径;
参数train表示是否是训练集,True表示下载训练集,False则表示下载测试集;
参数download表示是否下载,True表示若指定路径不存在数据集则联网下载;
将所有的数据集都经过上面定义的transforms组合操作,转换成Tensor格式和均值标准差归一化。

DataLoader
参数train_dataset指定数据集datasets
参数shuffle表示是否将数据集中的样本打乱顺序,训练集需要,测试集不需要
参数batch_size表示一次(batch)取多少个样本,至于一共取多少次取决于数据集总样本数

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

③模型构建

在这里插入图片描述
在这里插入图片描述
由图可知,输入图像(通道数为1)首先进入一个卷积层,卷积核大小为5×5,输出特征通道数为10,即torch.nn.Conv2d(1,10,kernel_size=5)
之后进入一个ReLU激活函数层,激活函数无需参数,即F.relu()
然后再进入一个核为2×2的MaxPool层,即torch.nn.MaxPool2d(2)

之后将通道数为10的特征参数再送入一个卷积层,卷积核大小为5×5,输出特征通道数为20,即torch.nn.Conv2d(10,20,kernel_size=5)
之后进入一个ReLU激活函数层,激活函数无需参数,即F.relu()
然后再进入一个核为2×2的MaxPool层,即torch.nn.MaxPool2d(2)

有第一张图可知,最终的特征参数个数为20×4×4=320,将这320个特征参数通过线性层(全连接层),转到10个维度上,即torch.nn.Linear(320,10),因为是10分类任务,故需要转到10个维度上

在模型参数函数(def __init__(self):)中,池化层操作都一样,故定义一个即可,最终,卷积操作两个,一个池化操作,一个线性层(全连接)操作
在前向传播函数(def forward(self,x):)中,数据集中x为[B,C,W,H],故通过x.size(0)取出batch_size,即B的值

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,10,kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(10,20,kernel_size=5)
        self.fc = torch.nn.Linear(320,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = x.view(batch_size,-1)
        x = self.fc(x)
        
        return x

model = yNet()

GPU加速
只需要通过.to()方法,将模型、训练函数中数据集、测试函数中数据集调用该方法即可

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

④损失函数和优化器

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

⑤训练函数定义

for i, data in enumerate(train_loader,0):
train_loader这个DataLoader中进行枚举,0表示从DataLoader下标为0处开始,train_loader返回两个值,索引数据,其中数据包括两类,x和y
i接收索引、data接收数据
x,y = data,x和y分别接收data中的28×28=784个参数,y为所对应的某一个类别

测试

x,y = test_dataset[0]
x.shape
"""
torch.Size([1, 28, 28])
"""
y
"""
7
"""

完整代码

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        #x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch输出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0 #每次epoch都将损失清零,方便计算下一次的损失

⑥测试函数定义

def ytest():
    correct = 0#模型预测正确的数量
    total = 0#样本总数
    with torch.no_grad():#测试不需要梯度,减小计算量
        for data in test_loader:#读取测试样本数据
            images, labels = data
            #images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#预测,每一个样本占一行,每行有十个值,后续需要求每一行中最大值所对应的下标
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿着第一个维度,一行一行来,去找每行中的最大值,返回每行的最大值和所对应下标
            total += labels.size(0)#labels是一个(N,1)的向量,对应每个样本的正确答案
            correct += (pred_maxindex == labels).sum().item()#使用预测得到的最大值的索引和正确答案labels进行比较,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct预测正确的样本个数 / 样本总数 * 100 = 模型预测正确率

⑦主函数调用

if __name__ == '__main__':
    for epoch in range(100):#训练10次
        ytrain(epoch)#训练一次
        if epoch%10 == 9:
            ytest()#训练10次,测试1次

⑧完整代码

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #为了使用relu激活函数
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把图片变成张量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和标准差进行数据标准化,这俩值都是经过整个样本集计算过的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,10,kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(10,20,kernel_size=5)
        self.fc = torch.nn.Linear(320,10)
        
    def forward(self,x):#传入单张样本x
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = x.view(batch_size,-1)
        x = self.fc(x)
        
        return x
    
model = yNet()   
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch输出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0
            

def ytest():
    correct = 0#模型预测正确的数量
    total = 0#样本总数
    with torch.no_grad():#测试不需要梯度,减小计算量
        for data in test_loader:#读取测试样本数据
            images, labels = data
            images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#预测,每一个样本占一行,每行有十个值,后续需要求每一行中最大值所对应的下标
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿着第一个维度,一行一行来,去找每行中的最大值,返回每行的最大值和所对应下标
            total += labels.size(0)#labels是一个(N,1)的向量,对应每个样本的正确答案
            correct += (pred_maxindex == labels).sum().item()#使用预测得到的最大值的索引和正确答案labels进行比较,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct预测正确的样本个数 / 样本总数 * 100 = 模型预测正确率
        

if __name__ == '__main__':
    for epoch in range(10):#训练10次
        ytrain(epoch)#训练一次
        if epoch%10 == 9:
            ytest()#训练10次,测试1次

⑨测试一下

x,y = train_dataset[9]#第9个数据x为图片,对应的结果为2
y
"""
2
"""
x = x.view(-1,1,28,28)#因为tensor需要格式为(B,C,W,H)转换一下格式
y_hat = model(x)#放入模型中进行预测,因为时十分类任务,输出十个值
y_hat 
"""
tensor([[-2.8711, -2.2891, -0.5218, -2.0884,  6.2099, -0.1559,  1.9904, -0.8938,
          1.3734,  2.9303]], grad_fn=<AddmmBackward0>)
"""


pred_maxvalue, pred_maxindex = torch.max(y_hat,dim=1)#选出值最大的,和相对于的下标索引

pred_maxvalue#最大值
"""
tensor([6.2099], grad_fn=<MaxBackward0>)
"""
pred_maxindex#最大值所对应的索引下标值
"""
tensor([4])
"""

预测错了,得多训练几轮

四、课后作业

在这里插入图片描述
除网络模型外,其他的都可以复用

这里就不再赘述,直接对模型结构进行搭建

查看下官网给的卷积层padding的计算公式
在这里插入图片描述
以下是我个人设计的网络模型,接下来开始去实现模型架构
在这里插入图片描述
在这里插入图片描述

①调试

加载数据集

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #为了使用relu激活函数
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把图片变成张量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和标准差进行数据标准化,这俩值都是经过整个样本集计算过的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

#这里取测试集中的一个样本
x,y = test_dataset[1]

x.shape
"""
torch.Size([1, 28, 28])
"""
y
"""
2
"""

第一个卷积层

因为数据集中样本shape是torch.Size([1, 28, 28]),而pytorch提供的接口都得适应[B,C,W,H]形式,故需要先通过x = x.view(-1,1,28,28)转换一下类型
在这里插入图片描述
根据结构需要,定义第一个卷积层,为了后续计算方便,这里加边padding=1,保证输入和输出特征图大小一致,这里仅为了测试,batch取1
conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)

x = x.view(-1,1,28,28)
x.shape
"""
torch.Size([1, 1, 28, 28])
"""
conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
x1 = conv_1(x)
x1.shape
"""
torch.Size([1, 5, 28, 28])
"""

由输出结果可知,通过第一个卷积层之后,特征图x1[1,5,28,28]
x1传入第一个最大池化层

第一个最大池化层

x1的形状为[1,5,28,28]
定义最大池化层:pooling = torch.nn.MaxPool2d(2)
x1传入最大池化层,得到特征x2
在这里插入图片描述

pooling = torch.nn.MaxPool2d(2)
x2 = pooling(x1)
x2.shape
"""
torch.Size([1, 5, 14, 14])
"""

输出结果x2的形状为[1, 5, 14, 14]
x2传入第二个卷积层中

第二个卷积层

x2的形状为[1, 5, 14, 14]
定义第二个卷积层:conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
x2传入第二个卷积层,得到特征x3
在这里插入图片描述

conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
x3 = conv_2(x2)
x3.shape
"""
torch.Size([1, 10, 14, 14])
"""

输出结果x3的形状为[1, 10, 14, 14]
x3传入第二个最大池化层中

第二个最大池化层

x3的形状为[1, 10, 14, 14]
使用上述同样的最大池化层:pooling = torch.nn.MaxPool2d(2)
x3传入第二个最大池化层,得到特征x4
在这里插入图片描述

pooling = torch.nn.MaxPool2d(2)
x4 = pooling(x3)
x4.shape
"""
torch.Size([1, 10, 7, 7])
"""

输出结果x4的形状为[1, 10, 7, 7]
x4传入第三个卷积层中

第三个卷积层

x4的形状为[1, 10, 7, 7]
定义第三个卷积层:conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
x4传入第三个卷积层,得到特征x5
在这里插入图片描述

conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
x5 = conv_3(x4)
x5.shape
"""
torch.Size([1, 20, 7, 7])
"""

输出结果x5的形状为[1, 20, 7, 7]
x5传入第三个最大池化层中

第三个最大池化层

x5的形状为[1, 20, 7, 7]
使用上述同样的最大池化层:pooling = torch.nn.MaxPool2d(2)
x5传入第二个最大池化层,得到特征x6

在这里插入图片描述

pooling = torch.nn.MaxPool2d(2)
x6 = pooling(x5)
x6.shape
"""
torch.Size([1, 20, 3, 3])
"""

输出结果x6的形状为[1, 20, 3, 3]
x6传入第一个线性层中

第一个全连接层

x6的形状为[1, 20, 3, 3],此时特征图x6共有1×20×3×3=180个参数
因为线性层传入的特征是二维矩阵形式,每个batch占一行,每行存放单个样本的所有参数信息,故需要将x6形状进行转变,x6.size(0)获取batch,这里的batch是1,剩下的,系统进行自动排列,x_all = x6.view(x6.size(0),-1),此时的x_all的形状为[1,180]
之后根据需求,定义第一个线性层:fc_1 = torch.nn.Linear(180,120),这里的输入180,必须和最终的特征x_all吻合
x_all传入第一个全连接层,得到特征x_x1
在这里插入图片描述

x6.shape
"""
torch.Size([1, 20, 3, 3])
"""
x6.size(0)
"""
1
"""

x_all = x6.view(x6.size(0),-1)
x_all.shape
"""
torch.Size([1, 180])
"""

fc_1 = torch.nn.Linear(180,120)
x_x1 = fc_1(x_all)
x_x1.shape
"""
torch.Size([1, 120])
"""

输出结果x_x1的形状为[1, 120]
x_x1传入第二个全连接层中

第二个全连接层

x_x1的形状为[1, 120]
根据需求,定义第二个全连接层,fc_2 = torch.nn.Linear(120,60)
x_x1传入第二个全连接层,得到特征x_x2
在这里插入图片描述

fc_2 = torch.nn.Linear(120,60)
x_x2 = fc_2(x_x1)
x_x2.shape
"""
torch.Size([1, 60])
"""

输出结果x_x2的形状为[1, 60]
x_x2传入第三个全连接层中

第三个全连接层

x_x2的形状为[1, 60]
根据需求,定义第三个全连接层,fc_3 = torch.nn.Linear(60,10)
x_x2传入第三个全连接层,得到特征x_x3
在这里插入图片描述

fc_3 = torch.nn.Linear(60,10)
x_x3 = fc_3(x_x2)
x_x3.shape
"""
torch.Size([1, 10])
"""

最终结果为x_x3,形状为[1, 10],十分类任务,十个概率值,取最大的,就是最终预测的结果

②模型构建

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
        self.conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
        
        self.fc_1 = torch.nn.Linear(180,120)
        self.fc_2 = torch.nn.Linear(120,60)
        self.fc_3 = torch.nn.Linear(60,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = self.pooling(F.relu(self.conv_3(x)))
        x = x.view(batch_size,-1)
        x = self.fc_1(x)
        x = self.fc_2(x)
        x = self.fc_3(x)
        
        return x
       
model = yNet()   

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")#GPU加速
model.to(device)

③完整代码

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #为了使用relu激活函数
import torch.optim as optim 

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),#把图片变成张量形式
    transforms.Normalize((0.1307,),(0.3081,)) #均值和标准差进行数据标准化,这俩值都是经过整个样本集计算过的
])

train_dataset = datasets.MNIST(root='./',train=True,download=True,transform = transform)
train_loader = DataLoader(train_dataset,shuffle=True,batch_size=batch_size)

test_dataset = datasets.MNIST(root="./",train=False,download=True,transform=transform)
test_loader = DataLoader(test_dataset,shuffle=False,batch_size=batch_size)

class yNet(torch.nn.Module):
    def __init__(self):
        super(yNet,self).__init__()
        
        self.conv_1 = torch.nn.Conv2d(1,5,kernel_size=3,padding=1)
        self.pooling = torch.nn.MaxPool2d(2)
        self.conv_2 = torch.nn.Conv2d(5,10,kernel_size=3,padding=1)
        self.conv_3 = torch.nn.Conv2d(10,20,kernel_size=3,padding=1)
        
        self.fc_1 = torch.nn.Linear(180,120)
        self.fc_2 = torch.nn.Linear(120,60)
        self.fc_3 = torch.nn.Linear(60,10)
        
    def forward(self,x):
        batch_size = x.size(0)
        x = self.pooling(F.relu(self.conv_1(x)))
        x = self.pooling(F.relu(self.conv_2(x)))
        x = self.pooling(F.relu(self.conv_3(x)))
        x = x.view(batch_size,-1)
        x = self.fc_1(x)
        x = self.fc_2(x)
        x = self.fc_3(x)
        
        return x
    
model = yNet()   
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

lossf = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr=0.0001,momentum=0.5)

def ytrain(epoch):
    loss_total = 0.0
    for batch_index ,data in enumerate(train_loader,0):
        x,y = data
        x,y = x.to(device), y.to(device)#GPU加速
        optimizer.zero_grad()
        
        y_hat = model(x)
        loss = lossf(y_hat,y)
        loss.backward()
        optimizer.step()
        
        loss_total += loss.item()
        if batch_index % 300 == 299:# 每300epoch输出一次
            print("epoch:%d, batch_index:%5d \t loss:%.3f"%(epoch+1, batch_index+1, loss_total/300))
            loss_total = 0.0
            

def ytest():
    correct = 0#模型预测正确的数量
    total = 0#样本总数
    with torch.no_grad():#测试不需要梯度,减小计算量
        for data in test_loader:#读取测试样本数据
            images, labels = data
            images, labels = images.to(device), labels.to(device) #GPU加速
            pred = model(images)#预测,每一个样本占一行,每行有十个值,后续需要求每一行中最大值所对应的下标
            pred_maxvalue, pred_maxindex = torch.max(pred.data,dim=1)#沿着第一个维度,一行一行来,去找每行中的最大值,返回每行的最大值和所对应下标
            total += labels.size(0)#labels是一个(N,1)的向量,对应每个样本的正确答案
            correct += (pred_maxindex == labels).sum().item()#使用预测得到的最大值的索引和正确答案labels进行比较,一致就是1,不一致就是0
        print("Accuracy on testset :%d %%"%(100*correct / total))#correct预测正确的样本个数 / 样本总数 * 100 = 模型预测正确率
        

if __name__ == '__main__':
    for epoch in range(10):#训练10次
        ytrain(epoch)#训练一次
        if epoch%10 == 9:
            ytest()#训练10次,测试1次

④测试一下

x,y = train_dataset[12]#第12个数据x为图片,对应的结果为3
y
"""
3
"""
x = x.view(-1,1,28,28)#因为tensor需要格式为(B,C,W,H)转换一下格式
y_hat = model(x)#放入模型中进行预测,因为时十分类任务,输出十个值
y_hat 
"""
tensor([[ 0.0953,  0.0728,  0.0505,  0.0618, -0.0512, -0.1338, -0.0261, -0.0677,
         -0.0265,  0.0236]], grad_fn=<AddmmBackward0>)
"""


pred_maxvalue, pred_maxindex = torch.max(y_hat,dim=1)#选出值最大的,和相对于的下标索引

pred_maxvalue#最大值
"""
tensor([0.0953], grad_fn=<MaxBackward0>)
"""
pred_maxindex#最大值所对应的索引下标值
"""
tensor([0])
"""

好家伙,又预测错了,确实得多训练几轮

又是动笔画,又是单步调试,若各位客官姥爷有所收获,还请点个小小的赞,这将是对我的最大的鼓励,万分感谢~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL--03】表的操作

文章目录1.表的操作1.1创建表1.2创建表案例1.3查看表结构1.4修改表1.5删除表1.表的操作 1.1创建表 语法&#xff1a; CREATE TABLE table_name(filed1 datatype,filed2 datatype,filed3 datatype )character set 字符集 collate 校验规则 engine 存储引擎;说明&#xff1a; …

Redis,Redis Sentinel ,集群

1&#xff1a;由于服务器优先&#xff0c;只能在同一台服务器搭建2个Redis&#xff0c;2个Redis Sentinel&#xff0c;实现Redis的集群 2&#xff1a;Linux上下载Redis&#xff0c;并安装和配置 下载执行一下命令&#xff1a; $ wget http://download.redis.io/releases/redi…

MySQL数据库(Python)

文章目录一、数据库安装&#xff08;Windows版&#xff09;二、数据库概念三、MySQL数据库3.1 数据类型3.2 数据库基本操作&#xff08;windows&#xff09;3.3 数据表的操作3.4 表数据操作四、PyMySQL的使用一、数据库安装&#xff08;Windows版&#xff09; 到mysql数据库官…

MATLAB | R2023a更新了哪些好玩的东西

R2023a来啦&#xff01;&#xff01;废话不多说看看新版本有啥有趣的玩意和好玩的特性叭&#xff01;&#xff01;把绘图放最前面叭&#xff0c;有图的内容看的人多。。 1 区域填充 可以使用xregion及yregion进行区域填充啦&#xff01;&#xff01; x -10:0.25:10; y x.^…

spdk环境搭建

SPDK环境搭建运行环境源码拉取编译增加虚拟盘&#xff0c;运行样例本来21年就写了这篇博客&#xff0c;但因为在博客中放了vmware的密钥&#xff0c;违规了&#xff0c;最近正好又要用到spdk&#xff0c;就重新搭建一下spdk&#xff0c;简单改一下博客再发一遍运行环境 VMware…

Unity云渲染,加移动

上次我们根据官方所推出的教程&#xff0c;完成了云渲染&#xff0c;这次我们加个移动。 原谅我又水一篇文章&#x1f604;&#x1f604;&#x1f604;&#x1f604;&#x1f604;&#x1f604;&#x1f604;&#x1f604;&#x1f604; 云渲染的文章看这里&#xff1a;Unity…

关于nn.CrossEntropyLoss交叉熵损失中weight和ignore_index参数

目录 1. 交叉熵损失 CrossEntropyLoss 2. ignore_index 参数 3. weight 参数 4. 例子 1. 交叉熵损失 CrossEntropyLoss CrossEntropyLoss 交叉熵损失可函数以用于分类或者分割任务中&#xff0c;这里主要介绍分割任务 建立如下的数据&#xff0c;pred是预测样本&#xff…

MongoDB 聚合管道的字段投影($addFields,$set,$unset,$project)

上一篇我们介绍了MongoDB 聚合管道的文档筛选及分组统计&#xff1a; $match&#xff1a;文档过滤 $group&#xff1a;文档分组&#xff0c;并介绍了分组中的常用操作&#xff1a;$addToSet&#xff0c;$avg&#xff0c;$sum&#xff0c;$min&#xff0c;$max等。 如果需要进一…

Ceph集群修复 osd 为 down 的问题

问题描述 由于突然断电了&#xff0c;导致 ceph 服务出现了问题&#xff0c;osd.1 无法起来 ceph osd tree解决方案 尝试重启 systemctl list-units |grep ceph systemctl restart ceph-f0e59898-71d4-11ec-924c-000c290a1a98osd.1.service发现重启无望&#xff0c;可采用…

国内企业使用敏捷开发的多吗?《2022中国企业敏捷实践白皮书》发布(附完整版下载)

通过2021-2022调研数据对比发现&#xff0c;受访者所在企业的敏捷团队占比从2021年的55%提升至2022年的63%&#xff0c;说明越来越多的中国企业正在从传统研发模式转变为敏捷研发模式&#xff0c;并不断扩大敏捷适用范围来促进企业整体敏捷转型&#xff1b; 与2021年的白皮书相…

android jetpack Navigation的使用(java)

简介 Navigation通过图形化的方式管理配置页面的切换。 基本使用 添加依赖 implementation androidx.navigation:navigation-fragment:2.5.3implementation androidx.navigation:navigation-ui:2.5.3创建xml文件&#xff08;添加导航图&#xff09;——nav_graph.xml nav_…

Java奠基】Java经典案例讲解

目录 卖飞机票 找质数 开发验证码 数组元素的复制 评委打分 数字加密 数字解密 抢红包 模拟双色球 二维数组 卖飞机票 需求&#xff1a;机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。按照如下规则计算机票价格&#xff1a; 旺季&…

ROS实践14 分布式通信

文章目录运行环境&#xff1a;思路&#xff1a;1.1 设置固定IP2.1 修改hosts文件3.1 检查是否成功通信4.1 修改bashrc5.1 演示运行环境&#xff1a; ubuntu20.04 noetic 宏基暗影骑士笔记本 思路&#xff1a; 主机启动roscore和乌龟速度订阅节点&#xff0c;从机启动乌龟键盘…

大模型时代下做科研的思路

总结zhu老师观点 Efficient 1.这篇论文是真的好orz&#xff0c;总结了目前的视频类模型 修改周边的一些参数&#xff0c;来训练&#xff0c;不改基础的模型&#xff08;太大了。。。没资源没卡&#xff09; 引申&#xff1a; prompt 是你想模型干什么你就给提示&#xff08…

python win环境 pip setuptools wheel安装

2023年。 今年的测试小学弟问我python这个安装怎么这么啥b。没有安装pip时 python setup.py install时需要setuptools&#xff0c;安装setuptools需要安装pip。 我看了看他的python是官网下的压缩包解压来的&#xff0c;内部非常干净。python-3.10.11 1. 安装pip 遇到这种情况…

“智慧赟”平台型经济引领行业新标杆

​  2021年&#xff0c;国家高度重视区块链行业发展&#xff0c;各部委发布的区块链相关政策已超60项&#xff0c;区块链不仅被写入“十四五”规划纲要中&#xff0c;各部门更是积极探索区块链发展方向&#xff0c;全方位推动区块链技术赋能各领域发展。在区块链产业具体内容…

【JavaEE】Spring中存储和获取Bean(使用注解)

目录 存储Bean 配置文件中设置扫描路径 使用注解存储Bean 五大类注解存储Bean 五大类注解之间的关系 为什么要有五大类注解 Bean方法注解存储方法返回值 注入Bean 属性注入 Setter方法注入 构造方法注入 Resource注解 存储Bean 上篇文章的存储Bean是在Spring的配置…

16.网络爬虫—字体反爬(实战演示)

网络爬虫—字体反爬一字体反爬原理二字体反爬模块FonttoolsTTF文件三FontCreator 14.0.0.2790FontCreatorPortable下载与安装四实战演示五后记前言&#xff1a; &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域新星…

一天吃透MySQL面试八股文

什么是MySQL MySQL是一个关系型数据库&#xff0c;它采用表的形式来存储数据。你可以理解成是Excel表格&#xff0c;既然是表的形式存储数据&#xff0c;就有表结构&#xff08;行和列&#xff09;。行代表每一行数据&#xff0c;列代表该行中的每个值。列上的值是有数据类型的…

python调用matlab源码函数

Background 关于在python中调用matlab函数&#xff0c;我之前已经写过两篇文章了&#xff0c;非常详细&#xff0c;且之前的方法可以不用安装matlab程序&#xff0c;只需要按照mcr运行环境就行了。具体可以参考&#xff1a;【java和python调用matlab程序详细记录】【Python 高效…