본문 바로가기
Deep Learning/기타

딥러닝 간단정리 [인코딩 / 이미지 데이터 처리 / 최적화모델 / MLP, CNN, VGG16 ]

by leehii 2022. 9. 5.

데이터 전처리 (인코딩)

 

1. 원핫인코딩

: 다중분류의 경우 모델이 예측한 확률값과

실제 정답의 scale (범위)가 같아야 제대로 오차를 출력해낼수 있음

따라서 신경망이 제대로 학습할 수 있도록 정답데이터의 원핫인코딩이 필요함

a) pandas 객체로 리턴

pd.getdummies(답 데이터)

 

b) ndarray 객체로 리턴

from tensorflow.keras.utils import to_categorical

to_categorical(답 데이터)

 

c) complie할때 인코딩 진행하기

loss = 'sparse_categoricial_crossentropy'

 

 

2. CNN 다차원 데이터 처리

: CNN을 사용할 경우다차원 데이터에 대한 표시가 필요함

흑백은 1, 컬러(rgb)는 3 으로 표시해야하므로 

 

data명.shape() 로 해당 이미지의 크기를 확인한 후

data명.reshape( data명.shape[0], data명.shape[1], data명.shape[2], 1 or 3 )

으로 처리해준다

 

여기서 data명.shape의 출력값의 예시는 (10000, 28,28 ) 이런 식이다

 

-----------------------------------------------------------------------------------------------

 

 

데이터 전처리 (이미지)

 

from PIL import Image

img = Image.open('해당파일 디렉토리').convert('?')

: convert('L')은 흑백, convert('RGB')는 컬러

 

-----------------------------------------------------------------------------------------------

 

최적화모델 찾기 >> 

 

미리 선언해두고 밑에서 fit으로 학습할때

callbacks = [ ]  리스트 안에 해당 변수들 넣기

 

1. ModelChechPoint : 모델 저장기능 (콜백함수) ,  확장자명 hdf5

 

path = ' ~경로~파일명.hdf5'

model_check = ModelCheckPoint(filepath = 'path',

                                                               monitor = '?',

                                                               save_best_only = True,

                                                               mode = '?',

                                                               verbose = 1 )

# monitor :

해당 값을 기준으로 파일을 저장 / val_acc , val_loss등등



# save_best_only :

monitor 값이 최저점이거나 최고점을 갱신할때 모델 저장



# mode = 'auto or max or min' :

save_best_only가  True일 경우 모니터링하는 값의 기준를 결정

( loss 값의 경우 min , accuracy 값의 경우 max. auto로 넣으면 알아서 저장)



# verbose = 0 or 1 : 0일 경우 화면 표시 x / 1일경우 화면 표시

 

 

 

2. EarlyStopping : 조기학습중단 (시간낭비방지 / 과대적합시 종료)


early = EarlyStopping(monitor = '?', mode = '?', patience = 숫자

 

# patience : 인내심, 즉 몇번까지는 조기중단안하고 눈감아 줄껀지.

 

 

-----------------------------------------------------------------------------------------------

 

신경망 구성

: 신경망 구조 설계 > 학습방법, 평가방법 설정 > 학습 및 시각화 > 평가, 예측

 

 

1.신경망 구조 설계

: 객체 선언 > (특성추출주 설정) > 층쌓기 > (분류기 설정) 

 

- 객체 선언

from tensorflow.keras import Sequental

from tensorflow.keras.layers import Dense, Flatten , Conv2D, MaxPooling2D

등등 필요한 것 불러오기


model = Sequential( ) 

 

- 층 쌓기

model.add( Dense  

                      Flatten  데이터를 1차원으로 펴주는 모델 

                      Conv2D  이미지의 특징을 도드라지게 강조

                      Maxpooling2D  이차원 데이터 필요없는 부분 삭제,  

                      핵심특징만 남기기 

)

 

 

CNN 모델 사용할 때의 특성 추출부 Conv2D, MaxPooling2D 

 

(ex1)  일반 데이터

model.add(Dense(input_dim = 특성개수,  units = 40, activation = 'relu') 입력층

model.add(Dense(units = 20, activation = 'relu')

model.add(Dense(units = 10, activation = 'relu')

model.add(Dense(units = 1, activation = 'softmax') 출력층

# 활성화함수 : 자극에 대한 반응 여부를 결정하는 함수

       기본값은 linear (입력뉴런과 가중치로 계산된 결과값이 그대로 출력)

       (relu를 주로 사용함 : 역전파 시에 좋은 성능)

       (이진분류의 출력층은 sigmoid로 고정)

       (softmax 다중 클래스 분류 문제에서 출력층에 사용)

 

    # 입력층

        input_dim : 특성의 개수  /  input_shape : Flatten에서 사용하는 특성 개수

        units : 유닛 수

        activation  : 활성화 함수 (임계값 이상의 값에 반응) . Sigmoid, Relu 등

 

    # 중간층 n개만큼 쌓기 (input_dim은 입력층에서 넣었으므로 생략)

 

    # 출력층

       units :  분류할 클래스의 개수만큼 설정 /

 

       이진분류 : units = 1, activation = 'sigmoid' 로 출력층 고정 

       ( sigmoid 0.5를 기준으로 0 또는 1로 최종 예측값 분류)

       (Yes or  NO로 분류하는 1개의 클래스이므로 units가 1임)

 

       다중분류 : activation = 'softmax' 로 출력층 고정  /

 

       회귀 : linear(항등함수)로 신경망에서 도출된 수치값을 그대로 예측값으로                    사용하므로 생략함 /

 

 

(ex2) 이미지 데이터(MLP사용) :

이미지행열을 1차원배열로 만들고 입력, 가중치 계산하으모 정보 손실이 큼

model.add(Flatten(input_shape = (224,224)) 입력층

model.add(Dense(units = 40, activation = 'relu')

model.add(Dense(units = 20, activation = 'relu')

model.add(Dense(units = 10, activation = 'relu')

model.add(Dense(units = 1, activation = 'softmax') 출력층

 

 

 

(ex3) 이미지 데이터 (CNN모델 사용) :

이미지행열을 가로,세로축 모두 합성곱연산, 풀링연산등을 통해

특징점을 추출하여 정보 손실이 적음 >>

Conv2D와 MaxPooling 설정후 층을 쌓고 분류기설정(MLP)

 

 

 

특성추출부 (Conv2D) 설정

cnn_model.add(Conv2D(input_shape = (24, 24, 1 or 3), 

                               filters = 128,  

                               kernel_size = (3, 3), 

                               padding = 'same',                              

                               activation = 'relu',

                               strides = (1, 1)

                               ))

  # input_shape : 행, 열, 흑백 or 컬러 

  # filters : 특징추출을 해서 도드라지게 할 돋보기(추출하는 특징의 개수)

  # kernel_size : 필터=커널의 크기 설정

  # padding : 원본데이터의 크기와 동일하게 맞추기 위해 주변을 0으로 채움

                         same은 패딩하겠다 valid는 패딩 안하겠다

  # strides : 필터로 합성곱 연산시 건너뛰는 행, 열 크기 

 

특성추출부 (MaxPooling2D) 설정

  cnn_model.add(MaxPooling2D(pool_size = 2,

                               strides = 2

                               ))

 # pool_size : default 값은 2 

 

층쌓기


cnn_model.add(Conv2D(

                               filters = 256,  

                               kernel_size = (3, 3), 

                               padding = 'same',                              

                               activation = 'relu',

                               ))

cnn_model.add(Conv2D(

                               filters = 128,  

                               kernel_size = (3, 3), 

                               padding = 'same',                              

                               activation = 'relu',

                               ))



cnn_model.add(Conv2D(

                               filters = 64,  

                               kernel_size = (3, 3), 

                               padding = 'same',                              

                               activation = 'relu',

                               ))


......

# Conv 설정때의 filters 는 특징의 개수였으나 여기는 층쌓기임

 

분류기 설정

cnn_model.add(Flatten( ))

cnn_model.add(Dense(units = 40, activation = 'relu')

cnn_model.add(Dense(units = 20, activation = 'relu')

cnn_model.add(Dense(units = 10, activation = 'relu')

cnn_model.add(Dense(units = 1, activation = 'softmax') 

 

 

 

- model.summary() : 모델정보 확인

 

 

 

 

2. 평가방법 설정

 

  - 평가방법 설정 : model. compile ( loss = ? , optimizer = ? , metrics = [ ? ] )

 

 

    # loss (손실/비용함수)

       이진분류 : binary_crossentropy

       다중분류 : categorical_crossentropy

       다중분류+ 원핫인코딩 :  sparse_categoricial_crossentropy

 

    # optimizer (최적화함수 :  최적의 가중치를 검색하는 데 사용되는

                           최적화 알고리즘)

       sgd, adam 등 ( adma을 주로 사용함)

 

       optimezer = 'Adam'

       optimizer = Adam (learning_rate - 0.0005) 이런식으로 학습률 설정도 가능

 

 

    # metrics(평가방법 : 평가 척도를 나타내며 분류 문제에서는

                      일반적으로 ‘accuracy’으로 지정)

       accuracy 등

 

 

3. 학습 및 시각화

 

his = model.fit(훈련용 문제, 인코딩한 훈련용 답,

                            validation_split = 비율,

                            epochs = 반복횟수,

                            batch_size = 잘라서 확인할 횟수,

                            callbacks = [ CollBack변수명, EarlyStop변수명 ]

                            verbose = ? )

 

    # validation_split :train 셋에서 자동으로 검증셋을 만들어주는 함수 

                                     일반적으로 0.2, 0.3 정도 비율로 사용함 

    # callbacks : 최적화모델 확인하는 ModelCheckPoint와 EarlyStoppin 

 

 

  - plt 함수를 이용해서 시각화 ( 이미지는 plt.imshow )

    # his.history['accuracy'] ,  his.history['loss'] 등을

        plt함수를 이용해 그래프를 그려 모델 정확도, 오차율등을 시각화 가능

 

4. 모델 평가 / 예측

 

  - model. predict(X_test) :에측

  - model. evaluate(X_test, y_test) : 평가

 

5. 정확도, 정밀도, 재현율, F1스코어 확인하기

from sklearn.metrics import classification_report 

print( classification_report(y_test, np.argmax(pre, axis = 1) ) )

 

np.argmax( ) :  가장 큰 값의 인덱스를 반환하는 함수 / axis = 1을 주면 2차원 배열인  pre의 내부 배열의 1차원만 보겠다는 뜻

 

-----------------------------------------------------------------------------------------------

 

 

이미지 데이터 (VGG16모델 사용)

직접 설정한 CNN모델은 데이터 수 적음 등의 이유로 큰 효과를 보기힘듬

 vgg16 : CNN모델을 기반으로 사전에 학습된 신경망

 

 

1차 전이학습



from tensorflow.keras.applications import VGG16

vgg = VGG16 ( include_top = False,

                                          weight = 'imagenet',

                                          input_shape = (224, 224, 4) )

 

vgg_model = Sequential( )

vgg_model.add(vgg)

vgg_model.add(Flatten())

vgg_model.add(Dense(128, activation = 'relu'))

vgg_model.add(Dense(64, activation = 'relu'))

vgg_model.add(Dense(32, activation = 'relu'))

vgg_model.add(Dense(16, activation = 'relu'))

vgg_model.add(Dense(3, activation = 'softmax'))

 

vgg_model.compile( loss = 'sparse_categorical_crossentropy',

                                       optimizer = 'adam',
                                        metrics = [ ''accuracy ] )

vgg_model.fit( 훈련용 문제, 훈련용 답,
                             validation_split = 0.2,

                             batch_size = 128,

                             epochs = 30,

                             callbacks = [ CollBack변수명, EarlyStop변수명 ] )

pre = vgg_model.predict(X_test)
print(classification_report(y_test, np.argmax(pre, axis=1)))


 

미세조정 전이학습


1. 1차 전이학습 과정에서 마지막 Conv layer 확인

for layer in vgg.layers : 
    print(layer.name)


2. 마지막 Conv만 학습하도록 설정

for layer in vgg.layers : 
    if layer.name == 'block5_conv3' :
        layer.trainable = True

    else :

        layer.trainable = False

 

3. 데이터 증감

 

# 객체선언

vgg_model2 = Sequential( )

# 특성추출부

vgg_model2.add(vgg)

# MLP층

vgg_model2.add(Flatten())

# 중간층

vgg_model2.add(Dense(128, activation = 'relu'))

vgg_model2.add(Dense(64, activation = 'relu'))

vgg_model2.add(Dense(32, activation = 'relu'))

# 출력층

vgg_model2.add(Dense(3, activation = 'softmax'))

# 평가/학습방법 설정

vgg_model2.compile( loss = 'sparse_categorical_crossentropy',

                                       optimizer = 'adam',
                                        metrics = [ ''accuracy ] )

# 데이터 증감 (이미지 증식)

from tensorflow.keras.preprocessing.image import ImageDataGenerator
aug = ImageDataGenerator ( rotation_range = 30,
                                                     width_shift_range = 0.2,

                                                     height_shift_range = 0.2,

                                                     zoom_range = 0.2,

                                                     horizontal_flip = True,

                                                     fill_mode = 'nearest')

ImageDataGenerator : 이미지 증식을 위한 라이브러리

    - rotation_range : 이미지 회전각도 범위

    - width_shift_range : 수평이동 범위 (몇% 이내인지)

    - height_shift_range  : 수직이동 범위 (몇% 이내인지)

    - zoom_range : 축소 / 확대 ( 0.8 ~ 1.2배 )

    - horizontal_flip : 수평방향으로 뒤집기     

    - fill_mode : 이미지가 변형될때 생기는 공간을 채우는 모드



# 학습

vgg_model2.fit( aug.flow(훈련용 문제, 훈련용 답,
                                              validation_split = 0.2,

                                              batch_size = 128,

                                              epochs = 30,

                                              steps_per_epoch = 훈련샘플수 / 배치사이즈,

                                              callbacks = [ CollBack변수명, EarlyStop변수명 ] )

 

# 예측/평가

pre = vgg_model2.predict(X_test)
print(classification_report(y_test, np.argmax(pre, axis=1)))