Chainer에서 단일 회귀

9859 단어 Chainer기계 학습

개요



이제 Chainer를 배우고 있습니다. 본래의 Chainer 의 사용법은 아닙니다만, chainer.Link 와 chainer.Optimizer 라고 하는 제일 기본적인 클래스만을 이용해, 베타에 단회귀를 구현하면 어떻게 되는가? 라고 하는 실험을 실시했습니다(물론, 실제로 단회귀를 실시하고 싶을 때는 다른 방법으로 하는 편이 좋습니다).

단회귀



3점 $ (1, 1), (2, 3), (3, 4) $ 의 가능한 가까이를 통과하는 직선 $ y_p = wx + b $ 를 생각해 그 기울기 $ w $ 와 절편 $ b $ 를 구하는 것 생각합니다.

$i$ 두 번째 점을 $(x^{(i)},y^{(i)})$로 나타내면 평균 제곱 오차 $loss$
loss = (1/3)  \sum_{i=1}^{3} ((wx^{(i)} + b) - y^{(i)})^2

가 최소가 되도록 $w$ 와 $b$ 를 정하기로 합니다.

실제로 다른 도구로 계산해 보면,
w = 1.5, b = -0.333333

됩니다.



이 계산을 아래에서 Chainer 를 사용해 봅니다.

코드


import numpy as np
import chainer

class SimpleRegression(chainer.Link):
    def __init__(self):
        super().__init__(
            w = (1),
            b = (1),
        )
        self.w.data = np.array([2], dtype = np.float32)
        self.b.data = np.array([0], dtype = np.float32)

    def __call__(self, x):
        return (self.w * x) + self.b

def lossfun(model, xs, ys):
    loss = 0
    for i in range(len(xs)):
        yp = model(xs[i])
        z = yp - ys[i]
        loss += z * z
    return loss / len(xs)

def main():
    xs = [1, 2, 3]
    ys = [1, 3, 4]
    model = SimpleRegression()
    optimizer = chainer.optimizers.SGD(lr = 0.1)
    optimizer.setup(model)
    for i in range(500):
        model.zerograds()
        print("=== Epoch %d ===" % (i + 1))
        print("model.w.data = %f" % model.w.data)
        print("model.w.grad = %f" % model.w.grad)
        print("model.b.data = %f" % model.b.data)
        print("model.b.grad = %f" % model.b.grad)
        loss = lossfun(model, xs, ys)
        print("loss = %f" % loss.data)
        print("")
        loss.backward()
        optimizer.update()

main()

실행 결과


=== Epoch 1 ===
model.w.data = 2.000000
model.w.grad = 0.000000
model.b.data = 0.000000
model.b.grad = 0.000000
loss = 2.000000

=== Epoch 2 ===
model.w.data = 1.400000
model.w.grad = 0.000000
model.b.data = -0.266667
model.b.grad = 0.000000
loss = 0.080000

=== Epoch 3 ===
model.w.data = 1.466667
model.w.grad = 0.000000
model.b.data = -0.240000
model.b.grad = 0.000000
loss = 0.057007

...
=== Epoch 499 ===
model.w.data = 1.500000
model.w.grad = 0.000000
model.b.data = -0.333333
model.b.grad = 0.000000
loss = 0.055556

=== Epoch 500 ===
model.w.data = 1.500000
model.w.grad = 0.000000
model.b.data = -0.333333
model.b.grad = 0.000000
loss = 0.055556

$ w $( model.w.data ) = 1.5, $b$( model.b.data ) = - 0.333333 이라는 해에 수렴하고 있는 것을 알 수 있습니다.

해설


SimpleRegressionchainer.Link 클래스의 서브클래스로 $ y_p = wx + b $ 라는 모델을 표현하고 있습니다 (가설 ​​함수(hypothesis function)). 대조적으로, lossfun 함수는이 모델 (가설 함수)을 사용할 때 평균 제곱 오차를 계산합니다. 이 함수의 반환값이 chainer.Variable 객체인 것에 주의해 주세요. loss.backward() 에서 $w$ 및 $b$ 기울기( model.w.gradmodel.b.grad )를 계산하고 optimizer.update() 에서 $w$ 및 $b$ ( model.w.datamodel.b.data 갑니다.

참고문헌



Introduction to Chainer

좋은 웹페이지 즐겨찾기