本文首先介绍了数据预处理的方式,如dataset,dataloader。其次通过全连接网络来进行训练。
torchvision是pytorch的一个图形库,它服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。以下是torchvision的构成:
1. 将输入转为tensor
2. 规范图片格式为 (channel, height, width) 常见的图片格式为:H,W,C
3. 将像素取值范围规范到(0,1) 图像取值在0-255之间,totensor将图片的所有像素都除以255
1.乱序 shuffle
2.将数据采样为小批次 batch_size : 小批次的批次训练
3. num_workers
4. 设置批次处理函数 collate_fn
import numpy as np
np.argmax([0.9, 0.04, 0.06])
torch.argamx
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import torchvision
from torchvision.transforms import ToTensor
import torch
# In[2]:
train_ds = torchvision.datasets.MNIST('data',
train=True,
transform=ToTensor(),
download=True)
# In[3]:
test_ds = torchvision.datasets.MNIST('data',
train=False,
transform=ToTensor(),
download=True)
常见的图片格式: (高, 宽, 通道)ToTensor() 作用:
1. 将输入转为tensor
2. 规范图片格式为 (channel, height, width)
3. 将像素取值范围规范到(0,1)torch.utils.data.DataLoader 对dataset进行封装:
1.乱序 shuffle
2.将数据采样为小批次 batch_size : 小批次的批次训练
3. num_workers
4. 设置批次处理函数 collate_fn
# In[4]:
train_dl = torch.utils.data.DataLoader(train_ds,
batch_size=64,
shuffle=True)
# In[5]:
test_dl = torch.utils.data.DataLoader(test_ds,
batch_size=64)
# In[6]:
imgs, labels = next(iter(train_dl))
# In[7]:
imgs.shape
# In[8]:
import matplotlib.pyplot as plt
import numpy as np
# #创建一个 10 * 1 点(point)的图,
# 创建一个新的 1 * 1 的子图,接下来的图样绘制在其中的第 1 块(也是唯一的一块)
# subplot(1,1,1)
# In[9]:
#展示前十张图片
plt.figure(figsize=(10, 1))
for i, img in enumerate(imgs[:10]):
npimg = img.numpy()
npimg = np.squeeze(npimg)
# 绘制图片一行十列
plt.subplot(1, 10, i+1)
plt.imshow(npimg)
plt.axis('off')
# In[10]:
labels[:10]
# # 激活函数
# In[11]:
# relu激活: f(x) = max(x, 0)
# In[12]:
input = torch.randn(5)
# In[13]:
input
# In[14]:
torch.relu(input)
# In[15]:
torch.sigmoid(input)
# In[16]:
torch.tanh(input)
# In[17]:
from torch import nn
# In[18]:
nn.LeakyReLU(input)
# In[19]:
#创建多层感知器模型
# In[20]:
from torch import nn
# In[21]:
# nn.Linear() # 全连接层 要求输入的数据是一维 (batch, features)
# In[22]:
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))
logits = self.linear_3(x)
return logits # 未激活的输出,叫做logits
# In[23]:
#模型输出是C个可能值上概率, C表示类别总数 np.argmax([0.1, 0.2, 0.8])
# logits 【5, 10, 40】
# # 如何解析模型预测结果
# import numpy as np
#
# np.argmax([0.9, 0.04, 0.06])
#
# # torch.argamx
# In[24]:
# 两个概率分布的计算: [0.9, 0.04, 0.06] [0, 0, 1]
# In[25]:
# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()
# #损失函数的输入:
#
# loss_fn : target : 0,1,2、、、、 并不是独热编码的形式
#
# input: logits
# In[26]:
# 优化: 根据计算得到的损失,调整模型参数,降低损失的过程 Adam、SGD
# In[27]:
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Model().to(device) # 初始化模型
# In[28]:
opt = torch.optim.SGD(model.parameters(), lr=0.001)
# # 编写训练循环
# In[29]:
# 训练函数
def train(dl, model, loss_fn, optimizer):
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()
loss.backward()
optimizer.step()
with torch.no_grad():
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
train_loss += loss.item()
correct /= size
train_loss /= num_batches
return correct, train_loss
# In[30]:
# 测试函数
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
# In[31]:
# 训练50 个epoch, 每一个epoch代表将全部数据集训练一遍
# In[33]:
epochs = 50
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('Done')
# In[34]:
import matplotlib.pyplot as plt
# In[35]:
plt.plot(range(epochs), train_loss, label='train_loss')
plt.plot(range(epochs), test_loss, label='test_loss')
plt.legend()
# In[36]:
plt.plot(range(epochs), train_acc, label='train_acc')
plt.plot(range(epochs), test_acc, label='test_acc')
plt.legend()
# In[ ]: