KT 에이블스쿨 복습

[0415 복습] 딥러닝 기초_딥러닝 개념, 회귀 모델링, 이진분류, 다중분류, CNN 등

리니끄적 2024. 4. 15. 22:55

**셀프 복습용으로 작성한 것이라 실수가 있을 수 있습니다!

혹시 실수를 발견하시면 댓글로 알려주시면 감사드리겠습니다 :)

 

딥러닝 기초

CH1. 딥러닝 개념 이해

가중치와 가중치 조정

  • 각 변수별 중요도를 선정하여 변수 X 가중치를 통해 모델링 
  • 최적의 모델 = 오차가 가장 적은 모델, 최적의 가중치를 찾아 오차를 줄이는 방식
  • weight를 조정해 모델 학습, 오차가 줄어드는지 확인 → 지정한 횟수만큼 or 더 이상 오차가 줄지 않을 때까지 반복

  • model.fit(x_train, y_train)을 통해 학습
  • 가중치에 초기값을 랜덤으로 지정 후 → 예측 결과 뽑음 (학습 데이터)
  • 오차 계산 후 오차를 줄이는 방향으로 가중치 조정 (Optimizer; 가중치를 어떻게 줄여야 하는지 찾는 역할)
  • 이 과정을 계속 반복
  • 가중치 = 파라미터라고도 부름! (하이퍼 파라미터는 인간이 조정, 파라미터는 학습 과정에서 선정)

오차 순전파: 입력값 → 예측값 → 오차 계산

오차 역전파: 오차 확인 → 가중치 조정을 통한 업데이트

 

- 학습곡선: 모델의 오차가 줄어드는 과정 시각화

- learning_rate(하이퍼 파라미터): 가중치를 조절하는 양에 영향을 미침, 오차를 조절하는 폭을 결정, 가중치의 업데이트 정도를 조절

** 작은 학습률은 안정적으로 모델을 수렴 가능, 수렴까지 오래 걸릴 수 있음

**큰 학습률은 빠르게 수렴할 수 있지만, 최적값을 지나치거나 발산할 가능성이 있음

 

 

 

CH2. 딥러닝 모델링_Regression (회귀 모델링)

딥러닝 전처리: 스케일링

  • 딥러닝은 스케일링이 선택이 아닌 필수!
  • 스케일링 방법
    • 정규화(Nomalization): 모든 값의 범위를 0 ~ 1로 변환

정규화 공식

  • 표준화(Standardization): 모든 값을 평균 = 0, 표준편차 =  1로 변환

표준화 공식

 

딥러닝 구조(Process)

  • 각 task는 output이었다가 다음으로 넘겨줄 때 input이 됨!

코드 실습

  • input_shape= (,): 분석단위에 대한 shape, 1차원: (feature수, )로 표기, 2차원: (행, 열)로 표기
  • output: 예측 결과가 1개 변수(y가 1개 변수), Dense(1, inp~) 에서 1이 output 의미
  • compile(컴파일)
    • loss function(오차함수): 오차 계산을 무엇으로 할지 결정하는 함수
    • mse: 회귀모델은 보통 mse로 오차 계산
    • optimizer: 오차를 최소화하도록 가중치를 조절하는 역할
    • optimizer= 'adam', learning_rate 기본값 = 0.001
    • optimizer = Adam(lr= 0.1) 로도 표기-> 0.1은 조정 가능한 숫자
  • epochs 반복횟수: 가중치 조정 반복 횟수, 전체 데이터를 몇 번 학습할 것인지 정해줌!
  • validation_split = 0.2: train 데이터에서 20%를 검증셋으로 분리
  • history: 에포크로 반복되는 그 때마다의 성능을 측정해 기록 → 학습곡선 그림
# Sequential 타입 모델 선언, (nfeatures, )는 shape의 1차원을 표현하는 방식: 값의 개수만 표현
model = Sequential( Dense(1, input_shape = (nfeatures,))  )   

# 컴파일, 우리가 짠 코드를 컴퓨터가 이해하도록 변환하는 과정
model.compile(optimizer='adam', loss='mse')

# 학습
hist = model.fit(x_train, y_train, epochs=20, validation_split=.2).history # 에포크 반복되는 로그를 보겠다!

 

** 바람직한 곡선의 모습: epoch가 증가하면서 loss가 큰 폭으로 축소 → 점차 loss 감소 폭이 줄어들면서 완만해짐

 

 

은닉층(Hidden Layer)

  • layer가 여러 개: 리스트 [] 로 입력함!
  • input_shape은 첫 번째 layer만 필요
  • activation(활성함수): 모든 은닉층은 활성함수를 필요로 함, 보통 'relu' 를 사용
    • relu는 0보다 작으면 0을 출력, 0보다 크면 자기값을 출력하는 함수 max(0, x)

 

활성화 함수(Activation Function)

  • 현재 레이어(각 노드)의 결과값을 다음 레이어(연결된 각 노드)로 어떻게 전달할지 결정/변환해주는 함수
  • 만약 활성화 함수가 없다면 히든 레이어를 아무리 추가해도, 그냥 선형회귀(선형함수)로 나타남
  • hidden layerd에서는 선형함수 → 비선형 함수로 변환해주는 역할
  • output layer에서 결과값을 다른 값으로 변환해주는 역할 (분류 모델에서 필요)

 

CH3. Feature Representation

  • hidden layer를 여러개 생성하면서 새로운 특징(New feature)을 생성!
  • 오차를 최소화 해주는 유익한 특징! → feature engineering / 새롭게 표현됨! 

 

CH4. 이진분류

  • 딥러닝에서 결과값을 0, 1 중 하나로 도출하기 위한 이진분류
  • node의 결과를 변환해주는 함수가 필요함 (이진분류에서는 sigmoid)
Layer Activation Function 기능
Hidden Layer ReLU 좀 더 깊이 있는 학습을 시키려고
hidden layer를 여러 층 쌓으려고
선형모델을 비선형 모델로 바꾸려고
Output Layer 회귀 X X
이진분류 sigmoid 결과를 0,1로 변환하기 위해 (0~1 사이의 확률값으로 변환)
다중분류 softmax 각 범주에 대한 결과를 범주별 확률값으로 변환
  • 이진 분류 모델에서 사용되는 loss function: binary_crossentropy
  • cross entropy: 두 분포의 차이를 계산, y와 y햇의 오차 계산

 

코드 실습

# 학습 데이터에서 행의 개수 추출 (분석 단위 개수 구하기 위함)
n = x_train.shape[1]

# Sequential 모델 (hidden layer포함) 
# Dense 4는 hidden layer 노드 개수, 하이퍼 파라미터로 우리가 최적의 노드 수 찾아야 함!
model = Sequential([ Dense( 4, input_shape = (n ,), activation = 'relu'),   
                      Dense( 1, activation = 'sigmoid')])

# compile 학습
model3.compile( optimizer=Adam(learning_rate= 0.01), loss ='binary_crossentropy')
hist = model3.fit(x_train, y_train, epochs = 50, validation_split=.2 ).history

# 예측, where의 조건문은 T/F로 나옴! T이면 1, F면 0 출력
pred = model.predict(x_val)
pred = np.where( pred >= .5 , 1, 0)
print(classification_report(y_val, pred))

 

 

CH5. 다중분류

Output Layer

  • 다중분류 모델에서 Output Layer의 node 수는 y의 범주 수 (class 수) 와 같음

softmax: 각 class 별로 예측한 값을 하나의 확률값으로 변환해주는 활성함수 → 각 범주별 확률값의 합은 1

 

다중 분류 모델링을 위한 전처리

 

 

정수 인코딩, 원핫 인코딩 코드 차이

# 정수 인코딩
model.compile(optimizer = Adam(learning_rate = 0.001), loss = 'sparse_categorical_crossentropy')

# 원핫 인코딩
model.compile(optimizer = Adam(learning_rate = 0.001), loss = 'categorical_crossentropy')

 

MNIST 데이터 실습

- 손 글씨 이미지를 2차원 데이터셋으로 변환해 다중 분류 모델링 수행! (숫자 0~9)

# 케라스 데이터셋으로 부터 mnist 불러오기, 튜플형태로 반환
(x_train, y_train), (x_val, y_val) = mnist.load_data()

# 28 X 28 짜리 2차원 데이터가 6만 개 있다!
x_train.shape, y_train.shape     # ((60000, 28, 28), (60000,))

# 데이터를 2차원으로 펼치기 → 행 6만개로 펼쳐줘!, -1 옵션은 나머지 알아서~
x_train = x_train.reshape(60000, -1)        # (60000, 784) 로 나옴
x_val = x_val.reshape(10000, -1)            # (10000, 784) 로 나옴

# 스케일링
x_train = x_train / 255.
x_val = x_val / 255.

 

 

- 모델링

nfeatures = x_train.shape[1]
nfeatures

model = Sequential(Dense(10, input_shape = (nfeatures,), activation = 'softmax'))
model.compile(optimizer=Adam(learning_rate=0.001), loss= 'sparse_categorical_crossentropy' )
history = model.fit(x_train, y_train, epochs = 20, validation_split=0.2).history

dl_history_plot(history)
pred = model.predict(x_val)   # e-0n 숫자가 낮은게(n값 작은게) 가장 큰 확률, e-01을 찾아라!
pred_1 = pred.argmax(axis=1)  # 예측값들 중에서 가장 큰 값의 인덱스를 뽑아줘!

 

 

CH6. CNN 개념 이해

CNN학습: 고양이를 잘 맞추는 필터 여러 개 만들기

  • 학습: 고양이를 찾는 데에 오차를 최소화하는 특징을 추출하는 필터를 만들기
  • 필터: 특징추출기

 

딥러닝 구조 - CNN

1. input_shape

  • 분석 단위인 이미지 한 장의 크기! (픽셀 사이즈, 세로 * 가로 * 채널(깊이))
    • 채널: 흑백 = 1, 컬러 = 3
    • CNN은 input_shape가 3차원의 데이터여야만 한다! → 3차원 데이터들이 모이면 데이터 셋은 4차원임
    • x_train, x_val 이 3차원이면 reshape을 통해 4차원으로 변환해줘야 함

2. Convolutional Layer

  • 필터로 지역적인 특성(feature)을 뽑는 과정
  • 합성곱: 같은 위치끼리 곱한 다음 더해달라는 뜻 !
    • padding = same
    • kernel = (3,3) or kernel = 3
    • stride = 1

3. Max pooling Layer

  • 뽑은 특징을 요약(압축) → 데이터를 압축하라는 뜻
    • pooling  = 2 X 2
    • Stride = 2

4. 펼쳐서(Flatten), Dense Layer에 연결

 

CNN 코드 - ConvNet

# 3차원의 데이터 확인
x_train.shape, x_val.shape

# 4차원으로 데이터셋 변환
x_train = x_train.reshape(60000,28,28,1)
x_val = x_val.reshape(10000,28,28,1)

# Min-Max 스케일링
x_train = x_train / 255.
x_val = x_val / 255.

 

ConvNet(특히 Con2D): 이미지 분석에 주로 사용

  • 데이터에 담겨 있는 지역적(Local) 특징을 추출
  • 필터(커널): 개수 32개
    • 2차원으로 이동하며 feature map을 구성
    • kernel_size = (3, 3) 가로 3 X 세로 3 모양의 필터 → 가로세로 길이가 같으면 kernel_size = 3으로도 사용
  • Stride: 몇 칸씩 이동할 것인지 지정
    • strides = (1, 1) 가로, 세로 이동 칸 수 
    • strides = 1 가로 = 세로 1 칸씩 이동 (기본값)
  • Stride를 사용하면 사이즈가 축소되기 때문에 유지하려면 padding 옵션을 사용
  • Padding: 사이즈 유지되도록 이미지 둘레에 0으로 덧데는 과정
    • input: 5 X 5 → output: 5 X 5 이려면 padding = 'same' 주면 됨
  • MaxPooling(pool_size = (2, 2), strides = (2,2)
    • 출력 데이터의 크기를 줄이거나 특정 데이터를 강조하기 위해 사용 (묶음을 만들어서 가장 큰 값만 추출)
    • pooling_size: 풀링 크기 행 X 열
    • strides: 생략하면 pool_size와 동일
    • 출력 데이터 크기: Input Size // Pooling Size (나머지는 버림)
  • Flatten과 Dense Layer: 최종 예측 결과로 뽑기 위해 Dense Layer로 연결
# Conv2D: 필터 16개를 만들어줘, 필터의 크기는 3 (3 X 3이라는 뜻), input_shape는 이미지 한 장이 3차원!
# CNN도 히든 레이어니까 활성함수 = relu
# Flatten: 2차원 데이터를 1차원으로 평평하게 만드는 것!, Dense 레이어로 연결하려면 펼쳐야 하고
# output 레이어, softmax 활용하려면 Dense 레이어로 연결해야 함!

model = Sequential([Conv2D(16, kernel_size = 3, input_shape=(28, 28, 1),   
                           padding='same', activation='relu'),    # strides = 1(기본값,1)         
                    MaxPooling2D(pool_size = 2 ),      # strides = 2(기본값이 pool_size 동일)                       
                    Flatten(),                                             
                    Dense(10, activation='softmax')
                    ])

model.summary()

model.compile(optimizer=Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy')

 

 

 

model = Sequential([Conv2D(32, kernel_size = (3,3), input_shape=(28, 28, 1),
                           padding='same', activation='relu'),
                    MaxPooling2D(pool_size = (2,2), strides=2 ),
                    Conv2D(64, kernel_size = (3,3), padding='same', activation='relu'),
                    MaxPooling2D(pool_size = (2,2), strides=2),
                    Flatten(),
                    Dense(128, activation='relu'),
                    Dense(10, activation='softmax')