Advanced Multi-Layer Perceptron
Advanced techniques for training neural networks
- Weight Initialization
- Nonlinearity (Activation function)
- Optimizers
- Batch Normalization
- Dropout (Regularization)
- Model Ensemble
Weight Initialization
SGD에서 w 초기값?
Sigmoid에서 문제 -
sigmoid 함수의 변수범위를 참고하여 -4~4로 초기화-> 대부분 출력값이 0, 1이 대부분이라. 학습이 안 됨
w값이 큰 게 문제다 -> N(0, 0.1) 정규분포로 초기화 -> sigmoid 분포
weight값은 +,-범위에 굉장히 작은 값이어야 한다.
Xavier Initialization
이전 노드와 다음 노드의 개수에 의존하여 표준편차 계산
ReLU에서 문제 - He Initialization
Xavier 방법이 비효율적이라서.
기본적으로 w값이 매우 작아야(sd작아야) 발산하는 경우가 없음
X_train.shape
# (60000, 28, 28)
X_train.shape[0]
#개수 60000개
# reshaping X data: (n, 28, 28) => (n, 784)
# X set 2차원을 1차원으로
X_train = X_train.reshape((X_train.shape[0], -1))
X_test = X_test.reshape((X_test.shape[0], -1))
reshape에서 두번째 parameter를 -1로 설정하는 것은
앞의 조건을 지키고 나머지 영역은 알아서 묶어달라는 의미
위는 3차원을 2차원으로 바꾸는데 n만 지키고 나머지 영역을 묶어 한 차원으로 바꾸라는 의미
train_test_split
# use only 33% of training data to expedite the training process
X_train, _ , y_train, _ = train_test_split(X_train, y_train, test_size = 0.67, random_state = 7)
train_test_split: 자주 쓰는 함수라서. split하여 (1-p), p 순으로 리턴
# converting y data into categorical (one-hot encoding)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
one-hot encoding: 1차원 벡터->2차원 벡터
0 -> 1 0 0 이 한 줄이 one binary class
1 -> 0 1 0 행렬로 구하면 빨라
2 -> 0 0 1
model.add(Dense(50, input_shape = (784, )))
model.add(Activation('sigmoid'))
model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dense(50))
model.add(Activation('sigmoid'))
model.add(Dense(10))
model.add(Activation('softmax')) #출력층
출력층: binary 땐 sigmoid 썼지만
multiple는 softmax 사용. binary와 똑같지만 여러번 처리
softmax: sigmoid와의 차이점은 정규화해줌 (값의 합 1로 scaling)
출력갯수 10개, class가 10개니까
# optimzer="adam" 은 디폴트값밖에 못 써. 아래처럼 사용하면 learning rate 설정 가능
sgd = optimizers.SGD(lr = 0.001) #Adam하면 금방 올라감
model.compile(optimizer = sgd, loss = 'categorical_crossentropy', metrics = ['accuracy'])
history = model.fit(X_train, y_train, batch_size = 256, validation_split = 0.3, epochs = 200, verbose = 0)
validation_split: train data를 내부적으로 또 나눠.
70개는 학습, 30개는 validation data set으로 사용하겠다
내가 학습을 제대로 하고 있는지 검증하는 또다른 test set. overfitting 검사가능
training data set: 학습 인식률
validation data set: test 인식률
// 테스트 인식률이 더 좋을 수는 없다. 항상 training data 인식률이 test data 인식률보다 더 높아
- if validation_split 옵션 지우면
validation data set이 없으니까 (전체 set을 학습으로만 사용하니까) validation data 인식률은 나올 수 없지
-> loss function 하나만 확인 가능
-> validation value 조금이라도 주는 게 좋아
# from now on, create a function to generate (return) models
def mlp_model():
model = Sequential()
model.add(Dense(50, input_shape = (784, ), kernel_initializer='he_normal')) # use he_normal initializer
model.add(Activation('sigmoid'))
model.add(Dense(50, kernel_initializer='he_normal')) # use he_normal initializer
model.add(Activation('sigmoid'))
model.add(Dense(50, kernel_initializer='he_normal')) # use he_normal initializer
model.add(Activation('sigmoid'))
model.add(Dense(50, kernel_initializer='he_normal')) # use he_normal initializer
model.add(Activation('sigmoid'))
model.add(Dense(10, kernel_initializer='he_normal')) # use he_normal initializer
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr = 0.001)
model.compile(optimizer = sgd, loss = 'categorical_crossentropy', metrics = ['accuracy'])
return model
model = mlp_model()
history = model.fit(X_train, y_train, validation_split = 0.3, epochs = 100, verbose = 0)
어느 순간에 초기화를 잘 해서 쭉 올라가.
정확도가 45퍼센트로 확 뜀
초기값을 적절히 잘 세팅해야 해.
Nonlinearity (Activation function)
def mlp_model():
model = Sequential()
model.add(Dense(50, input_shape = (784, )))
model.add(Activation('relu')) # use relu
model.add(Dense(50))
model.add(Activation('relu')) # use relu
model.add(Dense(50))
model.add(Activation('relu')) # use relu
model.add(Dense(50))
model.add(Activation('relu')) # use relu
model.add(Dense(10))
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr = 0.001)
model.compile(optimizer = sgd, loss = 'categorical_crossentropy', metrics = ['accuracy'])
return model
model = mlp_model()
history = model.fit(X_train, y_train, validation_split = 0.3, epochs = 100, verbose = 0)
ReLU (비선형 함수) 사용, 초기값 설정 안 해도 성능 좋아
마지막 값이 아니라, 그 중에서 validation value 가장 좋았던 값을 저장.
선형함수 쓰면 2차원 곡선 형태밖에 안 나와
비선형 함수로 activation하면 굴곡이 더 생겨
'Python > Deep learning' 카테고리의 다른 글
CNN (0) | 2020.01.21 |
---|---|
다층 퍼셉트론을 향상시키는 방법 - 2 (0) | 2020.01.21 |
케라스 회귀 (0) | 2020.01.20 |
DNN (Deep Neural Network) (0) | 2020.01.20 |
경사하강법(SGD) (0) | 2020.01.20 |