<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Ex 1-1 by Chainer
https
Step1:  클래스를 통한 모델 구성
Step2:  II. 내장된 trainer를 사용하지 않고 학습하기
단순한 모델 구성
Chainer는 모델을 만들 때, 케라스나 파이토치하고 다른 형태로 만든다. 예제 1-1은 단일 노드로 구성된 단일 계층 네트웍을 다루고 있기 때문에 Linear(1,1)로 뉴럴넷을 모델링했다. 복수 계층을 가지는 경우는 다른 형태로 모델링을 구성해야 한다.
Step3:  클래스를 통한 모델 구성
https
<ASSISTANT_TASK:>
Python Code:
import chainer
import numpy as np
x = np.array([0, 1, 2, 3, 4]).astype('float32').reshape(-1,1) 
y = x * 2 + 1
predictor = chainer.links.Linear(1,1)
model = chainer.links.Classifier(predictor, lossfun=chainer.functions.mean_squared_error,
                                accfun=chainer.functions.mean_squared_error)
#model = chainer.links.Linear(1,1)
Optimizer = chainer.optimizers.SGD()
Optimizer.setup(model)
train = list(zip(x[:2,:1], y[:2,:1]))
Train_iter = chainer.iterators.SerialIterator(train, 2)
Updater = chainer.training.updaters.StandardUpdater(Train_iter, Optimizer)
Trainer = chainer.training.Trainer(Updater, (1000, 'epoch'))
Trainer.run()
predictor(x)
Explanation: Ex 1-1 by Chainer
https://docs.chainer.org/en/stable/examples/mnist.html
https://github.com/kose/chainer-linear-regression/blob/master/net.py
https://multithreaded.stitchfix.com/blog/2015/12/09/intro-to-chainer/
I. 케라스처럼 제공하는 trainer 툴을 이용하는 방법
내장된 trainer를 이용할 때는 모델 클래스의 forward(self, x, t)가 오류값을 생성하는 함수로 정의되어야 한다. 자체적으로 training code를 작성하는 경우에는 forward()는 주로 모델을 출력값을 생성하는 함수로 사용될 수 있다. 그리고 클래스를 통한 모델 구성시, 케라스 방식과 달리 변수들이 나오기 전에 with self.init_scope()을 열어주고 시작해야 한다. 그렇지 않으면 변수들이 학습되지 않는다. 
단순한 모델 구성
https://stackoverflow.com/questions/56111935/regression-with-chainer
chainer.links.Classifier()를 이용하면 loss와 accuracy 정의를 포함하는 model로 만들 수 있다. 이 모델을 만들어야 하는 이유는 이렇게 만들어나야 trainer를 사용할 수 있기 때문이다. 인공지능을 모르는 사람들에게는 편리한 방법이 될 수 있다.
End of explanation
import chainer
import numpy as np
x = np.array([0, 1, 2, 3, 4]).astype('float32').reshape(-1,1) 
y = x * 2 + 1
class Model(chainer.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.layer = chainer.links.Linear(1,1)
    def predict(self, x):
        return self.layer(x)
    def forward(self, x, t):        
        return chainer.functions.mean_squared_error(self.predict(x), t)
model = Model()
    
#model = chainer.links.Linear(1,1)
Optimizer = chainer.optimizers.SGD()
Optimizer.setup(model)
train = list(zip(x[:2,:1], y[:2,:1]))
Train_iter = chainer.iterators.SerialIterator(train, 2)
Updater = chainer.training.updaters.StandardUpdater(Train_iter, Optimizer)
Trainer = chainer.training.Trainer(Updater, (1000, 'epoch'))
Trainer.run()
model.predict(x)
Explanation: 클래스를 통한 모델 구성
End of explanation
import chainer
import numpy as np
x = np.array([0, 1, 2, 3, 4]).astype('float32').reshape(-1,1) 
y = x * 2 + 1
model = chainer.links.Linear(1,1)
optimizer = chainer.optimizers.SGD()
optimizer.setup(model)
for _ in range(1000):
    output = model(x)
    loss = chainer.functions.mean_squared_error(y, output)
    model.zerograds()
    loss.backward()
    optimizer.update()
model(x)
Explanation: II. 내장된 trainer를 사용하지 않고 학습하기
단순한 모델 구성
Chainer는 모델을 만들 때, 케라스나 파이토치하고 다른 형태로 만든다. 예제 1-1은 단일 노드로 구성된 단일 계층 네트웍을 다루고 있기 때문에 Linear(1,1)로 뉴럴넷을 모델링했다. 복수 계층을 가지는 경우는 다른 형태로 모델링을 구성해야 한다.
End of explanation
import chainer
import numpy as np
x = np.array([0, 1, 2, 3, 4]).astype('float32').reshape(-1,1) 
y = x * 2 + 1
class Model(chainer.Chain):
    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.layer = chainer.links.Linear(1,1)
    def forward(self, x):
        return self.layer(x)
model = Model()
    
#model = chainer.links.Linear(1,1)
optimizer = chainer.optimizers.SGD()
optimizer.setup(model)
for _ in range(1000):
    output = model(x)
    loss = chainer.functions.mean_squared_error(y, output)
    model.zerograds()
    loss.backward()
    optimizer.update()
model(x)
Explanation: 클래스를 통한 모델 구성
https://docs.chainer.org/en/stable/examples/train_loop.html
직접 학습하는 경우도 마찬가지로 클래스를 통한 모델 구성시 케라스 방식과 달리 변수들이 나오기 전에 with self.init_scope()을 열어주고 시작해야 한다. 그렇지 않으면 가중치과 바이어스가 학습되지 않는다.
End of explanation
<END_TASK>