Keras:进行超参数网格搜索时内存不足
Keras: Out of memory when doing hyper parameter grid search
我正在 运行 多个嵌套循环来进行超参数网格搜索。每个嵌套循环都运行一个超参数值列表,在最内层的循环中,每次使用生成器构建和评估 Keras 顺序模型。 (我没有做任何训练,我只是随机初始化然后多次评估模型,然后检索平均损失)。
我的问题是,在此过程中,Keras 似乎正在填满我的 GPU 内存,以至于我最终遇到 OOM 错误。
有人知道如何解决这个问题并在每次评估模型后释放 GPU 内存吗?
在模型被评估之后我就不再需要它了,我可以每次都把它完全扔掉,然后在内循环的下一个通道中构建一个新模型。
我正在使用 Tensorflow 后端。
这是代码,尽管其中大部分与一般问题无关。该模型建立在第四个循环内,
for fsize in fsizes:
我想模型构建的细节并不重要,但这里就是全部:
model_losses = []
model_names = []
for activation in activations:
for i in range(len(layer_structures)):
for width in layer_widths[i]:
for fsize in fsizes:
model_name = "test_{}_struc-{}_width-{}_fsize-{}".format(activation,i,np.array_str(np.array(width)),fsize)
model_names.append(model_name)
print("Testing new model: ", model_name)
#Structure for this network
structure = layer_structures[i]
row, col, ch = 80, 160, 3 # Input image format
model = Sequential()
model.add(Lambda(lambda x: x/127.5 - 1.,
input_shape=(row, col, ch),
output_shape=(row, col, ch)))
for j in range(len(structure)):
if structure[j] == 'conv':
model.add(Convolution2D(width[j], fsize, fsize))
model.add(BatchNormalization(axis=3, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
if activation == 'elu':
model.add(ELU())
model.add(MaxPooling2D())
elif structure[j] == 'dense':
if structure[j-1] == 'dense':
model.add(Dense(width[j]))
model.add(BatchNormalization(axis=1, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
elif activation == 'elu':
model.add(ELU())
else:
model.add(Flatten())
model.add(Dense(width[j]))
model.add(BatchNormalization(axis=1, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
elif activation == 'elu':
model.add(ELU())
model.add(Dense(1))
average_loss = 0
for k in range(5):
model.compile(optimizer="adam", loss="mse")
val_generator = generate_batch(X_val, y_val, resize=(160,80))
loss = model.evaluate_generator(val_generator, len(y_val))
average_loss += loss
average_loss /= 5
model_losses.append(average_loss)
print("Average loss after 5 initializations: {:.3f}".format(average_loss))
print()
如前所述,使用的后端是 Tensorflow。使用 Tensorflow 后端,当前模型不会被销毁,因此您需要清除会话。
使用完模型后:
if K.backend() == 'tensorflow':
K.clear_session()
包括后端:
from keras import backend as K
您也可以使用 sklearn wrapper 进行网格搜索。检查这个例子:here. Also for more advanced hyperparameter search you can use hyperas.
根据 indraforyou 给出的提示,我在传递给 GridSearchCV 的函数中添加了清除 TensorFlow 会话的代码,如下所示:
def create_model():
# cleanup
K.clear_session()
inputs = Input(shape=(4096,))
x = Dense(2048, activation='relu')(inputs)
p = Dense(2, activation='sigmoid')(x)
model = Model(input=inputs, outputs=p)
model.compile(optimizer='SGD',
loss='mse',
metrics=['accuracy'])
return model
然后我可以调用网格搜索:
model = KerasClassifier(build_fn=create_model)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1)
应该可以。
干杯!
添加 backend.clear_session() 对我有用:
from keras import backend as backend
def model_builder(hp):
backend.clear_session()
model = Sequential()
hp_drop = hp.Float('drop', min_value=0, max_value=0.2, step=0.025)
model.add(Dense(128, activation = "relu"))
model.add(Dropout(hp_drop))
model.add(Dense(1, activation = "relu"))
model.compile(
loss='mean_absolute_error',
optimizer=tf.keras.optimizers.Adam(0.001),
metrics=["mean_absolute_percentage_error"]
)
return model
我正在 运行 多个嵌套循环来进行超参数网格搜索。每个嵌套循环都运行一个超参数值列表,在最内层的循环中,每次使用生成器构建和评估 Keras 顺序模型。 (我没有做任何训练,我只是随机初始化然后多次评估模型,然后检索平均损失)。
我的问题是,在此过程中,Keras 似乎正在填满我的 GPU 内存,以至于我最终遇到 OOM 错误。
有人知道如何解决这个问题并在每次评估模型后释放 GPU 内存吗?
在模型被评估之后我就不再需要它了,我可以每次都把它完全扔掉,然后在内循环的下一个通道中构建一个新模型。
我正在使用 Tensorflow 后端。
这是代码,尽管其中大部分与一般问题无关。该模型建立在第四个循环内,
for fsize in fsizes:
我想模型构建的细节并不重要,但这里就是全部:
model_losses = []
model_names = []
for activation in activations:
for i in range(len(layer_structures)):
for width in layer_widths[i]:
for fsize in fsizes:
model_name = "test_{}_struc-{}_width-{}_fsize-{}".format(activation,i,np.array_str(np.array(width)),fsize)
model_names.append(model_name)
print("Testing new model: ", model_name)
#Structure for this network
structure = layer_structures[i]
row, col, ch = 80, 160, 3 # Input image format
model = Sequential()
model.add(Lambda(lambda x: x/127.5 - 1.,
input_shape=(row, col, ch),
output_shape=(row, col, ch)))
for j in range(len(structure)):
if structure[j] == 'conv':
model.add(Convolution2D(width[j], fsize, fsize))
model.add(BatchNormalization(axis=3, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
if activation == 'elu':
model.add(ELU())
model.add(MaxPooling2D())
elif structure[j] == 'dense':
if structure[j-1] == 'dense':
model.add(Dense(width[j]))
model.add(BatchNormalization(axis=1, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
elif activation == 'elu':
model.add(ELU())
else:
model.add(Flatten())
model.add(Dense(width[j]))
model.add(BatchNormalization(axis=1, momentum=0.99))
if activation == 'relu':
model.add(Activation('relu'))
elif activation == 'elu':
model.add(ELU())
model.add(Dense(1))
average_loss = 0
for k in range(5):
model.compile(optimizer="adam", loss="mse")
val_generator = generate_batch(X_val, y_val, resize=(160,80))
loss = model.evaluate_generator(val_generator, len(y_val))
average_loss += loss
average_loss /= 5
model_losses.append(average_loss)
print("Average loss after 5 initializations: {:.3f}".format(average_loss))
print()
如前所述,使用的后端是 Tensorflow。使用 Tensorflow 后端,当前模型不会被销毁,因此您需要清除会话。
使用完模型后:
if K.backend() == 'tensorflow':
K.clear_session()
包括后端:
from keras import backend as K
您也可以使用 sklearn wrapper 进行网格搜索。检查这个例子:here. Also for more advanced hyperparameter search you can use hyperas.
根据 indraforyou 给出的提示,我在传递给 GridSearchCV 的函数中添加了清除 TensorFlow 会话的代码,如下所示:
def create_model():
# cleanup
K.clear_session()
inputs = Input(shape=(4096,))
x = Dense(2048, activation='relu')(inputs)
p = Dense(2, activation='sigmoid')(x)
model = Model(input=inputs, outputs=p)
model.compile(optimizer='SGD',
loss='mse',
metrics=['accuracy'])
return model
然后我可以调用网格搜索:
model = KerasClassifier(build_fn=create_model)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1)
应该可以。
干杯!
添加 backend.clear_session() 对我有用:
from keras import backend as backend
def model_builder(hp):
backend.clear_session()
model = Sequential()
hp_drop = hp.Float('drop', min_value=0, max_value=0.2, step=0.025)
model.add(Dense(128, activation = "relu"))
model.add(Dropout(hp_drop))
model.add(Dense(1, activation = "relu"))
model.compile(
loss='mean_absolute_error',
optimizer=tf.keras.optimizers.Adam(0.001),
metrics=["mean_absolute_percentage_error"]
)
return model