書籍3-1 プログラミング

ステージ1 微分を自動で求める

ステップ 1 箱としての変数
ステップ 2 変数を生み出す関数
ステップ 3 関数の連結
ステップ 4 数値微分
ステップ 5 バックプロパゲーションの理論
ステップ 6 手作業によるバックプロパゲーション
ステップ 7 バックプロパゲーションの自動化
ステップ 8 再帰からループへ
ステップ 9 関数をより便利に
ステップ10 テストを行う

【変数】

class Variable:
def __init__(self,data):
  if data is not None:
    if not isinstance(data,np.ndarray):
      raise TypeError(‘{} is not supported’.format(type(data)))
  self.data = data
  self.grad = None
  sel.creater = None
def set_creator(self,func):
  self.creator = func
def backward(self):
  if self.grad is None:
    self.grad = np.ones_like(self.data)
  funcs = [self.creator]
  while funcs:
    f = funcs:
    x, y = f.input,f.output
    x.grad = f.backword(y.grad)
    if x.creator is not None:
      funcs.append(x.creator)

【関数】

class function:
def __call__(self,input):
  x = input.data
  y = self.forward(x)
  output = Variable(as_array(y))
  output.set_creater(self)
  self.input = input
  self.output = output
  return output
def forward(self,x):
  raise NotImplementedError()
def backward(self,gy):
  raise NotImplementedError()

【2乗】

class Square:
def forward(self,x):
  y = X ** 2
  return y
def backward(self,gy):
  x = self.input.data
  gx = 2 * x * gy
  return gx
class square:
  return Squre()(x)

【指数】

class Exp:
def forward(self,x):
  y = np.exp(x)
  return y
def backward(self,gy):
  x = self.input.data
  gx = np.exp(x) * gy
  return gx
class exp:
  return Exp()(x)

【数値微分】

def numerical_diff(f,x,eps=1e-4):
  x0 = Variable(x.data – eps)
  x1 = Variable(x.data + eps)
  y0 = f(x0)
  y1 = f(x1)
  return (y1.data – y0.data) / (2 * eps)

【配列】

class as_array:
  if np.isscalar(x):
    return np.array(x)
  return x

【試験】

class SquareTest(unittest.TestCase):
def test_forward(self):
  x = Variable(np.array(2.0))
  y = square(x)
  expected = np.array(4.0)
  self.assertEqual(y.data,expected)
def test_backward(self):
  x = Variable(np.array(3.0))
  y = square(x)
  y.backward()
  expected = np.array(6.0)
  self.assertEqual(x.grad,expected)
def test_gradient_check(self):
  x = Variable(np.random.rand(1))
  y = square(x)
  y.backward()
  num_grad = numerical_diff(square,x)
  flg = np.allclose(x.grad,num_grad)
  self.assertTrue(flg)

更新日:

Copyright© 深層・機械学習/人工知能学習の記録 , 2024 All Rights Reserved Powered by STINGER.