2017-09-04 7 views
3

온라인 학습을 위해 CNTK의 C++ API를 사용하려고합니다. 단위 테스트의 소스 코드와 CNTKLibrary.h 헤더를 읽는 동안 Trainer.TrainMinibatch 메서드 만 모델을 훈련 시켰습니다. 이 방법을 사용하여 단일 입출력 데이터 포인트를 전달할 수 있습니까? 가능하다면 가장 쉬운 방법은 무엇입니까? C++을 사용하는 CNTK의 이진 분류 자 ​​

은 내가 다음 TrainMinibatch 기능에 사용하고자 시퀀스를 생성 할 CNTK::Value::CreateSequence 방법을 사용했지만, 나는 그것이 작동 것으로 예상되는 방식으로 작동하지 않는 그 :

내가이 python 코드 포트에 노력을 C++ :

num_hidden_layers = 2 
num_output_classes = 2 
input_dim = 1 
hidden_layers_dim = 400 

input_var = C.input_variable(input_dim) 
label_var = C.input_variable(num_output_classes) 

def create_model(features): 
    with C.layers.default_options(init = C.glorot_uniform(), activation=C.ops.relu): 
     h = features 
     for _ in range(num_hidden_layers): 
      h = C.layers.Dense(hidden_layers_dim, activation=C.sigmoid)(h) 
     r = C.layers.Dense(num_output_classes, activation=None)(h) 
     return r 

z = create_model(input_var) 
loss = C.cross_entropy_with_softmax(z, label_var) 
label_error = C.classification_error(z, label_var) 

learning_rate = 0.2 
lr_schedule = C.learning_rate_schedule(learning_rate, C.UnitType.minibatch) 
learner = C.sgd(z.parameters, lr_schedule) 
trainer = C.Trainer(z, (loss, label_error), [learner]) 

input_map = { label_var : None, input_var : None} 
training_progress_output_freq = 500 

for i in range(0, 10000): 
    input_map[input_var] = np.array([np.random.randint(0,2)], dtype=np.float32); 
    if input_map[input_var] == 0: 
     input_map[label_var] = np.array([1,0], dtype=np.float32) 
    else: 
     input_map[label_var] = np.array([0, 1], dtype=np.float32) 
    trainer.train_minibatch(input_map) 

내가이 C로 결국 ++ 코드 :

const size_t inputDim = 1;// 28 * 28; 
const size_t numOutputClasses = 2;// 10; 
const size_t hiddenLayerDim = 400; 
const size_t numHiddenLayers = 2; 

//build the model 
auto input = InputVariable({ inputDim }, DataType::Float, L"features"); 
FunctionPtr classifierOutput = input; 
for (int i = 0; i < numHiddenLayers; i++) 
{ 
    classifierOutput = FullyConnectedDNNLayer(classifierOutput, hiddenLayerDim, device, std::bind(Sigmoid, _1, L"")); 
} 
classifierOutput = FullyConnectedLinearLayer(classifierOutput, 2, device); 

auto labels = InputVariable({ numOutputClasses }, DataType::Float, L"labels"); 
auto trainingLoss = CrossEntropyWithSoftmax(classifierOutput, labels, L"lossFunction"); 
auto prediction = Minus(Constant::Scalar(1.0f, device), ClassificationError(classifierOutput, labels, L"classificationError")); 

LearningRatePerMinibatchSchedule learningRatePerSample = 0.2; 
auto trainer = CreateTrainer(classifierOutput, trainingLoss, prediction, 
{ SGDLearner(classifierOutput->Parameters(), learningRatePerSample) } 
); 

std::cout << "Starting to train...\n"; 
size_t outputFrequencyInMinibatches = 500; 
for (size_t i = 0; i < 10000; ++i) 
{ 
    //input data 
    std::vector<float> inputData(1); 
    inputData[0] = ((float)rand())/RAND_MAX; 

    //output data 
    std::vector<float> outputData(2); 
    outputData[0] = inputData[0] > 0.5 ? 1.0 : 0.0; 
    outputData[1] = 1.0 - outputData[0]; 

    ValuePtr inputSequence = CNTK::Value::CreateSequence(NDShape({ 1 }), inputData, device); 
    ValuePtr outputSequence = CNTK::Value::CreateSequence(NDShape({ 2 }), outputData, device); 

    std::unordered_map<Variable, ValuePtr> map = {{ input, inputSequence }, { labels, outputSequence } }; 
    trainer->TrainMinibatch(map, device); 
} 

내가 코드를 컴파일 할 수 오전 C++ 버전의 손실은 0으로 수렴하지 않습니다. 몇 백 번 반복 한 후 파이썬 버전에서 손실이 더 나

답변

1

그것은 파이썬의 입력 데이터를 0 또는 1 것 같다 ... 0 이하 :

input_map[input_var] = np.array([np.random.randint(0,2)], dtype=np.float32); 

동안 C++ 코드에서 사이 부동의를 0 및 1

//input data 
std::vector<float> inputData(1); 
inputData[0] = ((float)rand())/RAND_MAX; 

컨버전스 속도가 다른지 확인하십시오.