共用方式為


使用 BrainScript 進行模型編輯

(附注:舊版CNTK針對此目的使用 「MEL」 (模型編輯語言) 。 我們仍在轉換範例的過程中。 如需 MEL 的檔,請參閱 這裡。)

CNTK允許在事實之後編輯模型。 這是藉由在複製已套用修改) 現有模型的 (部分時,建立新的模型來完成。 為此,CNTK提供三個基本函式:

  • BS.Network.Load() 載入現有的模型
  • BS.Network.CloneFunction() 以擷取現有模型的區段以供重複使用
  • BS.Network.Edit() 表示複製已套用節點逐節點修改的模型

編輯作業不是個別的步驟。 相反地,應該關閉修改模型的命令不會指定要 modelPath 載入模型的 ,而是一個 BrainScriptNetworkBuilder 區段,它會在內部載入模型,並從即時載入的模型建構新的模型。

範例:離散預先定型

辨別預先定型是一種技術,其中深層網路是藉由定型一連串淺層網路所建立的技術。 從 1 隱藏層網路開始,訓練至部分聚合,然後移除輸出層、新增隱藏層,以及新增輸出層。 重複執行,直到達到所需的隱藏層數目為止。

讓我們假設使用非常簡單的起始模型

BrainScriptNetworkBuilder = [
    N = 40; M = 9000; H = 512
    W1   = Parameter (H, N); b1   = Parameter (H)
    Wout = Parameter (M, H); bout = Parameter (M)
    x = Input (N, tag=‘feature’) ; labels = Input (M, tag=‘labels’)
    h1 = Sigmoid (W1 * x  + b1)
    z  = Wout * h1 + bout
    ce = CrossEntropyWithSoftmax (labels, z, tag=‘criterion’)
]

讓我們定型此模型,並儲存在 「model.1.dnn」 底下。 接下來,我們想要使用兩個隱藏層來定型模型,其中第一個隱藏層是從上面定型的值初始化。 若要這樣做,我們會建立個別的定型動作來建立新的模型,但重複使用前一個模型的部分,如下所示:

BrainScriptNetworkBuilder = {
    # STEP 1: load 1-hidden-layer model
    inModel = BS.Network.Load ("model.1.dnn")
    # get its h1 variable --and also recover its dimension
    h1 = inModel.h1
    H = h1.dim
    # also recover the number of output classes
    M = inModel.z.dim

    # STEP 2: create the rest of the extended network as usual
    W2   = Parameter (H, H); b2   = Parameter (H)
    Wout = Parameter (M, H); bout = Parameter (M)
    h2 = Sigmoid (W2 * h1  + b2)
    z  = Wout * h2 + bout
    ce = CrossEntropyWithSoftmax (labels, z, tag=‘criterion’)
}

首先,步驟 1 會使用 Load() 將網路載入 BrainScript 變數。 網路的行為就像 BrainScript 記錄,其中所有最上層節點 (所有不包含 .[ 的節點名稱,) 可透過記錄語法存取。 新的網路可以參考已載入網路中的任何節點。 在此範例中,載入的網路包含節點,這是第一個 h1 隱藏層的輸出,而 z 節點是輸出類別的未正規化記錄海報機率, (Softmax 函式的輸入) 。 這兩個節點都可以透過點語法從 BrainScript 存取,例如 inModel.h1inModel.z

請注意,常數不會儲存在模型中,因此也無法 NM 從模型取得。 不過,您可以從載入的模型重新建構它們。 為此,計算節點的行為也會像 BrainScript 記錄一樣,並公開 dim 屬性。

接下來,步驟 2 會使用一般 BrainScript 來建構新網路的其餘部分。 請注意,這個新區段只會使用輸入模型中的節點 h1 作為輸入,就像使用任何其他節點一樣。 從輸入網路參考節點會自動讓此節點相依于新建立網路的所有節點。 例如,輸入節點 x 會自動成為新網路的一部分。

另請注意,輸出層會重新建構。 如此一來,其模型參數就會重新建立。 (若要不要這麼做,而是重複使用現有的參數, inModel.Wout 但請注意,在此特定範例中,從網路設計觀點而言並不合理。)

範例:使用預先定型的模型

以下是從檔案 "./featext.dnn") 做為特徵擷取器使用預先定型模型 (的範例:

BrainScriptNetworkBuilder = {
    # STEP 1: load existing model
    featExtNetwork = BS.Network.Load ("./featext.dnn")

    # STEP 2: extract a read-only section that is the feature extractor function
    featExt = BS.Network.CloneFunction (
                  featExtNetwork.input,    # input node that AE model read data from
                  featExtNetwork.feat,     # output node in AE model that holds the desired features
                  parameters="constant")   # says to freeze that part of the network

    # STEP 3: define the part of your network that uses the feature extractor
    # from the loaded model, which above we isolated into featExt().
    # featExt() can be used like any old BrainScript function.
    input = Input (...)
    features = featExt (input)  # this will instantiate a clone of the above network

    # STEP 4: and add the remaining bits of the network in BrainScript, e.g.
    h = Sigmoid (W_hid * features + b_hid) # whatever your hidden layer looks like
    z = W_out * h + b_out
    ce = CrossEntropyWithSoftmax (labels, z)
    criterionNodes = (ce)
}

步驟 1 會使用 Load() 將網路載入 BrainScript 變數。

步驟 2 會使用 CloneFunction() 從載入的網路複製功能擷取相關區段,這是連接到 featExtNetwork.inputfeatExtNetwork.feat 的子圖形。 因為我們指定 parameters="constant" 了 ,所以所有相依的參數 featExtNetwork.feat 也會複製並變成隻讀。

在步驟 3 和 4 中,會定義新的網路。 這就像任何其他 BrainScript 模型一樣完成,只有現在我們可以使用 函 featExt() 式來執行此動作。

具有 .[ 和 的節點名稱問題]

若要參考網路中包含 .[] 的節點,請將這些字元取代為 _ 。 例如,如果 network 包含名為 的 result.z 節點, network.result.z 將會失敗;請改為說 network.result_z

範例:修改現有網路的節點

若要修改現有網路的內部部分,實際上會複製網路,而修改則會套用為複製程式的一部分。 這是由 BS.Network.Edit() 完成。 Edit() 會逐一查看網路的所有節點,並將每個節點逐一提供給呼叫端所傳遞的 Lambda 函式。 然後,這些 Lambda 函式可以檢查節點,並傳回未修改的節點,或傳回新的節點。 Edit() 會依未指定的順序逐一查看節點。 如果取代節點參考已取代的網路節點, Edit() 將會更新個別取代的所有這類參考, (也稱為「執行正確的事」) 。

TODO:範例。

下一步: 完整函式參考