【问题标题】:CNTK Sequences in C#C# 中的 CNTK 序列
【发布时间】:2017-09-25 11:30:06
【问题描述】:

我在 python 中编写了一个工作脚本,用一些数据样本训练 CNTK 模型。现在我试图在 CNTK V2.2 中将它翻译成 C#,但我得到了不同的结果。

这是我在 Python 中创建模型的内容:

def create_model_function(num_hidden_layers,hidden_layers_dim,num_output_classes):
    return Sequential([For(range(num_hidden_layers)
                           , lambda i: Dense(hidden_layers_dim
                           , activation=cntk.tanh))
                           , Dense(num_classes,init=cntk.glorot_uniform()
                           , activation=cntk.softmax)])

谢谢


我的 C# 函数如下所示:

private Function CreateModel(DeviceDescriptor device, int HiddenLayerCount, int HiddenLayerDimension,int OutputClassesCount, Variable Input)
    {

        Function[] HiddenLayers= new Function[HiddenLayerCount];
        for (int i = 1; i < HiddenLayerCount - 1; i++)
        {
            HiddenLayers[i] = Dense(HiddenLayers[i - 1], HiddenLayerDimension, device, Activation.Tanh, "");
        }

       return Dense(HiddenLayers[HiddenLayerCount-1], OutputClassesCount, device, Activation.Sigmoid, "");

    }

我只是不确定这是否等同于 Python 顺序。

【问题讨论】:

  • 你的等效 C# 代码是什么?结果有何不同?
  • 我试过这个函数: private Function CreateModel(DeviceDescriptor device, int HiddenLayerCount, int HiddenLayerDimension,int OutputClassesCount, Variable Input) { Function[] HiddenLayers= new Function[HiddenLayerCount]; for (int i = 1; i

标签: c# .net cntk


【解决方案1】:

C# 尚不直接支持 Python Dense 函数。您在 C# 中使用的 Dense 函数可能与 CNTK Python 实现不同。您能否使用 C# 中可用的运算符在 C# 和 python 中构建一个模型,看看它们是否相同?

我附上了一个 C# 函数来帮助您检查模型图。将它与加载到 C# 中的 python 模型一起使用,并与您在 C# 中创建的模型进行比较。谢谢。

    static void PrintGraph(Function function, int spaces, bool useName = false)
    {
        string indent = new string('.', spaces);
        if (function.Inputs.Count() == 0)
        {
            Console.WriteLine(indent + "(" + (useName ? function.Name : function.Uid) + ")" +
                "(" + function.OpName + ")" + function.AsString());
            return;
        }

        foreach (var input in function.Inputs)
        {
            Console.WriteLine(indent + "(" + (useName ? function.Name : function.Uid) + ")" +
                "(" + function.OpName + ")" + "->" +
                "(" + (useName ? input.Name : input.Uid) + ")" + input.AsString());
        }

        foreach (var input in function.Inputs)
        {
            if (input.Owner != null)
            {
                Function f = input.Owner;
                PrintGraph(f, spaces + 4, useName);
            }
        }
    }

【讨论】:

    【解决方案2】:

    以下示例显示了从左到右的简单前馈路径。

    要生成深度网络, 根据您的要求控制 FOR LOOP。

    在这个例子中, 循环控制正在修改具有偶数和奇数循环计数的节点数。 CreateUniteLayer 构建一个单元层 - 左侧的 LXNodes 连接到右侧的 LYNodes。 其他变量自行解释。

    需要 ParameterVector NetParamVec 来创建训练器。 如果您使用 CNTKLib.xxxx_learner 函数,请将此作为参数传递。

    仔细检查输入要素与第一层的连通性, 第一层到中间层 然后最后一层连接 最后导致sigmoid。 根据需要适当调整 LXNodes 和 LYNodes 变量。

    将此代码添加到类中或将其拉入适合您的应用程序的方法中。

    如果构建相同节点大小的所有层, LXNodes = LYNodes = 每层节点数

    NetOut 代表深度网络的最终输出。

    希望这有助于建立您正在寻找的网络。

    最好的祝愿。

    List<Function> Layers  = new List<Function>() ; 
    ParameterVector NetParamVec = new ParameterVector ();
    
    // Define first layer immediately after input.
    Function layer1 = CreateUnitLayer(features, LXNodes, inputDim, "NetLayer0", InitWeight, InitBias); 
    Layers.Add(layer1);
    
    //Defines Intermediate hidden layers
    for (int i = 1; i < LayerCount; i++)
    {
       Function ly; 
       if (i % 2 == 0) 
          ly = CreateUnitLayer(Layers[i - 1], LXNodes, LYNodes, "NetLayer" + i.ToString(), InitWeight, InitBias);
       else
           ly = CreateUnitLayer(Layers[i - 1], LYNodes, LXNodes, "NetLayer" + i.ToString(), InitWeight, InitBias);
       Layers.Add(ly);
    }
    
    //Defines Last layer 
    int lastDim = LXNodes; 
    if (LayerCount % 2 == 0)lastDim = LYNodes;
    Function layerLast = CreateUnitLayer(Layers[LayerCount - 1], outDim, lastDim, "NetLayerOut", InitWeight, InitBias);
    Layers.Add(layerLast);
    
    Function NetOut = CNTKLib.Sigmoid(layerLast);
    
    public Function CreateUnitLayer(Variable LXIn, int LYNodes, int LXNodes, string LYName, float InitWeight, float InitBias)
    {
         Parameter weightParamy = new Parameter(new int[] { LYNodes, LXNodes }, DataType.Float, InitWeight, device, "W" + LYName);
         Parameter biasParamy = new Parameter(new int[] { LYNodes }, DataType.Float, InitBias, device, "B" + LYName);
         Function LayerY = CNTKLib.Plus(CNTKLib.Times(weightParamy, LXIn), biasParamy);
         NetParamVec.Add(weightParamy);
         NetParamVec.Add(biasParamy);
         return LayerY;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-24
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多