共用方式為


透過命令列剖析規則的 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.cntkyourExpC.cntkyourExpB.cntkyourExpB.cntkyourExpA.cntk 如果組態檔包含多次 (例如,'A' 包含 'B' 和 'C',而 'B' 也包含 'C') ,則只會在第一次遇到組態檔時有效地包含它。

字串化變數

雖然分層組態檔可讓使用者在實驗之間重複使用組態檔,但這仍然是很麻煩的程式。 針對每個實驗,使用者可能必須覆寫數個參數,其中一些可能是長檔案路徑 (例如 、 stderrmodelPathfile) 。 「stringize」 功能可讓此程式更容易。 它可讓使用者指定如下的設定:

command = SpeechTrain
stderr = "$Root$\$RunName$.log"
speechTrain = [
    modelPath = "$Root$\$RunName$.cn"
    SGD = [
        reader = [
            features = [
                type = "real"
                dim = "$DataSet1_Dim$"
                file = "$DataSet1_Features$"
            ]
        ]
    ]
]

在這裡, RootRunNameDataSet1_DimDataSet1_Features 是組態中其他位置所指定的變數 (範圍,可從) 使用範圍。 解譯此組態檔時,剖析器會將表單 $VarName$ 的每個字串取代為字串 VarValue ,其中 VarValue 代表名為 VarName 的變數值。 變數解析程式是遞迴的;例如,如果 A=$B$、B=$C$和 C=HelloWorld.txt,則 A 會解析為 「HelloWorld.txt」。 請確定組態檔中沒有參考迴圈。 否則,剖析器此時會進入無限迴圈。

請注意,因為使用者相當於在組態檔和命令列中指定變數的值,所以可以在任一位置指定這些變數的值。 回想一下,變數的值取決於上次指派的時間、發生在組態檔或命令列上。 因此,如果在 Root config1.txt 中定義,但在命令列上覆寫,則命令列中指定的值會是用來解析 configFile1.txt 中 實例 $Root$ 的值。 其中一個實用的功能是,如果 stderrmodelPath 指向不存在的目錄,這些目錄將會由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