Jak mogę trenowanie modeli w języku BrainScript
- Czy przeprowadzić trenowanie warstwowe?
- Trenowanie z celem wielotaskowym?
- Trenowanie modelu regresji na obrazach?
- Trenowanie klasyfikatora wieloznakowego?
- Rozpoczynanie sekwencji modelowania?
- Wytrenuj model DSSM (lub konwolucyjny-DSSM)?
- Trenowanie automatycznego kodera obrazu przy użyciu deconvolution i unpooling?
- Wykrywanie obiektów za pomocą szybkiej sieci R-CNN?
Trenowanie warstwowe
Aby przeprowadzić trenowanie w warstwie, wystarczy użyć wielu "poleceń" w pliku konfiguracji, gdzie każde polecenie jest typu action=train.
command = TrainLayer1:TrainLayer2:TrainLayer3:EndToEndTrain:Test:Output
TrainLayer1= [
action = train
...
]
TrainLayer2= [
action = train
...
]
...
Trenowanie za pomocą celu wielotaskowego
Możesz po prostu zdefiniować połączone kryterium jako wyrażenie BrainScript i monitorować wszystkie straty poszczególnych zadań, określając je jako evaluationNodes
.
task1loss = CrossEntropyWithSoftMax(prediction,label)
task2loss = SquareError(reconstruction,input)
mtloss = task1loss + Constant(0.3) .* task2loss
criterionNodes = (mtloss)
evaluationNodes = (task1loss:task2loss)
Trenowanie modelu regresji na obrazach
Poniżej opisano sposób przewidywania co najmniej jednej wartości zmiennoprzecinkowej dla obrazu wejściowego przy użyciu zestawu CNTK. Przykładem przypadku użycia jest przewidywanie pola ograniczenia, na przykład (x, y, w, h) obiektu na danym obrazie. Można również myśleć o przewidywaniu ceny samochodu, patrząc na obraz tego samochodu (byłoby interesujące w rzeczywistości). W tym miejscu używamy bardzo prostego przykładu, w którym trenujemy sieć do przewidywania średnich wartości RGB obrazu (znormalizowanych do [0, 1]). Jednak te same kroki dotyczą innych przypadków użycia. Te kroki są następujące:
- Definiowanie zarówno obrazu, jak i etykiet regresji prawdy podstawowej jako danych wejściowych w sieci
- Definiowanie sieci, która przewiduje zgodną liczbę wartości w.r.t. etykiet regresji
- Definiowanie funkcji straty, która porównuje przewidywane wartości z prawem podstawy
- Dostosuj sekcję czytelnika w pliku konfiguracji .cntk, aby odczytywać etykiety obrazów i regresji
Oto jak można to zrobić. Pełny plik konfiguracji znajduje się w folderze Examples (Przykłady) w folderze Examples/Image/Regression/RegrSimple_CIFAR10.cntk. Ten folder zawiera również skrypty umożliwiające pobranie danych obrazu i wygenerowanie podstawowej prawdy o regresji na potrzeby trenowania i testowania.
1–3) Definiowanie danych wejściowych, funkcji sieci i utraty:
BrainScriptNetworkBuilder = [
imageShape = 32:32:3
featScale = Constant(1/256)
labelDim = 3
model (features) = {
featNorm = Scale(features, featScale)
h1 = LinearLayer {100, init="gaussian", initValueScale=1.5} (featNorm)
ol = LinearLayer {labelDim, init="gaussian", initValueScale=1.5} (h1)
}.ol
# inputs
features = Input {imageShape}
regrLabels = Input {labelDim}
# apply model to features
ol = model (features)
# define regression loss
# rmse = sqrt(SquareError(regrLabels, ol) / labelDim)
sqerr = SquareError (regrLabels, ol)
rmse = Sqrt (Constant(1/labelDim).* sqerr)
featureNodes = (features)
labelNodes = (regrLabels)
criterionNodes = (rmse)
evaluationNodes = (rmse)
OutputNodes = (ol)
]
- Definiowanie czytnika złożonego przy użyciu elementów ImageReader i CNTKTextFormatReader:
reader = {
verbosity = 0 ; randomize = true
deserializers = ({
type = "ImageDeserializer" ; module = "ImageReader"
file = "$dataDir$/cifar-10-batches-py/train_map.txt"
input = {
features = { transforms = (
{ type = "Scale" ; width = 32 ; height = 32 ; channels = 3 ; interpolations = "linear" } :
{ type = "Transpose" }
)}
ignored = { labelDim = 10 }
}
} : {
type = "CNTKTextFormatDeserializer" ; module = "CNTKTextFormatReader"
file = "$dataDir$/cifar-10-batches-py/train_regrLabels.txt"
input = {
regrLabels = { dim = 3 ; format = "dense" }
}
})
}
Czytnik jest czytnikiem złożonym, który używa elementu ImageReader do odczytywania obrazów i klasy CNTKTextFormatReader w celu odczytywania etykiet prawdy podstaw regresji. Robi to przez zdefiniowanie tablicy deserializatorów (przy użyciu ) {...} : {...}
i przypisanie danych wejściowych zgodnie z definicją w powyższej sieci (cf. features and regrLabels).
Zobacz Przykłady/Obraz/Różne/CIFAR-10/06_RegressionSimple.cntk , aby uzyskać pełny plik konfiguracji i odpowiedni plik Readme w tym folderze, aby uruchomić przykład.
Trenowanie klasyfikatora wieloznakowego
W przypadku klasyfikacji wieloebelowej należy unikać używania crossentropy, ponieważ może obsługiwać tylko wektory wejściowe, które sumuje się do 1. Rozsądną alternatywą jest użycie sumy funkcji strat logistycznych, po jednym dla każdego wyjścia
...
probabilities = DenseLayer {outputSize, activation=Sigmoid} (hidden)
logisticLoss = Logistic (multiLabels, probabilities)
trainingCriterion = (logisticLoss)
...
Oprócz samej utraty możesz monitorować inne metryki, takie jak liczba nieprawidłowych przewidywań. Dla tego wyrażenia nie ma wbudowanego wyrażenia, ale można je wyrazić jako
...
hammingLoss (y, p) = ReduceSum (y != (p > 0.5))
hl = hammingLoss(multiLabels,probabilities)
evaluationNodes = (hl)
...
To zlicza liczbę razy y[i] nie zgadza się z p[i]>0,5.
Wprowadzenie do modelowania sekwencji
W tym praktycznym laboratorium opisano główne składniki umożliwiające rozpoczęcie przetwarzania sekwencji, takie jak format tekstu CNTK, oraz sposób konfigurowania czytnika pod kątem używania krótkich aliasów dla różnych sekwencji wejściowych. Przykład grapheme-to-phoneme (G2P) przedstawia rzeczywiste zadanie sekwencyjne-sekwencyjne.
Ważnym problemem w przypadku modelowania sekwencyjnego jest sposób dekodowania danych testowych za pomocą funkcji wyszukiwania wiązki. Można to zrobić za pomocą polecenia w sekcji konfiguracji, w której akcja najwyższego poziomu to "write". Dekodowanie wymaga wyszukiwania najbardziej prawdopodobnej sekwencji danych wyjściowych. CNTK ma dekoder wyszukiwania wiązki , podczas gdy można wywołać w ten sposób
BrainScriptNetworkBuilder = (BS.Seq2Seq.BeamSearchSequenceDecoderFrom (
BS.Network.Load (decodeModelPath), beamSize))
i będzie wykonywać wyszukiwanie wiązki o określonym rozmiarze wiązki. W przypadku belki o rozmiarze 1 istnieje wyspecjalizowany chciwy dekoder
BrainScriptNetworkBuilder = (BS.Seq2Seq.GreedySequenceDecoderFrom (
BS.Network.Load (decodeModelPath)))
Oba dekodatory mają określone wymagania dotyczące sieci, jak pokazano w przykładzie G2P
Trenowanie modelu DSSM (lub konwolucyjnego dsSM)
DSSM (lub Model podobieństwa semantycznego głębokiego) to model nazwy rozproszonej wyszkolony na parach tekstów źródłowych docelowych na potrzeby uczenia się przestrzeni osadzania krótkiego tekstu, gdzie odpowiednie pary źródłowe i docelowe są bliżej. Wprowadzanie tekstu do modelu jest reprezentowane przez wstępnie obliczony skrót trigramów (zobacz, Huang et al.). W przypadku C-DSSM skrót trigramu jest obliczany na słowo, a następnie połączony w kolejności, w której wyrazy występują w tekście. Dane wejściowe obu modeli mają stały rozmiar. Jeśli rozważymy 50 000 trigramów, dane wejściowe DSSM odpowiadające źródle i tekst docelowy będzie wektorem długości 50K każdy. W przypadku C-DSSM wektor ma długość 50 000 x n, gdzie pierwsze wektory wyrazów n-1 są łączone, a wektor n-ty zawiera sumę wektorów odpowiadających wszystkim pozostałym wyrazom w tekście. Jeśli tekst zawiera mniej niż n wyrazów, reszta wektora jest dopełniona zerami. Aby narysować analogię do obrazu, można traktować wprowadzanie tekstu dla maszyny C-DSSM jako obraz o wymiarach 10x1 i 50K przechowywanych w [C x H x W]
formacie.
W tym przykładzie pokazano, jak wytrenować model DSSM/C-DSSM przy użyciu klasy CNTKTextFormatReader. Dane powinny zawierać 2 funkcje (tekst źródłowy i docelowy) oraz 1 etykietę (która jest zawsze ustawiona na wartość 1 w danych treningowych, ponieważ zawiera tylko dodatnie próbki — podczas trenowania ujemne przykłady docelowe są generowane przez losowe próbkowanie). Oto konfiguracja czytnika
reader = {
verbosity = 0
randomize = true
deserializers = ({
type = "CNTKTextFormatDeserializer"
module = "CNTKTextFormatReader"
file = "data.txt"
input = {
Q = { dim = 500000; format = "sparse" }
D = { dim = 500000; format = "sparse" }
L = { dim = 1; format = "dense" }
}
})
}
Próbka danych wejściowych,
|L 1 |Q 482:1 761:1 1832:1 2117:1 12370:1 17131:1 17854:1 24976:1 27676:1 28055:1 28177:1 29507:1|D 482:1 761:1 1832:1 2117:1 12370:1 17131:1 17854:1 24976:1 27676:1 28055:1 28177:1 29507:1
|L 1 |Q 149:1 153:1 595:1 671:1 675:1 1110:1 1517:1 2077:1 2114:1 5533:1 5662:1 6886:1 6901:1 7294:1 12846:1 13033:1 16614:1 19425:1 22015:1 24839:1 24994:1 26196:1 26358:1 27565:1|D 149:1 153:1 595:1 671:1 675:1 1110:1 1517:1 2077:1 2114:1 5533:1 5662:1 6886:1 6901:1 7294:1 12846:1 13033:1 16614:1 19425:1 22015:1 24839:1 24994:1 26196:1 26358:1 27565:1
|L 1 |Q 187:1 2294:1 2800:1 6920:1|D 187:1 2294:1 2800:1 6920:1
I wreszcie definicja sieci,
BrainScriptNetworkBuilder = {
# Constants scalars
isConvolutional = true
numWords = (if isConvolutional then 10 else 1)
numTrigramsPerWord = 50000
numHiddenNodes = 300
wordWindowSize = 3
numWindows = numWords - wordWindowSize + 1
numNeg = 50
# Constant tensors
CONST_GAMMA = Constant(10)
CONST_SHIFT = Constant(1)
CONST_NEG = Constant(numNeg)
CONST_PAD_NEG = Constant(0, rows=numNeg, cols=1)
CONST_PAD_POS = Constant(1, rows=1, cols=1)
CONST_PAD = Splice(CONST_PAD_POS : CONST_PAD_NEG, axis=1)
# Inputs
Q = Input(500000)
D = Input(500000)
L = Input(1)
qr = if isConvolutional
then TransposeDimensions(ReshapeDimension(Q, 1, numTrigramsPerWord:1:numWords), 1, 3)
else Slice(0, numTrigramsPerWord, Q, axis=1)
dr = if isConvolutional
then TransposeDimensions(ReshapeDimension(D, 1, numTrigramsPerWord:1:numWords), 1, 3)
else Slice(0, numTrigramsPerWord, D, axis=1)
qdssm = Sequential (
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh})
qcdssm = Sequential (
ConvolutionalLayer {numHiddenNodes, (wordWindowSize:1), pad=false, activation=Tanh} :
MaxPoolingLayer {(numWindows:1), stride=(1:1)} :
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh})
ddssm = Sequential (
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh})
dcdssm = Sequential (
ConvolutionalLayer {numHiddenNodes, (wordWindowSize:1), pad=false, activation=Tanh} :
MaxPoolingLayer {(numWindows:1), stride=(1:1)} :
DenseLayer {numHiddenNodes, activation=Tanh} :
DenseLayer {numHiddenNodes, activation=Tanh})
qembed = if isConvolutional
then qcdssm
else qdssm
dembed = if isConvolutional
then dcdssm
else ddssm
qf = qembed(qr)
df = dembed(dr)
lf = Times(CONST_PAD, L)
c = CosDistanceWithNegativeSamples(qf, df, CONST_SHIFT, CONST_NEG)
s = Slice(0, 1, c, axis=1, tag="output")
ce = CrossEntropyWithSoftmax(lf, Scale(CONST_GAMMA, c), tag="criterion")
}
Uwaga:
- Podczas gdy C-DSSM wykazano, że konsekwentnie działa lepiej niż DSSM, również trenuje wolniej (czasami do 5-10x wolniejsze). Dlatego w niektórych przypadkach można uzyskać lepszą wydajność z dsSM w tym samym czasie trenowania przez trenowanie większej ilości danych (lub w przypadku większej liczby epok).
- Oryginalne maszyny DSSM/C-DSSM zostały wytrenowane na parach tytułów zapytań i dokumentów. Możesz jednak poznać inne relacje między krótkimi tekstami, szkoląc się na innych rodzajach danych, takich jak pary zapytań sesji lub pary prefiks-sufiks zapytania.
Trenowanie automatycznego kodera obrazów przy użyciu deconvolution i unpooling
W tym miejscu znajdują się instrukcje.
Trenowanie wykrywania obiektów przy użyciu szybkiej sieci CNN języka R
W tym miejscu znajdują się instrukcje.