学习方法:torch 边用边学,边查边学 真正用查的过程才是学习的过程
直接上案例,先来跑,遇到什么解决什么
数据集Minist 数据集
做简单的任务 Minist 分类任务
总体代码(可以跑通)
from pathlib import Path
import requests
import pickle
import gzip
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
from torch import optim
import numpy as np
bs=64
DATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"
PATH.mkdir(parents=True, exist_ok=True)
URL = "http://deeplearning.net/data/mnist/"
FILENAME = "mnist.pkl.gz"
with gzip.open((PATH / FILENAME).as_posix(), "rb") as f:
((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")
from matplotlib import pyplot
import numpy as np
print(x_train.shape)
# pyplot.imshow(x_train[0].reshape((28, 28)), cmap="gray")
#获取训练数据和测试数据
x_train, y_train, x_valid, y_valid = map(
torch.tensor, (x_train, y_train, x_valid, y_valid)
)
#设置模型结构
class Mnist_NN(nn.Module):
def __init__(self):
super().__init__()
self.hidden1 = nn.Linear(784, 128)
self.hidden2 = nn.Linear(128, 256)
self.out = nn.Linear(256, 10)
def forward(self, x):
x = F.relu(self.hidden1(x))
x = F.relu(self.hidden2(x))
x = self.out(x)
return x
net = Mnist_NN()
# print(net)
# for name, parameter in net.named_parameters():
# print(name, parameter,parameter.size())
#设置数据集和数据集加载器
train_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=64, shuffle=True)
valid_ds = TensorDataset(x_valid, y_valid)
valid_dl = DataLoader(valid_ds, batch_size=64 * 2)
def get_data(train_ds, valid_ds, bs):
return (
DataLoader(train_ds, batch_size=bs, shuffle=True),
DataLoader(valid_ds, batch_size=bs * 2),
)
loss_func = F.cross_entropy
def loss_batch(model, loss_func, xb, yb, opt=None):
loss = loss_func(model(xb), yb)
if opt is not None:
loss.backward()
opt.step()
opt.zero_grad()
return loss.item(), len(xb)
#训练参数
def fit(steps, model, loss_func, opt, train_dl, valid_dl):
for step in range(steps):
model.train()
for xb, yb in train_dl:
loss_batch(model, loss_func, xb, yb, opt)
model.eval()
with torch.no_grad():
losses, nums = zip(
*[loss_batch(model, loss_func, xb, yb) for xb, yb in valid_dl]
)
val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)
print('当前step:'+str(step), '验证集损失:'+str(val_loss))
def get_model():
model = Mnist_NN()
return model, optim.SGD(model.parameters(), lr=0.001)
train_dl, valid_dl = get_data(train_ds, valid_ds, bs)
model, opt = get_model()
fit(20, model, loss_func, opt, train_dl, valid_dl)
corret=0
total=0
for xb,yb in valid_dl:
outputs=model(xb)
_,predicted=torch.max(outputs.data,1)
total+=yb.size(0)
corret+=(predicted==yb).sum().item()
print('准确率是:%d %%'%(100*corret/total))
1.首先我们从最终实现的fit 函数开始看,
在fit h函数之前有一个get_model 函数 得到model和优化器
model, opt = get_model()
得到模型的优化器以后
需要把训练轮数 模型 损失函数 训练数据 测试数据传入fit 训练函数
fit(20, model, loss_func, opt, train_dl, valid_dl)
fit 函数
def fit(steps, model, loss_func, opt, train_dl, valid_dl):
for step in range(steps):
model.train()
for xb, yb in train_dl:
loss_batch(model, loss_func, xb, yb, opt)
model.eval()
with torch.no_grad():
losses, nums = zip(
*[loss_batch(model, loss_func, xb, yb) for xb, yb in valid_dl]
)
val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)
print('当前step:'+str(step), '验证集损失:'+str(val_loss))
xb是从dataloader 中取64个训练数据图片 也就是64*784维度,784代表28*28的手写数字图片的展平成一维向量
yb是64个图片对应的数字值
loss_batch(model, loss_func, xb, yb, opt)
我们看一下loss_batch 函数
loss 反向传播——更新优化器——优化器梯度归0
loss 是一个带有梯度的tensor .item()返回的是loss 的值 len(xb )是为了求精度的时候算
输入是模型损失函数xb ,yb 和优化器
loss_func = F.cross_entropy 损失函数是交叉熵损失函数
将xb 经过model 得到输出后 和xb 求损失函数 model 是定义的一个简单的模型有两个隐藏层一个输出层 784——128——256——10
再回到fit 函数的验证部分model.evl()
先来一个
with torch.no_grad()
不去计算梯度
zip(*的意思是解压缩 分别得到losses 和nums)
loss 和num 鲜橙 求每64个batch 的总loss 再将datalosder的所有batch 相加除以总数得到训练损失