動手深度學習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

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