16-2. Convolutional Neural Network
1) Features
- 신경망 모델(Neural Net)은 입력값으로 객체의 특성(feature)을 받고,
- 출력된 값과 실제 값을 비교하는 과정을 거침 (지도학습; Supervised Learning)
- 하나의 이미지는 수많은 픽셀들이 모여 형성하고 있으며, 특정 색에 해당하는 특정 값을 가짐
- 따라서, 이미지의 모든 픽셀값들을 입력값으로 갖는 신경망 모델을 만들 수 있음
2) Intuitions
- 하지만, 고해상도 이미지의 경우 특성feature의 수가 너무 많아지므로
- 모든 뉴런들이 모든 픽셀들과 모두 연결되어 있을 경우 (fully connected) 모델 학습에 큰 어려움이 있음
- 따라서, 각 뉴런들이 이미지의 일부의 특성feature만 연결될 수 있는 구조가 더 적합함
- Convolution operation을 통해 이를 구현할 수 있음
3) Convolution Operation
- 임의의 값으로 설정된 filter가 전체 이미지 중 일부의 선형 결합을 계산함
- 각각의 결과값은 하나의 Neuron이 되며, filter는 해당 Neuron의 가중치가 됨
- 결과값의 사이즈를 정하기 위해선 Stride, Padding 그리고 Depth을 고려해야함
4) Pooling
- Convoltional Layer 사이에 Pooling Layer를 넣어주는 방법이 많이 사용됨
- 추출해낸 이미지에서 지역적인 부분의 특징만을 뽑아 다음 layer로 넘겨줌
- 이를 통해, 1) 가중치들의 수를 줄일 수 있으며 2) 과적합(overfitting)을 방지함
- 대표적으로 가장 큰 값(Local Maxima)만을 뽑아내는 Max Pooling이 많이 사용됨
5) MNIST
- 손으로 쓴 숫자들을 인식하기 위해 사용되는 데이터
- 28x28 pixel (784)의 흑백 이미지(0~255)들이 있음
- 0부터 9까지 총 70,00개의 손글씨 이미지들이 있음
- 상대적으로 신경망 모델을 학습하기에 작은 사이즈를 가지고 있음
- 출처(http://yann.lecun.com/exdb/mnist)
6) CNN in R
- 신경망 모델 생성을 위한 패키지 : mxnet
- MNIST 데이터 불러오기
mn1 <- read.csv("mini_mnist.csv")
set.seed(123)
N<-nrow(mn1)
tr.idx<-sample(1:N, size=N*2/3, replace=FALSE)
학습 데이터 : 2/3
테스트 데이터 : 1/3
train_data<-data.matrix(mn1[tr.idx,])
test_data<-data.matrix(mn1[-tr.idx,])
test<-t(test_data[,-1]/255)
features<-t(train_data[,-1]/255)
labels<-train_data[,1]
0과 1사이에 분포하도록(Normalized)
(0 : 검정색 / 255 : 흰색)
features_array <- features
dim(features_array) <- c(28,28,1,ncol(features))
test_array <- test
dim(test_array) <- c(28,28,1,ncol(test))
입력 데이터의 차원을 설정 (픽셀 * 객체 개수)
ncol(features) : 학습 데이터 수(866)
ncol(features)
[출력 결과]
[1] 866
table(labels)
[출력 결과]
labels
0 1 2
282 307 277
- Convolutional Layer 구성
my_input = mx.symbol.Variable('data')
conv1 = mx.symbol.Convolution(data=my_input, kernel=c(4,4), stride=c(2,2), pad=c(1,1), num.filter = 20, name='conv1')
relu1 = mx.symbol.Activation(data=conv1, act.type='relu', name='relu1')
mp1 = mx.symbol.Pooling(data=relu1, kernel=c(2,2), stride=c(2,2), pool.type='max', name='pool1')
conv2 = mx.symbol.Convolution(data=mp1, kernel=c(3,3), stride=c(2,2), pad=c(1,1), num.filter = 40, name='conv2')
relu2 = mx.symbol.Activation(data=conv2, act.type='relu', name='relu2')
mp2 = mx.symbol.Pooling(data=relu2, kernel=c(2,2), stride=c(2,2), pool.type='max', name='pool2')
fc1 = mx.symbol.FullyConnected(data=mp2, num.hidden = 1000, name='fc1')
1000개의 뉴런들이 모두 연결되어 있음
relu3 = mx.symbol.Activation(data=fc1, act.type='relu', name='relu3')
fc2 = mx.symbol.FullyConnected(data=relu3, num.hidden = 3, name='fc2')
sm = mx.symbol.SoftmaxOutput(data=fc2, name='sm')
3개의 뉴런들 중 가장 확률이 높은 값이 0~2 중 하나를 가리킴
- 모델 훈련
mx.set.seed(100)
device <- mx.cpu()
model <- mx.model.FeedForward.create(symbol=sm,
optimizer = "sgd",
array.batch.size=30,
num.round = 70, learning.rate=0.1,
X=features_array, y=labels, ctx=device,
eval.metric = mx.metric.accuracy,
epoch.end.callback=mx.callback.log.train.metric(100))
Stochastic Gradient Descent
batch size = 30 (총 29개 그룹)
Iteration(epoch) : 70
Learning Step : 0.1
graph.viz(model$symbol)
- 모델 테스트
predict_probs <- predict(model, test_array)
predicted_labels <- max.col(t(predict_probs)) - 1
table(test_data[, 1], predicted_labels)
sum(diag(table(test_data[, 1], predicted_labels)))/length(predicted_labels)
- 네트워크 시각화 함수 : graph.vis(model$symbol)
graph.viz(model$symbol)
'공부 > R & Python' 카테고리의 다른 글
16-3. 웹문서 텍스트마이닝 - 한글 웹문서의 자연어 처리와 정보 추출 - (0) | 2020.03.06 |
---|---|
16-1. 딥러닝과 텍스트 마이닝-Neural Network (0) | 2020.03.06 |
15-3. Partial Least Square (0) | 2020.03.06 |
15-2. 주성분 회귀분석(Principle Component Regression) (0) | 2020.03.06 |
15-1. 주성분 분석과 부분 최소자승법-주성분분석(Principle Component Analysis) (0) | 2020.03.06 |