透過命令列剖析規則的 BrainScript
以下我們將說明命令列剖析規則CNTK。 CNTK是由數個元件所組成,可完成工作。 這些元件大部分都需要一些可用的組態資訊才能運作,而且這些組態參數是透過 CNTK 中的組態檔提供。
組態檔是名稱/值組的集合。 組態資料可以是下列其中一種類型:
- 簡單:將單一值指派給組態參數。 例如:
deviceId = "Auto"
。 - 陣列:已指派組態參數的值陣列,這些值不需要屬於統一類型。
:
是陣列的預設分隔符號。 分隔符號可以藉由將陣列值括在括弧中,並將新的分隔符號緊接在左括弧後面來變更。*
字元允許在陣列中重複多次特定值。 例如,minibatchSize = 256:512:512:512:1024
等於minibatchSize = 256:512*3:1024
。 - Set:參數集包含任何型別的組態參數集合。 參數集可以是巢狀的。 參數集的預設分隔符號是在
;
一行中包含多個專案時。 行分隔符號也可做為專案的分隔符號。 例如:
block1 = [id=1;size=256]
block2 = [
subblock = [string="hi";num=5]
value = 1e-10
array = 10:"this is a test":1.25
]
在CNTK中,組態檔會以階層方式組織。 在CNTK元件要求值之前,不會評估實際的資料值。 當元件要求值時,CNTK會先在元件區塊內搜尋。 如果找不到值,則會繼續查看父系和父系參數集,直到找到參數,或達到組態階層的最上層,而不會有相符專案。 這可讓不同區塊更容易共用相同的參數值。 如先前所述,若要執行CNTK您需要在命令列中指定組態檔,因為 cntk configFile=yourExp.cntk
這會載入要求的組態檔,並執行組態檔中命令參數中列出的任何命令區塊。
命令和動作
必須有最上層命令參數,它會定義 (與組態檔中執行) 分隔 :
的命令。 每個命令都會參考檔案中的命令區塊,該區塊必須包含定義區塊將執行的作業的動作參數。 例如,下列命令會執行 區塊,該區塊會執行 mnistTrain
定型動作,後面接著 mnistTest
評估模型的 區塊。
command = mnistTrain:mnistTest
mnistTrain = [
action = "train"
...
]
mnistTest = [
action = "eval"
...
]
命令列中的組態多載
通常會有一個組態可用來做為基底組態,並且只修改每個實驗性回合的幾個參數。 這可以透過幾種不同的方式來完成,其中一種是覆寫命令列上的設定。 例如,若要覆寫模型檔案路徑,您可以直接修改命令列,如下所示:
cntk configFile=yourExp.cntk stderr="c:\temp\newpath"
這會使用新值覆寫組態檔根層級所定義的目前設定 stderr
。 如果需要修改命令區塊內的參數,也必須指定 區塊。 例如,使用者可以將命令列中實驗的 變更 minibatchSize
為
cntk configFile=yourExp.cntk mnistTrain=[minibatchSize=256]
或修改用於實驗的資料檔案
cntk configFile=yourExp.cntk mnistTrain=[reader=[file="mynewfile.txt"]]
分層組態檔
除了使用命令列參數覆寫組態檔的某些部分,也可以指定多個組態檔,其中後者的檔案會覆寫先前的組態檔。 這可讓使用者擁有主要組態檔,然後在個別的組態檔中指定它們想要針對指定執行CNTK覆寫的主要參數。 這可藉由指定組態檔的 '+' 分隔清單,或使用 configFile=
標記多次來完成。 以下用法是相同的。
cntk configFile=yourExp1.cntk+yourExp2.cntk
cntk configFile=yourExp1.cntk configFile=yourExp2.cntk
如果 yourExp2.cntk
只包含字串 mnistTrain=[reader=[file=mynewfile.txt]]
,則這兩個命令都相當於:
cntk configFile=yourExp1.cntk mnistTrain=[reader=[file="mynewfile.txt"]]
請注意,變數的值一律取決於上次指派的值。 您也可以任意組合混合命令列參數和分層組態檔。 例如,
cntk configFile=yourExp1.cntk+yourExp2.cntk var1=value configFile=yourExp3.cntk
會依照命令列上出現的連續處理這些組態參數,以及最後指派的任何值都是使用的值。
除了能夠在命令列指定多個組態檔之外,使用者還可以在另一個組態檔中包含一個組態檔。 例如,如果 的第一行 yourExp2.cntk
是
include=yourExp1.cntk
然後直接執行
cntk configFile=yourExp2.cntk
相當於執行中
cntk configFile=yourExp1.cntk+yourExp2.cntk
在此後者的案例中, yourExp2.cntk
不包含 include 語句。 請注意,這些 include 語句可以出現在組態檔內的任何位置;不論 include 語句出現在何處,也就是將包含指定組態檔的位置。 包含組態檔相當於將該檔案的內容貼到 include 語句的位置。 Include 語句會以遞迴方式解析 (使用深度優先搜尋) ,這表示如果包含 和 ,則會解析完整鏈結,並 yourExpC.cntk
有效地包含在 中 yourExpA.cntk
。 yourExpC.cntk
yourExpB.cntk
yourExpB.cntk
yourExpA.cntk
如果組態檔包含多次 (例如,'A' 包含 'B' 和 'C',而 'B' 也包含 'C') ,則只會在第一次遇到組態檔時有效地包含它。
字串化變數
雖然分層組態檔可讓使用者在實驗之間重複使用組態檔,但這仍然是很麻煩的程式。 針對每個實驗,使用者可能必須覆寫數個參數,其中一些可能是長檔案路徑 (例如 、 stderr
、 modelPath
、 file
) 。 「stringize」 功能可讓此程式更容易。 它可讓使用者指定如下的設定:
command = SpeechTrain
stderr = "$Root$\$RunName$.log"
speechTrain = [
modelPath = "$Root$\$RunName$.cn"
SGD = [
reader = [
features = [
type = "real"
dim = "$DataSet1_Dim$"
file = "$DataSet1_Features$"
]
]
]
]
在這裡, Root
、 RunName
、 DataSet1_Dim
和 DataSet1_Features
是組態中其他位置所指定的變數 (範圍,可從) 使用範圍。 解譯此組態檔時,剖析器會將表單 $VarName$
的每個字串取代為字串 VarValue
,其中 VarValue
代表名為 VarName
的變數值。 變數解析程式是遞迴的;例如,如果 A=$B$、B=$C$和 C=HelloWorld.txt,則 A 會解析為 「HelloWorld.txt」。 請確定組態檔中沒有參考迴圈。 否則,剖析器此時會進入無限迴圈。
請注意,因為使用者相當於在組態檔和命令列中指定變數的值,所以可以在任一位置指定這些變數的值。 回想一下,變數的值取決於上次指派的時間、發生在組態檔或命令列上。 因此,如果在 Root
config1.txt 中定義,但在命令列上覆寫,則命令列中指定的值會是用來解析 configFile1.txt 中 實例 $Root$
的值。 其中一個實用的功能是,如果 stderr
或 modelPath
指向不存在的目錄,這些目錄將會由CNTK建立;這可讓您指定類似 stderr = $Root$\$RunName$\$RunName$.log
的內容,即使目錄 $Root$\$RunName$
不存在也一樣。
預設值、重複的值和批註
組態檔中的大部分參數都有預設值,如果未指定任何組態值,則會使用此值。 如果沒有預設值,而且搜尋中找不到值,則會顯示例外狀況,而且程式將會結束。 如果指定參數名稱一次以上,最後一個值會設定為該值,就是要維護的值。 唯一的例外狀況是在參數集中,這些參數集會以 [
方 ]
括弧括住,在這些情況下,大括弧內的值會被視為參數集,而且會新增至目前現有的參數集。 例如:
params=[a=1;b=2;c=3]
params=[c=5;d=6;e=7]
實際上等於:
params=[a=1;b=2;c=5;d=6;e=7]
請注意,這個附加處理不會用於陣列元素,而且如果設定多次,則會取代整個陣列。 #
字元表示批註的開頭,忽略 之後 #
所發生的所有內容。 #
前面必須加上空白字元,或位於行開頭,才能解譯為批註。 以下是有效的批註
stderr="c:\cntk\log\cntk" # "_mnistTrain_mnistTest.log"
以下是不會解譯為批註的值範例。 它會將 參數 var
設定為無限大, #
因為 中的 1#INF
不是註解標記
var=1#INF