(附注:舊版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.h1 和 inModel.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:範例。
下一步: 完整函式參考