1 패션 MNIST 데이터

캐글 패션 MNIST를 다운로드 받아도 되고, 앞서 RStudio Keras를 설치하게 되면 포함된 데이터를 사용했다.

1.1 데이터 가져오기 1

fashion-mnist 데이터는 10개 범주로 구분된 70,000개 흑백이미지 데이터로 구성되고, 각 이미지 크기는 \(28 \times 28\) 크기를 갖고 keras 팩키지 dataset_fashion_mnist() 함수를 사용해서 데이터를 받아낼 수 있지만, 직접 데이터를 다운로드 받아 이를 패션 MNIST 이미지 분류에 사용한다.

> # 1. 데이터 -----
> library(tidyverse)
> library(gridExtra)
> library(keras)
> library(glue)
> 
> # 이미지 폴더 경로설정
> cur_dir <- getwd()
> 
> train_image_files_path <- glue(cur_dir, "/data/fashion/fashion-mnist_train.csv")
> test_image_files_path <- glue(cur_dir,  "/data/fashion/fashion-mnist_test.csv")
> 
> class_names <- c('T-shirt/top',
+                 'Trouser',
+                 'Pullover',
+                 'Dress',
+                 'Coat', 
+                 'Sandal',
+                 'Shirt',
+                 'Sneaker',
+                 'Bag',
+                 'Ankle boot')
> 
> ## 1.1. 데이터 불러오기-----
> train_df <- read_csv(train_image_files_path)
> test_df <- read_csv(test_image_files_path)
> 
> 
> ## 1.2. 훈련/시험 데이터 분할
> train_x_df <- train_df %>% select(-label)
> train_y_df <- train_df %>% select(label)
> 
> test_x_df <- test_df %>% select(-label)
> test_y_df <- test_df %>% select(label)

2 탐색적 데이터 분석

훈련과 시험 데이터로 이미지를 나누고, 훈련데이터 수는 70,000개 중에서 60,000개, 시험데이터는 10,000개로 구성된다. table(train_labels) 함수로 10개 범주에 각 6,000개씩 훈련범주로 구성된 것이 확인된다. 이미지 다수 뽑아내서 image 함수로 시각화한다.

> display_fashion <- function(input, i){
+   m <- matrix(unlist(input), nrow = 28, byrow = FALSE)
+   # m <- t(apply(apply(m, 2, rev),2, rev))
+   # m <- t(apply(m, 2, rev))
+   m <- t(apply(t(m), 2, rev))
+   image(m, col=grey.colors(255),  xaxt = 'n', yaxt = 'n',
+         main = paste(class_names[train_y_df$label[i] + 1]))
+ }
> 
> par(mfrow = c(3,5))
> map(sample(1:nrow(train_x_df), 15), ~display_fashion(train_x_df[.x,], .x))

[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

[[6]]
NULL

[[7]]
NULL

[[8]]
NULL

[[9]]
NULL

[[10]]
NULL

[[11]]
NULL

[[12]]
NULL

[[13]]
NULL

[[14]]
NULL

[[15]]
NULL

3 딥러닝 예측모형

3.1 계층 설정(Setup the layer)

첫번째 계층은 입력값(\(25 \times 25 = 784 \text{픽셀}\))을 받도록 layer_flatten()을 지정하고, 이에 맞춰 데이터를 배열로 정리해 둔다. 그리고, 중간에 dropout도 두어 딥러닝 계층을 적당히 쌓아 구성하여 학습시킨다.

> # 3. 딥러닝 예측모형 -----
> ## 3.1. 입력값을 배열로 변환
> train_x <- array(data.matrix(train_x_df), dim = c(dim(train_x_df)[[1]], 784))
> test_x <- array(data.matrix(test_x_df), dim = c(dim(test_x_df)[[1]], 784))
> 
> ## 0과 1 사이 값으로 조정
> train_x <- train_x / 255
> test_x <- test_x / 255
> 
> ## 3.2.  딥러닝 학습
> model <- keras_model_sequential()
> 
> model %>%
+   layer_dense(units=128, input_shape=c(784))  %>%
+   layer_dropout(rate=0.7) %>%
+   layer_dense(units=64, activation="relu")  %>%
+   layer_dropout(rate=0.5) %>%
+   layer_dense(units=64, activation="relu")  %>%
+   layer_dropout(rate=0.5) %>%
+   layer_dense(units=10,activation="softmax") 
> 
> model %>% compile(
+   optimizer = 'adam', 
+   loss = 'sparse_categorical_crossentropy',
+   metrics = c('accuracy')
+ )
> 
> model %>% fit(train_x, train_y_df$label, epochs = 5)

3.2 모형 평가(evaluate-the-model)

evaluate() 함수를 통해서 훈련에 사용된 적이 없는 시험 데이터를 활용해서 패션 MNIST 옷범주 예측 성능을 평가한다.

> score <- model %>% evaluate(test_x, test_y_df$label)
> 
> cat('Test loss:', score$loss, "\n")
Test loss: 0.5261209 
> cat('Test accuracy:', score$acc, "\n")
Test accuracy: 0.8045 

3.3 예측

evaluate() 함수를 통해서 훈련에 사용된 적이 없는 시험 데이터를 활용해서 패션 MNIST 옷범주 예측 성능을 평가한다.

> predictions <- model %>% predict(test_x)
> predictions[1,]
 [1] 8.407388e-01 1.818733e-07 4.327471e-05 4.265987e-03 3.463851e-08
 [6] 4.390896e-15 1.549499e-01 2.239527e-17 1.771002e-06 1.696929e-13
> which.max(predictions[1, ])
[1] 1
> class_pred <- model %>% predict_classes(test_x)
> class_pred[1:20]
 [1] 0 1 2 2 3 6 8 6 5 0 3 4 4 4 8 5 2 3 6 4

직접 이미지를 넣어 예측할 수도 있다.

> smpl_img <- test_x[15, , drop = FALSE]
> dim(smpl_img)
[1]   1 784
> smpl_predictions <- model %>% predict(smpl_img)
> smpl_predictions
          [,1]         [,2]        [,3]        [,4]        [,5]
[1,] 0.0209148 2.664965e-05 0.002350399 0.001399777 0.004597607
             [,6]       [,7]         [,8]      [,9]        [,10]
[1,] 0.0003920342 0.04990342 9.061085e-05 0.9203224 2.283938e-06
> class_pred <- model %>% predict_classes(smpl_img)
> class_pred
[1] 8