最近刚接触的深度学习,直接就被迷“五迷三道”,就当笔记来整理一下基础模型的构造,也方便之后的学习(幸亏之前有点算法基础,高数还算的过去,真的一开始就和听天书一样)。
只是基础的模型处理,有一定的参考价值
import torchvision
from torchvision.transforms import ToTensor
import torch
import matplotlib.pyplot as plt
import numpy as np
from torch import nn
#本人用的MNIST进行的模拟
train_ds = torchvision.datasets.MNIST('data',
train=True,#进行测试的数据
transform=ToTensor(),#转换成这个格式
download=True)
test_ds = torchvision.datasets.MNIST('data',
train=False,
transform=ToTensor(),
#内置数据集中提供了torch.utils.data.DataLoader转换数据类型
train_dl = torch.utils.data.DataLoader(train_ds,
batch_size=64,#进行小批次训练
shuffle=True)#乱序才能够保证数据的更加准确
test_dl = torch.utils.data.DataLoader(test_ds,
batch_size=64)#检测数据不需要过多的进行分析与处理,减少计算的次数
class Model(nn.Module):
def __init__(self):
super().__init__()
self.linear_1 = nn.Linear(28*28, 120)
self.linear_2 = nn.Linear(120, 84)
self.linear_3 = nn.Linear(84, 10)
def forward(self, input):
x = input.view(-1, 1*28*28)
x = torch.relu(self.linear_1(x))
x = torch.relu(self.linear_2(x))#relu激活函数,自己去查是啥样的
logits = self.linear_3(x)#直接返回了,没有激活
return logits # 未激活的输出,叫做logits
# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()#因为没有激活,所以使用了交叉熵计算
#优化器
opt = torch.optim.SGD(model.parameters(), lr=0.001)#SGD是随机梯度下降
#cpu的预处理
device = 'cuda' if torch.cuda.is_available() else 'cpu'
#实例化对象
model = Model().to(device) # 初始化模型 # 初始化模型(这样会比直接初始化模型更好)
#两个函数,训练函数,以及测试函数
def train(dl,model,loss_fn,optimizer):#dl所有数据进行处理,model模型,loss损失,op是优化器
size=len(dl.dataset)#先将数据进行转换求个数
num_batches=len(dl)#一共有多少层数
train_loss,correct=0,0
for x,y in dl:
x,y=x.to(device),y.to(device)
pred=model(x)
loss=loss_fn(pred,y)#计算损失函数
optimizer.zero_grad()#梯度重新为0
loss.backward()#反向计算
optimizer.step()#更新权重
with torch.no_grad():
correct += (pred.argmax(1) == y).type(torch.float).sum().item()#求总的正确率v
train_loss += loss.item()
correct/=size#计算现有的正确性
train_loss/=num_batches#平均的误差值
return correct,train_loss
# 测试函数
def test(test_dl, model, loss_fn):
size = len(test_dl.dataset)
num_batches = len(test_dl)
test_loss, correct = 0, 0
with torch.no_grad():
for x, y in test_dl:
x, y = x.to(device), y.to(device)
pred = model(x)
loss = loss_fn(pred, y)
#测试函数不需要重置
test_loss += loss.item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
correct /= size
test_loss /= num_batches
return correct, test_loss#返回了还是两个参数,一个是在准确率,一个是平均误差
#最重要的函数来了,考验cpu的时刻
#fit进行训练的函数
def fit(epochs,train_dl,test_dl,model,opt):#epochs训练的次数
train_loss = []
train_acc = []
test_loss = []
test_acc = []
for epoch in range(epochs):
epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)#训练的的数据集
epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)#测试的数据集
train_acc.append(epoch_acc)#将元素添加进列表里面去,这是正确率
train_loss.append(epoch_loss)#这是平均损失
test_acc.append(epoch_test_acc)
test_loss.append(epoch_test_loss)
template = ("epoch:{:2d}, train_Loss:{:.5f}, train_acc:{:.1f},test_Loss:{:.5f}, test_acc:{:.1f}")
print(template.format(epoch, epoch_loss, epoch_acc*100, epoch_test_loss, epoch_test_acc*100))
print('结束')
return train_loss,train_acc,test_loss,test_acc
#使用fit函数
(train_loss,train_acc,test_loss,test_acc)=fit(100,train_dl,test_dl,model,opt)
#然后就是画图观察数据了(这里其实看模拟出来的数据也是可以看出来的,画图的话就可以更直接的看出来,主要是为了防止过拟合的现象出现)
#误差的函数
epochs=100
plt.plot(range(epochs), train_loss, label='train_loss')
plt.plot(range(epochs), test_loss, label='test_loss')
plt.legend()
#准确率的函数
plt.plot(range(epochs), train_acc, label='train_acc')
plt.plot(range(epochs), test_acc, label='test_acc')
plt.legend()
#如果发生了过拟合现象就要及时处理激活函数,误差函数,以及优化器
改内容借鉴于日月光华。