动手深度学习Pytorch笔记

参考资料

Dive-into-DL-PyTorch:动手深度学习之Pytorch

数据操作

第三章

3.1 线性回归

3.2 线性回归的从零开始实现

import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random

num_inputs = 2
num_examples = 1000
w = [2, -3.4]
b = 4.2
features = torch.from_numpy(np.random.normal(0, 1, (num_examples, num_inputs)))
labels = w[0]*features[:, 0] + w[1]* features[:, 1] + b
labels += torch.from_numpy(np.random.normal(0, 0.01, size = labels.size()))

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        j = torch.LongTensor(indices[i:min(i + batch_size, num_examples)])
        yield features.index_select(0, j), labels.index_select(0, j)
        
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)))
b = torch.zeros(1)
w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)

def linreg(X, w, b):
    return torch.mm(X, w) + b

def squared_loss(y_hat, y):
    return (y_hat - y.view(y_hat.size())) ** 2 / 2

def sgd(params, lr, batch_size):
    for param in params:
        param.data -= lr * param.grad / batch_size

batch_size = 10
lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss
for epoch in range(num_epochs):
    for X, y in data_iter(batch_size, features, labels):
        l = loss(net(X, w, b), y).sum()
        l.backward()
        sgd([w, b], lr, batch_size)
        w.grad.data.zero_()
        b.grad.data.zero_()
    train_l = loss(net(features, w, b), labels)
    print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item()))

epoch 1, loss 0.033245
epoch 2, loss 0.000145
epoch 3, loss 0.000053

print(true_w, '\n', w)
print(true_b, '\n', b)

tensor([[ 2.0009], [-3.4001]], dtype=torch.float64, requires_grad=True)
tensor([[ 2.0009], [-3.4001]], dtype=torch.float64, requires_grad=True)
tensor([4.1995], requires_grad=True)
tensor([4.1995], requires_grad=True)

3.3 线性回归的简洁实现

import torch
import numpy as np

num_inputs = 2
num_examples = 1000
true_w = [2, -3.4]
true_b = 4.2
features = torch.tensor(np.random.normal(0, 1, (num_examples,
num_inputs)), dtype=torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)

# 读取数据
import torch.utils.data as Data
batch_size = 10
# 将训练数据的特征和标签组合
dataset = Data.TensorDataset(features, labels)
# 随机读取小批量
data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)

import torch.nn as nn

# class LinearNet(nn.Module):
#     def __init__(self, n_feature):
#         super(LinearNet, self).__init__()
#         self.linear = nn.Linear(n_feature, 1)
#         # forward 定义前向传播
#     def forward(self, x):
#         y = self.linear(x)
#         return y
    
# net = LinearNet(num_inputs)
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
    ('linear', nn.Linear(num_inputs, 1))
    # ......
    ]))

from torch.nn import init
init.normal_(net[0].weight, mean=0, std=0.01)
init.constant_(net[0].bias, val=0) # 也可以直接修改bias的data:
net[0].bias.data.fill_(0)

loss = nn.MSELoss()

import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.03)

num_epochs = 3
for epoch in range(1, num_epochs + 1):
    for X, y in data_iter:
        output = net(X)
        l = loss(output, y.view(-1, 1))
        optimizer.zero_grad() # 梯度清零,等价于net.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d, loss: %f' % (epoch, l.item()))

epoch 1, loss: 0.000086
epoch 2, loss: 0.000026
epoch 3, loss: 0.000095

dense = net[0]
print(true_w, dense.weight)
print(true_b, dense.bias)

[2, -3.4] Parameter containing: tensor([[ 1.9999, -3.3998]], requires_grad=True)
4.2 Parameter containing: tensor([4.1996], requires_grad=True)

3.4 SOFTMAX回归

3.5 图像分类数据集(FASHION-MNIST)

3.5.1 获取数据集

import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import time
import sys
sys.path.append("..") # 为了了导入入上层目目录的d2lzh_pytorch
import d2lzh_pytorch as d2l

mnist_train = torchvision.datasets.FashionMNIST(root='./Datasets/FashionMNIST',
train=True, download=True, transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='./Datasets/FashionMNIST',
train=False, download=True, transform=transforms.ToTensor())
print(type(mnist_train))
print(len(mnist_train), len(mnist_test))

feature, label = mnist_train[0]
print(feature.shape, label) # Channel x Height X Width

# 本函数已保存在d2lzh包中方方便便以后使用用
def get_fashion_mnist_labels(labels):
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankleboot']
    return [text_labels[int(i)] for i in labels]
# 本函数已保存在d2lzh包中方方便便以后使用用
def show_fashion_mnist(images, labels):
    d2l.use_svg_display()
    # 这里里里的_表示我们忽略略(不不使用用)的变量量
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        f.imshow(img.view((28, 28)).numpy())
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()
    
X, y = [], []
for i in range(10):
    X.append(mnist_train[i][0])
    y.append(mnist_train[i][1])
show_fashion_mnist(X, get_fashion_mnist_labels(y))

batch_size = 256
if sys.platform.startswith('win'):
    num_workers = 0 # 0表示不不用用额外的进程来加速读取数据
else:
    num_workers = 4
train_iter = torch.utils.data.DataLoader(mnist_train,
batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test,
batch_size=batch_size, shuffle=False, num_workers=num_workers)

start = time.time()
for X, y in train_iter:
    continue
print('%.2f sec' % (time.time() - start))

在这里插入图片描述

3.7 SOFTMAX回归的简洁实现

import torch
import torchvision
import numpy as np
from torch import nn
from torch.nn import init
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs = 784
num_outputs = 10
W = torch.tensor(np.random.normal(0, 0.01, (num_inputs,
num_outputs)), dtype=torch.float)
b = torch.zeros(num_outputs, dtype=torch.float)
W.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)

def softmax(x):
    X_exp = X.exp()
    partition = X_exp.sum(dim = 1, keepdim = True)
    return X_exp / partition
def net(X):
    return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)

class FlattenLayer(nn.Module):
    def __init__(self):
        super(FlattenLayer, self).__init__()
    def forward(self, x): # x shape: (batch, *, *, ...)
        return x.view(x.shape[0], -1)
from collections import OrderedDict
net = nn.Sequential(
    # FlattenLayer(),
    # nn.Linear(num_inputs, num_outputs)
    OrderedDict([
    ('flatten', FlattenLayer()),
    ('linear', nn.Linear(num_inputs, num_outputs))])
    )
init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0)
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,
batch_size, None, None, optimizer)

epoch 1, loss 0.0031, train acc 0.750, test acc 0.758
epoch 2, loss 0.0022, train acc 0.812, test acc 0.800
epoch 3, loss 0.0021, train acc 0.825, test acc 0.797
epoch 4, loss 0.0020, train acc 0.832, test acc 0.818
epoch 5, loss 0.0019, train acc 0.837, test acc 0.817

3.8 多层感知机

3.9 多层感知机的从零开始实现

import torch
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d21

batch_size = 256
train_iter, test_iter = d21.load_data_fashion_mnist(batch_size)
num_inputs, num_outputs, num_hiddens = 784, 10, 256

W1 = torch.tensor(np.random.normal(0, 0.01, (num_inputs,
num_hiddens)), dtype=torch.float)
b1 = torch.zeros(num_hiddens, dtype=torch.float)
W2 = torch.tensor(np.random.normal(0, 0.01, (num_hiddens,
num_outputs)), dtype=torch.float)
b2 = torch.zeros(num_outputs, dtype=torch.float)

params = [W1, b1, W2, b2]
for param in params:
    param.requires_grad_(requires_grad=True)
def relu(X):
    return torch.max(input = X, other = torch.tensor(0.0))

def net(X):
    X = X.view((-1, num_inputs))
    H = relu(torch.matmul(X, W1) + b1)
    return torch.matmul(H, W2) + b2
loss = torch.nn.CrossEntropyLoss()

num_epochs, lr = 5, 100.0
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,
batch_size, params, lr)

epoch 1, loss 0.0031, train acc 0.710, test acc 0.804
epoch 2, loss 0.0019, train acc 0.822, test acc 0.763
epoch 3, loss 0.0017, train acc 0.842, test acc 0.828
epoch 4, loss 0.0016, train acc 0.855, test acc 0.836
epoch 5, loss 0.0015, train acc 0.863, test acc 0.848

3.10 多层感知机的简洁实现

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l

num_inputs, num_outputs, num_hiddens = 784, 10, 256
net = nn.Sequential(
    d2l.FlattenLayer(),
    nn.Linear(num_inputs, num_hiddens),
    nn.ReLU(),
    nn.Linear(num_hiddens, num_outputs),
    )
for params in net.parameters():
    init.normal_(params, mean=0, std=0.01)
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,
batch_size, None, None, optimizer)

epoch 1, loss 0.0031, train acc 0.704, test acc 0.760
epoch 2, loss 0.0019, train acc 0.825, test acc 0.820
epoch 3, loss 0.0017, train acc 0.844, test acc 0.781
epoch 4, loss 0.0015, train acc 0.855, test acc 0.821
epoch 5, loss 0.0014, train acc 0.866, test acc 0.810

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章