スクラッチ学習Pytorchから線形回帰

 

直線回帰

主な内容は次のとおりです。

  1. 線形回帰の基本要素

  2. ゼロを達成するために、線形回帰モデル

  3. pytorchを達成するために、単純な線形回帰モデルを使用して

線形回帰の基本要素

モデル

簡単にするために、我々は、価格は2つのだけの要因、すなわち面積(平方メートル)と建物の年数(年)の住宅事情に依存していることを前提としています。次に、我々はこの2つの要因の価格で特定の関係を探求したいです。線形回帰は、線形関係は、それぞれの入力と出力との間に想定されています。

データセット

我々は通常、そのようなエリアやFanglingを対応する複数の家屋とその実際の販売価格などの実際のデータ、一連の収集します。私たちは、本当の価格の価格を予測するために、誤差モデルを最小限にするために上記のモデルパラメータでこのデータを見つけることを願っています。機械学習の用語では、データセットは、トレーニングデータセット(トレーニングデータセット)またはトレーニングセット(トレーニングセット)と呼ばれ、家を試料(サンプル)と呼ばれ、実際の販売価格タグ(ラベルと呼ばれています)、2つの要因が)特性(機能と呼ばれるラベルを予測するために使用しました。前記サンプルは、機能を特徴づけるために使用されます。

損失関数

モデルのトレーニングでは、予測値と真の値の価格との間の誤差を測定する必要があります。通常、我々は、エラーとして、負でない数を選択するであろう、そして小さい値が小さい誤差を表します。一般的な選択は、二乗関数です。サンプルのエラーのためには、評価指標式

最適化機能 - 確率的勾配降下

モデルの損失関数と単純な形は、問題の上記誤差最小化溶液を処方することができるときに直接発現。このような解決策は、解析解(解析解)と呼ばれています。線形回帰二乗誤差は、このセクションで使用され、このカテゴリーに入るだけ。しかし、最も深い学習モデルと分析ソリューションは、反復モデルパラメータのアルゴリズム有限数を最適化することにより、可能な限り損失関数の値を低減するだけでなく。そのような溶液は、数値解法(数値解)と呼ばれています。

最適化アルゴリズムの数値解では、確率的勾配降下法少量(ミニバッチ確率的勾配降下法)が広く深さの学習に使用されています。これは非常に単純なアルゴリズムは次のとおり、ランダム選択などのモデルパラメータの初期値の第1のセットを選択するステップと、次に、各反復がそれほど損失関数の値ことを低減することができる、複数の反復パラメータ。各反復において、第1のランダム均一これで、最終的にガイド少量の数(勾配)でのデータサンプルの平均損失のモデルパラメータに対して訓練データ少量(ミニバッチ)からなるサンプル、および要件の固定数をサンプリングし、そして現在の反復の減少の所定量としてのモデルパラメータの肯定的な結果の積。

学習率:ステップの大きさを学ぶことが可能であり、それぞれの最適化を表し
バッチサイズを:バッチサイズバッチサイズは、小ロットの計算であります

要約すると、最適化機能は、次の2つのステップがあります。

  • (I)のランダムな初期化を使用して、一般的には、モデルパラメータを初期化します。

  • (II)我々は、各パラメータは勾配パラメータの負方向に移動することによって更新され、データに複数回反復します。

ベクトル計算

モデルのトレーニングまたは予測するとき、私たちはしばしば、複数のデータサンプルおよび使用ベクトル演算を処理します。線形回帰ベクトルの計算式の導入前に、2つのベクトルを追加するための二つの方法を考えてみましょう。

  1. ベクトルを追加する方法は、2つの要素のスカラー加算を行うための一つ一つに記載のベクターです。

  2. ベクトル加算の別の方法は、二つのベクトルのベクトル加算に直接形成されています。

import torch
import time

# init variable a, b as 1000 dimension vector
n = 1000
a = torch.ones(n)
b = torch.ones(n)
# define a timer class to record time
class Timer(object):
    """Record multiple running times."""
    def __init__(self):
        self.times = []
        self.start()

    def start(self):
        # start the timer
        self.start_time = time.time()

    def stop(self):
        # stop the timer and record time into a list
        self.times.append(time.time() - self.start_time)
        return self.times[-1]

    def avg(self):
        # calculate the average and return
        return sum(self.times)/len(self.times)

    def sum(self):
        # return the sum of recorded time
        return sum(self.times)

今、私たちはテストすることができます。まず、スカラー加算製1つのループ素子ずつに使用される2つのベクター。

timer = Timer()
c = torch.zeros(n)
for i in range(n):
    c[i] = a[i] + b[i]
'%.5f sec' % timer.stop()

输出:'0.01232 sec'

さらに、トーチは、2つのベクトルの直接のベクトル加算を行うために使用されます。

timer.start()
d = a + b
'%.5f sec' % timer.stop()

输出:'0.00029 sec'

もちろんその結果、操作が速く前者よりもです。したがって、我々は可能な限りベクトルとして計算効率を向上させるために計算する必要があります。

ゼロを達成するために、線形回帰モデル

# import packages and modules
%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random

print(torch.__version__)

输出:1.3.0

データセットを生成します

1000個のサンプルのデータセットを生成し、データセットを生成するために線形モデルを用いて、線形関係は、以下のデータを生成するために使用されます。

# set input feature number 
num_inputs = 2
# set example number
num_examples = 1000

# set true weight and bias in order to generate corresponded label
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)

ショーに生成された画像データを用いて、

plt.scatter(features[:, 1].numpy(), labels.numpy(), 1);

features = torch.randn(num_examples, num_inputs,
                      dtype=torch.float32)
print(features)

输出:tensor([[ 0.0908, -0.8646],
        [-1.6370,  1.6305],
        [-0.1965,  0.8613],
        ...,
        [-0.9776,  0.0575],
        [ 1.9371, -0.1497],
        [-0.1417, -1.0046]])

データセットを読みます

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)
        
batch_size = 10
for X, y in data_iter(batch_size, features, labels):
    print(X, '\n', y)
    break
输出:tensor([[ 1.3591,  0.6950],
        [ 0.5206, -0.2726],
        [-0.6639,  0.9716],
        [ 2.7164, -0.6513],
        [-1.0642,  1.9331],
        [-2.2240, -0.3616],
        [-0.9094,  0.6691],
        [-0.2991,  0.2488],
        [ 1.8312,  0.2209],
        [ 0.2833, -1.1672]]) 
 tensor([6.9694, 6.0005, 9.5797, 0.6944, 4.1964, 6.8519, 2.5178, 4.4217, 5.4679,
        9.9754])

モデルの初期化パラメータ

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

定義された損失関数

私たちは、平均二乗誤差損失関数を使用しています:

l^{(i)}(\mathbf{w}, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2,

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

定義された最適化機能

ここでは、最適化機能は、少量の確率的勾配降下法で使用されます。

(\mathbf{w},b) \leftarrow (\mathbf{w},b) - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{(\mathbf{w},b)} l^{(i)}(\mathbf{w},b)

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()))
    
输出:epoch 1, loss 7.605014
epoch 2, loss 7.521966
epoch 3, loss 7.550967
epoch 4, loss 7.542496
epoch 5, loss 7.535208

pytorchを達成するために、単純な線形回帰モデルを使用して

import torch
from torch import nn
import numpy as np
torch.manual_seed(1)
torch.set_default_tensor_type('torch.FloatTensor')

データセットを生成します

ここでは最初から実装して設定データを生成することとまったく同じです。

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

# 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
)
for X, y in data_iter:
    print(X, '\n', y)
    break
    
输出:tensor([[ 0.5584, -0.4995],
        [-0.1495, -1.6520],
        [-0.3280,  0.2594],
        [-0.4857, -1.2976],
        [ 1.8603,  0.4539],
        [-0.3628,  0.0064],
        [ 1.3235, -0.3536],
        [-2.3426, -0.5968],
        [-0.6290, -0.2948],
        [-0.0787,  0.2180]]) 
 tensor([7.0088, 9.5071, 2.6718, 7.6535, 6.3802, 3.4601, 8.0475, 1.5223, 3.9682,
        3.2977])

定義モデル

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
    
net = LinearNet(num_inputs)
# 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))
          # ......
        ]))

モデルの初期化パラメータ

from torch.nn import init

init.normal_(net[0].weight, mean=0.0, std=0.01)
init.constant_(net[0].bias, val=0.0)  # or you can use `net[0].bias.data.fill_(0)` to modify it directly

输出:Parameter containing:
tensor([0.], requires_grad=True)

for param in net.parameters():
    print(param)
输出:Parameter containing:
tensor([[-0.0142, -0.0161]], requires_grad=True)
Parameter containing:
tensor([0.], requires_grad=True)

定義された損失関数

loss = nn.MSELoss()    # nn built-in squared loss function
                       # function prototype: `torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')`

定義された最適化機能

import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr=0.03)   # built-in random gradient descent function
print(optimizer)  # function prototype: `torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)`
输出: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() # reset gradient, equal to net.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d, loss: %f' % (epoch, l.item()))
# result comparision
dense = net[0]
print(true_w, dense.weight.data)
print(true_b, dense.bias.data)

输出:epoch 1, loss: 0.000103
epoch 2, loss: 0.000097
epoch 3, loss: 0.000079

 

发布了139 篇原创文章 · 获赞 49 · 访问量 4万+

おすすめ

転載: blog.csdn.net/xiewenrui1996/article/details/104309458