chainer의 connection을 괴롭히고 새로운 층을 만든다 (2)
환경
GPU GTX1070
우분투 14.04
chainer 1.14.0
등
소개
chainer에서 최신 모델을 구현할 때는 links/connection이나 functions/connection을 괴롭힐 필요가 있다. 그래서 가장 단순한 linear.py를 만나 새로운 레이어를 만들어 보자.
전회는
chainer/functions/connection/linear.py
의 forward 함수를 만져 순전파를 개량했다.ぃ tp // 코 m / 설마 46 / ms / 1 A 5d6cbd49279 Ah f734
이번에는 backward 함수를 만지면서 오차 역전파를 개량한다.
오차 역전파 계산
오차 역전파의 연산은 이하의 도면과 같이 된다.
gx를 구하는데, W의 in_size/n측을 n배하면 계산이 편해진다. 또한 gW를 구하는 연산을 도식화하면 다음과 같다.
이번에는 gx와 x와의 행렬 곱으로 출력된 것을 in_size축측에 압축·합치게 할 필요가 있다. 이때 cupy.sum()을 사용한다.
linear.py 변경
chainer/functions/connection/linear.py
내의 backward 함수를 다음과 같이 수정한다. def backward(self, inputs, grad_outputs):
x = _as_mat(inputs[0])
W = inputs[1]
gy = grad_outputs[0]
W_tile = cupy.tile(W, (1, common_num)).astype(W.dtype, copy=False)
gx = gy.dot(W_tile).astype(gy.dtype, copy=False)
gW_wide = gy.T.dot(x).astype(W.dtype, copy=False)
gW_cube = gW_wide.reshape(len(gW_wide), common_num, -1).astype(W.dtype, copy=False)
gW = gW_cube.sum(axis=1).astype(W.dtype, copy=False)
if len(inputs) == 3:
gb = gy.sum(0)
return gx, gW, gb
else:
return gx, gW
행렬 곱의 결과 (gW_wide)에 대해 먼저 차원을 늘립니다 (gW_cube). 다음으로 그 차원에 대해 더해(sum 함수) 있다.
수정 모델 학습 결과
수정 모델을 실행하여 accuracy와 처리 속도를 원래 모델과 비교합니다.
python train_mnist3.py -g=0 -e=50
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 50
epoch main/loss validation/main/loss main/accuracy validation/main/accuracy
1 0.204286 0.10436 0.936834 0.9683
2 0.0795502 0.0783082 0.975266 0.974
・・・
49 0.00331749 0.124306 0.999166 0.9843
50 0.00580243 0.136195 0.998583 0.9836
50회의 학습으로 1분 30초, accuracy는 0.968에서 0.984로 상승했다. 원래 모델이라고 학습 시간 1분 54초에 accuracy는 0.971에서 0.985이다. 따라서 예상대로 학습 시간이 줄어들어 accuracy가 약간 감소했습니다.
Reference
이 문제에 관하여(chainer의 connection을 괴롭히고 새로운 층을 만든다 (2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/masataka46/items/d093fef0192b5c705b69텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)