Огромные реквизиты @amoeba за этот замечательный пример. Я просто хочу показать, что процедура обучения и реконструкции авто-кодировщика, описанная в этом посте, может быть выполнена также в R с такой же легкостью. Приведенный ниже автокодер настроен таким образом, чтобы он подражал примеру amoeba как можно ближе - тот же оптимизатор и общая архитектура. Точные затраты не воспроизводимы из-за того, что серверная часть TensorFlow не засеяна подобным образом.
Инициализация
library(keras)
library(rARPACK) # to use SVDS
rm(list=ls())
mnist = dataset_mnist()
x_train = mnist$train$x
y_train = mnist$train$y
x_test = mnist$test$x
y_test = mnist$test$y
# reshape & rescale
dim(x_train) = c(nrow(x_train), 784)
dim(x_test) = c(nrow(x_test), 784)
x_train = x_train / 255
x_test = x_test / 255
PCA
mus = colMeans(x_train)
x_train_c = sweep(x_train, 2, mus)
x_test_c = sweep(x_test, 2, mus)
digitSVDS = svds(x_train_c, k = 2)
ZpcaTEST = x_test_c %*% digitSVDS$v # PCA projection of test data
автоассоциатор
model = keras_model_sequential()
model %>%
layer_dense(units = 512, activation = 'elu', input_shape = c(784)) %>%
layer_dense(units = 128, activation = 'elu') %>%
layer_dense(units = 2, activation = 'linear', name = "bottleneck") %>%
layer_dense(units = 128, activation = 'elu') %>%
layer_dense(units = 512, activation = 'elu') %>%
layer_dense(units = 784, activation='sigmoid')
model %>% compile(
loss = loss_mean_squared_error, optimizer = optimizer_adam())
history = model %>% fit(verbose = 2, validation_data = list(x_test, x_test),
x_train, x_train, epochs = 5, batch_size = 128)
# Unsurprisingly a 3-year old laptop is slower than a desktop
# Train on 60000 samples, validate on 10000 samples
# Epoch 1/5
# - 14s - loss: 0.0570 - val_loss: 0.0488
# Epoch 2/5
# - 15s - loss: 0.0470 - val_loss: 0.0449
# Epoch 3/5
# - 15s - loss: 0.0439 - val_loss: 0.0426
# Epoch 4/5
# - 15s - loss: 0.0421 - val_loss: 0.0413
# Epoch 5/5
# - 14s - loss: 0.0408 - val_loss: 0.0403
# Set the auto-encoder
autoencoder = keras_model(model$input, model$get_layer('bottleneck')$output)
ZencTEST = autoencoder$predict(x_test) # bottleneck representation of test data
Построение проекции PCA бок о бок с представлением узкого места
par(mfrow=c(1,2))
myCols = colorRampPalette(c('green', 'red', 'blue', 'orange', 'steelblue2',
'darkgreen', 'cyan', 'black', 'grey', 'magenta') )
plot(ZpcaTEST[1:5000,], col= myCols(10)[(y_test+1)],
pch=16, xlab = 'Score 1', ylab = 'Score 2', main = 'PCA' )
legend( 'bottomright', col= myCols(10), legend = seq(0,9, by=1), pch = 16 )
plot(ZencTEST[1:5000,], col= myCols(10)[(y_test+1)],
pch=16, xlab = 'Score 1', ylab = 'Score 2', main = 'Autoencoder' )
legend( 'bottomleft', col= myCols(10), legend = seq(0,9, by=1), pch = 16 )
Перестройки
Мы можем сделать восстановление цифр обычным способом. (В верхнем ряду находятся исходные цифры, в среднем ряду реконструкции PCA, а в нижнем ряду реконструкции автоэнкодера.)
Renc = predict(model, x_test) # autoencoder reconstruction
Rpca = sweep( ZpcaTEST %*% t(digitSVDS$v), 2, -mus) # PCA reconstruction
dev.off()
par(mfcol=c(3,9), mar = c(1, 1, 0, 0))
myGrays = gray(1:256 / 256)
for(u in seq_len(9) ){
image( matrix( x_test[u,], 28,28, byrow = TRUE)[,28:1], col = myGrays,
xaxt='n', yaxt='n')
image( matrix( Rpca[u,], 28,28, byrow = TRUE)[,28:1], col = myGrays ,
xaxt='n', yaxt='n')
image( matrix( Renc[u,], 28,28, byrow = TRUE)[,28:1], col = myGrays,
xaxt='n', yaxt='n')
}
Как уже отмечалось, большее количество эпох и более глубокая и / или более умно обученная сеть дадут гораздо лучшие результаты. Например, ошибка восстановления PCA при = 9 составляет приблизительно , мы можем получить почти такую же ошибку ( ) из автоэнкодера, описанного выше, просто увеличив период обучения с 5 до 25. В этом сценарии использования 2 Компоненты, полученные из автоэнкодера, будут иметь такую же ошибку восстановления, как и 9 основных компонентов. Круто!0,0356 0,0359k0.03560.0359