目录
一.课程内容
相比于上一个模型,此时输出也变成了多维的了,有10个输出值 。
但是y值输出是实数集,不是概率,为了让模型确定出是哪一个输出,我们要让十个y值符合概率分布,即P(x=1)+...+P(x=10)=1且每一项均大于零。
此时才能给出预测值。
通过softmax将(最后一次未进行线性变换的结果)用函数将其变为概率分布。
再利用NLLloss计算损失
跟这个是不是几乎一模一样。
当h(x)=sigmoid()时,就是BCEloss
sunshi=torch.nn.CrossEntropyLoss()
y=torch.LongTensor([2,0,1])
y1=torch.Tensor([[0.1,0.2,0.9],[1.1,0.1,0.2],[0.2,2.1,0.1]])
l1=sunshi(y1,y)
print('batch loss=',l1.data)
二.代码复现
from ast import Return
from operator import itemgetter
from pickletools import optimize
from unittest import result
from winreg import REG_FULL_RESOURCE_DESCRIPTOR
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import Dataset #抽象类,不能有实例化对象,只能被继承
from torch.utils.data import DataLoader
import numpy.matlib
import torch
import numpy as np
import torch.optim as optim
import torch.nn.functional as F
import matplotlib.pyplot as plt
batch_size=64
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081))])
#计算像素均值得到的结果,数据标准化。让数据压缩到[0.1]之间,满足正态分布————神经网络在这种情况下效果最好
train_dataset = datasets.MNIST(root='../data/mnist',train=True, download=True, transform=transform)
train_loader=DataLoader(train_dataset,shuffle=True,batch_size=batch_size)
test_dataset=datasets.MNIST(root='../data/mnist',train=False, download=True, transform=transform)
test_loader=DataLoader(test_dataset,shuffle=False,batch_size=batch_size)
class Model(torch.nn.Module):
def __init__(self) :
super(Model,self).__init__()
self.linear1=torch.nn.Linear(784,512)
self.linear2=torch.nn.Linear(512,256)
self.linear3=torch.nn.Linear(256,128)
self.linear4=torch.nn.Linear(128,64)
self.linear5=torch.nn.Linear(64,10)
def forward(self,x):
x=x.view(-1,784)
x=F.relu(self.linear1(x))
x=F.relu(self.linear2(x))
x=F.relu(self.linear3(x))
x=F.relu(self.linear4(x))#最后一层不需要线性变换
return self.linear5(x)#避免出现参数传递错误,就不设置新参数而是选择x自动代换
model=Model()
sunshi=torch.nn.CrossEntropyLoss()
youhua=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
def train(epoch):
running_loss=0.0
for batch_idx, data in enumerate(train_loader,0):
input,target=data
output=model(input)
loss=sunshi(output,target)
loss.backward()
youhua.step()
youhua.zero_grad()
running_loss+=loss.item()
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:
image,labels=data
output=model(image)
_,predicted= torch.max(output.data,dim=1)
total+=labels.size(0)
correct+=(predicted==labels).sum().item()
print("正确率:%d %%"%(100*correct/total))
if __name__=='__main__':
for epoch in range(10):
train(epoch)
test()
三.补充
1. 写代码的时候发现这个清零的位置非常重要,不可以放在backward后面,在前面的时候一直没有认识到这个先后顺序的重要性,尝试在原来的代码上修改出现了相同的情况。 当我把他放到step后面我就发现问题了,如果在step之前清零,就无法完成更新,在更早的代码中之所以可以写道backward之后也是因为没有放到正最后。
2.这个数据集在下载的时候频繁报错,解决方法就是换个wifi,效果极佳。