基于CNTK/C#实现逻辑回归【附源码】


前言

本文基于CNTK实现逻辑回归二分类,并以之前的不同,本次使用C#实现,不适用python,python版的CNTK比较简单,而且python版的cntk个人感觉没什么必要,毕竟是微软的框架因此本人强迫症犯了,所以使用C#实现CNTK
环境版本:
Visualstudio 2022
C# .net4.6
cntk 2.7
cuda 10.1


一、VS2022+CNTK环境搭建

首先把CNTK的需要的dll解压出来,可直接从此处免费下载:
CNTK安装
然后再项目上引入dll,如图:
在这里插入图片描述


二、逻辑回归代码构建

1.逻辑回归构建

在这里插入图片描述
从网上对逻辑回归的图的解释,可以使用CNTK很容易就可以构建逻辑回归的结构

private static Function CreateLinearModel(Variable input, int outputDim, DeviceDescriptor device)
{
    int inputDim = input.Shape[0];
    var weightParam = new Parameter(new int[] { outputDim, inputDim }, DataType.Float, 1, device, "w");
    var biasParam = new Parameter(new int[] { outputDim }, DataType.Float, 0, device, "b");

    return CNTKLib.Times(weightParam, input) + biasParam;
}

这里的可以简单的理解为y=kx+b的结构。

2.训练数据的生成

这里主要是每次训练的时候会生成一批数据,首先对输入批次/输出批次构建数组,然后使用随机数种子,生成一批数据,服从高斯分布随机数,注意这里的mean和std

private static double GenerateGaussianNoise(double mean, double stdDev, Random random)
{
     double u1 = 1.0 - random.NextDouble();
     double u2 = 1.0 - random.NextDouble();
     double stdNormalRandomValue = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
     return mean + stdDev * stdNormalRandomValue;
 }
 private static void GenerateRawDataSamples(int sampleSize, int inputDim, int numOutputClasses, out float[] features, out float[] oneHotLabels)
 {
     Random random = new Random(0);

     features = new float[sampleSize * inputDim];
     oneHotLabels = new float[sampleSize * numOutputClasses];

     for (int sample = 0; sample < sampleSize; sample++)
     {
         int label = random.Next(numOutputClasses);
         for (int i = 0; i < numOutputClasses; i++)
         {
             oneHotLabels[sample * numOutputClasses + i] = label == i ? 1 : 0;
         }

         for (int i = 0; i < inputDim; i++)
         {
             features[sample * inputDim + i] = (float)GenerateGaussianNoise(3, 1, random) * (label + 1);
         }
     }
 }

3.模型训练

static void Main(string[] args)
{
    //设置逻辑回归的输入和输出的量,三入二出,因逻辑回归基本是二分类,因此这里输出的是2
    int inputDim = 3;
    int numOutputClasses = 2;
    
    //使用GPU模块
    var device = DeviceDescriptor.GPUDevice(0);
    
    //设置输入输出
    Variable featureVariable = Variable.InputVariable(new int[] { inputDim }, DataType.Float);
    Variable labelVariable = Variable.InputVariable(new int[] { numOutputClasses }, DataType.Float);

    //网络结构的构建及损失计算,这里使用CNTK的Softmax
    var classifierOutput = CreateLinearModel(featureVariable, numOutputClasses, device);
    var loss = CNTKLib.CrossEntropyWithSoftmax(classifierOutput, labelVariable);
    var evalError = CNTKLib.ClassificationError(classifierOutput, labelVariable);
    
    //学习率的设置
    TrainingParameterScheduleDouble learningRatePerSample = new TrainingParameterScheduleDouble(0.02, 1);
    IList<Learner> parameterLearners = new List<Learner>() { Learner.SGDLearner(classifierOutput.Parameters(), learningRatePerSample) };

    //构建训练迭代器
    var trainer = Trainer.CreateTrainer(classifierOutput, loss, evalError, parameterLearners);

    //训练批次
    int minibatchSize = 64;
    int numMinibatchesToTrain = 10000;
    int updatePerMinibatches = 10;

    // 循环训练
    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);

        PrintTrainingProgress(trainer, minibatchCount, updatePerMinibatches);
    }
    Console.ReadLine();
}

三、效果展示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的广东仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值