KT 에이블스쿨 : 딥러닝 기초 (회귀, 이중분류, 다중분류, MNIST, CNN, 성능관리)
딥러닝 기초
1일차 - 24.04.11 (목)
그동안 어렵게만 느껴졌던 딥러닝을 오늘부터 한기영 강사님이랑 공부하게 되었다.
머신러닝, 딥러닝은 이름 자체부터 어렵게 느껴졌는데 강사님이 천천히 쉽게 가르쳐주셔서 따라가기 쉬웠다.
오늘 배운걸 간략하게 정리하자면, 딥러닝의 개념과 구조, 회귀 딥러닝 모델링을 배웠
- 머신러닝 복습
- ML 알고리즘, 평가지표 중 R2 스코어의 의미
- 딥러닝 코드 순서
- 데이터 전처리(스케일링 필수) → 모델구조 선언, 컴파일 → 학습, 학습곡선 → 예측 및 검증
- 딥러닝 개념
- 가중치, fit 학습 절차(compile의 optimizer, epochs, learning_rate 비교)
- optimizer : 오차를 줄이는 방향으로 가중치를 조정하는 역할
- epochs(ep) : 학습 반복 횟수
- learing_rate(lr) : 학습 가중치 크기 조절
- batch_size : 기본값으로 두면됨.
- 딥러닝 모델링 - 회귀
- 딥러닝 구조
- Dense : 레이어
- Dense(1, input_shape = (x_train.shape[1], ))
- model.compile(optimizer = Adam(learning_rate = 0.1), loss=’mse’)
- optimizer : 오차를 최소화하도록 가중치를 조절하는 역할
- loss : 손실함수, 오차 계산을 무엇으로 할지 결정
- 학습곡선
- history = model.fit(x_train, y_train, epochs = 20, validation_split=0.2).history
- 히든레이어
- model3 = Sequential([ Dense(4, input_shape = (nfeatures,), activation = 'relu'), Dense(1) ])
- 활성화함수 'relu' 사용 : 히든레이어에서 선형 함수를 비선형 함수로 변환해주는 역할
- output layer 활성화함수 없음
질문
Q) Sequential 타입 모델 선언 부분의 input_shape = (nfeatrues,) 여기에 , 로 끝나는 이유
A) 함수를 쓸려면 입력과 출력을 알아야하는데, Sequential 함수의 입력에 np.array의 shape 값이 들어감
a = up.array([1, 2, 3, 4]) ⇒ a.shape = (4, ) 이렇게 크기가 나옴 (단위데이터)
feautre가 6개이면 (6, )으로 들어감
nfeatures = x_train.shape[1]
model = Sequential(Dense(1, input_shape = (nfeatures, )))
A) 손실함수(오차계산을 무엇으로 할지 결정함, 회귀모델은 보통 mse로 선택) 의 결과값을 y축으로 두어 그래프를 그린것이 학습곡선임
x축은 epochs 로 가중치의 오차를 줄이기 위해 반복한 횟수가 들어간다.
2일차 - 24.04.12 (금)
- CRISP-DM 복습
- 비즈니스 이해 - 데이터 이해 - 데이터 준비 - 모델링 - 평가 - 배포
- 가장 처음 단계에서 비즈니스 문제정의를 하고 초기 가설 수립을 하는게 비즈니스적으로 중요함
- 딥러닝 모델링 학습을 시키면, 랜덤으로 가중치를 할당함
오차를 줄이기 위해 가중치 조정을 반복함
(optimizer, loss, validation_split 등)
- 평가 단계에서 MAPE(평균 오차율), MAE(평균 오차)를 비즈니스 적으로 설명하기 용이해, 주로 사용함
- MAPE = 0.3이면, 평균적으로 예측값과 차이가 날 오차율
실제값에 0이 있으면 무한대의 값처럼 큰값이 나옴 . MAPE가 큰값이 나오면 무의미한 값
- MAE = 10000이면 평균적으로 1만원정도 차이가 난다는것 (y가 20만원인걸 예측할때)
sales가 100개 일때, 1.14 오차는 100*1.14 = 114 개로 나올수도 있다는 것
- MSE, RMSE 는 제곱 오차라서, 고객에게 설명하기 힘듬
- 딥러닝 모델링 - 이진분류
- 범주값이 0 또는 1 , Yes 또는 No
- 히든레이어 > activation = 'sigmoid'
- compile > loss function = 'binary_crossentropy'
- metrics = ['acc']
- predict > pred = np.where(pred >= .5, 1, 0)
- 머신러닝 sklearn에서는 predict 단계에서 로지스틱 회귀의 0~1 확률값을 알아서 나눴지만,
딥러닝은 자동으로 안됨.
0.5 기준으로 1, 0으로 안나누면 오류남
- 딥러닝 모델링 - 다중분류
- 다중분류 모델에서 output layer 의 노드 수는 y 범주의 수와 같음
- Dense( 3 , activation = 'softmax')
- 히든레이어 > activation = 'softmax'
- 인코딩 방법 2가지
- 1. 정수 인코딩 (LabelEncoder / map / replace )
- loss = 'sparse_categorical_crossentropy'
- 2. 원핫 인코딩 (OneHotEncoder / to_categorical)
- loss = 'categorical_crossentropy'
- 예측 > argmax
- 다중분류일때, 가장 예측값이 큰 인덱스가 무엇인지 알기위함
pred = model.predict(x_val)
pred_1 = pred.argmax(axis=1)
y_val_1 = y_val.argmax(axis=1)
print(confusion_matrix(y_val_1, pred_1))
print(classification_report(y_val_1, pred_1))
3일차 - 24.04.15 (월)
- MNIST
- 차원 : 이미지는 2차원, 이미지가 여러개인 이미지 데이터셋은 3차원
- 흑백이미지의 픽셀 값만으로 이미지 인식함 - CNN에 비해 성능이 낮음
- 1. flatten : 2차원 데이터를 1차원으로 펼침
- 2. 차원확인
- 3. 스케일링
- 전처리 과정에서 스케일링을 해도되고
(x_train = x_train / 255.) (x_val = x_val / 255.) - 모델 구조 선언할때 스케일링 해도됨
model = Sequential( [ Input(shape = (32, 32, 3)), keras.layers.Rescaling(1/225), Flatten(), Dense(64, activation='relu') ~~~~~~, model.add( Dense(10, activation='softmax') ) ])
- 4. 모델링
- 5. 컴파일 : loss = 다중분류
- sparse_categorical_crossentropy (클래스 넘버 > 정수인코딩)
categorical_crossentropy
- 6. 예측
- argmax로 예측값 뽑음
- CNN
- MNIST 때는 1차원으로 flatten 한뒤에, 모델링되지만,
CNN은 2차원 형태 그대로에서 feature map을 통해 특징이 추출됨
- 학습 : CNN에서는 학습 과정에서 오차를 최소화하는 특징을 추출하는 필터를 찾는것 (convalution 합성곱)
- 필터 = 특징 추출기 = feature map
- 예측 : 학습된 필터를 이용해 valid 사진에서 특징을 추출해 class에 해당되는지 아닌지 판별함
- 예측할때는 입력데이터(input_shape)와 크기가 같아야함
test_num = img.reshape(1,28,28,1) - 이미지 한장(2차원)을 예측하더라도 데이터셋의 구조와 동일하게 맞춰야함
- CNN 구조
- input_shape : 분석 단위인 이미지 한장의 크기
- 픽셀사이즈 = 세로 * 가로 * 채널 (행, 열, 깊이)
- 흑백 : 채널 = 1
- 컬러 : 채널 = 3 (ex, input_shape = (28, 28, 1))
- 합성곱 - ConvNet (Conv2D)
- filter = 32 : 필터 종류가 32개여서 32개의 다른 합성곱 과정을 거치는 것
- stride : 몇칸씩 이동할것인지 지정
- padding = 'same' : 사이즈를 유지하도록 이미지 둘레를 0으로 덧데는 것
- padding 사용하는 이유1) 합성곱을 거칠때마다 사이즈가 줄어들게 되는데 이를 막기 위해
- padding 사용하는 이유2) 외곽에 중요한 정보가 있을수도 있기에 사이즈 유지를 위함
- maxPooling
- feature map이 돌아다니면서 max값(그중 가장 중요한것)만 남기고, 덜 중요한건 버림
- 뽑은 특징을 요약(압축)해 크기를 줄임
- 일반적으로 feature map을 겹치지 않고, 독립적이게 만듦
- 마지막에 flatten 펼쳐서, dense output layer에 연결
clear_session()
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(), # 3차원의 데이터를 flatten으로 1차원형태로 만듬
Dense(10, activation='softmax')]) # output layer
model.summary()
model.compile(optimizer=Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy')
- 성능관리
- 과적합 방지
- 1. EarlyStopping
- 2. 가중치 규제
- L1규제 (Lasso) / L2 규제(Ridge)
- 가중치가 크면 과적합이기에 가중치를 줄이는 규제
- Dense의 은닉층 안에 옵션으로 지정 (노드수, 활성화함수, 커널규제)
Dense(64, activation = ‘relu’, kernel_regularizer = l1(0.01))
- 3. Dropout
- 훈련 과정에서 신경망의 일부 뉴런을 임의로 비활성화(연결끊음) 시킴 -> 모델을 강제로 일반화
- 매 epochs 마다 다른 부분 집합의 뉴런을 비활성화 ➔ 앙상블 효과
- 보통 0.2 ~ 0.5 사이로 범위 지정
Dropout(0.3)
- ModelCheckPoint : 모델 저장
- 성능이 개선된 부분까지의 epochs를 저장함
- 딥러닝 모델 성능 높이는 방법
- 데이터
- 스케일링 필수
- 입력 데이터 정제, 적절한 전처리
- 데이터 늘리기 : 열(적절한 feature 추가), 행(데이터 건수 늘리기)
- 모델 구조
- 은닉층, 노드 수 늘리기 : 성능이 증가할때 까지
- activation , loss 모델구조에 맞춰서 잘 쓰기
- 학습
- epochs, learning_rate, optimizer
- 과적합 문제 해결
- 데이터 건수 늘리기
- 모델 복잡도 조절 -> 가중치 규제 - kernel_regularizer
- early stopping
- 모델 저장하기
- 최종 모델 저장
- 체크 포인트에서 모델 저장 - ModelCheckPoint
댓글
댓글 쓰기