C#/.NET API에서 CNTK 사용

CNTK v2.2.0은 CNTK 모델을 빌드, 학습 및 평가하는 C# API를 제공합니다. 이 섹션에서는 CNTK C# API에 대한 개요를 제공합니다. C# 학습 예제는 CNTK github 리포지토리에서 사용할 수 있습니다.

C#/.NET 관리형 API를 사용하여 심층 신경망 빌드

CNTK C# API는 CNTKLib 네임스페이스에서 기본 작업을 제공합니다. CNTK 작업은 필요한 매개 변수를 사용하여 하나 또는 두 개의 입력 변수를 사용하고 CNTK 함수를 생성합니다. CNTK 함수는 입력 데이터를 출력에 매핑합니다. CNTK 함수는 변수로 처리되고 다른 CNTK 작업에 대한 입력으로 사용될 수도 있습니다. 이 메커니즘을 사용하면 연결 및 구성을 통해 기본 CNTK 작업을 통해 심층 신경망을 빌드할 수 있습니다. 예를 들어


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는 기본 CNTK 작업입니다. 입력 인수는 데이터 기능을 나타내는 CNTK 변수일 수 있습니다. 또 다른 CNTK 함수일 수도 있습니다. 이 코드는 학습 단계에서 조정된 매개 변수를 사용하여 간단한 계산 네트워크를 빌드하여 적절한 다중 클래스 분류자를 만듭니다.

CNTK C# API는 CNN(나선형 신경망) 및 RNN(되풀이 신경망)을 빌드하는 작업을 제공합니다. 예를 들어 2계층 CNN 이미지 분류자를 빌드하려면 다음을 수행합니다.


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

LTSM(장기 메모리)을 사용하여 RNN을 빌드하는 예제도 제공됩니다.

C#/.NET을 사용하여 데이터 준비

CNTK는 학습을 위한 데이터 준비 유틸리티를 제공합니다. CNTK C# API는 이러한 유틸리티를 노출합니다. 다양한 전처리된 양식에서 데이터를 가져옵니다. 데이터 로드 및 일괄 처리는 효율적으로 수행됩니다. 예를 들어 "Train.ctf"라는 다음 CNTK 텍스트 형식의 텍스트에 데이터가 있다고 가정합니다.

|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

CNTK DataSource는 다음과 같은 방식으로 만들어집니다.


    var minibatchSource = MinibatchSource.TextFormatMinibatchSource(
        Path.Combine(DataFolder, "Train.ctf"), streamConfigurations,
        MinibatchSource.InfinitelyRepeat, true);

일괄 처리 데이터를 검색하고 나중에 학습에 사용할 수 있습니다.


    var minibatchData = minibatchSource.GetNextMinibatch(minibatchSize, device);

C#/.NET 관리 API를 사용하여 심층 신경망 학습

SGD(확률적 그라데이션 하강)는 미니배치 학습 데이터를 사용하여 모델 매개 변수를 최적화하는 방법입니다. CNTK는 딥 러닝 문헌에서 일반적으로 볼 수 있는 많은 SGD 변형을 지원합니다. CNTK C# API에 의해 노출됩니다.

다양한 학습 최적화 프로그램의 일반적인 개요는 확률적 그라데이션 하강을 참조하세요.

CNTK 트레이너는 미니배치 교육을 수행하는 데 사용됩니다. 미니배치 학습을 위한 C# 코드 스니핑:


    // 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);
    }

이 코드 스니핑에서는 샘플 학습 속도 = 0.02인 CNTK 기본 제공 SGD 학습자가 사용됩니다. 학습자는 모델의 모든 매개 변수를 최적화하는 것입니다. 학습자, 손실 함수 및 평가 함수를 사용하여 트레이너를 만듭니다. 각 학습 반복 중 미니배치 데이터는 모델 매개 변수를 업데이트하도록 트레이너에게 공급됩니다. 학습 중에 도우미 메서드와 함께 Trainig 손실 및 평가 오류가 표시됩니다.
코드에서는 레이블 및 기능의 통계적으로 분리 가능한 데이터의 두 클래스를 생성합니다. 더 현실적인 다른 예제에서는 공개 테스트 데이터가 CNTK MinibatchSource를 사용하여 로드됩니다.

C#/.NET 관리형 API를 사용하여 심층 신경망 평가

C# API에는 모델 평가를 수행하는 평가 API가 있습니다. 대부분의 C# 학습 예제는 학습 후 모델 평가를 수행합니다.

CNTK C# API를 사용하는 추가 모델 평가 세부 정보는 에서 찾을 수 있습니다.

C# 교육 예제 시작

이 개요를 완료한 후에는 GitHub의 CNTK 원본을 사용하거나 Windows용 CNTK NuGet을 사용하여 CNTK 예제를 사용하는 두 가지 방법으로 C# 교육 예제를 진행할 수 있습니다.

CNTK 원본 작업

  • 페이지의 단계에 따라 창에서 CNTK를 설정합니다.
  • Visual Studio를 사용하여 CNTK.sln을 빌드합니다.
  • 샘플 데이터를 준비합니다.
  • CNTKLibraryCSTrainingTest.csproj에서 엔드투엔드 테스트로 예제 실행

CNTK NuGet을 사용하여 CNTK 예제 사용