概要
- 線形回帰の基本要素
- 最初から線形回帰モデルを達成するために
- pytorchを達成するために、単純な線形回帰モデルを使用して
線形回帰の基本要素
モデル
それが唯一の住宅価格の住宅の面積(平方メートル)と建物の年数(年)、我々はこの2つの要因の特定率との関係を探求したいという仮定に依存しています。線形回帰は、線形関係は、それぞれの入力と出力との間に想定されています。
前記は、(領域)W及びW(年齢)は体重をFanglingハウジング領域の重量であり、Bはバイアスです。
データセット
私たちは、最初にこのような領域とFanglingを対応する複数の家屋とその実際の販売価格として、データ収集の作業を行います。私たちは、本当の価格の価格を予測するために、誤差モデルを最小限にするために上記のモデルパラメータでこのデータを見つけることを願っています。機械学習の用語では、データセットは家は、ラベル(面積とFanglingを予測二つの要因のためにその実際の販売価格タグとして知られているサンプルと呼ばれ、トレーニングデータセットやトレーニングセットと呼ばれています)と呼ばれる機能。前記サンプルは、機能を特徴づけるために使用されます。
損失関数
モデルのトレーニングでは、予測値と真の値の価格との間の誤差を測定する必要があります。通常、我々は、エラーとして、負でない数を選択するであろう、そして小さい値が小さい誤差を表します。一般的な選択は、二乗関数です。それは私のように表現される評価用サンプルインデックスの誤差であります
最適化機能
モデルの損失関数と単純な形は、問題の上記誤差最小化溶液を処方することができるときに直接発現。このようなソリューションは、解析解と呼ばれています。線形回帰と使用ここ二乗誤差は、ちょうどこのカテゴリに分類されます。しかし、最も深い学習モデルと分析ソリューションは、反復モデルパラメータのアルゴリズム有限数を最適化することにより、可能な限り損失関数の値を低減するだけでなく。このような解決策は、数値解法と呼ばれています。
最適化アルゴリズムの数値解では、確率的勾配降下法少量(ミニバッチ確率的勾配降下法)が広く深さの学習に使用されています。これは非常に単純なアルゴリズムは次のとおり、ランダム選択などのモデルパラメータの初期値の第1のセットを選択するステップと、次に、各反復がそれほど損失関数の値ことを低減することができる、複数の反復パラメータ。各反復において、第1のランダム均一これで、最終的にガイド少量の数(勾配)でのデータサンプルの平均損失のモデルパラメータに対して訓練データ少量(ミニバッチ)からなるサンプル、および要件の固定数をサンプリングし、そして現在の反復の減少の所定量としてのモデルパラメータの肯定的な結果の積。
ここで、ηは、知ることができる、各最適化ステップサイズを表す、学習率であり、バッチサイズは、β(バッチサイズ)で計算の少量。最適化機能は、次の2つのステップがあります。
- モデルパラメータの初期化、一般的にランダムな初期化。
- 複数の反復のデータは、各パラメータは勾配パラメータの負方向に移動することによって更新されます。
最初から線形回帰モデルを達成するために
必要なライブラリをインポート
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
データセットを生成します
ここでは、次の線形関係は、データを生成するために使用された1000個のサンプルのデータセットを生成し、データセットを生成するために線形モデルを使用します。
# 设置输入特征数量为2个特征
num_inputs = 2
# 设置样本数量为1000
num_examples = 1000
# 设置真实的权重和偏差
true_w = [2, -3.4]
true_b = 4.2
features = torch.randn(num_examples, num_inputs, dtype=torch.float32)
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.float32)
matplotlibの我々は、生成されたデータを表示するために使用することができます。
def use_svg_display():
display.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)):
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
set_figsize()
plt.scatter(features[:, 1].numpy(), labels.numpy(), 1);
結果は以下の通りであります:
データセットを読みます
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
# 打乱数据集
random.shuffle(indices) # random read 10 samples
for i in range(0, num_examples, batch_size):
j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) # the last time may be not enough for a whole batch
yield features.index_select(0, j), labels.index_select(0, j)
モデルの初期化パラメータ
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32)
b = torch.zeros(1, dtype=torch.float32)
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
トレーニング
場合は、データセット、モデル、機能の喪失と最適化機能は、モデルのトレーニングの良いスタートの後に定義されています。
# super parameters init
lr = 0.03
num_epochs = 5
net = linreg
loss = squared_loss
# training
for epoch in range(num_epochs): # training repeats num_epochs times
# in each epoch, all the samples in dataset will be used once
# X is the feature and y is the label of a batch sample
for X, y in data_iter(batch_size, features, labels):
l = loss(net(X, w, b), y).sum()
# calculate the gradient of batch sample loss
l.backward()
# using small batch random gradient descent to iter model parameters
sgd([w, b], lr, batch_size)
# reset parameter gradient
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()))
結果は以下の通りであります:
トレーニングとともに、損失が減少し続け、見ることができます。最後に、我々の出力、Bおよび実際のtrue_wワットトレーニングの結果、true_b:
W:(テンソル([2.0007]、[-3.3999]、requires_grad = TRUE)、 true_w:[2、-3.4]、 B:テンソル([4.2005]、requires_grad = TRUE)、 true_b:4.2
2間の比較、結果は非常に接近しています。
pytorchを達成するために、単純な線形回帰モデルを使用して
非常にシンプルになり、線形回帰関数を実現するためにpytorchメソッドを使用します。
データセットを生成します
スクラッチ実装からデータセットを生成すると、まったく同じです。
データセットを読みます
ここでpytorch utilsパッケージを使用して、データモジュールは、データセット、データローダパッケージ形式にデータセットを読み取るためのモジュール。
import torch.utils.data as Data
batch_size = 10
# combine featues and labels of dataset
dataset = Data.TensorDataset(features, labels)
# put dataset into DataLoader
data_iter = Data.DataLoader(
dataset=dataset, # torch TensorDataset format
batch_size=batch_size, # mini batch size
shuffle=True, # whether shuffle the data or not
num_workers=2, # read data in multithreading
)
定義モデル
私たちは、ネットワークモデルクラス、シンプルな神経回路網の中にカプセル化された線形回帰モデルを作成します。
class LinearNet(nn.Module):
def __init__(self, n_feature):
super(LinearNet, self).__init__() # call father function to init
self.linear = nn.Linear(n_feature, 1) # function prototype: `torch.nn.Linear(in_features, out_features, bias=True)`
def forward(self, x):
y = self.linear(x)
return y
リニアネットワークは、一層のみを持って、我々は、必要に応じて3通りの方法で使用したマルチレイヤネットワークを初期化することができます。
# ways to init a multilayer network
# method one
net = nn.Sequential(
nn.Linear(num_inputs, 1)
# other layers can be added here
)
# method two
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......
# method three
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
('linear', nn.Linear(num_inputs, 1))
# ......
]))
モデルの初期化パラメータ
pytorch NNモジュールのinit初期化モデルのパラメータするために使用されます。
from torch.nn import init
init.normal_(net[0].weight, mean=0.0, std=0.01)
init.constant_(net[0].bias, val=0.0)
定義された損失関数
pytorchはちょうどすることができ、それを呼び出す、私たちに良いパッケージシリーズの損失関数を助けている、例えば、スコアの損失は、我々は機能MSELoss()を使用します。
loss = nn.MSELoss()
定義された最適化機能
pytorch也帮我们封装好了一系列优化函数,例如我们使用的小批量随机梯度下降函数为SGD()。
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.03)
训练
训练时使用pytorch自动求导机制。
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() # reset gradient, equal to net.zero_grad()
l.backward()
optimizer.step()
print('epoch %d, loss: %f' % (epoch, l.item()))