ML/프로젝트CNN

[keras] CNN분류 모델 만들기 5 - 학습에 필요한 변인

IagreeBUT 2020. 8. 20. 13:51
728x90

이 실험은 딱히 성공했다고 보기 어렵고 아직 공부가 부족하고,

딥러닝은 데이터에 따라 차이가 크고 아직까지 딱 뭐가 좋다! 라고 정해진게 부족하기 때문에

참고용으로만 보시는 것이 좋을 것 같습니다. (약간 공개하기 부끄럽기도..)

저는 프로젝트 기록 + 복습 으로 작성한 게시글입니다. 

 

 

 

우선 분류 모델만들기 4 게시글에서 분석한 것을 토대로 

저의 데이터에 맞게 전처리 부분을 바꾸었습니다.

import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedShuffleSplit
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten, Convolution1D, Dropout
from keras.optimizers import SGD
from keras.utils import np_utils

#구글 드라이브와 연동 
from google.colab import drive
drive.mount('/gdrive')

#데이터 불러오기 
train = pd.read_csv('/gdrive/My Drive/데이터/maybe_final/r_training_set_9001.csv',header=None)
val = pd.read_csv("/gdrive/My Drive/데이터/maybe_final/r_validation_set_9001.csv",header=None)
test = pd.read_csv('/gdrive/My Drive/데이터/maybe_final/r_test_set_9001.csv',header=None)

#드롭 
train.rename(columns={9000:'act_id'},inplace=True)
val.rename(columns={9000:'act_id'},inplace=True)
test.rename(columns={9000:'act_id'},inplace=True)



def encode(train,val,test):
    label_encoder = LabelEncoder().fit(train.act_id)
    
    labels = label_encoder.transform(train.act_id)
    # y data
    train_label = train.act_id
    val_label = val.act_id
    test_label = test.act_id
    # x data
    train = train.drop(['act_id'],axis=1)
    val = val.drop(['act_id'],axis=1)
    test = test.drop(['act_id'],axis=1)
    classes = list(label_encoder.classes_)

    return train, val, test, train_label, val_label, test_label, classes

#label / data 분리 
train, val, test, train_label, val_label, test_label, classes = encode(train, val, test)

# standardize train features ->왜하냐고 
scaler = StandardScaler().fit(train.values)
scaled_train = scaler.transform(train.values)


nb_features = 3000 # number of features per features type (shape, texture, margin)   
nb_class = 25 #1~24이므로 [0,25) 를 사용해줘야 표현가능

# reshape train data 
X_train_r = np.zeros((len(train), 3,nb_features)) # 세트수->[행,열] : 3x3000이 617개 
X_train_r[:, 0, :] = train.iloc[:, 0:nb_features]
X_train_r[:, 1, :] = train.iloc[:, nb_features:nb_features+3000]
X_train_r[:, 2, :] = train.iloc[:, nb_features+3000:nb_features+6000]

# reshape validation data
X_valid_r = np.zeros((len(val), 3, nb_features))
X_valid_r[:, 0, :] = val.iloc[:, 0:nb_features]
X_valid_r[:, 1, :] = val.iloc[:, nb_features:nb_features+3000]
X_valid_r[:, 2, :] = val.iloc[:, nb_features+3000:nb_features+6000]


#
X_test_r = np.zeros((len(test), 3, nb_features))
X_test_r[:, 0, :] = test.iloc[:, 0:nb_features]
X_test_r[:, 1, :] = test.iloc[:, nb_features:nb_features+3000]
X_test_r[:, 2, :] = test.iloc[:, nb_features+3000:nb_features+6000]

 

이제 본격적으로 학습을 해야하는데 , 저희가 바꾸어볼 수 있는 부분은 이 부분들 입니다.

# Keras model with one Convolution1D layerm
# unfortunately more number of covnolutional layers, filters and filters lenght 
# don't give better accuracy
model = Sequential()
model.add(Convolution1D(filters=512,kernel_size=1, padding="same", strides=1, input_shape=(3,nb_features)))
model.add(Activation('relu'))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(nb_class))
model.add(Activation('softmax'))

model.summary()


#y_train = np_utils.to_categorical(train_label, nb_class)
#y_valid = np_utils.to_categorical(val_label, nb_class)

sgd = SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)
model.compile(loss='sparse_categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])

nb_epoch = 30
model.fit(X_train_r, train_label, epochs=nb_epoch,validation_data=(X_valid_r, val_label), batch_size=15)

 

여러가지가 있는데 나열해보면

  • Convolution1D를 사용할 것인가? 2D를 사용할 것인가?
  • Convolution층은 몇개로 구성할 것인가?
  • 각각 층의 필터 사이즈 / 필터 수 / stride 는 어떻게 할 것인가?
  • Activation층의 활성화 함수로는 어떤 것을 사용할 것인가?
  • Dense층은 몇개로 구성할 것인가? 뉴런의 수는? 
  • Dropout은 몇으로 설정할 것인가? 
  • batch size는 몇으로 지정할 것인가?
  • epoch는 몇으로 지정할 것인가?
  • 더 나아가면 model.compile부분에서 loss함수로는 무엇을 사용할 것인지? 모맨텀은?

등등이 있다. 

 

<방법>

딥러닝은 실험을 통해 최고의 정확도( 시간도 중요함) 을 내는 것 이기 때문에 정답은 없다..

정말 하나하나 변인을 통제해 가며 실험하며 구해내는 것인데...

변인은 다음 순서대로 실험하는 것이 좋다(정답은 아님) 

가장 높은 정확도가 나온 수를 중심으로 간격을 좁혀가며 그 부분을 실험하고, 그 중 가장 높은 정확도가 나오면 그걸로 fix하고 다음 통제로 넘어간다.

Conv1d vs Conv2d -> Conv층수 -> 필터수 -> 필터 사이즈 -> 배치사이즈 ... 

 

나는 처음인 나머지 정말 어디부터 시작해야할지 감이 안와서 나름 대로 보편적으로는 어떤 값들을 사용하는지 좀 조사했다

(사실 큰 도움은 안됐다 ㅎㅎ)

 

필터 수

넓은 범위에서 필터 수를 정할 때는 2^n 단위로 증가시키면서 관찰하는 것이 좋고,

어느 하나가 가장 좋은 정확도를 보이면 그 근처에서 +- 적절한 값을 이용해서 더 좋은 값을 찾아낸다.  -> 사실 난 여기는 시간이 부족해서 못했다. 피드백 받은 부분이었음 

 

dropout

개념에 대해서는 여기를 참고하고

2020/07/12 - [ML] - [딥러닝의 정석]02. 전방향 신경망 학습

보편적으로 0.3~0.5사이의 값을 사용한다고 한다. 

 

epoch

 

 

그렇다면 에폭수를 늘려보고 시각화한 그래프를 보고 과적합 시점쯤음 에폭수로 줄여주면 될 것이다 

(너무 크면 오래걸리긴 한다..)

 

batch_size

batch_size = 1이면, 확률적 경사하강법(stochastic gradient) 이고, 

batch_size = (전체 사이즈) 이면, 경사하강법(batch_gradient)이다. (이쪽이 계산이 복잡하기 때문에 이론상 느림)

이에 절충안으로 나온것이 minibatch이다. 

 

minibatch는 보통 10~1000개로

memory사이즈에 맞추어 32, 64, 128 ... ( 2^n)을 사용한다.

 

하지만 데이터가 적을 경우 batch_gradient를 추천한다고 한다. 

보통 데이터는 하나의 클래스당 200개데이터가 있어도 적은편이다.. 나는 정말 매우 적었기 때문에.. (25 클래스 617개)

 

 

 

<나의 최종 코드>

# Keras model with one Convolution1D layerm
# unfortunately more number of covnolutional layers, filters and filters lenght 
# don't give better accuracy
model = Sequential()
model.add(Convolution2D(filters=256,kernel_size=3, padding="valid", strides=1, input_shape=(3,nb_features,1)))
model.add(Activation('relu'))
model.add(Dropout(0.4))
model.add(Flatten(data_format=None))
model.add(Dense(512, activation='relu'))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(nb_class))
model.add(Activation('softmax'))

model.summary()



#y_train = np_utils.to_categorical(train_label, nb_class)
#y_valid = np_utils.to_categorical(val_label, nb_class)

sgd = SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)
adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False)
model.compile(loss='categorical_crossentropy',optimizer=adam,metrics=['accuracy'])

nb_epoch = 40
mhistory = model.fit(X_train_r, train_label, epochs=nb_epoch,validation_data=(X_valid_r, val_label), batch_size=128)

 

Conv2d를 사용했으며, loss함수로 categorical_crossentropy를 사용했다.

실험결과가 어떻게 나왔는지에 대해서는 다음글에 분석하도록 한다.

 

 

<참고자료>

데이터의 마지막 전처리 밑 기본구조 잡기

www.kaggle.com/alexanderlazarev/simple-keras-1d-cnn-features-split/notebook?

 

에폭수(Epoch)

3months.tistory.com/424

 

Early Stopping 의 개념과 Keras 를 통한 구현

Early Stopping 이란 무엇인가? 딥러닝을 비롯한 머신러닝 모델의 한 가지 중요한 딜레마는 다음과 같다. 너무 많은 Epoch 은 overfitting 을 일으킨다. 하지만 너무 적은 Epoch 은 underfitting 을 일으킨다...

3months.tistory.com

 

batch size

goodtogreate.tistory.com/entry/Batch-크기의-결정-방법

 

Batch 크기의 결정 방법

Batch 크기의 결정 방법 보통 vectorization 방법으로 gradient descent 알고리즘의 효율을 높이게 된다. 하지만 input 데이터가 너무 크다면 그 방법을 사용할 수 없다. 메모리 문제도 발생하고 한 번 interati

goodtogreate.tistory.com

blog.lunit.io/2018/08/03/batch-size-in-deep-learning/

 

Batch Size in Deep Learning

딥러닝 모델의 학습은 대부분 mini-batch Stochastic Gradient Descent (SGD)를 기반으로 이루어집니다. 이 때 batch size는 실제 모델 학습시 중요한 hyper-parameter 중 하나이며, batch size가 모델 학습에 끼치는 영�

blog.lunit.io

 배치사이즈에 대한 논문들

 

데이터의 마지막 전처리 밑 기본 구조는 아래의 사이트를 활용했다

www.kaggle.com/alexanderlazarev/simple-keras-1d-cnn-features-split/notebook

 

Simple Keras 1D CNN + features split

Explore and run machine learning code with Kaggle Notebooks | Using data from Leaf Classification

www.kaggle.com

wdprogrammer.tistory.com/33

 

Regularization과 딥러닝의 일반적인 흐름 정리

2019-01-13-deeplearning-flow- 최적화(optimization) : 가능한 훈련 데이터에서 최고의 성능을 얻으려고 모델을 조정하는 과정 일반화(generalization) : 훈련된 모델이 이전에 본 적 없는 데이..

wdprogrammer.tistory.com

loss함수

wikidocs.net/32105

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

10퍼정도 나오는 쓰레기라고한다

728x90