我正在使用
keras
具有的库
tensorflow
后端和CUDA已启用。请参阅PIP软件包版本输出:
Keras (2.0.8)
tensorflow-gpu (1.3.0)
tensorflow-tensorboard (0.1.8)
我有以下代码创建
VGG16
模型和载荷图像净重:
def create_vgg16_model(target_size: tuple, n_classes: int):
base = VGG16(include_top=False,
input_shape=target_size,
weights='imagenet')
x = base.output
x = Flatten()(x)
x = Dense(n_classes, activation='softmax', name='top')(x)
model = Model(inputs=base.input, outputs=x)
for layer in model.layers[:-1]:
layer.trainable = False
model.compile(optimizer='adam', loss='categorical_crossentropy')
return model
模特的训练进行得很顺利
nvidia-smi
显示根据需要使用GPU内存。但我检查了
top
命令,下面是我看到的:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1268 ck 20 0 166288 31964 12416 S 29.5 0.1 13:05.39 Xtightvnc
32235 ck 30 10 32252 3700 3356 S 5.3 0.0 0:36.93 cwaves
------------------------------------------------------------------------------
32212 ck 20 0 27.485g 1.184g 190404 S 2.3 3.8 0:35.44 python
------------------------------------------------------------------------------
26015 root 20 0 0 0 0 S 0.3 0.0 0:00.30 kworker/3:1
31754 ck 20 0 43168 3904 3080 R 0.3 0.0 0:04.45 top
1 root 20 0 185644 6204 3984 S 0.0 0.0 0:10.44 systemd
我用调试器浏览了代码,并意识到内存是在以下函数中分配的
keras.backend.tensorflow_backed
这将创建
tf.Session
对象:
def get_session():
global _SESSION
if tf.get_default_session() is not None:
session = tf.get_default_session()
else:
if _SESSION is None:
if not os.environ.get('OMP_NUM_THREADS'):
config = tf.ConfigProto(allow_soft_placement=True)
else:
num_thread = int(os.environ.get('OMP_NUM_THREADS'))
config = tf.ConfigProto(intra_op_parallelism_threads=num_thread,
allow_soft_placement=True)
# next line allocates ~28GB of RAM
_SESSION = tf.Session(config=config)
session = _SESSION
if not _MANUAL_VAR_INIT:
with session.graph.as_default():
_initialize_variables()
return session
而且,所有可用模型都会发生这种情况,因为内存是在创建会话时分配的,在培训开始或变量初始化之前分配的。
我知道TF分配所有可用的GPU内存(除非您重写
ConfigProto
和/或调整您的环境变量),但它对RAM的作用是否相同?一、 似乎框架正在分配我机器上的所有RAM,除了一个已经由其他进程分配的RAM。
有人在不同版本的
张量流
或
凯拉斯
?你认为有没有办法限制内存的使用量?
更新1
前一段时间,我的一个训练脚本在经过50-60次训练后,因内存不足错误被内核杀死。尽管易失性GPU内存使用统计数据显示它也在使用。(据我所知,不仅仅是分配)。
更新2
同意,虚拟内存不是有效的指标。但我发现,在模型的训练过程中,内存消耗几乎呈线性增长。我有以下训练循环:
def train_model(model, x, y):
loss = model.train_on_batch(x, y)
return loss
def train_model_42(model, x, y):
# dummy function
return 42.0
def training_loop():
# training parameters
target_size = 224, 224, 3
batch_size = 128
# generator yielding batches of file paths
files_stream = FilesStream(folder=TRAIN_IMAGES, batch_size=batch_size)
files_source = files_stream()
# list of generators loading images from persistent storage
gens = [
image_loader(),
augment_images(horizontal_flip=True),
shuffle_samples(),
normalize_images(target_size=target_size)
]
# Model from keras.applications with replaced top layer
model = get_model('resnet50').build(n_classes=n_classes)
for epoch in range(1, 1001):
epoch_loss = []
for _ in range(files_stream.steps_per_epoch):
for gen in gens:
gen.send(None)
processed = next(files_source)
for gen in gens:
processed = gen.send(processed)
x, y = processed
loss = train_model_42(model, x, y) # <-- this shows pic. 1
# loss = train_model(model, x, y) <-- this shows pic. 2
epoch_loss.append(loss)
avg_loss = sum(epoch_loss) / len(epoch_loss)
print('Epoch %03d: train loss = %2.4f' % (epoch, avg_loss))
当我使用虚拟训练功能时,内存消耗图看起来如所示
pic 1
:
但是,在运行真正的培训过程时
pic 2
:
为什么在训练过程中内存消耗会增加?是否缓存了以前的数据批?模型/重量或其他任何东西是否应该占用越来越多的内存?
我认为我的数据预处理管道可能有问题,但我有意将预处理函数编写为生成器。是否有某种默认的Keras回调应用于跟踪训练信息的模型,从而提高内存使用率?