---
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`