65.9K
CodeProject 正在变化。 阅读更多。
Home

AlbiruniML

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2024年9月25日

GPL3

2分钟阅读

viewsIcon

5624

downloadIcon

60

AlbiruniML 是一个用纯 C# 语言编写的线性代数和机器学习库,灵感来自 tensorflow

AlbiruniML

AlbiruniML 是一个用纯 C# 语言编写的线性代数和机器学习库,灵感来自 TensorFlow 和 TensorFlow.js 团队的优秀工作。目前仅支持 CPU,很快将添加 cblas 本地支持,并且未来也将支持 GPU 内核“CUDA”。

主要特点

  • 只能使用浮点数数据类型。
  • 支持 NDArray 和 Tensor 操作
  • 自动微分
  • 易于导入许多 TensorFlow 模型。

构建库

目前没有第三方组件,可以直接在 x64 位环境中从 Visual Studio 构建。其他平台尚未测试。

使用库

与 TensorFlow 和 TensorFlow.js 一样,AlbiruniML 使用 Tensor 数据结构作为其所有操作的基本数据结构。Tensor 是向量、矩阵、体积或更高维度数组的推广。

要使用 AlbiruniML,首先添加所需的命名空间。

using Albiruni;
using alb = Albiruni.Ops;

对于一个简单的逻辑回归任务,其中数字小于 15 为假,大于 15 为真,我们生成数据集和标签如下

Tensor xs1 = new float[] 
{ 1f, 20f, 11f, 21f, 15, 25, 5, 30, 4, 20, 6, 11.5f, 22 }.ToTensor();
Tensor ys1 = new float[] 
{ 0f, 1f, 0f, 1f, 0, 1, 0, 1, 0, 1, 0, 0, 1 }.ToTensor();

接下来,我们定义变量 a 和 b,并使用随机值进行训练。

Random r = new Random();
var a = alb.variable(alb.scalar((float)r.NextDouble()));
var c = alb.variable(alb.scalar(0));

为了优化这些变量,我们需要一个优化器,我们将使用一个简单的随机梯度下降优化器,学习率为 0.1

var learningRate = 0.1f;
var optimizer = alb.train.sgd(learningRate);

接下来,我们定义我们的简单逻辑回归模型

Func<Tensor, Tensor> model = (Tensor x) =>
{  
        var y = a * x  + c;   
        return y.sigmoid(); 
};

接下来,我们定义训练循环并执行优化器的 minimize 函数。

Minimize 是魔法发生的地方,我们必须返回一个数值估计(即损失)来衡量我们使用变量的当前状态表现如何。

这里我们使用均方误差损失函数

这个优化器执行我们训练数据的“反向”步骤,更新先前定义的变量,以最小化损失。

Action<Tensor, Tensor, int, Action> train = (Tensor examples, Tensor label, int numIterations, Action done) =>
{
    for (int iter = 0; iter < numIterations; iter++)
    {  
            optimizer.minimize(() =>
            { 
                //Feed the examples into the model
                var pred = model(examples);
                var predLoss = alb.loss.meanSquaredError(label, pred);
                return predLoss;
            });
    } 
    done();
};

接下来,我们定义一个测试函数来检查我们的模型性能与标签的匹配程度

Action<Tensor, Tensor> test = (Tensor xs, Tensor ys) =>
{
    var xvalues = xs.ToArray();
    var yvalues = ys.ToArray();
    //Execute the model
    var predictedYs = model(xs).ToArray(); 
    Console.Write("Expected : ");
    for (int i = 0; i < yvalues.Length; i++)
    {
        Console.Write( yvalues[i].ToString()+", " );
    }
    Console.WriteLine();
    Console.Write("Got      : ");
    for (int i = 0; i < predictedYs.Length; i++)
    {
        var pred = predictedYs[i] > 0.5f ? 1 : 0;
        Console.Write( pred.ToString()+", " );
    } 
};

最后,我们启动训练过程并测试训练后的变量。

train(xs1, ys1, 1000, () =>
{ 
    test(xs1, ys1); 
});

输出应该如下所示

Expected : 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,
Got      : 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,

这里是完整的示例

using System;
using Albiruni;
using alb = Albiruni.Ops;
namespace SimpleExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Tensor xs1 = new float[] 
            { 1f, 20f, 11f, 21f, 15, 25, 5, 30, 4, 20, 6, 11.5f, 22 }.ToTensor();

            Tensor ys1 = new float[] 
            { 0f, 1f, 0f, 1f, 0, 1, 0, 1, 0, 1, 0, 0, 1 }.ToTensor();

            Random r = new Random();
            var a = alb.variable(alb.scalar((float)r.NextDouble()));
            var c = alb.variable(alb.scalar(0));
             
            var learningRate = 0.1f;
            var optimizer = alb.train.sgd(learningRate);
             
            Func<Tensor, Tensor> model = (Tensor x) =>
            {
                var y = a * x + c;
                return y.sigmoid();
            };
             
            Action<Tensor, Tensor, int, Action> train = 
            (Tensor examples, Tensor label, int numIterations, Action done) =>
            {
                for (int iter = 0; iter < numIterations; iter++)
                {
                    optimizer.minimize(() =>
                    {
                        // Feed the examples into the model
                        var pred = model(examples);
                        var predLoss = alb.loss.meanSquaredError(label, pred);
                        return predLoss;
                    });
                }
                done();
            };

            Action<Tensor, Tensor> test = (Tensor xs, Tensor ys) =>
            {
                var xvalues = xs.ToArray();
                var yvalues = ys.ToArray();
                var predictedYs = model(xs).ToArray();
                Console.Write("Expected : ");
                for (int i = 0; i < yvalues.Length; i++)
                {
                    Console.Write(yvalues[i].ToString() +", ");
                }
                Console.WriteLine();
                Console.Write("Got      : ");
                for (int i = 0; i < predictedYs.Length; i++)
                {
                    var pred = predictedYs[i] > 0.5f ? 1 : 0;
                    Console.Write(pred.ToString() + ", ");
                }
            };

            train(xs1, ys1, 1000, () =>
            {
                test(xs1, ys1); 
            });
        } 
    }
}

更多示例 AlbiruniML

© . All rights reserved.