Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
CNTK vooraf gedefinieerde een aantal algemene 'lagen', waardoor het heel eenvoudig is om eenvoudige netwerken te schrijven die bestaan uit standaardlagen die op elkaar zijn gelaagd.
Lagen zijn functieobjecten die kunnen worden gebruikt als reguliere BrainScript-functies, maar leerbare parameters bevatten en een extra paar {} hebben om bouwparameters of -kenmerken door te geven.
Dit is bijvoorbeeld de netwerkbeschrijving voor een eenvoudig 1 verborgen laagmodel met behulp van de DenseLayer{} laag:
h = DenseLayer {1024, activation=ReLU} (features)
p = DenseLayer {9000, activation=Softmax} (h)
die vervolgens, bijvoorbeeld, kan worden gebruikt voor training tegen een kruis-entropiecriterium:
ce = CrossEntropy (labels, p)
Als uw netwerk een rechte samenvoeging van bewerkingen (veel zijn) is, kunt u het alternatief gebruiken
Sequential() Notatie:
myModel = Sequential (
DenseLayer {1024, activation=ReLU} :
DenseLayer {9000, activation=Softmax}
)
en roep het als volgt aan:
p = myModel (features)
Voorbeeldmodellen
Hieronder ziet u een tagprogramma voor sleuf dat een woordenreeks insluit, verwerkt met een terugkerende LSTM en vervolgens elk woord classificeert:
taggingModel = Sequential (
EmbeddingLayer {150} : # embed into a 150-dimensional vector
RecurrentLSTMLayer {300} : # forward LSTM
DenseLayer {labelDim} # word-wise classification
)
En het volgende is een eenvoudig convolutioneel netwerk voor beeldherkenning:
convNet = Sequential (
# 3 layers of convolution and dimension reduction by pooling
ConvolutionalLayer {32, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
ConvolutionalLayer {32, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
ConvolutionalLayer {64, (5:5), pad=true, activation=ReLU} :
MaxPoolingLayer {(3:3), stride=(2:2)} :
# 2 dense layers for classification
DenseLayer {64, activation=ReLU} :
LinearLayer {10}
)
Parameter delen
Als u een laag toewijst aan een variabele en deze op meerdere plaatsen gebruikt, worden de parameters gedeeld. Als je zegt
lay = DenseLayer {1024, activation=Sigmoid}
h1 = lay (x)
h2 = lay (h1) # same weights as `h1`
h1 en h2deelt dezelfde parameters, zoals lay() in beide gevallen dezelfde functie .
In het bovenstaande geval is dit waarschijnlijk niet wat gewenst was, dus wees op de hoogte.
Als beide aanroepen van lay() hierboven zijn bedoeld om verschillende parameters te hebben, moet u twee afzonderlijke exemplaren definiëren, bijvoorbeeld lay1 = DenseLayer{...} en lay2 = DenseLayer{...}.
Waarom dit gedrag?
Lagen maken het mogelijk parameters te delen tussen secties van een model.
Overweeg een DSSM-model dat twee invoerafbeeldingen verwerkt, bijvoorbeeld doc en query identiek met dezelfde verwerkingsketen, en vergelijkt de resulterende verborgen vectoren:
imageToVec = Sequential (
ConvolutionalLayer {32, (5:5), pad = true, activation = ReLU} :
MaxPoolingLayer {(3:3), stride = (2:2)} :
ConvolutionalLayer {64, (5:5), pad = true, activation = ReLU} :
MaxPoolingLayer {(3:3), stride = (2:2)} :
DenseLayer {64, activation = ReLU} :
LinearLayer {10}
)
zDoc = imageToVec (doc)
zQuery = imageToVec (query) # same model as for zDoc
sim = CosDistance (zdoc, zQuery)
waarbij imageToVec het deel van het model is dat afbeeldingen converteert naar platte vector.
imageToVec is een functieobject dat op zijn beurt verschillende functieobjecten bevat (bijvoorbeeld drie exemplaren van ConvolutionalLayer{}).
imageToVec
wordt eenmaal geïnstantieerd en dit exemplaar bevat de leerbare parameters van alle opgenomen functieobjecten. Beide aanroepen delen model() deze parameters in de toepassing en hun kleurovergangen zijn de som van beide aanroepen.
Houd er ten slotte rekening mee dat als in het bovenstaande voorbeeld querydoc dezelfde dimensies moeten zijn, omdat ze worden verwerkt via hetzelfde functieobject, en dat de eerste laag van het functieobject de invoerdimensie heeft die overeenkomt met die van zowel query als doc.
Als hun dimensies verschillen, is dit netwerk ongeldig en mislukt de dimensiedeductie/validatie met een foutbericht.
Implementatienotitie
Veel lagen zijn wrappers rond onderliggende CNTK primitieven, samen met de respectieve vereiste leerbare parameters. Verpakt bijvoorbeeld ConvolutionalLayer{} de Convolution() primitieve.
De voordelen van het gebruik van lagen zijn:
- lagen bevatten leerbare parameters van de juiste dimensie
- lagen zijn samenstelbaar (cf.
Sequential())
DenseLayer, LinearLayer{}{}
Factory-functie voor het maken van een volledig verbonden laag.
DenseLayer{} gebruikt met een optionele niet-lineariteit.
DenseLayer {outDim, activation=Identity, init='glorotUniform', initValueScale=1, bias=true}
LinearLayer {outDim, init='glorotUniform', initValueScale=1, bias=true}
Parameters
-
outDim: uitvoerdimensie van deze laag -
activation(DenseLayer{}alleen): geef hier een functie door die moet worden gebruikt als de activeringsfunctie, zoalsactivation=ReLU -
init('heNormal'|'glorotUniform'|...): type initialisatie voor de gewichten. Zie hier voor een volledige lijst met initialisatieopties. -
initValueScale: de variantie van willekeurige initialisatie wordt vermenigvuldigd met deze -
bias: indien onwaar, geen vooroordelenparameter opnemen
Retourwaarde
Een functie waarmee de gewenste volledig verbonden laag wordt geïmplementeerd. Zie de beschrijving.
Description
Gebruik deze factoryfuncties om een volledig verbonden laag te maken.
Gebruik DenseLayer{} deze optie als u een activeringsfunctie wilt opnemen, anders LinearLayer{}.
Elk van deze factoryfuncties maakt een functieobject dat een leerbare gewichtsmatrix bevat en, tenzij bias=false, een leerbare vooroordelen. Het functieobject kan worden gebruikt als een functie, waarmee een van deze formules wordt geïmplementeerd:
DenseLayer{...} (v) = activation (W * v + b)
LinearLayer{...} (v) = W * v + b
waarbij W een gewichtsmatrix van dimensie is, b de vooroordelen van de dimensie [outdim][outDim x (dimension of v)]is en de resulterende waarde dimensies (of tensordimensies) heeft zoals aangegeven door outDim.
Ondersteuning voor Tensor
Als de geretourneerde functie wordt toegepast op een invoer van een tensor-rang > 1, bijvoorbeeld een 2D-afbeelding, W heeft de dimensie [outDim x (first dimension of input) x (second dimension of input) x ...].
Aan de andere kant outDim kan dit een vector zijn die bijvoorbeeld (10:10)tensordimensies aangeeft.
In dat geval W heeft de dimensie [outDim[0] x outDim[1] x ... x (dimension of input)]en b heeft de tensor-dimensies [outDim[0] x outDim[1] x ...].
CNTK matrixproduct interpreteert deze extra uitvoer- of invoerdimensies alsof ze in een lange vector zijn afgevlakt.
Zie de documentatie van Times()
Voorbeeld:
h = DenseLayer {1024, activation=Sigmoid) (v)
of als alternatief:
Layer = DenseLayer {1024, activation=Sigmoid)
h = Layer (v)
ConvolutionalLayer{}
Hiermee maakt u een convolutielaag met optionele niet-lineariteit.
ConvolutionalLayer {numOutputChannels, filterShape,
activation = Identity,
init = 'glorotUniform', initValueScale = 1,
stride = 1, pad = false, lowerPad = 0, upperPad = 0,
bias = true}
Parameters
-
numOutputChannels: aantal uitvoerkanalen (aantal filters) -
filterShape: ruimtelijke omvang van het filter, bijvoorbeeld(5:5)voor een 2D-filter. De dimensie invoerkanaal moet hier niet worden opgenomen. -
activation: optionele niet-lineariteit, bijvoorbeeldactivation=ReLU -
init('heNormal'|'glorotUniform'|...): type willekeurige initialisatie voor de gewichten. Zie hier voor een volledige lijst met opties voor willekeurige initialisatie. -
initValueScale: de variantie van willekeurige initialisatie wordt vermenigvuldigd met deze -
stride: verhogen wanneer u het filter over de invoer schuift.(2:2)Bijvoorbeeld om de dimensies met 2 te verminderen -
pad: als dit niet is ingesteld (standaard), wordt het filter over het 'geldige' invoergebied verplaatst, dat wil gezegd dat er geen waarde buiten het gebied wordt gebruikt. Alspadhet filter daarentegen is ingesteld, wordt het filter toegepast op alle invoerposities en worden waarden buiten de geldige regio beschouwd als nul. -
lowerPad,upperPad: geef expliciet verschillende marges op voor opvulling. Filters worden verplaatst over een geldige regio die (virtueel) is uitgebreid met nullen. Er wordt bijvoorbeeldlowerPad=(1:2)een kolom met nullen en twee rijen met nullen toegevoegd. De dimensie van de uitvoer wordt dienovereenkomstig uitgebreid. -
bias: indien onwaar, geen vooroordelenparameter opnemen
Retourwaarde
Een functie waarmee de gewenste volledig verbonden laag wordt geïmplementeerd. Zie de beschrijving.
Description
Gebruik deze factoryfuncties om een convolutielaag te maken.
De resulterende laag past een convolutiebewerking toe op een N-dimensionale tensor.
De aanroeper geeft de ruimtelijke uitbreiding van het filter op.
Een set filters van een bepaalde ruimtelijke omvang (bijvoorbeeld (5:5)) wordt gecorreleerd met elke locatie van de invoer (bijvoorbeeld een afbeelding van grootte [640 x 480]).
Ervan uitgaande dat opvulling is ingeschakeld (pad) en de stappen 1 zijn, genereert dit een uitvoerregio van dezelfde dimensie ([640 x 480]).
Meestal worden veel filters tegelijkertijd toegepast.
numOutputChannels geeft het getal op, dus voor elke invoerlocatie wordt een hele vector geproduceerd numOutputChannels .
Voor ons voorbeeld hierboven zou het instellen numOutputChannels op 64 in een tensor groot [640 x 480 x 64]zijn.
Deze laatste as wordt de kanaaldimensie genoemd.
Wanneer convolutie wordt toegepast op een invoer met een kanaaldimensie, bestaat elk filter ook uit vectoren van de kanaaldimensie van de invoer.
Bij het toepassen van convolutie met een opgegeven ruimtelijk filtergebied van een afbeelding met (5:5) een [640 x 480 x 3]kleurformaat, wordt elk filter een [5 x 5 x 3] tensor.
Alle numOutputChannels filters die samen zijn gestapeld, worden de kernel genoemd.
In ons voorbeeld is [5 x 5 x 3 x 64]de kernelshape.
Hieronder ziet u een overzicht van de relatie tussen de verschillende dimensies en vormen:
input shape : [ (spatial dims) x (#input channels) ]
spatial extent : [ (filterShape) ]
output shape : [ (spatial dims) x x numOutputChannels ]
kernel shape : [ (filterShape) x (#input channels) x numOutputChannels ]
in ons voorbeeld zijn:
input shape : [ 640 x 480 x 3 ]
spatial extent : [ 5 x 5 ]
output shape : [ 640 x 480 x x numOutputChannels ]
kernel shape : [ 5 x 5 x 3 x numOutputChannels ]
Opvulling
Als opvulling niet is ingeschakeld, wordt de uitvoerregio verkleind door de grenslocaties waarop de volledige filtergebied niet kan worden toegepast. Als u bijvoorbeeld een (5:5)-extent-filter toepast op een afbeelding zonder opvulling, zouden de buitenste 2 rijen en kolommen van pixels ertoe leiden dat het filter buiten grenzen wordt toegepast.
ConvolutionalLayer{} Daarom worden de dimensies dienovereenkomstig verminderd.
Een [640 x 480] afbeelding die is samengevoegd met een (5:5) filter zonder opvulling, laat een [636 x 476]uitvoergebied van grootte achter.
Passen
De stride parameters geven de toename van filters op.
Stride-waarden groter dan één leiden tot een subsampling van de uitvoerregio.
Als u bijvoorbeeld een [640 x 480] afbeelding filtert met een onderdrukking van (2:2) , resulteert dit in een gebied met opvulling van grootte [320 x 240]en [318 x 238] zonder opvulling.
Notities
Deze laag is een wrapper rond de Convolution() primitieve.
De naam van de filterkernelparameters, zoals wordt weergegeven in de validatiesectie van het logboek, eindigt op .W.
De dimensie wordt momenteel niet weergegeven zoals [ (filterShape) x (#input channels) x numOutputChannels ] hierboven beschreven, maar in plaats daarvan [ numOutputChannels x ((product over filtervorm) * (#input kanalen)) ]'.
Voorbeeld:
c = ConvolutionalLayer {64, (3:3), pad = true, stride = (1:1), bias=false} (x)
DeconvLayer{}
Hiermee maakt u een deconvolution-laag.
DeconvLayer {numOutputChannels,
filterShape, numInputChannels,
bias = true,
activation = (x=>x),
init = 'glorotUniform',
initValueScale = 0.001,
initBias = 0,
stride = 1, autoPadding = false,
lowerPad = 0, upperPad = 0,
maxTempMemSizeInSamples = 0}
Parameters
-
numOutputChannels: aantal uitvoerkanalen (aantal filters) -
filterShape: ruimtelijke omvang van het filter, bijvoorbeeld(5:5)voor een 2D-filter. De dimensie invoerkanaal moet hier niet worden opgenomen. -
numInputChannels: aantal invoerkanalen (aantal filters van het invoervolume) -
bias: indien onwaar, geen vooroordelenparameter opnemen -
activation: optionele niet-lineariteit, bijvoorbeeldactivation=ReLU -
init('heNormal'|'glorotUniform'|...): type willekeurige initialisatie voor de gewichten. Zie hier voor een volledige lijst met opties voor willekeurige initialisatie. -
initValueScale: de variantie van willekeurige initialisatie wordt vermenigvuldigd met deze -
initBias: de initiële waarde voor de vooroordelen -
stride: verhogen wanneer u het filter over de invoer schuift.(2:2)Bijvoorbeeld om de dimensies met 2 te verminderen -
autoPadding: als dit niet is ingesteld (standaard), wordt het filter over het 'geldige' invoergebied verplaatst, dat wil gezegd dat er geen waarde buiten het gebied wordt gebruikt. AlsautoPaddinghet filter daarentegen is ingesteld, wordt het filter toegepast op alle invoerposities en worden waarden buiten de geldige regio beschouwd als nul. -
lowerPad,upperPad: expliciet verschillende marges opgeven voor opvulling voor het uitvoervolume, d.w.w.v. de marges die zijn gebruikt voor de invoer in de bijbehorende convolutionele laag. Het is belangrijk om ze in overeenstemming te brengen met de convolutionele laag om dezelfde tensordimensies te bereiken.
Retourwaarde
Een functie waarmee de gewenste volledig verbonden laag wordt geïmplementeerd. Zie de beschrijving.
Description
Gebruik deze factory-functies om een deconvolution-laag te maken.
De resulterende laag past een deconvolution-bewerking toe op een N-dimensionale tensor.
Deze laag is een wrapper rond de Convolution() primitieve met deconv=true.
Een populaire usecase voor deconvolution is het reconstrueren van een afbeelding (zie hier bijvoorbeeld). Wanneer convolutie een 2D-invoergebied gebruikt en de correlatie berekent met een 2D-filter, neemt deconvolution een pixel en verspreidt deze over een 2D-regio.
Overweeg een afbeelding p(.,.), een pixellocatie (x,y) en een gecentreerd [3 x 3] filter met de volgende inhoud (momenteel geen dimensie voor de diepte van de functiekaart, bijvoorbeeld één kanaal):
[ . . c
a b .
. . . ]
Hier zijn een b en c gewichten van het filter, '.' Komt overeen met een nulgewicht. Convolution() berekent de uitvoer pixel q(x, y) op locatie (x, y) als:
q(x,y) = b * p(x,y) + a * p(x-1,y) + c * p(x+1,y-1)
Deconvolution neemt pixels q(x,y) en verspreidt ze over een regio rond (x,y). Als we hetzelfde filter hebben gebruikt, zou het de volgende bijdragen leveren aan de uitvoer r(x,y):
r(x,y) += b * q(x,y)
r(x-1,y) += a * q(x,y)
r(x+1,y-1) += c * q(x,y)
Als u weet dat hetzelfde geldt voor alle x en y in het vliegtuig, kunnen we dit uitdrukken voor r(x,y):
r(x,y) += b * q(x,y)
r(x,y) += a * q(x+1,y)
r(x,y) += c * q(x-1,y+1)
of in totaal,
r(x,y) = b * q(x,y) + a * q(x+1,y) + c * q(x-1,y+1)
Dit heeft dezelfde vorm als de bovenstaande Convolution, behalve dat het filter langs beide assen wordt gespiegeld.
Nu introduceren we functiekaarten in de mix. Dat is eenvoudig: in plaats van van invoerdiepte tot uitvoerdiepte te gaan, gaan we de andere richting uit.
Kortom, Convolution (W, x) == Deconvolution (W', x), waarbij
W : [W x H x C x K]
en
W’ = W met de waarden opnieuw gerangschikt als: [(W mirrored) x (H mirrored) x K x C]
Wat Deconvolution() impliciet doet, is:
- de twee dieptedimensies uitwisselen (transponeren)
- de ruimtelijke dimensies (de volgorde van de gegevens omkeren)
- Convolution() met deze
Voorbeeld:
deconv_A = DeconvLayer {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
Zie Het automatisch coderingsprogramma voor afbeeldingen met behulp van Deconvolution en Unpooling voor een gedetailleerd voorbeeld en stapsgewijze instructies.
MaxPoolingLayer, AveragePoolingLayer{}{}
Factory-functies voor het maken van een maximale of gemiddelde poollaag.
MaxPoolingLayer {poolShape, stride = 1, pad = false, lowerPad = 0, upperPad = 0}
AveragePoolingLayer {poolShape, stride = 1, pad = false, lowerPad = 0, upperPad = 0} =
Parameters
-
poolShape: de vorm van de regio naar pool, bijvoorbeeld(2:2) -
stride: verhogen wanneer u de pool over de invoer schuift.(2:2)Bijvoorbeeld om de dimensies met 2 te verminderen -
pad: als deze niet is ingesteld (standaard), wordt de pool over het 'geldige' invoergebied verplaatst, dat wil gezegd dat er geen waarde buiten het gebied wordt gebruikt. Alspadde pool daarentegen is ingesteld, wordt de pool toegepast op alle invoerposities en worden waarden buiten de geldige regio beschouwd als nul. Voor gemiddelde pooling bevat het aantal voor gemiddelden geen opgevulde waarden. -
lowerPad,upperPad: geef expliciet verschillende marges op voor opvulling. Filters worden verplaatst over een geldige regio die (virtueel) is uitgebreid met nullen. Er wordt bijvoorbeeldlowerPad=(1:2)een kolom met nullen en twee rijen met nullen toegevoegd. De dimensie van de uitvoer wordt dienovereenkomstig uitgebreid.
Retourwaarde
Een functie waarmee de gewenste poollaag wordt geïmplementeerd. Zie de beschrijving.
Description
Gebruik deze factory-functie om een poolbewerking te maken. Gebruik MaxPoolingLayer{} dit diagram om het maximum te berekenen over de waarden in het poolgebied en AveragePoolingLayer{} om het gemiddelde te berekenen.
Met de poolbewerking wordt een 'poolvenster' over locaties van een invoerregio verplaatst en wordt het maximum of het gemiddelde van de waarden in de respectieve poolregio berekend.
Deze bewerking is structureel vergelijkbaar met de convolutie, behalve dat de bewerking die op het schuifvenster wordt toegepast, van een andere aard is.
Alle overwegingen met betrekking tot invoerdimensies, opvulling en stappen zijn identiek van toepassing, dus zie ConvolutionalLayer{} voor meer informatie.
Voorbeeld:
p = MaxPoolingLayer {(3:3), stride=(2:2)} (c)
MaxUnpoolingLayer{}
Hiermee maakt u een maximaal onboetige laag.
MaxUnpoolingLayer {poolShape,
stride = 1, pad = false,
lowerPad = 0, upperPad = 0}
Parameters
-
poolShape: de vorm van de regio die moet worden uitgezet (de grootte van de uitvoerregio ), bijvoorbeeld(2:2) -
stride: verhogen bij het verschuiven van de pool over de uitvoer.(2:2)Bijvoorbeeld om de dimensies met 2 te verhogen -
pad: als deze optie niet is ingesteld (standaard), wordt de pool over het 'geldige' uitvoergebied verplaatst, dat wil gezegd dat er geen waarde buiten het gebied wordt gebruikt. -
lowerPad,upperPad: geef expliciet verschillende marges op voor opvulling. Filters gaan uit van een geldige uitvoerregio die (virtueel) is uitgebreid.
Retourwaarde
Een functie waarmee de gewenste laag voor het opheffen van de pool wordt geïmplementeerd. Zie de beschrijving.
Description
Gebruik deze factory-functie om een unpoolbewerking te maken.
De unpooling-bewerking is de inverse van een poolbewerking. Hiervoor zijn twee invoer vereist: de uitvoer van de bijbehorende poollaag, bijvoorbeeld p1 en de invoer van de bijbehorende poollaag, bijvoorbeeld r1. Het schuift een 'inverse poolvenster' over de locaties van de invoer p1en projecteert de waarde naar die positie van de uitvoerregio met de maximumwaarde in de bijbehorende poolbewerking, d.w.z. in r1. De tweede invoer r1 is vereist in CNTK om het doel van de unpooling-bewerking te bepalen, omdat CNTK geen zogenaamde switchvariabelen opslaat (zie hier voor meer informatie).
Voorbeeld:
unpool_A = MaxUnpoolingLayer {(2:2), stride=(2:2)}(deconv_B, relu_A)
Zie Het automatisch coderingsprogramma voor afbeeldingen met behulp van Deconvolution en Unpooling voor een gedetailleerd voorbeeld en stapsgewijze instructies.
EmbeddingLayer{}
EmbeddingLayer {outDim,
init='glorotUniform', initValueScale=1,
embeddingPath = '', transpose = false}
Parameters
-
outDim: de dimensie van de gewenste insluitingsvector -
init('heNormal'|'glorotUniform'|...): type initialisatie voor de gewichten. Zie hier voor een volledige lijst met initialisatieopties. -
initValueScale: de variantie van willekeurige initialisatie wordt vermenigvuldigd met deze -
embeddingPath: indien gegeven, worden insluitingen niet geleerd, maar geladen uit een bestand en niet verder bijgewerkt tijdens de training -
transpose: maakt het mogelijk om insluitingen te laden die zijn opgeslagen in getransponeerde vorm
Retourwaarde
Een functie waarmee de insluitlaag wordt geïmplementeerd. Zie de beschrijving.
Description
'Insluiten' verwijst naar het weergeven van woorden of andere discrete items door dichte doorlopende vectoren. In deze laag wordt ervan uitgegaan dat de invoer een dynamische vorm heeft. Voor een woordenschatgrootte van 10.000 wordt bijvoorbeeld verwacht dat elke invoervector dimensie 10.000 heeft en bestaat uit nullen, met uitzondering van één positie die een 1 bevat. De index van die locatie is de index van het woord of item dat het vertegenwoordigt.
In CNTK worden de bijbehorende insluitingsvectoren opgeslagen als kolommen van een matrix. Daarom wordt het toewijzen van een invoerwoord aan het insluiten ervan geïmplementeerd als een matrixproduct. Om dit zeer efficiënt te maken, is het belangrijk dat de invoervectoren worden opgeslagen in sparse-indeling.
Leuk feit: de kleurovergang van een insluitmatrix heeft de vorm van kleurovergangsvectoren die alleen niet-nul zijn voor woorden die in een minibatch worden gezien. Aangezien voor realistische woordenschats van tienduizenden, het overgrote deel van de kolommen nul zou zijn, heeft CNTK implementeert een specifieke optimalisatie om de kleurovergang in kolomsparsevorm weer te geven.
Bekend probleem: het bovenstaande kolomsparseovergangsformulier wordt momenteel niet ondersteund door onze 1-bits SGD-parallellisatietechniek . Gebruik in plaats daarvan de techniek voor blok-momentum .
Voorbeeld
Een geleerde insluiting die woorden uit een woordenschat van 87636 vertegenwoordigt als een 300-dimensionale vector:
input = Input{87636, sparse=true} # word sequence, as one-hot vector, sparse format
embEn = EmbeddingLayer{300} (input) # embed word as a 300-dimensional continuous vector
Bovendien sparse=truemoet men ook een invoer declareren als sparse in het reader configuratieblok.
Hier volgt een voorbeeld van het lezen van sparsetekstinvoer met het CNTKTextFormatReadervolgende:
reader = {
readerType = "CNTKTextFormatReader"
file = "en2fr.txt"
randomize = true
input = {
input = { alias = "E" ; dim = 87636 ; format = "sparse" }
labels = { alias = "F" ; dim = 98624 ; format = "sparse" }
}
}
Als in plaats daarvan de insluitingsvectoren al bestaan en uit een bestand moeten worden geladen, ziet deze er als volgt uit:
input = Input{87636, sparse=true} # word sequence, as one-hot vector, sparse format
embEn = EmbeddingLayer{300, embeddingPath="embedding-en.txt", transpose=true} (w) # embedding from disk
waarbij het bestand "embedding-en.txt" naar verwachting uit 87.636 tekstrijen bestaat, die elk bestaan uit 300 door spaties gescheiden getallen.
Omdat dit bestand de insluitingen opslaat als rijen in plaats van kolommen, transpose=true wordt de matrix direct getransponeerd.
TerugkerendeLSTMLayer{}, TerugkerendeLSTMLayerStack{}
Factory-functies voor het maken van een terugkerende LSTM met één laag of meerdere lagen.
RecurrentLSTMLayer {outDim, cellShape = None,
goBackwards = false,
usePeepholes = false,
init = 'glorotUniform', initValueScale = 1,
enableSelfStabilization = false,
allowOptimizedEngine = false}
RecurrentLSTMLayerStack {layerDims,
cellShapes = None,
usePeepholes = false,
init = 'glorotUniform', initValueScale = 1,
enableSelfStabilization = false,
allowOptimizedEngine = false}
Parameters
-
outDim(RecurrentLSTMLayer{}): dimensie van de uitvoer van het netwerk. Om een tensor van rang>1 aan te geven, kan dit een vector zijn, bijvoorbeeld(40:2) -
layerDims(RecurrentLSTMLayerStack{}): matrix van dimensies van de binnenste lagen en uitvoer van het netwerk -
cellShape( (RecurrentLSTMLayer{}, optioneel): de dimensie van de cel van de LSTM. Normaal gesproken is dit identiek aanoutDim. Als er een andere waarde wordt gegeven, wordt er een extra lineaire projectie ingevoegd om van de celdimensie naar de uitvoer te converteren. -
cellShapes( (RecurrentLSTMLayerStack{}, optioneel): matrix met waarden, zoalscellShapevoorRecurrentLSTMLayer()het aanduken van projectie -
goBackwards(optioneel): indien waar, wordt het terugkeerpatroon achterwaarts uitgevoerd -
usePeepholes(optioneel): indien waar, gebruik dan peephole-verbindingen in de LSTM -
init('heNormal'|'glorotUniform'|...): type initialisatie voor de gewichten. Zie hier voor een volledige lijst met initialisatieopties. -
initValueScale: de variantie van willekeurige initialisatie wordt vermenigvuldigd met deze -
enableSelfStabilization(optioneel): voeg indien waar een "stabilisator"-bewerking in die vergelijkbaar is metStabilizerLayer{} -
allowOptimizedEngine(optioneel, standaard false): indien waar, gebruik indien mogelijk de geoptimaliseerde RNNN-engine van cuDNN
Retourwaarde
Een functie die de gewenste laag(en) implementeert die een terugkerende LSTM toepast/toepast op de invoerreeks. Deze laag (-stack) wijst een invoerreeks toe aan een reeks verborgen statussen van dezelfde lengte.
Description
Hiermee wordt de terugkerende LSTM geïmplementeerd die moet worden toegepast op een reeks invoerwaarden, in twee varianten: één laag en een stack met meerdere lagen. Met deze bewerking wordt invoer van variabele lengte automatisch verwerkt. De initiële waarde van de verborgen status en cel is 0.
Als u deze laag toepast op een invoerreeks, wordt de reeks verborgen toestanden van de terugkerende LSTM (top-of-stack) geretourneerd (de waarde van de geheugencel van de LSTM-cel wordt niet geretourneerd).
De geretourneerde reeks heeft dezelfde lengte als de invoer.
Als alleen de laatste status gewenst is, zoals in volgordeclassificatie of een aantal reeks-naar-reeksscenario's, gebruikt BS.Sequences.Last() u deze optie om alleen de verborgen status van het laatste item te extraheren.
(In een achterwaarts terugkeerpatroon zou BS.Sequences.First()u .)
Als u een bidirectioneel model wilt maken met RecurrentLSTMLayer(), gebruikt u twee lagen, één met goBackwards=trueen Splice() de twee uitvoer samen.
RecurrentLSTMLayerStack() momenteel biedt geen ondersteuning voor bidirectionele modellen. U moet deze handmatig maken met meerdere RecurrentLSTMLayer()/Splice() combinaties.
De CuDNN5 RNN-engine gebruiken
Deze functie maakt indien mogelijk automatisch gebruik van cuDNN5's geoptimaliseerde RNN-engine.
- het opgegeven model is een model dat kan worden geïmplementeerd door CuDNN5's functie
- geen projectie (geen
cellShapeparameter) - geen peep-hole verbindingen
- geen zelfstabilisatie
- niet achteruit gaan
- voor
RecurrentLSTMLayerStack{}, alle laagdimensies hebben dezelfde waarde
- geen projectie (geen
allowOptimizedEngine=true
Met name moet CNTK inschakelenallowOptimizedEngine=true.
Dit komt doordat de CuDNN5 RNN is geïmplementeerd als een CNTK primitieve bewerking waarvoor een GPU is vereist.
Veel echte systemen maken echter gebruik van GPU's voor training, maar alleen CPU-servers in implementatie.
De CuDNN5 RNN is hier niet geschikt.
(Het is theoretisch mogelijk om de CuDNN5 RNN voor training te gebruiken en deze te vervangen voor implementatie door een bewerking met een equivalente expliciete LSTM-implementatie in BrainScript.)
Notities
Als allowOptimizedEngine=true deze twee laagvarianten wrappers rond de OptimizedRNNStack() primitieve zijn.
Voorbeeld
Een eenvoudige tekstclassificatie, waarmee een woordreeks wordt uitgevoerd door een terugkeerpatroon en vervolgens de laatste verborgen status van de LSTM doorgeeft aan een softmax-classificatie, kan dit formulier hebben:
w = Input{...} # word sequence (one-hot vectors)
e = EmbeddingLayer {150} (w) # embed as a 150-dimensional dense vector
h = RecurrentLSTMLayer {300} (e) # left-to-right LSTM with hidden and cell dim 300
t = BS.Sequences.Last (h) # extract last hidden state
z = DenseLayer {10000, activation=Softmax} (t) # softmax classifier
Als u het bovenstaande voorbeeld wilt wijzigen in een stack met drie lagen die gebruikmaakt van de CuDNN5 RNN-engine, wijzigt u deze regel:
h = RecurrentLSTMLayerStack {(300:300:300), allowOptimizedEngine=true} (e)
Als u een bidirectionele LSTM met één laag wilt maken (bijvoorbeeld door de helft van de verborgen dimensie te gebruiken in vergelijking met hierboven), gebruikt u dit:
hFwd = RecurrentLSTMLayer {150} (e)
hBwd = RecurrentLSTMLayer {150, goBackwards=true} (e)
h = Splice (hFwd:hBwd)
DelayLayer{}
Factory-functie voor het maken van een laag die de invoer vertraagt.
DelayLayer {T=1, defaultHiddenActivation=0}
Parameters
-
T: het aantal tijdsstappen dat moet worden vertraagd. Gebruik een negatieve waarde om toegang te krijgen tot toekomstige waarden -
defaultHiddenActivation: waarde die moet worden gebruikt voor de vertraagde frames aan de grenzen
Retourwaarde
Een functie die de gewenste vertragingsbewerking implementeert.
Description
Met deze bewerking wordt een invoerreeks met T stappen vertraagd (standaard 1).
Dit is bijvoorbeeld handig om een woordreeks om te zetten in een reeks overlappende woorddubbels.
Overweeg een invoerreeks "a b c b", die als volgt moet worden gecodeerd als een reeks van een-dynamische vectoren:
1 0 0 0
0 1 0 1
0 0 1 0
Hier is elke kolom een een-dynamische vector en komt overeen met een woord.
Als u op deze invoer toepast DelayLayer{T=1} , wordt deze reeks gegenereerd:
0 1 0 0
0 0 1 0
0 0 0 1
Alle tokens worden met één vertraging vertraagd en de eerste positie wordt ingevuld als een 0-vector.
Op dezelfde manier geeft het gebruik DelayLayer{T=-1} van (negatieve vertraging) toegang tot de toekomstige waarden en geeft u van rechts een pad met een nul:
0 0 0 0
1 0 1 0
0 1 0 0
Notities
Deze laag is een wrapper rond de PastValue() en FutureValue() primitieven.
Voorbeeld
Hieronder ziet u hoe u drie buurwoorden in een trigramvector kunt stapelen:
x = ... # input value, e.g. a N-dimensional one-hot vector
xp = DelayLayer{} (x) # previous value
xn = DelayLayer{T-1} (x) # next value (negative delay)
tg = Splice (xp : x : xn) # concatenate all into a 3N-dimensional three-hot vector
BatchNormalizationLayer, LayerNormalizationLayer{}{}, StabilizerLayer{}
Fabrieksfuncties voor het maken van lagen voor batchnormalisatie, laagnormalisatie en zelfstabilisatie.
BatchNormalizationLayer {spatialRank = 0,
normalizationTimeConstant = 5000,
initialScale = 1, epsilon = 0.00001, useCntkEngine = true}
LayerNormalizationLayer {initialScale = 1, initialBias = 0}
StabilizerLayer{}
Parameters
BatchNormalizationLayer:
-
spatialRank: normalisatieparameters worden gegroepeerd over de eerstespatialRankdimensies. Op dit moment zijn toegestane waarden 0 (geen pooling) en 2 (pooling op alle pixelposities van een afbeelding) -
normalizationTimeConstant(standaard 5000): tijdconstante in steekproeven van het filter met lage pass van de eerste volgorde dat wordt gebruikt voor het berekenen van gemiddelde/variantiestatistieken voor het gebruik van deductie -
initialScale: initiële waarde van schaalparameter -
epsilon: kleine waarde die wordt toegevoegd aan de variantieraming bij het berekenen van de inverse -
useCntkEngine: indien waar, gebruikt u de systeemeigen implementatie van CNTK. Als dit onwaar is, gebruikt u de implementatie van cuDNN (alleen GPU).
LayerNormalizationLayer:
-
initialScale: initiële waarde van schaalparameter -
initialBias: initiële waarde van de parameter bias
Retourwaarde
Een functie die een laag implementeert die de normalisatiebewerking uitvoert.
Description
BatchNormalizationLayer{} implementeert de techniek die wordt beschreven in paper Batch Normalization: Accelerating Deep Network Training by Reduce Internal Covariate Shift (Sergey Ioffe, Christian Szegedy).
Het normaliseert de invoer voor elke minibatch door de gemiddelde/variantie van de minibatch en normaliseert het met een geleerde schaalfactor en vooroordelen.
Deductie, in plaats van minibatch gemiddelde/variantie te gebruiken, maakt batchnormalisatie gebruik van een langlopende gemiddelde/var-schatting.
Deze schatting wordt berekend tijdens de training door minibatchstatistieken met weinig wachtwoordfilters te filteren.
De tijdconstante van het filter met lage pass kan worden gewijzigd door de normalizationTimeConstant parameter.
We raden u aan om te beginnen met de standaardwaarde (5000), maar experimenteer met andere waarden, meestal op volgorde van duizenden tot tienduizenden.
LayerNormalizationLayer{} implementeert Laagnormalisatie (Jimmy Lei Ba, Jamie Ryan Kiros, Tenant E. Hinton).
Elk invoervoorbeeld wordt genormaliseerd door het gemiddelde af te trekken over alle elementen van de steekproef en vervolgens te delen door de standaarddeviatie voor alle elementen van de steekproef.
StabilizerLayer{} implementeert een zelfstabilisator per zelfgestabiliseerd deep neural network (P. Ghahremani, J. Droppo).
Deze eenvoudige maar effectieve techniek vermenigvuldigt de invoer met een leerbare scalaire waarde (maar in tegenstelling tot laagnormalisatie wordt de invoer niet eerst genormaliseerd en wordt er ook geen gemiddelde afgetrokken).
In vergelijking met het oorspronkelijke document, dat een lineair scalaire beta of exponentiële Exp (beta)waarde voorstelt, hebben we het nuttig gevonden om een verscherpte softplus-bewerking te gebruiken volgens de suggestie van de tweede auteur, waardoor zowel negatieve waarden als instabiliteit van de exponentiële worden vermeden.
Notities
BatchNormalizationLayer{} is een wrapper rond de BatchNormalization() primitieve.
LayerNormalizationLayer{} en StabilizerLayer{} worden rechtstreeks uitgedrukt in BrainScript.
Voorbeeld
Een typische laag in een convolutioneel netwerk met batchnormalisatie:
MyLayer (x, depth, initValueScale) =
{
c = ConvolutionalLayer {depth, (5:5), pad=true, initValueScale=initValueScale} (x)
b = BatchNormalizationLayer {spatialRank = 2} (c) #####
r = ReLU (b)
p = MaxPoolingLayer {(3:3), stride = (2:2)} (r)
}.p
FeatureMVNLayer{}
Factory-functie om een laag te maken die functie-invoer normaliseert op basis van de gemiddelde en standaarddeviatie.
FeatureMVNLayer{}
Parameters
Lijst met lege argumenten {}.
Retourwaarde
Een functie die een laag implementeert die de normalisatiebewerking uitvoert.
Description
Deze laag normaliseert de invoer naar een neuraal netwerk door de vooroordelen en variantie. Deze waarden worden vooraf geschat door een volledige doorvoer door de trainingsgegevens uit te voeren en vervolgens op te slaan en te bevroren. Dit gebeurt automatisch.
Omdat de parameters van deze laag vooraf worden gecomputeerd in een afzonderlijke pas voordat de hoofdtraining wordt uitgevoerd, kan deze alleen worden toegepast op variabelen die zijn gedeclareerd als Input{}.
Voorbeeld
Dit is een typisch begin van een neuraal netwerk voor akoestische modellering van spraak:
features = Input{40} # e.g. speech features
featNorm = FeatureMVNLayer{} (features)
h = DenseLayer{2048} (featNorm)
...