Keras修改到位-如何在Keras中正确培训多个模型
这是关于R中的Keras,但据我所知,它也适用于python Keras模型是。在过去,我一开始不理解这意味着什么,所以我想我会写下这对在同一课程中训练多个模型意味着什么,这样其他人就可以避免犯我犯的错误 这意味着不能复制模型对象,例如:Keras修改到位-如何在Keras中正确培训多个模型,r,tensorflow,keras,R,Tensorflow,Keras,这是关于R中的Keras,但据我所知,它也适用于python Keras模型是。在过去,我一开始不理解这意味着什么,所以我想我会写下这对在同一课程中训练多个模型意味着什么,这样其他人就可以避免犯我犯的错误 这意味着不能复制模型对象,例如: model = keras_model_sequential() model %>% layer_dense( units = 50, input_shape = 100 ) model_copy = model 现
model = keras_model_sequential()
model %>%
layer_dense(
units = 50,
input_shape = 100
)
model_copy = model
现在,如果您尝试修改模型
或模型_copy
,则另一个模型也将被修改。下面的答案解释了原因。引言
R可以就地修改,这意味着在内存中修改对象,也可以在修改对象时创建对象的新副本。这是可以解释的。如果创建一个对象,以及指向第一个对象的另一个对象,它们将指向内存中的同一位置。但是,这意味着修改一个将修改另一个
为了避免这种情况,如果1个或>1个名称指向内存中的同一位置,则R跟踪。如果为1,则修改内存值是安全的。这是适当的修改。但是,如果大于1,则修改一个对象将修改另一个对象。因此,被修改的对象实际上被复制到内存的一个新部分,这样两个对象就不再指向内存的同一部分。这意味着修改一个对象不会影响另一个对象
这不是在R中的Keras中实现的,据我所知(尽管我还没有在python中使用Keras),它也不是在python中实现的。Keras总是就地使用修改,不管有多少名称指向内存中的点。因此,对一个模型所做的任何事情也会对另一个模型所做,因为实际上,它们只是同一个模型的两个名称——两个“对象”实际上只是一个对象
示例断开的代码
为了说明这会使您陷入困境,下面是一个示例,通过比较两个RMSProp学习率来训练mnist分类网络。如果不知道Keras中的修改,可以编写代码:
library(keras)
# data
mnist = dataset_mnist()
x_train = mnist$train$x
y_train = mnist$train$y
x_train = array_reshape(x_train, c(nrow(x_train), 784))
x_train = x_train / 255
y_train = to_categorical(y_train, 10)
# model
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')
# compile and train a model, given a learning rate
comp_train = function(learning_rate) {
model_copy = model
model_copy %>% compile(
loss = 'categorical_crossentropy',
optimizer = optimizer_rmsprop(
lr = learning_rate
),
metrics = c('accuracy')
)
training_history = model_copy %>% fit(
x_train, y_train,
epochs = 30, batch_size = 128,
validation_split = 0.2
)
return(
as.data.frame(training_history)
)
}
# test two learning rates
lr_0.001 = comp_train(0.001)
lr_0.0001 = comp_train(0.0001)
对于0.001的学习率,结果是有意义的:
但是,对于0.0001的学习率,结果非常出乎意料:
如果人们意识到第二幅图像只是第一幅图像的延续,并且延续了30个时代,那么这些结果也就不足为奇了。所以,把这两幅图像放在一起,只显示了同一个神经网络在60个时期内的训练。这是因为修改到位——当你训练“第二个”网络时,你实际上只是训练第一个,即使它已经训练过了
示例工作代码
那么,应该采取哪些不同的做法呢?对于Keras,不同的模型必须分别使用Keras\u model\u sequential()
或Keras\u model()
(无论您使用哪种类型)进行初始化。因此,我们分别定义了每个模型:
library(keras)
# data
mnist = dataset_mnist()
x_train = mnist$train$x
y_train = mnist$train$y
x_train = array_reshape(x_train, c(nrow(x_train), 784))
x_train = x_train / 255
y_train = to_categorical(y_train, 10)
# models
model_lr0.001 = keras_model_sequential()
model_lr0.0001 = keras_model_sequential()
model_lr0.001 %>%
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')
model_lr0.0001 %>%
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')
# compile and train a given model, also given a learning rate
comp_train = function(model, learning_rate) {
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = optimizer_rmsprop(
lr = learning_rate
),
metrics = c('accuracy')
)
training_history = model %>% fit(
x_train, y_train,
epochs = 30, batch_size = 128,
validation_split = 0.2
)
return(
as.data.frame(training_history)
)
}
# test two learning rates
lr_0.001 = comp_train(model_lr0.001, 0.001)
lr_0.0001 = comp_train(model_lr0.0001, 0.0001)
这一次,我们得到了预期的结果:
我们现在可以成功地比较这两种学习率。“更好”的工作代码是在函数中定义模型(使用keras\u model\u sequential()
),这也会给出预期的结果。这是留给读者的练习