[Machine Learning] ์‹ ๊ฒฝ๋ง ๊ธฐ์ดˆ 3

2023. 2. 8. 00:08
๐Ÿง‘๐Ÿป‍๐Ÿ’ป์šฉ์–ด ์ •๋ฆฌ

์—ฐ์‡„๋ฒ•์น™ - ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ์—ฐ์‡„๋ฒ•์น™

 

 

์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ์—ฐ์‡„๋ฒ•์น™

 

์ˆœ๋ฐฉ ๊ณ„์‚ฐ

 

def chain_length_3(chain: Chain,
                   x: ndarray) -> ndarray:
    '''
    3๊ฐœ์˜ ํ•จ์ˆ˜๋ฅผ ์—ฐ์‡„์ ์œผ๋กœ ํ‰๊ฐ€ํ•จ.
    '''
    assert len(chain) == 3, \
    "์ธ์ž chain์˜ ๊ธธ์ด๋Š” 3์ด์—ฌ์•ผ ํ•จ"

    f1 = chain[0]
    f2 = chain[1]
    f3 = chain[2]

    return f3(f2(f1(x)))

 

def chain_deriv_3(chain: Chain,
                  input_range: ndarray) -> ndarray:
    '''
    ์„ธ ํ•จ์ˆ˜๋กœ ๊ตฌ์„ฑ๋œ ํ•จ์„ฑํ•จ์ˆ˜์˜ ๋„ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์—ฐ์‡„๋ฒ•์น™์„ ์‚ฌ์šฉํ•จ
    (f3(f2(f1)))' = f3'(f2(f1(x))) * f2'(f1(x)) * f1'(x)
    '''

    assert len(chain) == 3, \
    "This function requires 'Chain' objects to have length 3"

    f1 = chain[0]
    f2 = chain[1]
    f3 = chain[2]

    # f1(x)
    f1_of_x = f1(input_range)

    # f2(f1(x))
    f2_of_x = f2(f1_of_x)

    # df3du
    df3du = deriv(f3, f2_of_x)

    # df2du
    df2du = deriv(f2, f1_of_x)

    # df1dx
    df1dx = deriv(f1, input_range)

    # ๊ฐ ์ ๋ผ๋ฆฌ ๊ฐ’์„ ๊ณฑํ•จ
    return df1dx * df2du * df3du

 

def square(x: ndarray) -> ndarray:
    '''
    ์ธ์ž๋กœ ๋ฐ›์€ ndarray ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Ÿ๊ฐ’์„ ์ œ๊ณฑํ•œ๋‹ค.
    '''
    return np.power(x, 2)

def leaky_relu(x: ndarray) -> ndarray:
    '''
    ndarry ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ์— 'Leaky ReLU' ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ๋‹ค.
    '''
    return np.maximum(0.2 * x, x)

def sigmoid(x: ndarray) -> ndarray:
    '''
    ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ndarray์˜ ๊ฐ ์š”์†Œ์— ๋Œ€ํ•œ sigmoid ํ•จ์ˆซ๊ฐ’์„ ๊ณ„์‚ฐํ•œ๋‹ค.
    '''
    return 1 / (1 + np.exp(-x))

 

def plot_chain(ax,
               chain: Chain, 
               input_range: ndarray,
               length: int=2) -> None:
    '''
    ์—ฐ์‡„๋ฒ•์น™์„ ์ด์šฉํ•ด ํ•ฉ์„ฑํ•จ์ˆ˜์˜ ๋„ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ๊ทธ๋ž˜ํ”„๋ฅผ ์ž‘๋„ํ•จ.
    
    ax: ์ž‘๋„์— ์‚ฌ์šฉํ•  matplotlib์˜ ์„œ๋ธŒํ”Œ๋กฏ
    '''
    
    assert input_range.ndim == 1, \
    "input_range๋Š” 1์ฐจ์› ndarray์—ฌ์•ผ ํ•จ"
    if length == 2:
        output_range = chain_length_2(chain, input_range)
    elif length == 3:
        output_range = chain_length_3(chain, input_range)
    ax.plot(input_range, output_range)

 

 

def plot_chain_deriv(ax,
                     chain: Chain,
                     input_range: ndarray,
                     length: int=2) -> ndarray:
    '''
    ์—ฐ์‡„๋ฒ•์น™์„ ์ด์šฉํ•ด ํ•ฉ์„ฑํ•จ์ˆ˜์˜ ๋„ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ๊ทธ๋ž˜ํ”„๋ฅผ ์ž‘๋„ํ•จ.
    
    ax: ์ž‘๋„์— ์‚ฌ์šฉํ•  matplotlib์˜ ์„œ๋ธŒํ”Œ๋กฏ
    '''

    if length == 2:
        output_range = chain_deriv_2(chain, input_range)
    elif length == 3:
        output_range = chain_deriv_3(chain, input_range)
    ax.plot(input_range, output_range)

 

 

fig, ax = plt.subplots(1, 2, sharey=True, figsize=(16, 8))  # 2 Rows, 1 Col

chain_1 = [leaky_relu, square, sigmoid]
chain_2 = [leaky_relu, sigmoid, square]

PLOT_RANGE = np.arange(-3, 3, 0.01)
plot_chain(ax[0], chain_1, PLOT_RANGE, length=3)
plot_chain_deriv(ax[0], chain_1, PLOT_RANGE, length=3)

ax[0].legend(["$f(x)$", "$\\frac{df}{dx}$"])
ax[0].set_title("$f(x) = sigmoid(square(leakyRrelu(x)))$์˜ ํ•จ์ˆ˜์™€ ๋„ํ•จ์ˆ˜")

plot_chain(ax[1], chain_2, PLOT_RANGE, length=3)
plot_chain_deriv(ax[1], chain_2, PLOT_RANGE, length=3)
ax[1].legend(["$f(x)$", "$\\frac{df}{dx}$"])
ax[1].set_title("$f(x) = square(sigmoid(leakyRelu(x)))$์˜ ํ•จ์ˆ˜์™€ ๋„ํ•จ์ˆ˜")

 

 

 

 

์ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

BELATED ARTICLES

more