線性回歸
%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
生成數據集
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)
for X, y in data_iter:
print(X, y)
break
tensor([[ 1.7049, -0.8767],
[-0.3974, -1.5000],
[-1.0354, 0.5294],
[ 0.4510, -0.7127],
[-0.7047, 0.5365],
[-1.2976, 0.2687],
[ 0.2578, -1.1967],
[-0.3486, -0.8338],
[-0.0983, 0.3548],
[ 0.8583, -0.0350]]) tensor([10.5730, 8.5051, 0.3426, 7.5293, 0.9773, 0.6846, 8.7867, 6.3263,
2.8024, 6.0356])
定義模型
from torch import 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)
print(net) # 使用print可以打印出網絡的結構
LinearNet(
(linear): Linear(in_features=2, out_features=1, bias=True)
)
# 寫法一
net = nn.Sequential(
nn.Linear(num_inputs, 1)
# 此處還可以傳入其他層
)
# 寫法二
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......
# 寫法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
('linear', nn.Linear(num_inputs, 1))
# ......
]))
print(net)
print(net[0])
Sequential(
(linear): Linear(in_features=2, out_features=1, bias=True)
)
Linear(in_features=2, out_features=1, bias=True)
for param in net.parameters():
print(param)
Parameter containing:
tensor([[-0.2189, -0.2392]], requires_grad=True)
Parameter containing:
tensor([0.3330], requires_grad=True)
初始化模型參數
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)
Parameter containing:
tensor([0.], requires_grad=True)
定義損失函數
loss = nn.MSELoss()
定義優化算法
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.03)
print(optimizer)
SGD (
Parameter Group 0
dampening: 0
lr: 0.03
momentum: 0
nesterov: False
weight_decay: 0
)
訓練模型
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.000229
epoch 2, loss: 0.000081
epoch 3, loss: 0.000098
dense = net[0]
print(true_w, dense.weight)
print(true_b, dense.bias)
[2, -3.4] Parameter containing:
tensor([[ 1.9999, -3.3999]], requires_grad=True)
4.2 Parameter containing:
tensor([4.1997], requires_grad=True)
softmax回歸的簡潔實現
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
獲取和讀取數據
# 本函數已保存在d2lzh_pytorch包中方便以后使用
def load_data_fashion_mnist(batch_size, root='D:/Jingxian Li/Documents/Machine Learning/5 Pytorch'):
"""Download the fashion mnist dataset and then load into memory."""
transform = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=False, transform=transform)
mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=False, transform=transform)
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)
return train_iter, test_iter
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, root='D:/Jingxian Li/Documents/Machine Learning/5 Pytorch')
定義和初始化模型
num_inputs = 784
num_outputs = 10
class LinearNet(nn.Module):
def __init__(self, num_inputs, num_outputs):
super(LinearNet, self).__init__()
self.linear = nn.Linear(num_inputs, num_outputs)
def forward(self, x): # x shape: (batch, 1, 28, 28)
y = self.linear(x.view(x.shape[0], -1))
return y
net = LinearNet(num_inputs, num_outputs)
# 本函數已保存在d2lzh_pytorch包中方便以后使用
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)
Parameter containing:
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], requires_grad=True)
softmax和交叉熵損失函數
loss = nn.CrossEntropyLoss()
定義優化算法
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
訓練模型
# 本函數已保存在d2lzh包中方便以后使用
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
params=None, lr=None, optimizer=None):
for epoch in range(num_epochs):
train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
for X, y in train_iter:
y_hat = net(X)
l = loss(y_hat, y).sum()
# 梯度清零
if optimizer is not None:
optimizer.zero_grad()
elif params is not None and params[0].grad is not None:
for param in params:
param.grad.data.zero_()
l.backward()
if optimizer is None:
d2l.sgd(params, lr, batch_size)
else:
optimizer.step() # “softmax回歸的簡潔實現”一節將用到
train_l_sum += l.item()
train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
n += y.shape[0]
test_acc = evaluate_accuracy(test_iter, net)
print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
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.745, test acc 0.782
epoch 2, loss 0.0022, train acc 0.813, test acc 0.811
epoch 3, loss 0.0021, train acc 0.826, test acc 0.817
epoch 4, loss 0.0020, train acc 0.833, test acc 0.823
epoch 5, loss 0.0019, train acc 0.836, test acc 0.821
多層感知機的簡潔實現
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, root='D:/Jingxian Li/Documents/Machine Learning/5 Pytorch')
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)