DonHurry

step22. μ—°μ‚°μž μ˜€λ²„λ‘œλ“œ(3) λ³Έλ¬Έ

DeZero/πŸ—»μ œ2κ³ μ§€

step22. μ—°μ‚°μž μ˜€λ²„λ‘œλ“œ(3)

_도녁 2023. 1. 23. 01:27

πŸ“’ λ³Έ ν¬μŠ€νŒ…μ€ λ°‘λ°”λ‹₯λΆ€ν„° μ‹œμž‘ν•˜λŠ” λ”₯λŸ¬λ‹3을 기반으둜 μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 배운 λ‚΄μš©μ„ κΈ°λ‘ν•˜κ³ , 개인적인 곡뢀λ₯Ό μœ„ν•΄ μž‘μ„±ν•˜λŠ” ν¬μŠ€νŒ…μž…λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ ꡐ재 ꡬ맀λ₯Ό κ°•λ ₯ μΆ”μ²œλ“œλ¦½λ‹ˆλ‹€.

 

 

이번 λ‹¨κ³„μ—μ„œλ„ μ΄μ–΄μ„œ μƒˆλ‘œμš΄ μ—°μ‚°μžλ“€μ„ μΆ”κ°€ν•˜κ² μŠ΅λ‹ˆλ‹€. λ¨Όμ € μŒμˆ˜μž…λ‹ˆλ‹€. μž„μˆ˜μ˜ 미뢄은 $y = -x$일 λ•Œ -1μž…λ‹ˆλ‹€.

class Neg(Function):
    def forward(self, x):
        return -x

    def backward(self, gy):
        return -gy


def neg(x):
    return Neg()(x)

 

λ‹€μŒμ€ λΊ„μ…ˆμž…λ‹ˆλ‹€. $y = x0 - x1$일 λ•Œ $dy/dx0 = 1$, $dy/dx1 = -1$μž…λ‹ˆλ‹€. λ”°λΌμ„œ λ‹€μŒκ³Ό 같이 κ΅¬ν˜„ν•©λ‹ˆλ‹€. $y = 2.0 - x$와 같은 μ½”λ“œλ„ μ²˜λ¦¬ν•˜λ„λ‘ rsubκΉŒμ§€ κ΅¬ν˜„ν•˜μ—¬ μ€λ‹ˆλ‹€. λ§μ…ˆμ΄λ‚˜ κ³±μ…‰κ³Ό 달리 λΊ„μ…ˆμ€ μˆœμ„œμ— 따라 κ²°κ³Όκ°€ 달라지기 λ•Œλ¬Έμ— rsubκΉŒμ§€ κ΅¬ν˜„ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

class Sub(Function):
    def forward(self, x0, x1):
        y = x0 - x1
        return y
    
    def backward(self, gy):
        return gy, -gy


def sub(x0, x1):
    x1 = as_array(x1)
    return Sub()(x0, x1)


def rsub(x0, x1):
    x1 = as_array(x1)
    return Sub()(x1, x0)

 

λ‹€μŒμ€ λ‚˜λˆ—μ…ˆμž…λ‹ˆλ‹€. λ‚˜λˆ—μ…ˆμ˜ 미뢄은 $y = x0/x1$일 λ•Œ, $dy/dx0 = 1/x1$, $dy/dx1 = -x0/(x1)^2$μž…λ‹ˆλ‹€.

class Div(Function):
    def forward(self, x0, x1):
        y = x0 / x1
        return y
    
    def backward(self, gy):
        x0, x1 = self.inputs[0].data, self.inputs[1].data
        gx0 = gy / x1
        gx1 = gy * (-x0 / x1 ** 2)
        return gx0, gx1


def div(x0, x1):
    x1 = as_array(x1)
    return Div()(x0, x1)


def rdiv(x0, x1):
    x1 = as_array(x1)
    return Div()(x1, x0)

 

λ§ˆμ§€λ§‰μœΌλ‘œ κ±°λ“­μ œκ³±μž…λ‹ˆλ‹€. κ±°λ“­μ œκ³±μ€ $y=x^c$ ν˜•νƒœμž…λ‹ˆλ‹€. μ΄λ•Œ 밑이 x인 경우만 λ―ΈλΆ„ν•˜κ³  μ§€μˆ˜ cλŠ” μƒμˆ˜λ‘œ μ·¨κΈ‰ν•˜μ—¬ λ”°λ‘œ λ―ΈλΆ„ 계산을 ν•˜μ§€ μ•Šκ² μŠ΅λ‹ˆλ‹€.

class Pow(Function):
    def __init__(self, c):
        self.c = c
    
    def forward(self, x):
        y = x ** self.c
        return y
    
    def backward(self, gy):
        x = self.inputs[0].data
        c = self.c

        gx = c * x ** (c-1) * gy
        return gx


def pow(x, c):
    return Pow(c)(x)

 

μœ„μ—μ„œ κ΅¬ν˜„ν•œ λ©”μ„œλ“œλ“€μ„ μ„€μ •κΉŒμ§€ λ§ˆλ¬΄λ¦¬ν•΄μ€λ‹ˆλ‹€. μ΄λ•Œ μ£Όμ˜ν•  점은 λ§μ…ˆκ³Ό κ³±μ…ˆμ€ μˆœμ„œκ°€ 변해도 κ²°κ³Όκ°€ κ°™κΈ° λ•Œλ¬Έμ— raddλ₯Ό add둜 μ„€μ •ν–ˆμ§€λ§Œ, λΊ„μ…ˆκ³Ό 같이 μˆœμ„œκ°€ μ€‘μš”ν•œ 연산은 λ”°λ‘œ 섀정을 ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

Variable.__add__ = add
Variable.__radd__ = add
Variable.__mul__ = mul
Variable.__rmul__ = mul
Variable.__neg__ = neg
Variable.__sub__ = sub
Variable.__rsub__ = rsub
Variable.__truediv__ = div
Variable.__rtruediv__ = rdiv
Variable.__pow__ = pow