Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Sieci niestandardowe są opisane w niestandardowym języku opisu sieci CNTK "BrainScript". Aby zdefiniować sieć niestandardową, dołącz sekcję o nazwie BrainScriptNetworkBuilder w konfiguracji trenowania. Szczegółowy opis języka opisu sieci można znaleźć na stronie Podstawowe pojęcia i odpowiednie podstrony.
Istnieją dwie formy korzystania z konstruktora sieci BrainScript, jeden z nawiasami (...)i krótką formę przy użyciu nawiasów klamrowych {...}. Aby opisać sieć w pliku zewnętrznym, określ blok podobny do następującego:
BrainScriptNetworkBuilder = (new ComputationNetwork {
include "yourNetwork.bs"
})
gdzie yourNetwork.bs zawiera sieć opisaną przy użyciu języka BrainScript. Plik yourNetwork.bs jest szukany jako pierwszy w tym samym katalogu co plik konfiguracji, a jeśli nie zostanie znaleziony, w katalogu pliku wykonywalnego CNTK. Nazwy ścieżek bezwzględnych i względnych są akceptowane tutaj. Np. bs/yourNetwork.bs oznacza plik znajdujący się w katalogu bs obok pliku konfiguracji (lub alternatywnie katalog wewnątrz katalogu bs wykonywalnego CNTK).
Uwaga: do wersji CNTK 1.6 język BrainScript używał nawiasów klamrowych zamiast nawiasów [...] klamrowych {...}. Nawiasy są nadal akceptowane, ale przestarzałe.
Alternatywnie możesz zdefiniować sieć w tekście bezpośrednio w pliku konfiguracji. Może to uprościć konfigurację, jeśli nie planujesz współużytkowania tego samego skryptu mózgu w wielu konfiguracjach. Użyj tego formularza:
BrainScriptNetworkBuilder = {
# insert network description here
}
Więc jak wygląda kod BrainScript, który przechodzi do nawiasów? Aby dowiedzieć się, przejdź bezpośrednio do podstaw brainscript podstawowych pojęć.
Możesz też pozostać na tej stronie i przeczytać na temat niektórych rzadziej potrzebnych szczegółów.
Powyższy {...} formularz jest naprawdę tylko krótką ręką dla tego:
BrainScriptNetworkBuilder = (new ComputationNetwork {
# insert network description here
})
Na koniec, jako zaawansowane użycie, (...) formularz nie jest ograniczony do użycia new. Zamiast tego każde wyrażenie BrainScript, które oblicza obiekt, ComputationNetwork jest dozwolone wewnątrz nawiasów. Na przykład:
BrainScriptNetworkBuilder = ({
include "myNetworks.bs"
network = CreateMyNetworkOfType42()
}.network)
Jest to zaawansowane użycie, które czasami występuje również w kontekście edycji modelu.
Dalej: Podstawowe pojęcia dotyczące języka BrainScript.
Starszych NDLNetworkBuilder
W starszych wersjach CNTK konstruktor sieci został nazwany NDLNetworkBuilder. Jego język definicji jest podzbiorem BrainScript. Stary analizator był mniej zdolny, ale również bardziej forgiving. Istnieją również inne małe różnice.
NDLNetworkBuilder jest teraz przestarzały, ale ze względu na podobieństwo nie jest trudno uaktualnić do BrainScriptNetworkBuilderklasy . Poniżej przedstawiono przewodnik dotyczący konwertowania NDLNetworkBuilder opisów sieci na BrainScriptNetworkBuilder's).
Aktualizowanie z NDLNetworkBuilder do BrainScriptNetworkBuilder
Konwertowanie istniejącej definicji sieci dla elementu NDLNetworkBuilder to BrainScriptNetworkBuilder jest proste w większości przypadków. Główne zmiany to otaczająca składnia. Sam opis sieci podstawowej jest w dużej mierze zgodny w górę i prawdopodobnie identyczny lub niemal identyczny, jeśli nie korzystasz z nowych funkcji językowych.
Aby przekonwertować opisy, należy przełączyć konstruktora sieci, dostosować składnię zewnętrzną w.r.t. i ewentualnie wprowadzić drobne dostosowania do samego kodu sieciowego.
Krok 1. Przełączanie konstruktora sieci. NDLNetworkBuilder Zastąp element odpowiednim BrainScriptNetworkBuilder blokiem w pliku konfiguracji CNTK. Jeśli opis sieci znajduje się w osobnym pliku:
# change from:
NDLNetworkBuilder = [
ndlMacros = "shared.ndl" # (if any)
networkDescription = "yourNetwork.ndl"
]
# ...to:
BrainScriptNetworkBuilder = (new ComputationNetwork {
include "shared.bs" # (if any)
include "yourNetwork.bs"
})
(Zmiana rozszerzenia nazwy pliku nie jest ściśle konieczna, ale zalecana).
Jeśli opis sieci znajduje się w .cntk samym pliku konfiguracji:
# change from:
NDLNetworkBuilder = [
# macros
load = [
SigmoidNetwork (x, W, b) = Sigmoid (Plus (Times (W, x), b))
]
# network description
run = [
feat = Input (13)
...
ce = CrossEntropyWithSoftmax (labels, z, tag="criterion")
]
]
# ...to:
BrainScriptNetworkBuilder = {
# macros are just defined inline
SigmoidNetwork (x, W, b) = Sigmoid (Plus (Times (W, x), b)) # or: Sigmoid (W * x + b)
# network description
feat = Input {13}
...
ce = CrossEntropyWithSoftmax (labels, z, tag="criterion")
}
Krok 2. Usuń load i run bloki. W programie BrainScriptNetworkBuildersą łączone definicje makr/funkcji i kod główny. Bloki load i run muszą zostać po prostu usunięte. Na przykład:
load = ndlMnistMacros
run = DNN
ndlMnistMacros = [
featDim = 784
...
labels = InputValue(labelDim)
]
DNN = [
hiddenDim = 200
...
outputNodes = (ol)
]
po prostu staje się:
featDim = 784
...
labels = InputValue(labelDim)
hiddenDim = 200
...
outputNodes = (ol)
Być może użyto zmiennej run do wybrania jednej z wielu konfiguracji ze zmienną zewnętrzną, np.:
NDLNetworkBuilder = [
run = $whichModel$ # outside parameter selects model, must be either "model1" or "model2"
model1 = [ ... (MODEL 1 DEFINITION) ]
model2 = [ ... (MODEL 1 DEFINITION) ]
]
Ten wzorzec był głównie niezbędny, ponieważ NDL nie ma wyrażeń warunkowych. W języku BrainScript zostanie to teraz napisane za if pomocą wyrażenia:
BrainScriptNetworkBuilder = (new ComputationNetwork
if "$whichModel$" == "model1" then { ... (MODEL 1 DEFINITION) }
else if "$whichModel$" == "model2" then { ... (MODEL 2 DEFINITION) }
else Fail ("Invalid model selector value '$whichModel$'")
)
Jednak często wybrane modele są bardzo podobne, więc lepszym sposobem byłoby scalenie ich opisów i zamiast tego użycie warunkowych w obrębie tylko tam, gdzie się różnią. Oto przykład, w którym parametr jest używany do wyboru między jednokierunkowym i dwukierunkowym LSTM:
encoderFunction =
if useBidirectionalEncoder
then BS.RNNs.RecurrentBirectionalLSTMPStack
else BS.RNNs.RecurrentLSTMPStack
encoder = encoderFunction (encoderDims, inputEmbedded, inputDim=inputEmbeddingDim)
Krok 3. Dostosowywanie opisu sieci. Jeśli chodzi o sam opis sieci (formuły), BrainScript jest w dużej mierze w górę zgodny z NDL. Są to główne różnice:
Zwracana wartość makr (funkcji) nie jest już ostatnią zmienną zdefiniowaną w nich, ale cały zestaw zmiennych. Musisz jawnie wybrać wartość wyjściową na końcu. Na przykład:
# NDL: f(x) = [ x2 = Times (x, x) y = Plus (x2, Constant (1)) ] # <-- return value defaults to last entry, i.e. y # BrainScript: f(x) = { x2 = x*x y = x2 + 1 }.y # <-- return value y must be explicitly dereferencedBez tej zmiany zwracana wartość funkcji będzie całym rekordem, a typowy błąd, który zostanie wyświetlony, jest to, że
ComputationNodeoczekiwano miejsca znalezienia elementuComputationNetwork.Język BrainScript nie zezwala na funkcje ze zmiennymi liczbami parametrów. Ma to znaczenie przede wszystkim dla
Parameter()funkcji: Parametr wektora nie może być już zapisywany jakoParameter(N), teraz musi być jawnie zapisany jako tensorParameterTensor{N}lub macierzParameter(N, 1)1-kolumnowa . Bez tej zmiany zostanie wyświetlony błąd dotyczący niezgodności liczby parametrów pozycyjnych. Ta notacja działa również z językiem NDL, aby można było najpierw wprowadzić tę zmianę i przetestować ją przy użyciu języka NDL przed przekonwertowaniem. Jest to również dobra okazja do zmiany nazwy wszystkich zastosowań starszej nazwyLearnableParameter()naParameterTensor{}.Ma to również znaczenie dla
RowStack()funkcji, która w języku BrainScript przyjmuje pojedynczy parametr, który jest tablicą danych wejściowych. Dane wejściowe muszą być rozdzielone dwukropkiem (:) zamiast przecinka, np.RowStack (a:b:c)zamiastRowStack (a, b, c).Niektóre wartości domyślne zostały zaktualizowane, przede wszystkim opcjonalny
imageLayoutparametrConvolution()operacji puli iImageInput(). W przypadku języka NDL te domyślne wartościlegacyto , natomiast teraz wartość domyślna jestcudnnwymagana do zgodności z elementami pierwotnymi cuDNN. (Wszystkie przykłady kodu NDL jawnie określają ten parametr jakocudnnjuż).Analizator BrainScript jest bardziej restrykcyjny:
Identyfikatory są teraz uwzględniane wielkość liter. Wbudowane funkcje używają funkcji PascalCase (np.
RectifiedLinear()), a wbudowane zmienne i nazwy parametrów używają camelCase (np.modelPath,criterionNodes), jak do ciągów opcji (init="fixedValue",tag="criterion"). Należy pamiętać, że w przypadku nazw parametrów opcjonalnych nieprawidłowe pisownie nie zawsze są przechwytywane jako błąd. Zamiast tego niektóre niepoprawnie napisane parametry opcjonalne są po prostu ignorowane. Przykładem są definicje "węzłów specjalnych". Ich poprawne pisownia dla tych jest teraz:featureNodes = ... labelNodes = ... criterionNodes = ... evaluationNodes = ... outputNodes = ...Skrócone nazwy alternatywne nie są już dozwolone, takie jak
Const()powinna być , powinna byćtag="evaluation"Constant(),tag="eval"ievalNodesjest terazevaluationNodes.Poprawiono niektóre nieprawidłowe nazwy:
criteriajest terazcriterion(podobniecriterionNodes),defaultHiddenActivityjest terazdefaultHiddenActivation.Znak
=nie jest już opcjonalny dla definicji funkcji.Chociaż może używać nawiasów dla bloków (
[ ... ]), jest przestarzały. Użyj nawiasów klamrowych ({ ... }).Etykiety opcji muszą być cytowane jako ciągi, np.
init="uniform"zamiastinit=uniform. Bez cudzysłowów kod BrainScript zakończy się niepowodzeniem z komunikatem o błędzie informującym, że symboluniformjest nieznany.Typy pierwotne BrainScript, które tworzą parametry (
Input{}iParameterTensor{}), powinny używać nawiasów klamrowych dla argumentów (np.f = Input{42}). Jest to konwencja, która nie jest wymuszana, ale zalecana w przyszłości.
Ta bardziej ograniczona składnia jest nadal akceptowana przez
NDLNetworkBuilderprogram , dlatego zalecamy najpierw wprowadzenie tych zmian syntatycznych i przetestowanie ich za pomocą języka NDL, zanim rzeczywiście zmieni się na BrainScript.
Krok 4. Usuń NDLNetworkBuilder z sekcji "write" i "test". Przejrzyj sekcje "write" i "test" w NDLNetworkBuilder sekcjach i usuń je. Niektóre z naszych stockowych przykładów NDL mają dodatkowe NDLNetworkBuilder sekcje. Nie są używane i nie powinny być tam. Jeśli konfiguracja jest oparta na jednym z tych przykładów, możesz również mieć takie sekcje. Kiedyś były ignorowane, ale w przypadku aktualizacji BrainScript zdefiniowanie nowej sieci w tych sekcjach ma teraz znaczenie (edytowanie modelu), więc nie są już ignorowane i dlatego należy je usunąć.
NDLNetworkBuilder reference (przestarzałe)
Składnia przestarzałego NDLNetworkBuilder elementu to:
NDLNetworkBuilder = [
networkDescription = "yourNetwork.ndl"
]
Blok NDLNetworkBuilder ma następujące parametry:
networkDescription: ścieżka pliku opisu sieci. W przypadku przestarzałejNDLNetworkBuilderwersji niestandardowej było użycie rozszerzenia.ndlpliku . Jeśli nienetworkDescriptionokreślono parametru, zakłada się, że opis sieci zostanie podkreślony w tym samymNDLNetworkBuilderpodbloku, określony za pomocą poniższego parametrurun. Należy pamiętać, że za pomocą parametru można określić tylko jedną ścieżkęnetworkDescriptionpliku. Aby załadować wiele plików makr, użyj parametrundlMacros.run: blok NDL, który zostanie wykonany. Jeśli zewnętrzny plik NDL jest określony za pośrednictwem parametrunetworkDescription,runparametr identyfikuje blok w tym pliku. Ten parametr zastępuje wszystkierunparametry, które mogą już istnieć w pliku. Jeśli nienetworkDescriptionokreślono pliku,runparametr identyfikuje blok w bieżącym pliku konfiguracji.load: bloki skryptów NDL do załadowania. Wiele bloków można określić za pośrednictwem listy rozdzielonej ciągiem ":". Bloki określone przezloadparametr zwykle zawierają makra do użycia przezrunblok. Podobnie jak w przypadku parametrurun,loadparametr identyfikuje bloki w zewnętrznym pliku NDL i zastępuje wszystkieloadparametry, które mogą już istnieć w pliku, jeśli plik jest określony przeznetworkDescriptionparametr . Jeśli nienetworkDescriptionokreślono pliku,loadidentyfikuje blok w bieżącym pliku konfiguracji.ndlMacros: ścieżka pliku, w której można załadować makra NDL. Ten parametr jest zwykle używany do ładowania domyślnego zestawu makr NDL, które mogą być używane przez wszystkie skrypty NDL. Wiele plików NDL, z których każdy określa różne zestawy makr, można załadować, określając rozdzielaną listę ścieżek plików "+" dla tegondlMacrosparametru. Aby udostępnić makra innym blokom poleceń, takim jak bloki języka edycji modelu NDL (MEL), należy zdefiniować je na poziomie głównym pliku konfiguracji.randomSeedOffset: wartość przesunięcia inicjującego losowe inicjowanie parametrów możliwych do nauki. Wartość domyślna to0. Dzięki temu użytkownicy mogą uruchamiać eksperymenty z inną losową inicjacją.