BrainScript via opdrachtregelparseringsregels
Hieronder beschrijven we de CNTK regels voor het parseren van opdrachtregels. CNTK bestaat uit een aantal onderdelen om een taak te voltooien. De meeste van deze onderdelen hebben enkele configuratiegegevens nodig die beschikbaar zijn om te kunnen functioneren en deze configuratieparameters worden geleverd via configuratiebestanden in CNTK.
Configuratiebestanden zijn verzamelingen naam-waardeparen. De configuratiegegevens kunnen een van de volgende typen zijn:
- Eenvoudig: er wordt één waarde toegewezen aan de configuratieparameter. Bijvoorbeeld
deviceId = "Auto"
. - Matrix: aan een configuratieparameter wordt een matrix met waarden toegewezen die niet van een uniform type hoeven te zijn.
:
is het standaardscheidingsteken voor matrices. Het scheidingsteken kan worden gewijzigd door de matrixwaarden tussen haakjes te plaatsen en het nieuwe scheidingsteken direct na het open haakje te plaatsen. Met*
het teken kan een bepaalde waarde meerdere keren in de matrix worden herhaald. Is bijvoorbeeldminibatchSize = 256:512:512:512:1024
gelijk aanminibatchSize = 256:512*3:1024
. - Set: parametersets bevatten sets configuratieparameters van elk type. Parametersets kunnen worden genest. Het standaardscheidingsteken voor parametersets is
;
als meerdere items op één regel zijn opgenomen. Lijnscheidingstekens fungeren ook als scheidingstekens voor items. Bijvoorbeeld:
block1 = [id=1;size=256]
block2 = [
subblock = [string="hi";num=5]
value = 1e-10
array = 10:"this is a test":1.25
]
In CNTK worden configuratiebestanden op hiërarchische wijze georganiseerd. De werkelijke gegevenswaarden worden pas geëvalueerd als een CNTK onderdeel de waarde aanvraagt. Wanneer een waarde wordt aangevraagd door een onderdeel, zoekt CNTK eerst in het onderdeelblok. Als de waarde niet wordt gevonden, blijft deze zoeken in de bovenliggende en grootouderparameter die is ingesteld totdat de parameter wordt gevonden, of wordt het hoogste niveau van de configuratiehiërarchie bereikt zonder overeenkomst. Hierdoor is het delen van dezelfde parameterwaarden eenvoudiger over verschillende blokken. Zoals we eerder hebben besproken, moet u het configuratiebestand op de opdrachtregel opgeven om CNTK uit te voeren, omdat cntk configFile=yourExp.cntk
hiermee het aangevraagde configuratiebestand wordt geladen en een opdrachtblok wordt uitgevoerd dat wordt vermeld in de opdrachtparameters in het configuratiebestand.
Opdrachten en acties
Er moet een opdrachtparameter op het hoogste niveau zijn, waarmee de opdrachten (gescheiden met :
) worden gedefinieerd die in het configuratiebestand worden uitgevoerd. Elke opdracht verwijst naar een opdrachtblok in het bestand, dat een actieparameter moet bevatten die de bewerking definieert die wordt uitgevoerd. Met de volgende opdracht wordt bijvoorbeeld het mnistTrain
blok uitgevoerd, waarmee de trainactie wordt uitgevoerd, gevolgd door het mnistTest
blok, waarmee het model wordt geëvalueerd.
command = mnistTrain:mnistTest
mnistTrain = [
action = "train"
...
]
mnistTest = [
action = "eval"
...
]
Overbelasting van configuraties op de opdrachtregel
Het is gebruikelijk om een configuratie te hebben die kan worden gebruikt als basisconfiguratie en slechts enkele parameters voor elke experimentele uitvoering kan wijzigen. Dit kan op een aantal verschillende manieren worden gedaan. Dit is het overschrijven van instellingen op de opdrachtregel. Als u bijvoorbeeld het pad naar het modelbestand wilt overschrijven, kunt u de opdrachtregel als volgt wijzigen:
cntk configFile=yourExp.cntk stderr="c:\temp\newpath"
Hiermee wordt de huidige instelling voor stderr
, die is gedefinieerd op het hoofdniveau van het configuratiebestand, overschreven met de nieuwe waarde. Als een parameter in een opdrachtblok moet worden gewijzigd, moet het blok ook worden opgegeven. U kunt bijvoorbeeld het minibatchSize
voor een experiment in de opdrachtregel wijzigen als
cntk configFile=yourExp.cntk mnistTrain=[minibatchSize=256]
of wijzig het gegevensbestand dat wordt gebruikt voor een experiment als
cntk configFile=yourExp.cntk mnistTrain=[reader=[file="mynewfile.txt"]]
Gelaagde configuratiebestanden
In plaats van bepaalde onderdelen van een configuratiebestand te overschrijven met opdrachtregelparameters, kan men ook meerdere configuratiebestanden opgeven, waarbij de laatste bestanden de eerdere overschrijven. Hierdoor kan een gebruiker een hoofdconfiguratiebestand hebben en vervolgens in een afzonderlijk configuratiebestand opgeven welke parameters van de master ze willen overschrijven voor een bepaalde uitvoering van CNTK. Dit kan worden bereikt door een door '+' gescheiden lijst met configuratiebestanden op te geven of door de configFile=
tag meerdere keren te gebruiken. Hieronder ziet u een equivalent.
cntk configFile=yourExp1.cntk+yourExp2.cntk
cntk configFile=yourExp1.cntk configFile=yourExp2.cntk
Als yourExp2.cntk
alleen de tekenreeks mnistTrain=[reader=[file=mynewfile.txt]]
bevat, zijn beide opdrachten gelijk aan:
cntk configFile=yourExp1.cntk mnistTrain=[reader=[file="mynewfile.txt"]]
Houd er rekening mee dat de waarde van een variabele altijd wordt bepaald door de laatste keer dat deze wordt toegewezen. Het is ook mogelijk om opdrachtregelparameters en gelaagde configuratiebestanden te combineren in willekeurige combinaties. Bijvoorbeeld:
cntk configFile=yourExp1.cntk+yourExp2.cntk var1=value configFile=yourExp3.cntk
verwerkt deze configuratieparameters in de volgorde waarin ze worden weergegeven op de opdrachtregel en de waarde die het laatst is toegewezen, is de gebruikte waarde.
Naast het kunnen opgeven van meerdere configuratiebestanden op de opdrachtregel, kan een gebruiker één configuratiebestand opnemen in een andere. Als de eerste regel yourExp2.cntk
bijvoorbeeld was
include=yourExp1.cntk
vervolgens gewoon worden uitgevoerd
cntk configFile=yourExp2.cntk
zou gelijk zijn aan actief
cntk configFile=yourExp1.cntk+yourExp2.cntk
indien in dit laatste geval yourExp2.cntk
niet de insluitingsinstructie bevat. Houd er rekening mee dat deze instructies overal in een configuratiebestand kunnen worden weergegeven; waar de insluitingsinstructie wordt weergegeven, is dat waar het opgegeven configuratiebestand wordt opgenomen. Het opnemen van een configuratiebestand is gelijk aan het plakken van de inhoud van dat bestand op de locatie van de insluitingsinstructie. Insluitingsinstructies worden recursief opgelost (met behulp van een diepte-eerste zoekopdracht), wat betekent dat, indien opgenomen en opgenomenyourExpC.cntk
, de volledige keten wordt opgelost en yourExpC.cntk
effectief wordt opgenomen in yourExpA.cntk
.yourExpB.cntk
yourExpB.cntk
yourExpA.cntk
Als een configuratiebestand meerdere keren is opgenomen (bijvoorbeeld 'A' bevat 'B' en 'C' en 'B' ook 'C', dan wordt het alleen opgenomen wanneer het voor het eerst wordt aangetroffen.
Variabelen tekenreeksen aanpassen
Hoewel gelaagde configuratiebestanden gebruikers in staat stellen configuratiebestanden opnieuw te gebruiken in experimenten, kan dit nog steeds een lastig proces zijn. Voor elk experiment moet een gebruiker mogelijk verschillende parameters overschrijven, waarvan sommige lange bestandspaden kunnen zijn (bijvoorbeeld stderr
, modelPath
, ). file
De functionaliteit 'stringize' kan dit proces veel eenvoudiger maken. Hiermee kan een gebruiker de configuratie als volgt opgeven:
command = SpeechTrain
stderr = "$Root$\$RunName$.log"
speechTrain = [
modelPath = "$Root$\$RunName$.cn"
SGD = [
reader = [
features = [
type = "real"
dim = "$DataSet1_Dim$"
file = "$DataSet1_Features$"
]
]
]
]
Root
RunName
Hier, ,, DataSet1_Dim
en DataSet1_Features
zijn variabelen die elders in de configuratie zijn opgegeven (op een bereik dat zichtbaar is vanaf het punt waarop ze worden gebruikt). Bij het interpreteren van dit configuratiebestand vervangt de parser elke tekenreeks van het formulier $VarName$
door de tekenreeks VarValue
, waarbij VarValue
de waarde van de variabele met de naam wordt aangegeven VarName
. Het proces voor variabeleomzetting is recursief; Als bijvoorbeeld A=$B$, B=$C$en C=HelloWorld.txt, wordt A omgezet als 'HelloWorld.txt'. Zorg ervoor dat uw configuratiebestand geen referentielus bevat. Anders gaat de parser op dit moment in oneindige lus.
Omdat het equivalent is voor een gebruiker om de waarde van een variabele in een configuratiebestand op te geven versus op de opdrachtregel, kunnen de waarden voor deze variabelen op beide locaties worden opgegeven. Zoals u weet, wordt de waarde van een variabele bepaald door de laatste keer dat deze is toegewezen, ongeacht of deze zich in een configuratiebestand of op de opdrachtregel bevindt. Dus, als Root
is gedefinieerd in config1.txt, maar wordt overschreven op de opdrachtregel, is de waarde die is opgegeven op de opdrachtregel de waarde die wordt gebruikt om instanties in $Root$
configFile1.txt op te lossen. Een handige functie is dat als stderr
of modelPath
verwijst naar mappen die niet bestaan, deze mappen worden gemaakt door CNTK; hiermee kunt u iets als stderr = $Root$\$RunName$\$RunName$.log
, zelfs als de map $Root$\$RunName$
niet bestaat, opgeven.
Standaardwaarden, herhaalde waarden en opmerkingen
De meeste parameters in configuratiebestanden hebben een standaardwaarde die wordt gebruikt als er geen configuratiewaarde is opgegeven. Als er geen standaardwaarde is en de waarde niet kan worden gevonden in een zoekopdracht, wordt er een uitzondering weergegeven en wordt het programma afgesloten. Als een parameternaam meer dan één keer is opgegeven, is de laatste waarde die is ingesteld op die waarde, degene die wordt onderhouden. De enige uitzondering hierop is in parametersets, die worden omgeven door [
vierkante accolades ]
, in deze gevallen worden de waarden binnen de accolades beschouwd als een parameterset en worden toegevoegd aan de huidige bestaande parameterset. Bijvoorbeeld:
params=[a=1;b=2;c=3]
params=[c=5;d=6;e=7]
is effectief gelijk aan:
params=[a=1;b=2;c=5;d=6;e=7]
Houd er rekening mee dat deze toevoegverwerking niet wordt gebruikt voor matrixelementen en dat de hele matrix wordt vervangen als deze meerdere keren is ingesteld. Het #
teken geeft het begin van een opmerking aan, alles wat zich voordoet nadat de #
opmerking is genegeerd. De #
regel moet worden voorafgegaan door een witruimte of aan het begin van de regel die moet worden geïnterpreteerd als opmerking. Hier volgt een geldige opmerking
stderr="c:\cntk\log\cntk" # "_mnistTrain_mnistTest.log"
Hier volgt een voorbeeld van een waarde die niet wordt geïnterpreteerd als opmerking. Hiermee wordt een parameter var
ingesteld op oneindig omdat de #
in 1#INF
geen opmerkingsmarkering is
var=1#INF