일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ai 캠프
- chromeextention
- sLLM
- Github
- Jupyterlab
- 정치기 필기
- 오블완
- ML
- 로컬 런타임
- django
- team_project
- pandas
- ai_캠프
- 파이썬
- lightsail
- aws
- mysql
- Python
- ollama
- streamlit
- EC2
- 머신러닝
- djangorestframework
- finpilot
- mifare
- 티스토리챌린지
- seaborn
- conda
- ai캠프
- pytorch
- Today
- Total
greatsangho의 이야기
캠프 26일차 - 딥러닝 (텐서플로, 케라스, 다층 퍼셉트론) 본문
텐서플로와 파이토치를 이용하여 딥러닝을 진행한다. 그 중 텐서플로는 사용이 간편하다는 장점이 있다. 파이토치는 다양한 hyperparameter 튜닝이 가능한 덕분에 연구에 많이 사용되었다고 한다. 그러나 텐서플로가 버전을 올리며 기존 문법을 크게 바꾸어 하위호환이 안 되게 되며 사람들의 관심이 크게 감소하였고, 파이토치를 사용하는 방향으로 변화하였다고 한다. 딥러닝을 처음 접할 때는 텐서플로를 이용해 공부를 하고 후에 파이토치로 넘어가 진행하고자 한다.
딥러닝 개요
딥러닝은 사람의 신경망에서 착안하여 만들어졌다. 뉴련이 수상돌기로 일정 수준 이상의 자극을 받아 들일 때, 축삭 돌기 말단의 시냅스를 통해 다음 뉴런으로 신호가 전달 된다. 이와 같은 모습을 본따 artifical neuron(인공뉴런)을 만들었다. 인공 뉴런은 하나 이상의 이진 입력(on/off)과 하나의 이진 출력을 가진다.
퍼셉트론 : 가장 간단한 인공 신경망 구조
TLU(threshold logic unit)으로 불리며 이진 입력이 아닌 숫자를 입/출력 하고 가중치를 가진다. 가중치의 합인 z = w1x1 + w2x2 + w3x3 + ... = (w^T)x 후 계단 함수(step function)을 적용한다. 이를 hw(x) = step(z)로 표현할 수 있다.
계단함수
- 헤비사이드 계산 함수 : 0, 1
- 부호 함수 : -1, 0, 1
계단함수를 통해 임곗값을 넘어야 값을 출력하게 된다. 한 층의 모든 뉴런이 이전 층의 모든 뉴런과 연결되면 완전 연결층이라 부러며. 퍼셉트론은 층이 1개인 TLU로 모든 입력이 연결되어 있어 완전 연결 층이다.
헤브 학습
뉴런은 서로 활성화 될 수록 연결되는 특징이 있는데 이에 착안하여 동시에 활성화 되는 뉴런에 가중치를 주는 것을 의미한다. 퍼셉트론 학습 규칙은 가중치 업데이트로 이루어지며 이전 학습에 오차와 학습률을 곱한 값을 더해 다음 가중치를 정하게 된다.
다층 퍼셉트론
퍼셉트론의 가장 문제인 XOR를 풀 수 없는 문제를 해결하기 위해 다층 퍼셉트론(MLP)이 제시 되었다. MLP는 입력층, 하나 이상의 은닉층, 그리고 출력층으로 구성되며, 각 층은 여러 노드(뉴런)로 이루어져 있다. 주로 분류 및 회귀 문제에 사용한다. 여기서 은닉층을 여러개 쌓아 올리면 심층 신경망(DNN; deep neural nework)가 된다.
다층 퍼셉트론의 훈련
다층 퍼셉트론을 훈련하는 방법으로 역전파(backpropagation)을 사용한다. 이는 경사 하강법을 이용하여 네트워크를 정방향 한 번, 역방향 한 번 통과하는 방법이다. 이 때 모델 파라미터 간 오차 그레이디언트를 계산하고 이에 대해 경사하강법을 적용한다. 이런 그레이디언트를 계산하는 자동 미분을 수행하는데 역전파는 계산한 그레이디언트에 대한 후진 모드 자동 미분을 진행하는 방법이다.
학습은 미니배치씩 진행되며 전체 훈련 세트를 진행하는데 이를 여러 번 반복한다. 한 반복을 에포크(epoch)라고 한다. 미니배치가 입력층 --> 은닉층 --> 출력층 의 순서로 이루어지는 것을 정방향 계산이라고 하며 역방향 계산을 위한 각 과정 중간 계산값을 저장한다. 그 다음 출력 오차를 측정한다. 출력 연결이 오차에 기여하는 정도를 연쇄 법칙으로 계산한다. 그 오차에 대한 그레이디언트가 얼마나 기여했는지 측정하고 이를 수정하는 방법이 정방향 계산과는 반대로 진행되는 역전파가 일어난다. 이렇게 측정한 오차를 바탕으로 연결 가중치에 대한 오차 그레이디언트를 경사 하강법을 수행하고 수정한다.
역전파 훈련 알고리즘을 다시 과정을 정리하면
1. 예측을 만드는 정방향 계산
2. 오차 측정
3. 역방향으로 각 연결이 오차에 기여한 정도 역방향 계산
4. 오차가 감소하도록 경사 하강법을 이용한 가중치 조정
의 과정이다.
가장 대표적인 fashion_mnist 데이터셋으로 인공신경망 실습을 해보자.
import tensorflow as tf
(x_train,y_train),(x_test,y_test) = tf.keras.datasets.fashion_mnist.load_data()
x_train.shape, x_test.shape, y_train.shape, y_test.shape
# ((60000, 28, 28), (10000, 28, 28), (60000,), (10000,))
from sklearn.model_selection import train_test_split
x_train,x_val,y_train,y_val = train_test_split(x_train, y_train, test_size=0.2,random_state=42)
# 정규화 또는 표준화 --> 스케일링
# 이미지는 픽셀당 값의 범위가 0 ~ 255 그래서 모든 픽셀을 255로 나누면 0 ~ 1 사이를 가지는 스케일링
x_train = x_train / 255.0
x_val = x_val / 255.0
x_test = x_test / 255.0
x_train.shape[1:] # (28, 28)
인공신경망을 학습 시키기 위해서는 train, validation, test로 데이터를 나누어야 한다. 먼저 train과 test 데이터를 나눈 뒤,
train 데이터를 다시 train과 val로 나눈다. val을 나누는 이유는 역전파 시 오차를 검증하며 학습이 필요하기 때문이다.
train(48,000) | val(12,000) | test(10,000) |
따라서 다음과 같이 train, val, test를 나눌 수 있다.
여기서 흑백 이미지의 픽셀당 값의 범위가 0 ~ 255이기 때문에 0 ~ 1 사이 값을 가지도록 스케일링을 위해 255로 나누었다. 스케일링을 진행한 하나의 train 데이터의 모양을 보면 (28,28) 형태의 2차원 배열임을 알 수 있다. tensorflow에서 학습을 시킬 때는 2차원으로 데이터를 받고, 이를 1차원으로 Flatten()을 진행한 뒤, 활성함수를 거쳐 출력하게 된다. 이를 코드로 보면 다음과 같이 표현된다.
tf.random.set_seed(42)
model = tf.keras.Sequential([
# tf.keras.layers.Dense(10, input_shape=x_train.shape[1:]),
tf.keras.layers.Input(shape = x_train.shape[1:]), # tf.keras.layers.Input(shape=[28,28])
# 1차원으로 차원을 변경
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(300, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax'),
])
여기서 중요한 점은 keras를 사용하기 위한 모델을 먼저 정의하고 그 다음 컴파일 하는 과정을 거친다는 점이다. 분류를 위해 softmax 함수를 출력층의 활성함수로 사용하였다. 최종적으로 10개의 출력 요소를 가지도록 정하였기 때문에 10가지 항목에 대한 분류를 진행한다. 먼저 정의된 model을 보면 다음과 같다.
model.summary()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ flatten_2 (Flatten) │ (None, 784) │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_6 (Dense) │ (None, 300) │ 235,500 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_7 (Dense) │ (None, 100) │ 30,100 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_8 (Dense) │ (None, 10) │ 1,010 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Flatten을 진행하면 28 * 28 = 784의 1차원 배열로 펼쳐진다.
은닉층이 가지는 parameter는 전 레이어의 요소와 해당 레이어의 shape를 곱하고 해당 레이어의 shape를 더한 만큼 생성된다. 첫 레이어에서 784 * 300 + 300 = 235,500으로 parameter가 생성되고, 그 다음은 300 * 100 + 100 = 30,100의 parameter가 생성된다.
model.compile(optimizer='adam', # 최적화 방법
loss='sparse_categorical_crossentropy', # 손실함수
metrics=['accuracy']) # 평가 방법
history = model.fit(x_train, y_train, epochs=20, validation_data=(x_val,y_val))
컴파일을 진행하고 모델을 fit 한다.
validation과 train data를 비교해보면, 과적합이 일어남을 확인할 수 있다.
과적합을 막기 위해 Dropout을 이용해 학습이 과하게 진행되는 것을 막는다.
tf.random.set_seed(42)
model2 = tf.keras.Sequential([
# tf.keras.layers.Dense(10, input_shape=x_train.shape[1:]),
tf.keras.layers.Input(shape = x_train.shape[1:]), # tf.keras.layers.Input(shape=[28,28])
# 1차원으로 차원을 변경
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(300, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='softmax'),
])
'프로그래밍 > SK AI 캠프' 카테고리의 다른 글
SK AI 캠프 7주차 후기 (2) | 2024.10.07 |
---|---|
Conda 환경에서 Nvidia GPU 사용하여 PyTorch 구동하기 (6) | 2024.09.29 |
캠프 23일차 - 머신러닝(앙상블 학습 및 랜덤 포레스트) (0) | 2024.09.28 |
캠프 20일차 - 머신러닝(분류와 로지스틱 회귀) (0) | 2024.09.23 |
SKN AI 캠프 4주차 (0) | 2024.09.19 |