Lua판 제로로부터 만드는 Deep Learning 그 11[구배의 산출]
과거 기사 요약
Lua판 제로로부터 만드는 Deep Learning 정리
소개
이번은 원서 4장의 경사의 부분을 실장합니다. 이번 부분은 기계 학습보다는 기초적인 설명이므로 날려도 괜찮습니다.
스크립트는 다음과 같습니다.
gradient_2d.lua
require 'gnuplot'
---勾配算出関数.
-- 入力値に対する多変数関数の勾配を求める
-- @param f 多変数関数 (Type:function)
-- @param x 入力値 (Type:Tensor ※1D Tensor)
-- @return 入力値に対する勾配の値 (Type:Tensor)
function _numerical_gradient_no_batch(f, x)
local h = 1e-4 -- 0.0001
grad = x:clone():zero()
for idx = 1, x:size()[1] do
local tmp_val = x:float()[idx]
x[idx] = tmp_val + h --一つの要素だけ動かす
local fxh1 = f(x) -- f(x+h)
x[idx] = tmp_val - h
local fxh2 = f(x) -- f(x-h)
grad[idx] = (fxh1 - fxh2) / (2*h)
x[idx] = tmp_val -- 値を元に戻す
end
return grad
end
---勾配算出関数.
-- 入力値(複数)に対する多変数関数の勾配を求める
-- @param f 多変数関数 (Type:function)
-- @param x 入力値 (Type:Tensor)
-- @return 入力値に対する勾配の値 (Type:Tensor)
function numerical_gradient(f, X)
if X:dim() == 1 then
return _numerical_gradient_no_batch(f, X)
else
local grad = X:clone():zero()
for idx = 1, X:size()[1] do
grad[idx] = _numerical_gradient_no_batch(f, X[idx]) --1Dずつ勾配を計算
end
return grad
end
end
---(Σxi^2)他変数関数.
-- @param x 入力値 (Type:Tensor)
-- @return 出力値 (Type:Tensor)
function function_2(x)
if x:dim() == 1 then
return torch.sum(torch.pow(x,2))
else
return torch.sum(torch.pow(x,2), 2)
end
end
--{3.0, 4.0}での勾配
print(numerical_gradient(function_2, torch.Tensor({3.0,4.0})))
--{0.0, 2.0}での勾配
print(numerical_gradient(function_2, torch.Tensor({0.0,2.0})))
--{3.0, 0.0}での勾配
print(numerical_gradient(function_2, torch.Tensor({3.0,0.0})))
local x0 = torch.range(-2, 2.5, 0.25)
local x1 = torch.range(-2, 2.5, 0.25)
--{x0[i], x1[j]}での各値に対する勾配(gradx,grady)と関数の値(surface)を計算
local gradx = torch.Tensor(x0:size()[1],x1:size()[1]):zero()
local grady = torch.Tensor(x0:size()[1],x1:size()[1]):zero()
local surface = torch.Tensor(x0:size()[1],x1:size()[1]):zero()
for xi = 1, x1:size()[1] do
for i = 1, x0:size()[1] do
gradx[{i,xi}] = numerical_gradient(function_2, torch.Tensor({x0[i], x1[xi]}))[1]
grady[{i,xi}] = numerical_gradient(function_2, torch.Tensor({x0[i], x1[xi]}))[2]
surface[{i,xi}] = function_2(torch.Tensor({x0[i], x1[xi]}))
end
end
--グラフ描写 ※x,y軸の目盛りは適当
gnuplot.figure(1)
gnuplot.splot(torch.sqrt(gradx:pow(2)+grady:pow(2))) --勾配の二乗平均
gnuplot.figure(2)
gnuplot.splot(surface) --関数の値
실행 결과는 다음과 같습니다.
실행 결과
$ th gradient_2d.lua
6.0000
8.0000
[torch.DoubleTensor of size 2]
0.0000
4.0000
[torch.DoubleTensor of size 2]
6.0000
0.0000
[torch.DoubleTensor of size 2]
torch의 표준으로 따라오는 gnuplot에서는 quiver를 묘사 할 수 없기 때문에 대신 x, y의 기울기의 뿌리 제곱 평균을 산출하고 플롯 해 보았습니다. 다만 죄송합니다만, 수고가의 관계로부터 x, y축의 눈금은 적당으로 하겠습니다. 10 정도가 본래의 원점이라고 생각해 보세요.
다음에 함수의 값에 대한 플롯도 나타냅니다. 이쪽이 알기 쉬울지도 모릅니다.
제대로 기울기를 계산할 수 있을 것 같네요.
결론
이번은 이상입니다.
다음번에는 구배법의 경우를 보고 싶습니다. 드디어 기계 학습인 것 같은 이야기가 되기 때문에 동기가 되겠네요.
고맙습니다.
Reference
이 문제에 관하여(Lua판 제로로부터 만드는 Deep Learning 그 11[구배의 산출]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Kazuki-Nakamae/items/104b9236ddf8f470ab51텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)