Ricerca per categorie eseguire il training dei modelli in BrainScript

Training saggio livello

Per eseguire il training su più livelli, è sufficiente usare più "comandi" nel file di configurazione, in cui ogni comando è di tipo action=train.

command = TrainLayer1:TrainLayer2:TrainLayer3:EndToEndTrain:Test:Output

TrainLayer1= [ 
   action = train
   ...
]

TrainLayer2= [ 
   action = train
   ...
]
...

Eseguire il training con un obiettivo multitasking

È sufficiente definire il criterio combinato come espressione BrainScript ed è possibile monitorare tutte le singole perdite di attività specificandole come evaluationNodes.

task1loss = CrossEntropyWithSoftMax(prediction,label)
task2loss = SquareError(reconstruction,input)
mtloss = task1loss + Constant(0.3) .* task2loss 
criterionNodes = (mtloss)
evaluationNodes = (task1loss:task2loss)

Eseguire il training di un modello di regressione sulle immagini

Di seguito viene descritto come stimare uno o più valori a virgola mobile per un'immagine di input usando CNTK. Un caso d'uso di esempio consiste nel prevedere un rettangolo di selezione, ad esempio (x, y, w, h), di un oggetto in una determinata immagine. Si potrebbe anche pensare di prevedere il prezzo per un'auto semplicemente guardando un'immagine di quella macchina (sarebbe interessante in realtà). In questo caso viene usato un esempio molto semplice in cui viene eseguito il training di una rete per stimare i valori RGB medi di un'immagine (normalizzati a [0, 1]). Tuttavia, gli stessi passaggi si applicano per altri casi d'uso. Questi passaggi sono i seguenti:

  1. Definire sia l'immagine che le etichette di regressione della verità di terra come input per la rete
  2. Definire una rete che stima un numero corrispondente di valori w.r.t. le etichette di regressione
  3. Definire una funzione di perdita che confronta i valori stimati con la verità di base
  4. Adattare la sezione reader nel file di configurazione con estensione cntk per leggere sia le etichette di immagine che di regressione

Ecco come è possibile farlo. Il file di configurazione completo è incluso nella cartella Examples in Examples/Image/Regression/RegrSimple_CIFAR10.cntk. Tale cartella contiene anche gli script per scaricare i dati dell'immagine e generare la verità del terreno di regressione per il training e il test.

1-3) Definizione di input, funzione di rete e perdita:

    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)
    ]
  1. Definizione di un lettore composito tramite ImageReader e 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" }
            }
        })
    }

Il lettore è un lettore composito che usa ImageReader per leggere le immagini e CNTKTextFormatReader per leggere le etichette di verità sul terreno di regressione. Lo fa definendo una matrice di deserializzatori (usando {...} : {...}) e assegnando gli input come definito nella rete precedente (ad esempio, funzionalità e regrLabels).

Vedere Examples/Image/Miscellaneous/CIFAR-10/06_RegressionSimple.cntk per il file di configurazione completo e il file Readme corrispondente in tale cartella per l'esecuzione dell'esempio.

Eseguire il training di un classificatore multi-etichetta

Per la classificazione multietichetta è consigliabile evitare di usare CrossEntropy perché può gestire solo i vettori di input che sommano a 1. Un'alternativa ragionevole consiste nell'usare una somma delle funzioni di perdita logistica, una per ogni output

...
probabilities = DenseLayer {outputSize, activation=Sigmoid} (hidden)
logisticLoss = Logistic (multiLabels, probabilities)
trainingCriterion = (logisticLoss)
...

Oltre alla perdita stessa, è possibile monitorare altre metriche, ad esempio il numero di stime non corrette. Non esiste un'espressione predefinita per questo, ma può essere espressa come

...
hammingLoss (y, p) = ReduceSum (y != (p > 0.5))
hl = hammingLoss(multiLabels,probabilities)
evaluationNodes = (hl)
...

Questo conteggia il numero di volte in cui y[i] non è d'accordo con p[i]>0,5.

Introduzione alla modellazione sequenza

Questo lab pratico descrive gli ingredienti principali per iniziare l'elaborazione delle sequenze, ad esempio il formato di testo CNTK e come configurare il lettore in modo da usare alias brevi per le varie sequenze di input. L'esempio da grapheme a phoneme (G2P) illustra un'attività effettiva da sequenza a sequenza.

Un problema importante per la modellazione da sequenza a sequenza consiste nel decodificare i dati di test con la ricerca trave. Questa operazione può essere eseguita con in una sezione della configurazione in cui l'azione di primo livello è "write". La decodifica richiede una ricerca per la sequenza di output più probabile. CNTK ha un decodificatore di ricerca fascio mentre è possibile chiamare come questo

BrainScriptNetworkBuilder = (BS.Seq2Seq.BeamSearchSequenceDecoderFrom (
                                        BS.Network.Load (decodeModelPath), beamSize))

e eseguirà la ricerca del fascio con la dimensione del fascio specificata. Per una dimensione del fascio di 1 c'è un decodificatore greedy specializzato

BrainScriptNetworkBuilder = (BS.Seq2Seq.GreedySequenceDecoderFrom (
                                        BS.Network.Load (decodeModelPath)))

Entrambi i decodificatori hanno requisiti specifici per la rete, come illustrato nell'esempio G2P

Eseguire il training di un DSSM (o un modello DSSM convoluzionale)

DSSM (o Deep Semantic Similarity Model) è un modello DNN sottoposto a training su coppie di testi di destinazione di origine, per apprendere uno spazio di incorporamento di testo breve in cui le coppie di testo di origine e di destinazione pertinenti sono più vicine. L'input di testo per il modello è rappresentato dal relativo hash trigramma precalcorato (vedere , Usare Il metodo et al.). Per C-DSSM, l'hash trigramma viene calcolato per parola e quindi concatenato nell'ordine in cui si verificano le parole nel testo. L'input per entrambi i modelli è di dimensioni fisse. Se si considerano 50.000 trigrammi, l'input DSSM corrispondente all'origine e il testo di destinazione sarà un vettore di lunghezza 50.000 ciascuno. Per C-DSSM, il vettore sarebbe di lunghezza 50K x n, dove i primi vettori di parole n-1 sono concatenati e il vettore n contiene una somma dei vettori corrispondenti a tutte le parole rimanenti nel testo. Se nel testo sono presenti meno di n parole, il resto del vettore viene riempito con zeri. Per disegnare un'analogia con l'immagine, è possibile considerare l'input di testo per C-DSSM come immagine con dimensioni 10x1 e 50K canali archiviati in un [C x H x W] formato.

Questo esempio illustra come eseguire il training di un modello DSSM/C-DSSM usando CNTKTextFormatReader. I dati devono contenere 2 funzionalità (testo di origine e di destinazione) e 1 etichetta (che viene sempre impostata sul valore 1 nei dati di training perché contiene solo campioni positivi: durante il training gli esempi di destinazione negativi vengono generati dal campionamento casuale). Ecco la configurazione del lettore,

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" }
        }
    })
}

Esempio dei dati di input,

|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

E infine la definizione di rete,

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")
}

Nota:

  • Anche se C-DSSM ha dimostrato di ottenere prestazioni coerenti migliori rispetto a DSSM, esegue anche il training più lento (a volte fino a 5-10 volte più lento). In alcuni casi è quindi possibile ottenere prestazioni migliori da DSSM nello stesso tempo di training eseguendo il training su più dati (o per più periodi).
  • Il training del DSSM/C-DSSM originale è stato eseguito su coppie di query e titolo del documento. È tuttavia possibile apprendere altre relazioni tra testi brevi eseguendo il training su altri tipi di dati, ad esempio coppie di query di sessione o coppie di suffissi di prefisso di query.

Eseguire il training di un codificatore automatico di immagini usando la deconvoluzione e l'unpooling

Sono disponibili istruzioni qui.

Eseguire il training del rilevamento di oggetti con fast R CNN

Sono disponibili istruzioni qui.