Keras 模型停止训练,但没有说明为什么以及如何启用 GPU 加速
Keras Model stops training without indication as to why and how to enable GPU-acceleration
我正在尝试在 c5.large 实例 (AWS) 上迁移学习预训练的 MobileNet 模型。
我首先训练(老化)最后一个密集层几个时期(在 5-20 之间尝试过,似乎并不重要)。
老化期过后,我想训练完整的模型。但是,这会在几个时期后停止而不会出现错误。
早些时候,我尝试过不使用老化期,但效果很好 "fine-ish"。通常会在大约 50 个 epoch 后使服务器崩溃(这就是我添加 clipnorm 的原因,这确实有点帮助)。
欢迎任何关于如何调试的想法。
控制台输出:
Total params: 3,239,114
Trainable params: 3,217,226
Non-trainable params: 21,888
_________________________________________________________________
Epoch 6/25
1/46 [..............................] - ETA: 9:22 - loss: 0.2123
2/46 [>.............................] - ETA: 7:46 - loss: 0.2028ubuntu@ip-XXX:~$ ls
培训代码:
base_model = _mobilenet.MobileNet(
input_shape=(224, 224, 3), include_top=False, pooling="avg"
)
if not options.mobile_net_weights:
pretrained_weights = os.path.join(
os.path.dirname(pretrained.__file__), "weights_mobilenet_aesthetic_0.07.hdf5"
)
base_model.load_weights(pretrained_weights, by_name=True)
# add dropout and dense layer
x = Dropout(0.6)(base_model.output)
x = Dense(units=classes, activation=last_activation)(x)
pretrained_model = Model(base_model.inputs, x)
# start training only dense layers
for layer in base_model.layers:
layer.trainable = False
pretrained_model.compile(loss=loss, optimizer=Adam(lr=0.001, decay=0, clipnorm=1.0))
pretrained_model.summary()
# add path equal to image_id
labels = [dict(item, **{"path": item["image_id"]}) for item in load_json(labels_path)]
training, validation = train_test_split(labels, test_size=0.05, shuffle=True)
train_data_gen = _DataGenerator(
training,
batch_size=options.batch_size,
base_dir=options.image_path,
n_classes=classes,
basenet_preprocess=_mobilenet.preprocess_input,
)
validation_data_gen = _DataGenerator(
validation,
batch_size=options.batch_size,
base_dir=options.image_path,
n_classes=classes,
basenet_preprocess=_mobilenet.preprocess_input,
training=False,
)
train_job_dir = f"train_jobs/{datetime.datetime.now().isoformat()}"
train_job_dir = os.path.join(options.results_path, train_job_dir)
tensorboard = TensorBoardBatch(log_dir=os.path.join(train_job_dir, "logs"))
model_save_name = "weights_{epoch:02d}_{val_loss:.3f}.hdf5"
model_file_path = os.path.join(train_job_dir, "weights", model_save_name)
if not os.path.exists(os.path.join(train_job_dir, "weights")):
os.makedirs(os.path.join(train_job_dir, "weights"))
model_checkpointer = ModelCheckpoint(
filepath=model_file_path,
monitor="val_loss",
verbose=1,
save_best_only=True,
save_weights_only=True,
)
pretrained_model.fit_generator(
train_data_gen,
steps_per_epoch=len(training) / options.batch_size / 10,
epochs=5,
verbose=1,
callbacks=[tensorboard, model_checkpointer],
validation_data=validation_data_gen,
validation_steps=len(validation) / options.batch_size,
)
# start training all layers
for layer in base_model.layers:
layer.trainable = True
pretrained_model.compile(
loss=loss, optimizer=Adam(lr=0.0001, decay=0.000023, clipnorm=1.0)
)
pretrained_model.summary()
pretrained_model.fit_generator(
train_data_gen,
steps_per_epoch=len(training) / options.batch_size / 10,
epochs=25,
initial_epoch=5,
verbose=1,
callbacks=[tensorboard, model_checkpointer],
validation_data=validation_data_gen,
validation_steps=len(validation) / options.batch_size,
)
更新跟进
原来的问题好像是机器可用内存太少造成的。我确实有一个不相关但相关的问题。在尝试使用 GPU 加速时,我一直在用头撞墙,因为我似乎无法让它工作。
是否有任何有用的(逻辑结构清晰且易于理解的)信息可以如何使用:
- Docker 在本地机器上(构建启用 GPU 加速的图像)
- 在 GPU 实例上安装所有相关的 (nvidia-) 驱动程序(多么疯狂的版本混乱)
- 运行 Docker 容器 (nvidia-docker2, nvidia-docker or --运行time==nvidia ??)
- Cuda 到底是什么东西,我为什么需要它?
- 我发现一些 sources 建议 Docker 中的 运行 Cuda,为什么?
当我似乎可以正常工作(即设置驱动程序,某些版本)并设法构建支持 GPU 的(即 tensorflow-gpu)Docker 图像时,我收到了这个错误:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "process_linux.go:430: container init caused \"process_linux.go:413: running prestart hook 1 caused \"error running hook: exit status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig.real --device=all --compute --utility --require=cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411 --pid=2113 /var/lib/docker/overlay2/4bf49d2555c40278b3249f73bf3d33484181f51b374b77b69a474fc39e37441b/merged]\nnvidia-container-cli: requirement error: unsatisfied condition: driver >= 410\n\"\"": unknown.
让我为你的大问题提供一个简单的解决方案(既然你已经解决了内存问题,尽管我认为在大型实例上仅使用 300 万个参数进行训练应该不会给你带来问题):
安装 Conda。
所以,这里发生的是你的 cuda docker 与你的 nvidia 驱动程序不兼容,反之亦然。安装 cuda 是一个痛苦的过程(我想很多人都可以在这里与我联系)。
但是您可以使用 conda
.
轻松安装 cuda 兼容版本的 tensorflow 和 pytorch
这是我每次设置云实例时都会使用的一组个人命令:
对于python 2.x:
wget https://repo.anaconda.com/miniconda/Miniconda2-latest-Linux-x86.sh
bash Miniconda2-latest-Linux-x86_64.sh
(如果找不到 conda,请使用命令 'bash' 然后输入 'conda --version' 进行检查)
conda install numpy
conda install tensorflow-gpu
对于Python3:
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
conda create -n TFGPU -c defaults tensorflow-gpu
conda activate TFGPU
conda install pytorch torchvision cudatoolkit=9.0 -c pytorch
conda install jupyter
conda install keras
您可以通过验证来检查控制台输出:
$python3
>>>import tensorflow as tf
>>>sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
这应该可以解决您所有的错误。
否则如果nvidia驱动有问题,你可以手动安装nvidia-smi
:
#!/bin/bash
echo "Checking for CUDA and installing."
# Check for CUDA and try to install.
if ! dpkg-query -W cuda-9-0; then
# The 16.04 installer works with 16.10.
curl -O http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
dpkg -i ./cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
apt-get update
apt-get install cuda-9-0 -y
fi
# Enable persistence mode
nvidia-smi -pm 1
nvidia-container-cli: requirement error: unsatisfied condition: driver>= 410
CUDA/Driver/GPU 兼容性矩阵可在此处获得:
https://github.com/NVIDIA/nvidia-docker/wiki/CUDA#requirements
关于您的问题:
Docker on a local machine (to build a GPU-accelerated enabled image)
我通常在我的 Ubuntu 机器上安装 docker-ce(社区版)。这里的说明很简单:https://docs.docker.com/install/linux/docker-ce/ubuntu/
Install all the relevant (nvidia-)drivers on the GPU instance (what an
insane version chaos)
最好从此处下载 OS 的安装程序,一次性安装 nvidia-drivers 和 CUDA。这样您就不会遇到 CUDA 驱动程序不匹配问题。
https://developer.nvidia.com/cuda-downloads
(例如 Ubuntu、sudo apt-get install cuda
)
Run the Docker container (nvidia-docker2, nvidia-docker or
--runtime==nvidia ?? )
nvidia-docker2
取代 nvidia-docker
。它将 GPU 设备 (/dev/nvidiaX
) 映射到 Docker 容器中,并将 运行 时间设置为 nvidia
。仅当使用 docker
命令时才需要使用 --runtime=nvidia
。如果您使用的是 Docker 版本 19.03 或更高版本,则不需要 nvidia-docker2,如此处的快速入门部分所述:https://github.com/NVIDIA/nvidia-docker/。
What the hell is Cuda and why do I need it?
CUDA Toolkit是NVIDIA为GPU编程打造的并行编程工具包。 Tensorflow 和 Pytorch 等深度学习框架在内部使用它 运行在 GPU 上执行您的代码(模型训练)。
https://devblogs.nvidia.com/even-easier-introduction-cuda/
Some sources that I found suggested to run Cuda in Docker, why?
如前一个答案所述,由于 DL 框架在 Docker 容器内执行,CUDA 工具包也需要在容器内 运行 以便框架可以使用工具包功能。此 link 处提供的框图非常有助于形象化:https://github.com/NVIDIA/nvidia-docker/
https://cloud.githubusercontent.com/assets/3028125/12213714/5b208976-b632-11e5-8406-38d379ec46aa.png
. GPU 驱动程序位于主机 OS 之上,Docker 容器托管 CUDA 工具包和应用程序(模型 training/inference 代码编写在深度学习框架中,如 Tensorflow 或 PyTorch)
您使用迁移学习重新训练的数据集的大小是多少。
我在那个例子中遇到了同样的问题,减少批量大小解决了我的问题。
我正在尝试在 c5.large 实例 (AWS) 上迁移学习预训练的 MobileNet 模型。
我首先训练(老化)最后一个密集层几个时期(在 5-20 之间尝试过,似乎并不重要)。
老化期过后,我想训练完整的模型。但是,这会在几个时期后停止而不会出现错误。
早些时候,我尝试过不使用老化期,但效果很好 "fine-ish"。通常会在大约 50 个 epoch 后使服务器崩溃(这就是我添加 clipnorm 的原因,这确实有点帮助)。
欢迎任何关于如何调试的想法。
控制台输出:
Total params: 3,239,114
Trainable params: 3,217,226
Non-trainable params: 21,888
_________________________________________________________________
Epoch 6/25
1/46 [..............................] - ETA: 9:22 - loss: 0.2123
2/46 [>.............................] - ETA: 7:46 - loss: 0.2028ubuntu@ip-XXX:~$ ls
培训代码:
base_model = _mobilenet.MobileNet(
input_shape=(224, 224, 3), include_top=False, pooling="avg"
)
if not options.mobile_net_weights:
pretrained_weights = os.path.join(
os.path.dirname(pretrained.__file__), "weights_mobilenet_aesthetic_0.07.hdf5"
)
base_model.load_weights(pretrained_weights, by_name=True)
# add dropout and dense layer
x = Dropout(0.6)(base_model.output)
x = Dense(units=classes, activation=last_activation)(x)
pretrained_model = Model(base_model.inputs, x)
# start training only dense layers
for layer in base_model.layers:
layer.trainable = False
pretrained_model.compile(loss=loss, optimizer=Adam(lr=0.001, decay=0, clipnorm=1.0))
pretrained_model.summary()
# add path equal to image_id
labels = [dict(item, **{"path": item["image_id"]}) for item in load_json(labels_path)]
training, validation = train_test_split(labels, test_size=0.05, shuffle=True)
train_data_gen = _DataGenerator(
training,
batch_size=options.batch_size,
base_dir=options.image_path,
n_classes=classes,
basenet_preprocess=_mobilenet.preprocess_input,
)
validation_data_gen = _DataGenerator(
validation,
batch_size=options.batch_size,
base_dir=options.image_path,
n_classes=classes,
basenet_preprocess=_mobilenet.preprocess_input,
training=False,
)
train_job_dir = f"train_jobs/{datetime.datetime.now().isoformat()}"
train_job_dir = os.path.join(options.results_path, train_job_dir)
tensorboard = TensorBoardBatch(log_dir=os.path.join(train_job_dir, "logs"))
model_save_name = "weights_{epoch:02d}_{val_loss:.3f}.hdf5"
model_file_path = os.path.join(train_job_dir, "weights", model_save_name)
if not os.path.exists(os.path.join(train_job_dir, "weights")):
os.makedirs(os.path.join(train_job_dir, "weights"))
model_checkpointer = ModelCheckpoint(
filepath=model_file_path,
monitor="val_loss",
verbose=1,
save_best_only=True,
save_weights_only=True,
)
pretrained_model.fit_generator(
train_data_gen,
steps_per_epoch=len(training) / options.batch_size / 10,
epochs=5,
verbose=1,
callbacks=[tensorboard, model_checkpointer],
validation_data=validation_data_gen,
validation_steps=len(validation) / options.batch_size,
)
# start training all layers
for layer in base_model.layers:
layer.trainable = True
pretrained_model.compile(
loss=loss, optimizer=Adam(lr=0.0001, decay=0.000023, clipnorm=1.0)
)
pretrained_model.summary()
pretrained_model.fit_generator(
train_data_gen,
steps_per_epoch=len(training) / options.batch_size / 10,
epochs=25,
initial_epoch=5,
verbose=1,
callbacks=[tensorboard, model_checkpointer],
validation_data=validation_data_gen,
validation_steps=len(validation) / options.batch_size,
)
更新跟进
原来的问题好像是机器可用内存太少造成的。我确实有一个不相关但相关的问题。在尝试使用 GPU 加速时,我一直在用头撞墙,因为我似乎无法让它工作。
是否有任何有用的(逻辑结构清晰且易于理解的)信息可以如何使用:
- Docker 在本地机器上(构建启用 GPU 加速的图像)
- 在 GPU 实例上安装所有相关的 (nvidia-) 驱动程序(多么疯狂的版本混乱)
- 运行 Docker 容器 (nvidia-docker2, nvidia-docker or --运行time==nvidia ??)
- Cuda 到底是什么东西,我为什么需要它?
- 我发现一些 sources 建议 Docker 中的 运行 Cuda,为什么?
当我似乎可以正常工作(即设置驱动程序,某些版本)并设法构建支持 GPU 的(即 tensorflow-gpu)Docker 图像时,我收到了这个错误:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "process_linux.go:430: container init caused \"process_linux.go:413: running prestart hook 1 caused \"error running hook: exit status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig.real --device=all --compute --utility --require=cuda>=10.0 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=410,driver<411 --pid=2113 /var/lib/docker/overlay2/4bf49d2555c40278b3249f73bf3d33484181f51b374b77b69a474fc39e37441b/merged]\nnvidia-container-cli: requirement error: unsatisfied condition: driver >= 410\n\"\"": unknown.
让我为你的大问题提供一个简单的解决方案(既然你已经解决了内存问题,尽管我认为在大型实例上仅使用 300 万个参数进行训练应该不会给你带来问题):
安装 Conda。
所以,这里发生的是你的 cuda docker 与你的 nvidia 驱动程序不兼容,反之亦然。安装 cuda 是一个痛苦的过程(我想很多人都可以在这里与我联系)。
但是您可以使用 conda
.
这是我每次设置云实例时都会使用的一组个人命令:
对于python 2.x:
wget https://repo.anaconda.com/miniconda/Miniconda2-latest-Linux-x86.sh
bash Miniconda2-latest-Linux-x86_64.sh
(如果找不到 conda,请使用命令 'bash' 然后输入 'conda --version' 进行检查)
conda install numpy
conda install tensorflow-gpu
对于Python3:
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
conda create -n TFGPU -c defaults tensorflow-gpu
conda activate TFGPU
conda install pytorch torchvision cudatoolkit=9.0 -c pytorch
conda install jupyter
conda install keras
您可以通过验证来检查控制台输出:
$python3
>>>import tensorflow as tf
>>>sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
这应该可以解决您所有的错误。
否则如果nvidia驱动有问题,你可以手动安装nvidia-smi
:
#!/bin/bash
echo "Checking for CUDA and installing."
# Check for CUDA and try to install.
if ! dpkg-query -W cuda-9-0; then
# The 16.04 installer works with 16.10.
curl -O http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
dpkg -i ./cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
apt-get update
apt-get install cuda-9-0 -y
fi
# Enable persistence mode
nvidia-smi -pm 1
nvidia-container-cli: requirement error: unsatisfied condition: driver>= 410
CUDA/Driver/GPU 兼容性矩阵可在此处获得: https://github.com/NVIDIA/nvidia-docker/wiki/CUDA#requirements
关于您的问题:
Docker on a local machine (to build a GPU-accelerated enabled image)
我通常在我的 Ubuntu 机器上安装 docker-ce(社区版)。这里的说明很简单:https://docs.docker.com/install/linux/docker-ce/ubuntu/
Install all the relevant (nvidia-)drivers on the GPU instance (what an insane version chaos)
最好从此处下载 OS 的安装程序,一次性安装 nvidia-drivers 和 CUDA。这样您就不会遇到 CUDA 驱动程序不匹配问题。
https://developer.nvidia.com/cuda-downloads
(例如 Ubuntu、sudo apt-get install cuda
)
Run the Docker container (nvidia-docker2, nvidia-docker or --runtime==nvidia ?? )
nvidia-docker2
取代 nvidia-docker
。它将 GPU 设备 (/dev/nvidiaX
) 映射到 Docker 容器中,并将 运行 时间设置为 nvidia
。仅当使用 docker
命令时才需要使用 --runtime=nvidia
。如果您使用的是 Docker 版本 19.03 或更高版本,则不需要 nvidia-docker2,如此处的快速入门部分所述:https://github.com/NVIDIA/nvidia-docker/。
What the hell is Cuda and why do I need it?
CUDA Toolkit是NVIDIA为GPU编程打造的并行编程工具包。 Tensorflow 和 Pytorch 等深度学习框架在内部使用它 运行在 GPU 上执行您的代码(模型训练)。
https://devblogs.nvidia.com/even-easier-introduction-cuda/
Some sources that I found suggested to run Cuda in Docker, why?
如前一个答案所述,由于 DL 框架在 Docker 容器内执行,CUDA 工具包也需要在容器内 运行 以便框架可以使用工具包功能。此 link 处提供的框图非常有助于形象化:https://github.com/NVIDIA/nvidia-docker/ https://cloud.githubusercontent.com/assets/3028125/12213714/5b208976-b632-11e5-8406-38d379ec46aa.png . GPU 驱动程序位于主机 OS 之上,Docker 容器托管 CUDA 工具包和应用程序(模型 training/inference 代码编写在深度学习框架中,如 Tensorflow 或 PyTorch)
您使用迁移学习重新训练的数据集的大小是多少。 我在那个例子中遇到了同样的问题,减少批量大小解决了我的问题。