ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AI] ๊ฒฝ์‚ฌํ•˜๊ฐ•๋ฒ•(feat: ์ตœ์ ํ™”, ์†์‹ค ํ•จ์ˆ˜) - ์„ ํ˜• ํšŒ๊ท€ ๋ถ„์„(2) with Python(๋ฐ‘๋ฐ”๋‹ฅ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๋”ฅ๋Ÿฌ๋‹)
    ๐Ÿ’ปProgramming/AI 2023. 12. 15. 17:05
    ๋ฐ˜์‘ํ˜•

    ๐Ÿ”— ํŒŒ์ดํ† ์น˜

    • 2017๋…„ ์ดˆ์— ๊ณต๊ฐœ๋œ ๋”ฅ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ
    • ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ์—ฐ๊ตฌ์ž๋“ค์ด ์‰ฝ๊ฒŒ GPU๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ธ๊ณต ์‹ ๊ฒฝ๋ง ๋ชจ๋ธ์„ ๋งŒ๋“ค๊ณ  ํ•™์Šต์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์คŒ
    • ํŽ˜์ด์Šค๋ถ์˜ ์ธ๊ณต์ง€๋Šฅ ์—ฐ๊ตฌํŒ€(AI Research) ๋ฉค๋ฒ„๋“ค์ด ์ฃผ๋กœ ๊ด€๋ฆฌ
    • ํŒŒ์ดํ† ์น˜ ํฌ๋Ÿผ: ๋…์ž์ ์œผ๋กœ ์šด์˜, ์‚ฌ๋žŒ๋“ค์ด ์งˆ๋ฌธ์„ ์˜ฌ๋ฆฌ๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๋ฅผ ๋น„๋กฏํ•œ ๋งŽ์€ ์‚ฌ๋žŒ์ด ๋‹ต์„ ํ•ด์ฃผ๋Š” ํ™œ๋ฐœํ•œ ๊ต๋ฅ˜๊ฐ€ ์ผ์–ด๋‚˜๊ณ  ์žˆ์Œ
    • ๊ธฐ์šธ๊ธฐ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ์—ฐ์‚ฐ ๊ทธ๋ž˜ํ”„๋ฅผ ์ญ‰ ๋”ฐ๋ผ์„œ ๋ฏธ๋ถ„ํ•  ๋•Œ, ํŒŒ์ดํ† ์น˜์—์„œ๋Š” backward() ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค. 
    • ๋‚ด๋ถ€์ ์œผ๋กœ CUDA, cuDNN์ด๋ผ๋Š” API๋ฅผ ํ†ตํ•ด GPU๋ฅผ ํ†ตํ•œ ์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ -> ์—ฐ์‚ฐ ์†๋„๊ฐ€ CPU์— ๋น„ํ•ด 15๋ฐฐ ์ด์ƒ ๋น ๋ฆ„
      • CUDA: ์—”๋น„๋””์•„๊ฐ€ GPU๋ฅผ ํ†ตํ•œ ์—ฐ์‚ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“  API ๋ชจ๋ธ
      • cuDNN: CUDA๋ฅผ ์ด์šฉํ•ด ๋”ฅ๋Ÿฌ๋‹ ์—ฐ์‚ฐ์„ ๊ฐ€์†ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

    ๐Ÿ”— ํŒŒ์ดํ† ์น˜์—์„œ์˜ ๊ฒฝ์‚ฌํ•˜๊ฐ•๋ฒ•

    ๐Ÿ“ ํ…์„œ(Tensor) 

    • ํ…์„œ = ๋‹ค์ฐจ์› ๋ฐฐ์—ด(multidimensional array)
    • ํŒŒ์ดํ† ์น˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๊ธฐ๋ณธ ๋‹จ์œ„

    ๐Ÿ“ ํ…์„œ ์ƒ์„ฑ

    • Shape์ด 2x3์ธ tensor์ƒ์„ฑ, tensor ์•ˆ ์›์†Œ์—๋Š” ์ž„์˜์˜ ๋‚œ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ
    import torch
    X = torch.Tensor(2,3)
    • Tensor๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ ์›ํ•˜๋Š” ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒฝ์šฐ
    X = torch.tensor([[1,2,3], [4,5,6]])

    ๐Ÿ“ backward()

    • ํŒŒ์ดํ† ์น˜์—์„œ ์ž๋™ ๋ฏธ๋ถ„์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋กœ, ์—ญ์ „ํŒŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ. ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํŒŒ์ดํ† ์น˜๋Š” ์—ฐ์‚ฐ ๊ทธ๋ž˜ํ”„๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ๊ฐ leaf node์— ๋Œ€ํ•œ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ณ„์‚ฐ

    ๐Ÿ“ ๋‹จ์ˆœํ•œ ๊ธฐ์šธ๊ธฐ ๊ณ„์‚ฐ

    # ๋จผ์ € ํŒŒ์ดํ† ์น˜๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
    import torch
    
    # x๋ฅผ [2.0, 3.0]์˜ ๊ฐ’์„ ๊ฐ€์ง„ ํ…์„œ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๊ณ  ๊ธฐ์šธ๊ธฐ ๊ณ„์‚ฐ์„ True๋กœ ์ผœ๋†“๋Š”๋‹ค. 
    # z = 2x^2+3
    x = torch.tensor(data=[2.0, 3.0], requires_grad=True)
    y = x**2 
    z = 2*y + 3
    
    # ๋ชฉํ‘œ๊ฐ’์„ ์ง€์ •
    target = torch.tensor([3.0, 4.0])
    
    # z์™€ ๋ชฉํ‘œ๊ฐ’์˜ ์ ˆ๋Œ€๊ฐ’ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐ
    # backward๋Š” ์Šค์นผ๋ผ ๊ฐ’์— ๋Œ€ํ•ด์„œ ๋™์ž‘ํ•˜๊ธฐ ๋–„๋ฌธ์— ๊ธธ์ด 2์งœ๋ฆฌ ํ…์„œ์ธ loss๋ฅผ torch.sum์„ ํ†ตํ•ด ํ•˜๋‚˜์˜ ์ˆซ์ž๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. 
    loss = torch.sum(torch.abs(z - target))
    
    # ์Šค์นผ๋ผ ๊ฐ’์ด ๋œ loss์— ๋Œ€ํ•ด backward๋ฅผ ์ ์šฉ
    loss.backward()
    
    # ์—ฌ๊ธฐ์„œ y์™€ z๋Š” ๊ธฐ์šธ๊ธฐ๊ฐ€ None์œผ๋กœ ๋‚˜์˜ค๋Š”๋ฐ ์ด๋Š” x, y, z์ค‘์— x๋งŒ์ด leaf node์ด๊ธฐ ๋•Œ๋ฌธ
    print(x.grad, y.grad, z.grad)
    • leaf node๋Š” ๊ณ„์‚ฐ ๊ทธ๋ž˜ํ”„์—์„œ์˜ ๋ ์ง€์ , ์ฆ‰ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ธฐ์ค€์ด ๋˜๋Š” ํ…์„œ๋ฅผ ์˜๋ฏธ. ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ํŒŒ์ดํ† ์น˜๋Š” leaf node์— ๋Œ€ํ•ด์„œ๋งŒ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ณ„์‚ฐ. backward()๋ฅผ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” leaf node์ธ x์— ๋Œ€ํ•ด์„œ๋งŒ .grad์†์„ฑ์— ๊ธฐ์šธ๊ธฐ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค. 

    ๐Ÿ“ ์„ ํ˜•ํšŒ๊ท€๋ถ„์„ ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

    1๏ธโƒฃ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ

    # ๋„˜ํŒŒ์ด์™€ ํŒŒ์ดํ† ์น˜๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค
    import numpy as np
    import torch
    
    # Neural Network์˜ ์•ฝ์ž๋กœ ์ธ๊ณต์‹ ๊ฒฝ๋ง ์—ฐ์‚ฐ๋“ค์ด ๋“ค์–ด๊ฐ€์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (ex. Linear, Convolution, RNN ๋“ฑ๋“ฑ)
    import torch.nn as nn
    
    # ๋ชจ๋ธ์„ ์ตœ์ ํ™” ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ตœ์ ํ™” ํ•จ์ˆ˜๋“ค์ด ๋“ค์–ด๊ฐ€์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (ex. SGD, ADAM, LBFGS ๋“ฑ๋“ฑ)
    import torch.optim as optim
    
    # ํ…์„œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์ด ๋“ค์–ด๊ฐ€์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (ex. uniform, normal, xavier ๋“ฑ๋“ฑ)
    import torch.nn.init as init
    
    # ๋ฐ์ดํ„ฐ๋‚˜ ํ•™์Šต ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    import matplotlib.pyplot as plt

    2๏ธโƒฃ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ

    # ๋ฐ์ดํ„ฐ์˜ ๊ฐœ์ˆ˜๋Š” 1000๊ฐœ, ํ•™์Šต ํšŸ์ˆ˜๋Š” 500ํšŒ๋กœ ์ง€์ •
    # ์ด๋Š” ์ž„์˜๋กœ ์ง€์ •ํ•œ ์ˆ˜์น˜
    num_data = 1000
    num_epoch = 500
    
    # ๋ฐ์ดํ„ฐ์— ์ถ”๊ฐ€ํ•  ๋…ธ์ด์ฆˆ๋ฅผ ์ •๊ทœ๋ถ„ํฌ๋ฅผ ๋”ฐ๋ฅด๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.
    # ์ด๋•Œ ํ‰๊ท ์€ ๋””ํดํŠธ๋กœ 0, ํŽธ์ฐจ๋Š” 0.2๋กœ ์ž„์˜๋กœ ์ง€์ •
    noise = init.normal_(torch.FloatTensor(num_data, 1), std=0.2)
    
    # x๋Š” -10์—์„œ 10์œผ๋กœ uniform ํ•˜๊ฒŒ ์ƒ์„ฑ
    # ์ด๋ ‡๊ฒŒ ๋˜๋ฉด x๋Š” 1000x1ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  -10์—์„œ 10 ์‚ฌ์ด์˜ ๊ฐ’๋“ค์„ uniform ํ•˜๊ฒŒ ๊ฐ–๊ฒŒ ๋œ๋‹ค
    x = init.uniform_(torch.Tensor(num_data, 1), -10, 10)
    
    # ์—ฐ์‚ฐ ๊ทธ๋ž˜ํ”„๋ฅผ ์ •์˜
    y = 2*x+3
    
    # y์— ๋…ธ์ด์ฆˆ๋ฅผ ๋”ํ•ด y_noise ๊ฐ’์„ ๋งŒ๋“ค์–ด์ค€๋‹ค
    # ํ•™์Šต๋•Œ y_noise๋ฅผ ๋ชฉํ‘œ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ
    # ์ด์œ : ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์—ฌ๋Ÿฌ ์ธก์ • ๊ณผ์ •์—์„œ ๋…ธ์ด์ฆˆ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ
    y_noise = y+noise

    3๏ธโƒฃ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”

    # figure์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •
    plt.figure(figsize=(10,10))
    
    # x์ถ•์—๋Š” x๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  y์ถ•์—๋Š” y_noise๋ฅผ ์‚ฌ์šฉํ•ด scatter plot ํ•ด์คŒ
    # ์ด ๋•Œ ์ ์˜ ํฌ๊ธฐ๋Š” 7, ์ ์˜ ์ƒ‰์ƒ์€ ํšŒ์ƒ‰
    plt.scatter(x.numpy(), y_noise.numpy(), s=7, c="gray")
    
    # figure์˜ x,y์ถ• ๋ฒ”์œ„๋ฅผ ์ง€์ •
    plt.axis([-12, 12, -25, 25])
    
    # figure ์ถœ๋ ฅ
    plt.show()

    4๏ธโƒฃ ๋ชจ๋ธ, ์†์‹คํ•จ์ˆ˜, ์ตœ์ ํ™”ํ•จ์ˆ˜ ์„ค์ •

    # ์„ ํ˜• ๋ชจ๋ธ ์ƒ์„ฑ
    # ์ž…๋ ฅ์œผ๋กœ ๋“ค์–ด์˜ค๋Š” x๊ฐ€ 1000x1์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์—ฌ๊ธฐ์„œ ํŠน์„ฑ์˜ ๊ฐœ์ˆ˜๋Š” 1์ด๊ธฐ ๋•Œ๋ฌธ์— ์•ž์— 1์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. Linear(1, ?)
    # ์ถœ๋ ฅ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฐ’ ๋˜ํ•œ 1000x1์˜ ํ˜•ํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ํŠน์„ฑ์˜ ๊ฐœ์ˆ˜๊ฐ€ 1๊ฐœ. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋’ค์— 1์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. Linear(?, 1)
    model = nn.Linear(1, 1)
    
    # ์†์‹ค ํ•จ์ˆ˜ ์ง€์ •
    # ์ž„์˜๋กœ L1 ์†์‹ค์„ ์ง€์ •(Mean Absolute Error Loss)
    loss_func = nn.L1Loss()
    
    # ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ €์ง•
    # ์ด๋•Œ ์ธ์ˆ˜๋กœ ํ•™์Šต์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ๋ชจ๋ธ์˜ ๋ณ€์ˆ˜(model.parameters())๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
    # ํ•™์Šต๋ฅ ์€ 0.01๋กœ ์ž„์˜๋กœ ์ง€์ •
    optimizer = optim.SGD(model.parameters(),lr=0.01)

    5๏ธโƒฃ ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ค‘๊ฐ„ ํ™•์ธ

    # ์†์‹ค์ด ์–ด๋–ป๊ฒŒ ๋ณ€ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด loss_arr๋ฅผ ๋งŒ๋“ค์–ด ๊ธฐ๋ก
    loss_arr = []
    
    # ๋ชฉํ‘œ๊ฐ’์€ y_noise๋กœ ์ง€์ •
    label = y_noise
    
    # 500์œผ๋กœ ์ง€์ •ํ–ˆ๋˜ ํ•™์Šต ํšŸ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต
    for i in range(num_epoch):
      # ์ด์ „ ํ•™์Šต์˜ ๊ธฐ์šธ๊ธฐ๋ฅผ ์ง€์šฐ๊ณ , ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ดˆ๊ธฐํ™”
      # ๊ธฐ์šธ๊ธฐ๋ฅผ ์ง€์šฐ์ง€ ์•Š์œผ๋ฉด ๊ธฐ์กด์˜ ์—…๋ฐ์ดํŠธ ๋•Œ๋ฌธ์— ํ•™์Šต์ด ์ž˜ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์Œ.
      optimizer.zero_grad()
    
      # ์ž…๋ ฅ๊ฐ’ x๋ฅผ ๋ชจ๋ธ์— ๋„ฃ์–ด ๊ฒฐ๊ณผ๊ฐ’์„ ์–ป๋Š”๋‹ค.
      output = model(x)
    
      # ๊ฒฐ๊ณผ๊ฐ’๊ณผ ๋ชฉํ‘œ๊ฐ’์˜ ์ฐจ์ด๋ฅผ L1 ์†์‹ค ํ•จ์ˆ˜๋กœ ๊ตฌํ•ด์ค€๋‹ค.
      loss = loss_func(output, label)
    
      # ์†์‹ค์— ๋Œ€ํ•œ ๊ธฐ์šธ๊ธฐ๋ฅผ ๊ตฌํ•œ๋‹ค.
      loss.backward()
    
      # ๊ตฌํ•œ ๊ธฐ์šธ๊ธฐ๋ฅผ ์ด์šฉํ•ด ๋ชจ๋ธ์˜ ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธ
      optimizer.step()
    
      # 10๋ฒˆ ๋งˆ๋‹ค ๋ชจ๋ธ์˜ ๋ณ€์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ถœ๋ ฅ.
      if i % 10 == 0:
        # ํ˜„์žฌ ์—ฐ์‚ฐ ๊ทธ๋ž˜ํ”„์— ์†ํ•ด์žˆ๋Š” x, output ๊ฐ’์„ detach๋ฅผ ํ†ตํ•ด ๋ถ„๋ฆฌํ•˜๊ณ , ํ…์„œ๋ฅผ ๋„˜ํŒŒ์ด ๋ฐฐ์—ด๋กœ ๋ฐ”๊ฟ”์„œ plt.scatter์— ์ „๋‹ฌ
        plt.scatter(x.detach().numpy(), output.detach().numpy())
        plt.axis([-10, -10, -30, -30])
        plt.show()
        print(loss.data)
    
      # ์†์‹ค์„ loss_arr์— ์ถ”๊ฐ€
      loss_arr.append(loss.detach().numpy())

    6๏ธโƒฃ ํ•™์Šต ํ›„ ๋ฐ์ดํ„ฐ์™€ ๋ชจ๋ธ ๊ฒฐ๊ณผ๊ฐ’ ํ™•์ธ

    # ํ•™์Šต ํ›„ ๋ฐ์ดํ„ฐ์™€ ๋ชจ๋ธ ๊ฒฐ๊ณผ๊ฐ’ ํ™•์ธ
    plt.figure(figsize=(15, 15))
    plt.scatter(x.numpy(), y_noise.numpy(), s = 5, c = "gray")
    plt.scatter(x.detach().numpy(), output.detach().numpy(), s = 5, c = "red")
    plt.axis([-10, 10, -30, 30])
    plt.show()
    • ์†์‹ค๊ทธ๋ž˜ํ”„ ํ™•์ธ
    # ์†์‹ค ๊ทธ๋ž˜ํ”„
    # matplotlib์˜ plot ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์†์‹ค์ด ์–ด๋–ป๊ฒŒ ์ค„์–ด๊ฐ€๋Š”์ง€ ํ™•์ธ
    plt.plot(loss_arr)
    plt.show()

    7๏ธโƒฃ ํ•™์Šต ํ›„ ๋ชจ๋ธ ๋ณ€์ˆ˜ ๊ฐ’ ํ™•์ธ

    # ํ•™์Šต ํ›„ ๋ชจ๋ธ ๋ณ€์ˆ˜ ๊ฐ’ ํ™•์ธ
    # ํ˜„์žฌ ๋ชจ๋ธ์€ weight ์™€ bias๋ฅผ ๋ณ€์ˆ˜๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ๊ทธ ๊ฐ’๋“ค์ด ํ•™์Šต ํ›„ ์‹ค์ œ ๋ช‡์ธ์ง€ ์ˆ˜์น˜์ ์œผ๋กœ ํ™•์ธํ•ด๋ณธ๋‹ค.
    param_list = list(model.parameters())
    print("Weight: ", param_list[0].item(), "\nBias: ", param_list[1].item())
    ๋ฐ˜์‘ํ˜•
Designed by Tistory.