一、说明
在深入研究第 1 部分中的介绍和实现,并在第 2 部分中探索训练过程之后,我们现在将重点转向在第 3 部分中通过超参数调整来优化模型的性能。要访问本系列的完整代码,请访问我们的 GitHub 存储库在GitHub - asokraju/ImageAutoEncoder: A repository to learn features from Off Road Navigation Vehicles
在任何机器学习模型中,超参数都是我们调整以获得最佳模型性能的旋钮和杠杆。然而,找到正确的设置有点像大海捞针——非常耗时,有时甚至令人困惑!但不用担心,我们将以简单直接的方式引导您完成整个过程。
在本部分中,我们将利用 Docker 和 Bash 脚本对变分自动编码器执行超参数调整。Docker 是一个用于部署应用程序的流行平台,它将帮助我们为实验创建一个隔离的环境,确保我们的结果是可重现的。同时,Bash 脚本将自动执行使用不同超参数运行模型的繁琐任务,从而使该过程更加高效。
那么,您准备好调整您对变分自动编码器的理解并释放模型的全部潜力了吗?让我们一起深入研究“变分自动编码器:使用 Docker 和 Bash 脚本进行超参数调整”!
如果您需要复习或想要重温任何概念,请不要忘记重温第 1 部分和第 2 部分。快乐学习!
二、超参数实验
任何机器学习模型的开发通常都涉及微调一系列超参数。然而,手动测试每种可能的组合将是一项艰巨的任务。这就是master.sh
派上worker.sh
用场的地方。这两个 bash 脚本自动化了尝试不同超参数并记录结果的过程,为我们节省了大量的时间和精力。
master.sh
是我们的控制室,编排我们希望测试的各种超参数组合。它系统地循环遍历我们预定义的一组超参数(在本例中为学习率、潜在维度和批量大小),并且对于每个独特的组合,它调用脚本worker.sh
。
剧本worker.sh
就是地面上的工人。每次调用它时,它都会从 接收超参数的独特组合master.sh
,为该实验设置专用日志目录,然后train.py
使用这些特定的超参数运行我们的模型(在本例中)。日志目录根据使用的超参数进行唯一命名,以便我们以后可以轻松识别每个实验的结果。
有了这两个脚本,我们就可以放松下来,让我们的机器完成繁重的工作,使用不同的超参数运行实验并记录结果,以便我们在闲暇时进行分析。
# Contents of master.sh #!/bin/bash -l
for learning_rates in 0.001
dofor latent_dims in 6 8dofor batch_sizes in 128do./scripts/call_experiments.sh $learning_rates $latent_dims $batch_sizesdonedone
done
现在让我们仔细看看这些脚本的详细信息。
主脚本:
该master.sh
脚本的主要功能是循环遍历我们想要测试模型训练的不同超参数,然后调用脚本worker.sh
使用提供的超参数执行每个实验。
我们来分解一下步骤:
#!/bin/bash -l
:这一行通常称为 shebang,告诉系统该文件是一个 bash 脚本,应该这样执行。for learning_rates in 0.001
:这将开始一个循环,迭代不同的学习率。在本例中,它仅包含一个值 0.001。您可以添加更多由空格分隔的值,例如for learning_rates in 0.001 0.01 0.1
。for latent_dims in 6 8
和for batch_sizes in 128
:这些是其他超参数的附加循环 - 潜在维度和批量大小。./scripts/call_experiments.sh $learning_rates $latent_dims $batch_sizes
call_experiments.sh
:这是使用当前选择的超参数调用脚本的关键步骤。这些值作为参数传递给worker.sh
脚本。done
:其中每一个都关闭一个 for 循环。由于存在三个for
循环,因此必须有三个done
命令。
本质上,该脚本将对指定学习率、潜在维度和批量大小的笛卡尔积执行超参数搜索,并worker.sh
为每个组合运行脚本。
工人脚本
该worker.sh
脚本旨在接受一组超参数作为输入,为实验设置唯一的日志目录,然后使用这些超参数运行 Python 训练脚本。
# contents of worker.sh#!/bin/bashlearning_rate=$1
latent_dim=$2
batch_size=$3PARENT_DIR="$(dirname $PWD)"
EXEC_DIR=$PWD
log_dir="logs/lr=${learning_rate}_latentdim=${latent_dim}_batchsize=${batch_size}"
mkdir -p $log_dir
echo "Current working directory is: $(pwd)"
python train.py --image-dir='../train_data' --learning-rate=${learning_rate} --latent-dim=${latent_dim} --batch-size=${batch_size} --logs-dir=${log_dir}
下面对其步骤进行详细说明:
#!/bin/bash
:就像在master.sh
脚本中一样,这个 shebang 将文件声明为 bash 脚本。learning_rate=$1
、latent_dim=$2
、batch_size=$3
:这些行捕获 提供的输入参数master.sh
并将它们分配给相应的变量。PARENT_DIR="$(dirname $PWD)"
,EXEC_DIR=$PWD
: 在这里,我们将父目录路径和当前目录路径保存到变量中以供将来使用。log_dir="logs/lr=${learning_rate}_latentdim=${latent_dim}_batchsize=${batch_size}"
,mkdir -p $log_dir
:这一对行创建一个唯一的目录来存储当前超参数集的日志。-p
命令中的标志确保mkdir
它创建整个目录路径(如果不存在)。echo "Current working directory is: $(pwd)"
:此行只是将当前工作目录打印到终端以进行调试。- 最后一行使用所选的超参数运行 Python 训练脚本,并指定本次运行的日志目录:
python train.py --image-dir='../train_data' --learning-rate=${learning_rate} --latent-dim=${latent_dim} --batch-size=${batch_size} --logs-dir=${log_dir}
总之,该worker.sh
脚本使用一组给定的超参数执行单个实验,将实验的输出记录在专用目录中,然后终止。
三、Docker 设置
Dockerfile 和 docker-compose 文件在 Docker 上下文中使用,Docker 是一个允许您将应用程序及其依赖项打包到隔离容器中的平台。
Dockerfile 是一个文本文件,其中包含一组用于构建 Docker 映像的指令。它定义基础映像,设置工作目录,将文件复制到映像中,安装依赖项,并指定启动容器时要运行的命令。
另一方面,docker-compose 文件用于定义和管理多个容器作为单个应用程序的一部分。它允许您定义服务、它们的配置以及它们如何相互交互。
# Contents of Dockerfile
# Use an official Tensorflow runtime as a parent image
FROM tensorflow/tensorflow:latest# Set the working directory to /app
WORKDIR /autoencodersCOPY . .# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install pyyamlRUN chmod +x scripts/master.sh
RUN chmod +x scripts/worker.sh# Run app.py when the container launches
CMD ["python", "train.py"]
现在,让我们详细了解 Dockerfile 中的每个步骤:
FROM tensorflow/tensorflow:latest
:此行指定要使用的基础映像,这是官方 TensorFlow 运行时映像的最新版本。WORKDIR /autoencoders
:将容器内的工作目录设置为/autoencoders
. 这是后续命令将被执行的地方。COPY . .
:将当前目录(Dockerfile所在目录)中的所有文件复制到/autoencoders
容器内的目录中。RUN pip install --no-cache-dir -r requirements.txt
:安装文件中指定的Python包requirements.txt
。该--no-cache-dir
标志用于避免在容器上缓存包索引。RUN pip install pyyaml
:pyyaml
使用 pip 安装软件包。某些 YAML 相关功能可能需要此包。RUN chmod +x scripts/master.sh
和RUN chmod +x scripts/worker.sh
:更改 shell 脚本的权限master.sh
并使worker.sh
它们可执行。CMD ["python", "train.py"]
:指定容器启动时运行的默认命令。train.py
在本例中,它使用 Python 解释器运行Python 脚本。
# contents of requirements.txt
pandas==1.3.3
numpy==1.21.2
matplotlib==3.4.3
argparse==1.4.0
protobuf==3.20.*
tensorflow==2.7.0
pyyaml
现在,让我们继续讨论 docker-compose 文件:
version: '3'
:指定正在使用的 docker-compose 文件格式的版本。services
:定义组成应用程序的服务(容器)。autoencoders
:服务的名称。build
:指定如何构建该服务的镜像。context: .
:将构建上下文设置为当前目录(docker-compose 文件所在的位置)。dockerfile: Dockerfile
:指定用于构建映像的 Dockerfile。ports: - "8080:80"
:将主机上的8080端口映射到容器上的80端口。这允许通过访问容器内运行的服务localhost:8080
。volumes: - ./:/autoencoders
:将主机上的当前目录挂载到/autoencoders
容器内的目录,确保主机上文件的更改反映在容器内。- type: bind source: F:/train_data target: /train_data
:将F:/train_data
主机上的目录与/train_data
容器内的目录绑定,允许从容器内访问训练数据。command: ./scripts/master.sh
:指定启动容器时运行的命令。在这种情况下,它运行master.sh
位于scripts
目录中的脚本。
# Contents of docker-compose.yml
version: '3'
services:autoencoders:build:context: .dockerfile: Dockerfileports:- "8080:80"volumes:- ./:/autoencoders- type: bindsource: F:/train_datatarget: /train_datacommand: ./scripts/master.sh
在您的docker-compose.yml
文件中,您指定了两个卷。第一个卷将docker-compose.yml
主机上的当前目录(文件所在的位置)映射到/autoencoders
Docker 容器中的目录。
第二个卷是绑定挂载,它将主机中的目录或文件绑定到 Docker 容器中的目录或文件。在本例中,您将F:/train_data
主机上的目录绑定到/train_data
Docker 容器中的目录。
此行很重要,因为您的训练脚本(在 Docker 容器内运行)期望在 处找到您的训练数据/train_data
。但由于 Docker 容器与主机隔离,因此您需要一种方法来向脚本提供训练数据。绑定挂载通过使F:/train_data
主机上的目录/train_data
在 Docker 容器中可用来实现这一点。
但是,并非每个使用您的脚本的人都会在 处获得训练数据F:/train_data
。这就是为什么您需要指示他们根据训练数据所在的位置更改此行。他们可以替换F:/train_data
为训练数据的路径。例如,如果他们的训练数据位于C:/Users/user123/data
,他们需要将此行更改为:
# Contents of docker-compose.yml
version: '3'
services:autoencoders:build:context: .dockerfile: Dockerfileports:- "8080:80"volumes:- ./:/autoencoders- type: bindsource: C:/Users/user123/datatarget: /train_datacommand: ./scripts/master.sh
这些步骤共同定义了用于构建映像并运行关联容器的 Dockerfile 和 docker-compose 文件,从而能够在容器化环境中训练自动编码器。