shell腳本長命令帶換行 注釋方法
命令行傳參
在訓練深度學習網絡時,我們每次實驗通常會有許多超參數需要設置,如batch size, epoch, gpu id, arch甚至還有一些具體的模型結構等。這事我們通常使用python模塊argparse
,在命令行進行傳參。
比如這樣:
# train.py
import argparseparser = argparse.ArgumentParser()
parser.add_argument("--batchSize", default=64)
parser.add_argument("--gpu_id", default="0")
parser.add_argument("--split", action='store_true')
config = parser.parse_args()
print(config)# ... your train loop
當然這里為了說明簡化了參數的個數,實際的工程中的超參數肯定比這要多得多。這時我們直接在命令行中傳參并運行:
python train.py --batchSize 32 --split --gpu_id 1
這樣就可以調整每次運行的參數。
shell腳本
超參數還少的時候這樣還行,但是面對巨多的超參數,每次實驗都手敲參數的話未免太麻煩了。所以,稍微進階一點的做法就是用shell腳本的方式將每個參數單行寫進去,然后每次只要更改shell腳本中的數值即可。
# train.sh
python train.py \
--batchSize 32 \
--split \
--gpu_id 1
然后我們每次實驗的時候只需更改shell腳本中的值,然后再命令行中sh train.sh
即可。
我們通過輸出驗證一下是否傳參成功:
Namespace(batchSize='32', gpu_id='1', split=True)
注意事項
注意使用多換行的shell腳本時有兩個注意事項:
- 每個換行
\
后面不能有空格,必須直接跟回車。 - 最后一行參數不要有換行符。
具體可以看這篇博客:shell error- unrecognized arguments- \
注釋單行
對于action='store_true'
型的參數,我們知道有這個參數,則python程序中該值會直接為True
,沒有則值為False
。那我們根據在實驗中需要這個值為True
或False
,就在shell腳本有時希望有這個參數,有時希望沒有。
由于我們又不想改變各個參數再shell腳本中的位置,所以最好不要直接刪掉那一行。那么在shell腳本最中最直接的想法就是直接單行注釋掉這一行,讓我們先來試一下直接注釋能不能行。
# train.sh
python test.py \
--batchSize 32 \
# --split \
--gpu_id 1 \
我們運行sh train.sh
試一下,輸出如下:
Namespace(batchSize='32', gpu_id='0', split=False)
test.sh: 4: test.sh: --gpu_id: not found
出大問題,報錯了。其實運行py程序的命令是成功運行了的,因為輸出了Namespace,但是我們發現我們設置的--gpu_id 1
參數沒有傳進去。而且后面又報了未找到--gpu_id
命令的問題。原因很明顯了:由于多了一個換行,系統將換行之后的參數當作了一個新命令。
解決方法是用 反引號`(backtick) 來包裹我們的注釋,就不會破壞掉腳本的語義了,能夠正確解析執行:
# train.sh
python test.py \
--batchSize 32 \
`# --split` \
--gpu_id 1 \
再次嘗試sh train.sh
,輸出:
Namespace(batchSize='32', gpu_id='1', split=False)
只將split
置為False
,其他傳參正常,成功解決。
Ref:
https://www.jb51.net/article/165139.htm