Usando O CNTK com a API C#/.NET
O CNTK v2.2.0 fornece a API C# para compilar, treinar e avaliar modelos CNTK. Esta seção fornece uma visão geral da API CNTK C#. Exemplos de treinamento em C# estão disponíveis no repositório github do CNTK.
Usando a API Gerenciada C#/.NET para criar uma rede neural profunda
A API CNTK C# fornece operações básicas no namespace CNTKLib. Uma operação CNTK usa uma ou duas variáveis de entrada com os parâmetros necessários e produz uma Função CNTK. Uma Função CNTK mapeia dados de entrada para saída. Uma função CNTK também pode ser tratada como uma variável e ser usada como entrada para outra operação CNTK. Com esse mecanismo, uma rede neural profunda pode ser criada com operações básicas de CNTK encadeando e composição. Por exemplo:
private static Function CreateLogisticModel(Variable input, int numOutputClasses)
{
Parameter bias = new Parameter(new int[]{numOutputClasses}, DataType.Float, 0}
Parameter weights = new Parameter(new int[]{input.Shape[0], numOutputClasses}, DataType.Float,
CNTKLib.GlorotUniformInitializer(
CNTKLib.DefaultParamInitScale,
CNTKLib.SentinelValueForInferParamInitRank,
CNTKLib.SentinelValueForInferParamInitRank, 1));
var z = CNTKLib.Plus(bias, CNTKLib.Times(weights, input));
Function logisticClassifier = CNTKLib.Sigmoid(z, "LogisticClassifier");
return logisticClassifier;
}
CNTKLib.Plus, CNTKLib.Times, CNTKLib.Sigmoid são operações básicas do CNTK. O argumento de entrada pode ser uma variável CNTK que representa os recursos de dados. Também pode ser outra função CNTK. Esse código cria uma rede de computação simples com parâmetros ajustados no estágio de treinamento para tornar um classificador de várias classes decente.
A API CNTK C# fornece operações para criar CNNs (redes neurais de convolução) e RNNs (redes neurais recorrentes). Por exemplo, para criar um classificador de imagem CNN de duas camadas:
var convParams1 = new Parameter(
new int[] { kernelWidth1, kernelHeight1, numInputChannels, outFeatureMapCount1 },
DataType.Float, CNTKLib.GlorotUniformInitializer(convWScale, -1, 2), device);
var convFunction1 = CNTKLib.ReLU(CNTKLib.Convolution(
convParams1, input,
new int[] { 1, 1, numInputChannels } ));
var pooling1 = CNTKLib.Pooling(convFunction1, PoolingType.Max,
new int[] { poolingWindowWidth1, poolingWindowHeight1 }, new int[] { hStride1, vStride1 }, new bool[] { true });
var convParams2 = new Parameter(
new int[] { kernelWidth2, kernelHeight2, outFeatureMapCount1, outFeatureMapCount2 },
DataType.Float, CNTKLib.GlorotUniformInitializer(convWScale, -1, 2), device);
var convFunction2 = CNTKLib.ReLU(CNTKLib.Convolution(
convParams2, pooling1,
new int[] { 1, 1, outFeatureMapCount1 } ));
var pooling2 = CNTKLib.Pooling(convFunction2, PoolingType.Max,
new int[] { poolingWindowWidth2, poolingWindowHeight2 }, new int[] { hStride2, vStride2 }, new bool[] { true });
var imageClassifier = TestHelper.Dense(pooling2, numClasses, device, Activation.None, "ImageClassifier");
Um exemplo para criar um RNN com LTSM (memória de curto prazo) também é fornecido.
Preparação de dados usando C#/.NET
O CNTK fornece utilitários de preparação de dados para treinamento. A API CNTK C# expõe esses utilitários. Ele usa dados de vários formulários pré-processados. O carregamento de dados e o envio em lote são feitos com eficiência. Por exemplo, supondo que tenhamos dados no texto no seguinte formato de texto CNTK chamado "Train.ctf":
|features 3.854499 4.163941 |labels 1.000000
|features 1.058121 1.204858 |labels 0.000000
|features 1.870621 1.284107 |labels 0.000000
|features 1.134650 1.651822 |labels 0.000000
|features 5.420541 4.557660 |labels 1.000000
|features 6.042731 3.375708 |labels 1.000000
|features 5.667109 2.811728 |labels 1.000000
|features 0.232070 1.814821 |labels 0.000000
Um CNTK DataSource é criado dessa forma:
var minibatchSource = MinibatchSource.TextFormatMinibatchSource(
Path.Combine(DataFolder, "Train.ctf"), streamConfigurations,
MinibatchSource.InfinitelyRepeat, true);
Os dados do lote podem ser recuperados e usados para treinamento posteriormente:
var minibatchData = minibatchSource.GetNextMinibatch(minibatchSize, device);
Usando a API Gerenciada C#/.NET para treinar uma rede neural profunda
A descendente de gradiente stocástico (SGD) é uma maneira de otimizar parâmetros de modelo com dados de treinamento de minibatch. O CNTK dá suporte a muitas variações de SGD que são comumente vistas na literatura de aprendizado profundo. Eles são expostos pela API CNTK C#:
- SGDLearner - um aprendiz de SGD interno do CNTK
- MomentumSGDLearner - um aprendiz interno do SGD momentum do CNTK
- FSAdaGradLearner - uma variação do aprendiz do AdaGrad
- AdamLearner - um aprendiz de Adam
- AdaGradLearner - um aprendiz de gradiente adaptável
- RMSPropLearner - um aprendiz RMSProp
- AdaDeltaLearner - um aprendiz de AdaDelta
Para obter uma visão geral de diferentes otimizadores de aprendizagem, consulte a descendente de gradiente stocástico.
Um treinador CNTK é usado para fazer o treinamento de minibatch. Um snip de código em C# para treinamento de minibatch:
// build a learning model
var featureVariable = Variable.InputVariable(new int[] { inputDim }, DataType.Float);
var labelVariable = Variable.InputVariable(new int[] { numOutputClasses }, DataType.Float);
var classifierOutput = CreateLinearModel(featureVariable, numOutputClasses, device);
var loss = CNTKLib.CrossEntropyWithSoftmax(classifierOutput, labelVariable);
var evalError = CNTKLib.ClassificationError(classifierOutput, labelVariable);
// prepare for training
var learningRatePerSample = new CNTK.TrainingParameterScheduleDouble(0.02, 1);
var parameterLearners =
new List<Learner>() { Learner.SGDLearner(classifierOutput.Parameters(), learningRatePerSample) };
var trainer = Trainer.CreateTrainer(classifierOutput, loss, evalError, parameterLearners);
int minibatchSize = 64;
int numMinibatchesToTrain = 1000;
// train the model
for (int minibatchCount = 0; minibatchCount < numMinibatchesToTrain; minibatchCount++)
{
Value features, labels;
GenerateValueData(minibatchSize, inputDim, numOutputClasses, out features, out labels, device);
trainer.TrainMinibatch(
new Dictionary<Variable, Value>() { { featureVariable, features }, { labelVariable, labels } }, device);
TestHelper.PrintTrainingProgress(trainer, minibatchCount, 50);
}
Neste snip de código, um aprendiz de SGD interno do CNTK com a taxa de aprendizado por exemplo = 0,02 é usado. O aprendiz é otimizar todos os parâmetros do modelo. Um treinador é criado com o aprendiz, uma função de perda e uma função de avaliação. Durante cada minibatch de iteração de treinamento, os dados são alimentados para que o treinador tenha parâmetros de modelo atualizados. Erro de avaliação e perda de treinamento são exibidos com um método auxiliar durante o treinamento.
No código, geramos duas classes de dados estatisticamente separados de rótulos e recursos. Em outros exemplos mais realistas, os dados de teste públicos são carregados com o CNTK MinibatchSource.
Usando a API Gerenciada C#/.NET para avaliar uma rede neural profunda
A API do C# tem a API de avaliação para fazer a avaliação do modelo. A maioria dos exemplos de treinamento em C# faz a avaliação do modelo após o treinamento.
Mais detalhes de avaliação de modelo usando a API CNTK C# podem ser encontrados em
- Avaliação da biblioteca CNTK no Windows
- Avaliação no Azure
- Avaliação em Plataforma Universal do Windows (UWP)
- Pacotes NuGet
Introdução aos exemplos de treinamento em C#
Depois de passar por essa visão geral, você poderá continuar com exemplos de treinamento em C# de duas maneiras: trabalhar com a origem CNTK do GitHub ou trabalhar com exemplos de CNTK usando o CNTK NuGet para Windows.
trabalhar com a origem do CNTK
- Siga as etapas nesta página para configurar o CNTK no Windows.
- Crie CNTK.sln com o Visual Studio.
- Preparar dados de exemplo.
- Executar exemplos como testes de ponta a ponta em CNTKLibraryCSTrainingTest.csproj
trabalhar com exemplos de CNTK com o NuGet do CNTK
- Baixar exemplos de treinamento CNTK C#
- Preparar dados de exemplo.
- Compile e execute os exemplos.