[keras] CNN분류 모델 만들기 5 - 학습에 필요한 변인
이 실험은 딱히 성공했다고 보기 어렵고 아직 공부가 부족하고,
딥러닝은 데이터에 따라 차이가 크고 아직까지 딱 뭐가 좋다! 라고 정해진게 부족하기 때문에
참고용으로만 보시는 것이 좋을 것 같습니다. (약간 공개하기 부끄럽기도..)
저는 프로젝트 기록 + 복습 으로 작성한 게시글입니다.
우선 분류 모델만들기 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)
batch size
goodtogreate.tistory.com/entry/Batch-크기의-결정-방법
blog.lunit.io/2018/08/03/batch-size-in-deep-learning/
배치사이즈에 대한 논문들
데이터의 마지막 전처리 밑 기본 구조는 아래의 사이트를 활용했다
www.kaggle.com/alexanderlazarev/simple-keras-1d-cnn-features-split/notebook
loss함수
10퍼정도 나오는 쓰레기라고한다