编程语言
首页 > 编程语言> > 使用C#加载(预训练)的CNTK模型

使用C#加载(预训练)的CNTK模型

作者:互联网

我正在使用CNTK.GPU v2.2.0,并使用以下方法保存了模型:

model.Save(modelFilePath);

现在我想再次加载它,例如继续训练或只是评估样本.我可以看到两种方式.一种方法可行,但不可行.第二个不起作用.

>我再次从头开始构建神经网络的整个结构,然后在其上调用以下方法:

model.Restore(modelFilePath);

确实,这可行.

>我使用以下静态方法创建模型:

Function.Load(modelFilePath, DeviceDescriptor.GPUDevice(0));

这是行不通的.

完成这些操作后,我只为模型创建了一个训练器,创建了一个minibatchSource并尝试以与保存模型之前相同的方式训练模型.

但是使用第二种策略时,我得到以下异常:

System.ArgumentOutOfRangeException:’1个必需参数’Input(‘features’,[28 x 28 x 1],[,#])’的值,即请求的输出’Output(‘aggregateLoss’,[],[ ]),Output(‘lossFunction’,[1],[,#]),Output(‘aggregateEvalMetric’,[],[])’依赖,尚未提供.

[CALL STACK]
    > CNTK::Internal::  UseSparseGradientAggregationInDataParallelSGD
    - CNTK::Function::  Forward
    - CNTK::  CreateTrainer
    - CNTK::Trainer::  TotalNumberOfSamplesSeen
    - CNTK::Trainer::  TrainMinibatch (x2)
    - CSharp_CNTK_Trainer_TrainMinibatch__SWIG_0
    - 00007FFA34AE8967 (SymFromAddr() error: The specified module could not be found.)

它说尚未提供输入功能.在训练和从头开始创建模型时,我正在使用输入:

var input = CNTKLib.InputVariable(_imageDimension, DataType.Float, _featureName);
var scaledInput = CNTKLib.ElementTimes(Constant.Scalar<float>(0.002953125f, _device), input);
...

因此,我认为我必须将加载的模型的输入替换为我为训练而创建的模型,并在从头开始创建模型时使用它-尽管输入没有不同.
但是我坚持尝试一下,因为我无法检索模型对象的输入,而我需要替换该输入(我认为).

model.FindByName(inputLayerName);

只是返回null,尽管我可以清楚地看到该名称与调试器中模型的“输入”列表中的图层名称匹配.

结果,我不知道如何正确加载保存的模型.我希望有一个人可以帮助我.

解决方法:

幸运的是,我自己找到了答案.我将其张贴在这里,因为可能还有其他CNTK初学者,他们可能会在这个问题上迷失方向,或者通常想知道如何正确加载模型.

问题是我没有使用相同的输入对象进行训练和模型创建.换句话说,如果让我通过提到的静态方法创建模型,我仍然必须确保模型中的对象与用于训练的对象相同.这应该通过以下方式实现:

>用您自己的输入对象替换已加载模型的输入,并将其用于训练.我没有测试,但是应该可以.
>提取已加载模型的输入并将其用于训练.我刚刚测试了它,它起作用了.
有我使用的代码:

var labels =
    CNTKLib.InputVariable(new int[] {_classesNumber}, DataType.Float, _labelNa

Variable input;
Function model;
if (File.Exists(_modelFile))
{
    model = Function.Load(_modelFile, DeviceDescriptor.GPUDevice(0));
    input = model.Arguments.Single(a => a.Name == _featureName);
}
else
{
    input = CNTKLib.InputVariable(_imageDimension, DataType.Float, _featureName);
    model = BuildNetwork(input);
}

var trainer = CreateTrainer(model, labels);

IList<StreamConfiguration> streamConfigurations = new StreamConfiguration[]
{
    new StreamConfiguration(_featureName, _imageSize), 
    new StreamConfiguration(_labelName, _classesNumber)
};

var minibatchSource = MinibatchSource.TextFormatMinibatchSource(
    Path.Combine(_ressourceFolder, _trainingDataFile),
    streamConfigurations,
    MinibatchSource.InfinitelyRepeat);

TrainModel(minibatchSource, trainer, labels, input);

我一开始也犯了一个错误,就是使用

Variable layer model.FindByName(inputLayerName)

虽然我不得不用

Variable layer = model.Arguments.Single(a => a.Name == inputLayerName);

标签:cntk,c
来源: https://codeday.me/bug/20191110/2015570.html