--- title: 'R語言之Autoencoder範例' disqus: hackmd --- R語言之Autoencoder範例 === [TOC] ## Mnist single fully-connected ### 載入所需套件 ``` R= rm(list=ls());gc() library(keras) # 深度學習Keras套件 library(ggplot2) # 資料視覺化套件 ``` ### 資料預處理 下載Mnist資料後,由於數值範圍為0~255(色彩),預處理方式為歸一化,再將28x28的矩陣平坦化至大小為784的向量。 ``` R= mnist <- dataset_mnist() x_train <- mnist$train$x/255 x_test <- mnist$test$x/255 x_train <- x_train %>% apply(1, as.numeric) %>% t() x_test <- x_test %>% apply(1, as.numeric) %>% t() ``` ### 模型建立 由於預處理完之數值範圍為0至1,輸出層activation設定為sigmoid, ```R= # this is our input placeholder input_img <- layer_input(shape = c(784)) encoded <- layer_dense(input_img,units = 128 ,activation = "relu") encoded <- layer_dense(encoded,units = 64 ,activation = "relu") encoded <- layer_dense(encoded,units = 10,activation = "relu") encoded <- layer_dense(encoded,units = 2 ,activation = "relu") decoded <- layer_dense(encoded,units = 10,activation = "relu") decoded <- layer_dense(decoded,units = 64 ,activation = "relu") decoded <- layer_dense(decoded,units = 128 ,activation = "relu") decoded <- layer_dense(decoded,units = 784 ,activation = "sigmoid") autoencoder <- keras_model(input_img, decoded) # this model maps an input to its encoded representation encoder <- keras_model(input_img, encoded) autoencoder %>% compile(optimizer = 'adadelta', loss = 'binary_crossentropy') ``` ### 訓練模型 因為autoencoder屬於非監督學習,將input進行壓縮解壓後輸出成output後和input進行比較,所以兩者皆為x_train ```R= history <- autoencoder %>% fit (x_train, x_train, epochs=20, batch_size=256, shuffle=TRUE) ``` ### 視覺化 ```R= # 設定多張圖片合併方式 par(mfrow=c(2,5)) x_test_image <- array(x_test[1:5,], c(5,28,28)) # 原圖形繪圖 apply(x_train_image, 1, function(x)plot(as.raster(x))) # 預測圖片繪圖 x_test_image_predict <- autoencoder %>% predict(x_test[1:5,]) %>% array(., c(5,28,28)) apply(x_test_image_predict, 1, function(x)plot(as.raster(x))) ``` ## Mnist - Convolutional Autoencoder ### 模型建立 由於輸入是圖形,使用卷積神經網絡作為編碼器和解碼器是有意義的。 在實際設置中,應用於圖像的自動編碼器多為卷積自動編碼器, 比將圖片平坦化後進行1D Autoencoder更能萃取圖形特徵及加快運算速度。 Mnist中圖片大小為$dim(28, 28)$,由於為灰色圖片,我們將圖片維度轉換為$dim(28, 28, 1)$。 ```R= # this is our input placeholder input_img <- layer_input(shape = c(28,28,1)) encoded <- layer_conv_2d(input_img,filters = 2, kernel_size = c(3,3),strides = c(1,1),padding = "same",activation = "relu") encoded <- layer_max_pooling_2d(encoded,pool_size = c(2,2)) encoded <- layer_conv_2d(encoded,filters = 4, kernel_size = c(3,3),strides = c(1,1),padding = "same",activation = "relu") encoded <- layer_max_pooling_2d(encoded,pool_size = c(2,2)) decoded <- layer_conv_2d(encoded,filters = 8, kernel_size = c(3,3),strides = c(1,1),padding = "same",activation = "relu") decoded <- layer_upsampling_2d(decoded,size = c(2,2)) decoded <- layer_conv_2d(decoded,filters = 1, kernel_size = c(3,3),strides = c(1,1),padding = "same",activation = "sigmoid") decoded <- layer_upsampling_2d(decoded,size = c(2,2)) autoencoder <- keras_model(input_img, decoded) # this model maps an input to its encoded representation encoder <- keras_model(input_img, encoded) autoencoder %>% compile(optimizer = 'adadelta', loss = 'binary_crossentropy') ``` ### 資料預處理 Mnist中圖片大小為$dim(28, 28)$,由於為灰色圖片,我們將圖片維度轉換為$dim(28, 28, 1)$。 ```R= mnist <- dataset_mnist() x_train <- mnist$train$x/255 x_test <- mnist$test$x/255 samples_Train <- array(x_train, dim = c(length(x_train),28,28,1)) ``` ### 模型訓練函數 我們將建立一個函數用來生成圖像數據, 此函數主要用於在訓練模型時每次batchsize下生成不同訓練樣本之圖片數據。 ```R= #fit_generator sample_train_size <- length(x_train) Train_num <- length(x_train) # 資料重新排序 order_Train<-sample(Train_num) Train_pic_list<- order_Train Train_label <- order_Train # 圖片pixel大小 maxlenUse<- 28 # 每個batch_size讀取圖片數量 batch_size_Final<- 256 Train_generator <- function(Index_mark_Train=Train_pic_list, Label_Train=Train_label, maxlen=maxlenUse, shuffle = FALSE, batch_size = 256) { i_generator_Train <- 1 # Index_mark的第一個開始 max_index_Train<-length(Index_mark_Train) if (shuffle) { #重新排序 order_Train<-1:length(Index_mark_Train) order_Train<-sample(order_Train) Index_mark_Train<-Index_mark_Train[order_Train] #重新標籤 } function() { if ((i_generator_Train + batch_size) >= max_index_Train) { i_generator_Train<<- 1 i_code_now_Train<<-0 } # 總體變數 (global variable) 指派值或者永久指派 # 資料夾內排序1~batchsize rows_Train <- c(i_generator_Train:min(i_generator_Train+batch_size-1, max_index_Train)) i_generator_Train <<- i_generator_Train + length(rows_Train) samples_Train <- array(0, dim = c(length(rows_Train),maxlen,maxlen,1)) targets_Train <- array(0, dim = c(length(rows_Train),maxlen,maxlen,1)) # length(rows_Train): batch_size for (plot_ind_Train in c(1:length(rows_Train))) { ixx<-rows_Train[plot_ind_Train] #抓取圖片 samples_Train[plot_ind_Train,,,1] <- x_train[plot_ind_Train,,] targets_Train[plot_ind_Train,,,1] <- x_train[plot_ind_Train,,] } # end of for (plot_ind in 1:length(rows)) cat("目前Train_list_num_table位置:",rows_Train[1]," ") list(samples_Train, targets_Train) } # end of function() } ``` ### 訓練模型 ```R= Train_gen <- Train_generator( Index_mark_Train=Train_pic_list, Label_Train=Train_label, maxlen=maxlenUse,#圖片的時間長度 目前只可以100因為list_num_table設定maxlen是100 shuffle = FALSE, batch_size = batch_size_Final) history <- autoencoder %>% fit_generator( Train_gen, steps_per_epoch = floor(length(Train_label)/batch_size_Final), epochs = 10 ) ``` ### 視覺化 ```R= #原本 par(mfrow=c(2,5)) x_test_image <- array(x_test[1:5,], c(5,28,28,1)) # 原圖形繪圖 apply(x_train_image, 1, function(x)plot(as.raster(x))) # 預測圖片繪圖 x_test_image_predict <- autoencoder %>% predict(x_test[1:5,]) %>% array(., c(5,28,28,1)) apply(x_test_image_predict, 1, function(x)plot(as.raster(x))) #plot(as.raster(a)) ``` ###### tags: `R` `LSTM` `Keras`