DAY2
1 - 复习
昨日我们了解了pytorch的基本内容,知道了张量Tensor的基本构造,并且了解了线性回归的基本原理,这些知识都是为后面的深度学习做铺垫的。
今天首先对Tensor的一些基本操作做一些总结,然后再学习一个基本的神经网络模型。
2 - 有关Tensor的一些基本操作
2-1 tensor的创建
见代码:
import numpy as np
import torch
# 1 - 使用nparray创建
a = np.array([1,3,2]) # 创建一个数组
b = torch.from_numpy(a)
print(b)
c = np.ones([2,3]) # 创建维度为2,3的数值为1的矩阵
d = torch.from_numpy(c)
print(c)
# 2 - 从list直接导入
m = torch.tensor = ([1.,2.3],
[2.,3.2])
print(m)
#注意,大写的Tensor直接写接受的是维度,加[]是数值
n = torch.Tensor = ([1.,2.3],
[2.,3.2])
print(n)
# 3 - 未初始化的数据后续必须赋值
2-2 Tensor的索引与切片操作
见代码:
import numpy as np
import torch
a = torch.rand(4,3,28,28)
print(a.shape)
# 1 - 索引
print(a[0].shape)
print(a[0,0].shape)
print(a[0,0,2,12].shape)
# 2 - 切片
# 切片规则( a : b : c)表示从a到b,以c为间隔取数
print(a[:2].shape) # 输出从0,1两个bitch
print(a[:2,:1,:,:].shape) # 输出0,1 bitch和0 channel
print(a[:2,1:,:,:].shape) # 输出0,1 bitch和 1,2 channel
print(a[:2,-1:,:,:].shape) # 输出0,1 bitch和 2 channel(-1表示最后一个元素)
2-3 Tensor维度变换
见代码:
import torch
a = torch.rand(4, 1, 28, 28)
print(a.shape)
b = a.view(4, 28*28)
print(b.shape)
c = a.view(4*28, 28)
print(c.shape)
d = a.reshape(4*28*28)
print(d.shape)
主要介绍这一方法,因为比较常用
3 - 分类识别网络实战
见代码,很好理解,有不懂可以去b站看看原视频讲解。
13.13 手写数字识别初体验-513_哔哩哔哩_bilibili
import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
from help import one_hot
# 加载数据集
batch_size = 512
train_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('mnist', train=True, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(
(0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
torchvision.datasets.MNIST('mnist', train=False, download=True,
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(
(0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=False)
# 构建神经网络
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# xw+b
self.fc1 = nn.Linear(28*28, 256)
self.fc2 = nn.Linear(256, 64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
# x: [b, 1, 28, 28]
# h1 = relu(xw1+b1)
x = F.relu(self.fc1(x))
# h2 = relu(h1w2+b2)
x = F.relu(self.fc2(x))
# h3 = h2w3+b3
x = self.fc3(x)
return x
net = Net()
# 优化器返回数值 [w1, b1, w2, b2, w3, b3]
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
train_loss = []
for epoch in range(3):
for batch_idx, (x, y) in enumerate(train_loader):
# x: [b, 1, 28, 28], y: [512]
# [b, 1, 28, 28] => [b, 784]
x = x.view(x.size(0), 28*28)
# out输出网络训练的10个分类
out = net(x)
# out输出真实的10个分类
y_onehot = one_hot(y)
# 计算x与y的loss
loss = F.mse_loss(out, y_onehot)
# 优化器的梯度清0
optimizer.zero_grad()
# 计算梯度
loss.backward()
# 使用优化器更新梯度
# w' = w - lr*grad
optimizer.step()
train_loss.append(loss.item())
if batch_idx % 10==0:
print(epoch, batch_idx, loss.item())
total_correct = 0
for x,y in test_loader:
x = x.view(x.size(0), 28*28)
out = net(x)
# out: [b, 10] => pred: [b]
# 预测值,返回的是预测的概率最大的索引
pred = out.argmax(dim=1)
# 真实值,返回预测对的个数
correct = pred.eq(y).sum().float().item()
# 总体正确预测数量
total_correct += correct
total_num = len(test_loader.dataset)
# 准确度 = 正确预测/总体样本
acc = total_correct / total_num
print('test acc:', acc)