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')