Keras是一个高层神经网络API,由纯Python编写而成。此API支持相同的代码无缝跑在CPU或GPU上;对用户友好,易于快速prototype深度学习模型;支持计算机视觉中的卷积网络、序列处理中的循环网络,也支持两种网络的任意组合;支持任意网络架构:多段输入或多段输出模型、层共享、模型共享等。这意味着Keras 本质上适合用于构建任意深度学习模型(从记忆网络到神经图灵机)兼容多种运行后端,例如TensorFlow、CNTK和Theano。
代码语言:javascript复制devtools::install_github("rstudio/keras")
library(keras)
install_keras()##安装依赖环境
当然,这里默认安装的是CPU版本,如果需要安装GPU版本则需要运行如下代码:
代码语言:javascript复制install_keras(tensorflow= "gpu")
安装成功的界面如下,如果失败需要多试几次,基本是网络不稳定的原因。
Linux版本:
接下来我们通过一个实例进行后面的分析:
代码语言:javascript复制##数据载入
mnist <-dataset_mnist() #导入mnist数据集
x_train <-mnist$train$x #训练集的自变量
y_train <-mnist$train$y #训练集的因变量
x_test <-mnist$test$x
y_test <-mnist$test$y
注意:在此处导入数据的时候,会因为不是GPU版本而有警告出现,可以不用管:
接下来我们要进行数据的结构转化,x_train和x_test数据是灰度值的三维数组(图像ID、宽度、高度)。为了准备训练数据,通过将宽度和高度转换为一维(28x28的矩阵被简化成长为784的向量),从而把三维数组转换为矩阵。然后,我们将值为0到255的整数之间的灰度值转换成0到1之间的浮点值。
代码语言:javascript复制##矩阵向量化
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
因变量数据也需要进行处理。首先y_train和y_test数据都是一个整型向量,其值从0到9。为了准备训练数据,我们利用 Keras to_categorical()函数,用one-hot编码方法将向量转化为二进制类矩阵。我们来看下具体的原理,也就是说每行代表一个y的特征,一共10列(0-9),找到y对应列标记为1,其余为0。这样就构建了一个n*10的矩阵。
代码语言:javascript复制##因变量结构改变
y_train <-to_categorical(y_train, 10)
y_test <-to_categorical(y_test, 10)
一. keras_model_sequential。序列在这里指的是比如语音数据、文本数据、视频数据等一系列具有连续关系的数据。接下来我们看下序列模型的构建。
代码语言:javascript复制##模型的定义
model <- keras_model_sequential()
model %>%
layer_dense(units =256, activation = 'relu', input_shape = c(784)) %>%
layer_dropout(rate = 0.4) %>%
layer_dense(units = 128, activation = 'relu')%>%
layer_dropout(rate = 0.3) %>%
layer_dense(units = 10, activation ='softmax')
layer_dense指的全连接层可以出现在输入,中间以及输出层。本质就是由一个特征空间线性变换到另一个特征空间。因此,dense层的目的是将前面提取的特征,在dense经过非线性变化,提取这些特征之间的关联,最后映射到输出空间上。如28*28转化为1:784。其中所涉及的参数:
units :代表该层的输出维度或神经元个数, units解释为神经元个数为了方便计算参数量,解释为输出维度为了方便计算维度。
activation=None:激活函数.但是默认 liner 。具体函数列表如下
use_bias=True:布尔值,该层是否使用偏置向量b
input_shape是指输入张量的shape。所谓张量就是维度,把矩阵的概念进行扩展。对应的矩阵,数组的大小。如784个元素的向量就是784。
input_dim是指的张量的维度。此处维度指的就是普通的矩阵就是二维张量,数组就是一维张量,空间矩阵就是三维张量,类似的,还有四维、五维、六维张量。
layer_dropout层,目的是为了防止模型过拟合。关键的想法是在训练期间从神经网络随机丢弃单位(以及它们的连接)。只需要按一定的概率(retaining probability)p 来对weight layer 的参数进行随机采样,将这个子网络作为此次更新的目标网络。可以想象,如果整个网络有n个参数,那么我们可用的子网络个数为 2^n 。并且,当n很大时,每次迭代更新 使用的子网络基本上不会重复,从而避免了某一个网络被过分的拟合到训练集上。
代码语言:javascript复制##设置优化项
model %>%compile(
loss = 'categorical_crossentropy',
optimizer = optimizer_rmsprop(),
metrics = c('accuracy')
)
其中optimizer包括optimizer_rmsprop(递归神经网络),optimizer_adagrad(),optimizer_adamax(), optimizer_adam(), optimizer_nadam(), optimizer_sgd()。
代码语言:javascript复制 ##训练模型
history <-model %>% fit(
x_train, y_train,
epochs = 30, batch_size= 128,
validation_split = 0.2
)
上图是动态生成的结果图,可以看到每次迭代的训练集和验证集的准确率,或者可以通过plot(history)直接看最终的结果:
Epochs 迭代的次数。
batch_size一次训练所选取的样本数。BatchSize的大小影响模型的优化程度和速度。同时其直接影响到GPU内存的使用情况,假如你GPU内存不大,该数值最好设置小一点。BatchSize从小到大的变化对网络影响
1、没有BatchSize,梯度准确,只适用于小样本数据库
2、BatchSize=1,梯度变来变去,非常不准确,网络很难收敛。
3、BatchSize增大,梯度变准确,
4、BatchSize增大,梯度已经非常准确,再增加BatchSize也没有用
注意:Batch Size增大了,要到达相同的准确度,必须要增大epoch。
代码语言:javascript复制##模型的评估
model %>%evaluate(x_test, y_test)
从上面结果可以看出其实在测试集准确率很低。
代码语言:javascript复制##数据的预测
model %>%predict(x_test)
二. keras_model_custom进行自定义的模型构建。和默认的模型的区别就是可以进行更多层的引入,并且可以进行多种情况的判断。我们直接看下实例:
代码语言:javascript复制##模型构建
keras_model_simple_mlp<- function(num_classes,
use_bn =FALSE, use_dp = FALSE,
name = NULL){
# define and return a custom model
keras_model_custom(name = name,function(self) {
# create layers we'll need for the call(this code executes once)
self$dense1 <- layer_dense(units = 32,activation = "relu")
self$dense2 <- layer_dense(units =num_classes, activation = "softmax")
if (use_dp)
self$dp <- layer_dropout(rate = 0.5)
if (use_bn)
self$bn <- layer_batch_normalization(axis= -1)
# implement call (this code executes duringtraining & inference)
function(inputs, mask = NULL, training =FALSE) {
x <- self$dense1(inputs)
if (use_dp)
x <- self$dp(x)
if (use_bn)
x <- self$bn(x)
self$dense2(x)
}
})
}
代码语言:javascript复制##模型实例化
# create themodel
model <-keras_model_simple_mlp(num_classes = 10, use_dp = TRUE)
# compile graph
model %>%compile(
loss = 'categorical_crossentropy',
optimizer = optimizer_rmsprop(),
metrics = c('accuracy')
)
# Generatedummy data
data <-matrix(runif(1000*100), nrow = 1000, ncol = 100)
labels <-matrix(round(runif(1000, min = 0, max = 9)), nrow = 1000, ncol = 1)
# Convertlabels to categorical one-hot encoding
one_hot_labels<- to_categorical(labels, num_classes = 10)
# Train themodel
model %>%fit(data, one_hot_labels, epochs=10, batch_size=32)
代码语言:javascript复制##模型的保存
save_model_hdf5(model,"model.h5")##hdf5格式
save_model_tf(model,"./")##pb格式
export_savedmodel(model,"./")##pb格式