引言

在前面的文章中,我们介绍了使用函数指针方便的选择不同函数,使用字典实现保存多套参数以待后续训练。但是在程序的运行过程中,仍然需要

1、每次修改PARAMS_SN中当前参数的编号;

2、新开终端,执行训练程序。

服务器可以容纳的同时运行的程序个数最多为14个,即使这样,我们仍然需要经过很多繁琐的操作才能达到我们的目的。

因此为了让训练时操作更加人性化,对传参训练部分进行修改:

1、开启新终端后,通过shell脚本读取命令行中输入的编号,

2、修改PARAMS_SN中的变量,来省略手动打开PARAMS_SN进行修改再保存的操作

3、读取对应编号的参数,并应用到训练程序中

读取编号

1、完成引言中的工作的第一步是读取命令行中输入的编号值。

使用read命令,-t 5表示等待5s,num就是命令行输入的值

#!/bin/bash
read -t 5 -p "请输入编号"  num

写入PARAMS_SN

2、重点是怎么将传入的值替换掉PARAMS_SN文件中的编号值。

首先获取原始文件中的编号值

full_of_it=$(cat Heating_distribution/PARAMS_SN.py) #注意不能有空格
origin_num=$(echo ${full_of_it} | tr -cd "[0-9]")

linux中tr命令的意思是控制字符,其中的-c的意思是取反,-d的意思是删除。因此这两条命令就是删除文件中非数字的字符。

3、接下来就是最关键的部分了,怎么将得到的已有数字origin_num替换成我们希望的数字num呢?

if (( ${#origin_num} == 1 ))
then
sed -i "s/[0-9]/${num}/g" Heating_distribution/PARAMS_SN.py
elif (( ${#origin_num} == 2 ))
then
sed -i "s/[0-9][0-9]/${num}/g" Heating_distribution/PARAMS_SN.py
else
echo "编号有误,请重新输入"
exit
fi

首先需要介绍这里用到的linux中if else的结构,判断的时候最好两边有空格:

if ((...))
then
...
elif ((...))
then
---
else
...
fi

然后代码讲解:

由于涉及到的数字可能是个位数,也可能是十位数,因此需要对这两种情况单独处理,在个位数的时候:

if (( ${#origin_num} == 1 ))
then
sed -i "s/[0-9]/${num}/g" Heating_distribution/PARAMS_SN.py

~首先判断字符长度,用${#...}表示

~然后就是sed表现得地方了:

    -i表示直接对文件进行编辑;

    将/代码中前两个//中的值替换为后两个//中的值;

    s表示需要实现替换;

    g表示全部替换;

    ${}实现了取变量的取得功能;

    使用正则表达式[0-9]匹配文件中的数字部分。

在处理十位数的时候,与个位数的唯一区别就是,正则表达式匹配的数字是两个。

读取编号

经过上面的处理,我们已经将用来存放参数编号的文件进行了修改,接下来就需要在训练的时候应用对应标号的参数了:

echo "正在训练第${num}种环境,主人~"
cd Heating_distribution
python train.py
cd ..

在train.py中,我们可以直接调用参数,而参数文件这样设置:

from PARAMS_SN import TARGET
def DQN_PARAMS(num=TARGET):
    res={
    1:{
    'yes':1,
    },
    }
    return res.get(num,None)

这样只要我们在train.py中调用这个函数,就可以默认得到对应标号的参数了。

效果展示

如果对你有帮助,请点赞、转发支持~~~

May the force be with you!