AlbiruniML





5.00/5 (1投票)
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); }); } } }