Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
(Poznámka: Starší verze CNTK k tomuto účelu používaly "MEL" (jazyk pro úpravy modelů). Stále probíhá převod příkladů. Dokumentaci k MEL najdete v zde.)
CNTK umožňuje úpravy modelů po faktu. To se provádí vytvořením nového modelu při klonování (částí) existujícího modelu s použitými úpravami. CnTK poskytuje tři základní funkce:
-
BS.Network.Load()načtení existujícího modelu -
BS.Network.CloneFunction()k extrahování části existujícího modelu pro opakované použití -
BS.Network.Edit()klonování modelu s použitými úpravami uzlů po uzlu
Operace úprav není samostatným krokem. Místo toho by příkaz, který by měl pracovat s upraveným modelem, nezadá modelPath pro načtení modelu z, ale spíše BrainScriptNetworkBuilder oddíl, který načte model uvnitř a vytvoří nový model z načteného modelu za běhu.
Příklad: Diskriminativní předtrénování
Diskriminativní předtrénování je technika, kdy je hloubková síť vytvořena trénováním posloupnosti mělkowerních sítí. Začněte sítí vrstvy s 1 skrytou vrstvou, trénujte na částečnou konvergenci, pak odeberte výstupní vrstvu, přidejte novou skrytou vrstvu a přidejte novou výstupní vrstvu. Opakujte, dokud nedosáhnete požadovaného počtu skrytých vrstev.
Předpokládejme, že s velmi jednoduchým počátečním modelem
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’)
]
Vytrénujme tento model a uložme ho pod "model.1.dnn". Dále chceme vytrénovat model se dvěma skrytými vrstvami, kde se první skrytá vrstva inicializuje z hodnot natrénovaných výše. K tomu vytvoříme samostatnou trénovací akci, která vytvoří nový model, ale znovu používáme části předchozího modelu, a to následujícím způsobem:
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’)
}
První krok 1 používá Load() k načtení sítě do proměnné BrainScriptu. Síť se chová jako záznam BrainScriptu, kde jsou všechny uzly nejvyšší úrovně (všechny uzly, které neobsahují . nebo [ v jejich názvech uzlů), přístupné prostřednictvím syntaxe záznamů. Nová síť může odkazovat na libovolný uzel v načtené síti. V tomto příkladu načtená síť obsahuje uzel h1, což je výstup první skryté vrstvy, a uzel z, což je nenormalizovaná pravděpodobnost protokolu posteriorní pravděpodobnost výstupních tříd (vstup do funkce Softmax). K oběma uzlům lze přistupovat z BrainScriptu prostřednictvím syntaxe tečky, např. inModel.h1 a inModel.z.
Všimněte si, že konstanty nejsou uloženy v modelech, takže N ani M nejsou z modelu k dispozici. Je však možné je rekonstruovat z načteného modelu. Pro tento účel se výpočetní uzly chovají také jako záznamy BrainScriptu a zveřejňují dim vlastnost.
Dále krok 2 vytvoří zbytek nové sítě pomocí běžného BrainScriptu. Všimněte si, že tento nový oddíl jednoduše používá uzel h1 ze vstupního modelu jako vstup, jako by používal jakýkoli jiný uzel. Odkazování na uzel ze vstupní sítě automaticky vytvoří všechny uzly, které tento uzel závisí také na části nově vytvořené sítě. Vstupní uzel x se například automaticky stane součástí nové sítě.
Všimněte si také, že výstupní vrstva je vytvořena znovu. Tímto způsobem se parametry modelu vytvoří nově. (Pokud to nechcete udělat a místo toho znovu použít existující parametry, můžete použít inModel.Wout, ale mějte na paměti, že to nemá smysl z hlediska návrhu sítě v tomto konkrétním příkladu.)
Příklad: Použití předem natrénovaného modelu
Následuje příklad použití předem natrénovaného modelu (ze souboru "./featext.dnn") jako extraktoru funkcí:
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)
}
KROK 1 používá Load() k načtení sítě do proměnné BrainScriptu.
KROK 2 používá CloneFunction() ke klonování oddílu souvisejícího s extrakcí funkcí z načtené sítě, což je dílčí graf, který připojuje featExtNetwork.input k featExtNetwork.feat. Vzhledem k tomu, že jsme zadali parameters="constant", všechny parametry, na featExtNetwork.feat závisí, jsou také klonovány a provedeny jen pro čtení.
V kroku 3 a 4 je definována nová síť. To se provádí stejně jako jakýkoli jiný model BrainScriptu, jen když teď můžeme použít funkci featExt().
Problémy s názvy uzlů s .[ a ]
Chcete-li odkazovat na uzel v síti, která obsahuje . nebo [ nebo ], nahraďte tyto znaky _.
Například pokud network obsahuje uzel s názvem result.z, network.result.z selže; místo toho řekněte network.result_z.
Příklad: Úprava uzlů existující sítě
K úpravě vnitřních částí existující sítě by se síť skutečně naklonovala, zatímco úpravy se použijí jako součást procesu klonování. Toho dosáhne BS.Network.Edit().
Edit() iteruje přes všechny uzly sítě a nabídne každý uzel jeden po druhém funkci lambda předávané volajícím. Tyto funkce lambda pak můžou zkontrolovat uzel a buď vrátit nemodifikovaný uzel, nebo vrátit nový uzel na svém místě.
Edit() bude iterovat nad uzly v nezadaném pořadí. Pokud náhradní uzel odkazuje na síťový uzel, který se zase nahradil, Edit() jako poslední krok aktualizuje všechny tyto odkazy na příslušné nahrazení (neboli "udělat správnou věc").
ÚKOL: Příklad.
Další: úplný odkaz na funkci