TensorFlow.NET (TF.NET) 提供了 TensorFlow 的 .NET Standard 绑定。它旨在用 C# 实现完整的 Tensorflow API,使 .NET 开发人员能够使用跨平台 .NET Standard 框架开发、训练和部署机器学习模型。TensorFlow.NET 内置了 Keras 高级接口,并作为独立软件包发布 TensorFlow.Keras。
English | 中文
[!IMPORTANT] 我们很高兴 tensorflow.net 的工作吸引了许多用户。然而,目前这个仓库的主要维护者都没有空闲时间来开发新功能和修复 bug。我们不会拒绝 PR,并且会帮助审查它们。
如果你想成为 tensorflow.net 的贡献者或维护者,我们愿意帮助你开始。
对此感到非常抱歉,一旦我们有时间,会恢复这个项目的维护。
master 分支和 v0.100.x 对应 tensorflow v2.10,v0.6x 分支从 tensorflow v2.6 开始,v0.15-tensorflow1.15 从 tensorflow1.15 开始。使用 nightly release 请将 https://www.myget.org/F/scisharp/api/v3/index.json
添加到 nuget 源。
为什么选择 Tensorflow.NET?
SciSharp STACK
的使命是将流行的数据科学技术带入 .NET 世界,为 .NET 开发人员提供强大的机器学习工具集,而不需要重新发明轮子。由于 API 尽可能相似,您可以立刻将任何现有的 TensorFlow 代码转化为 C# 或 F#,几乎不需要学习成本。看看比较图,看看用 TensorFlow.NET 如何轻松地将一个 TensorFlow/Python 脚本转化为 C# 程序。
SciSharp 的理念是让大量用 Python 编写的机器学习代码快速迁移到 .NET,使 .NET 开发人员能够使用最先进的机器学习模型并访问大量 TensorFlow 资源,而没有这个项目是无法实现的。
与其他项目相比,比如 TensorFlowSharp,它只提供 TensorFlow 的低级 C++ API 并且只能运行用 Python 构建的模型,Tensorflow.NET 可以使用纯 C# 和 F# 构建训练和推理的管道。此外,Tensorflow.NET 提供了 Tensorflow.Keras 的绑定,使得代码从 Python 转移到 .NET 非常容易。
ML.NET 也采用 Tensorflow.NET 作为训练和推理模型的后端之一,从而实现与 .NET 更好的集成。
文档
介绍和简单示例:Tensorflow.NET 文档
详细文档:Tensorflow.NET 权威指南
运行示例或安装过程中的常见问题:Tensorflow.NET 常见问题
使用方法
安装
您可以在 NuGet 管理器中搜索包名,或在包管理器控制台中使用以下命令。
安装包含两个部分,第一部分是主程序:
### 安装 Tensorflow.NET
PM> Install-Package TensorFlow.NET
### 安装 Tensorflow.Keras
PM> Install-Package TensorFlow.Keras
第二部分是计算支持部分。根据您的设备和系统,只需要以下包之一。
### Windows 和 Linux 的 CPU 版本
PM> Install-Package SciSharp.TensorFlow.Redist
### MacOS 的 CPU 版本
PM> Install-Package SciSharp.TensorFlow.Redist-OSX
### Windows 的 GPU 版本(需要 CUDA 和 cuDNN)
PM> Install-Package SciSharp.TensorFlow.Redist-Windows-GPU
### Linux 的 GPU 版本(需要 CUDA 和 cuDNN)
PM> Install-Package SciSharp.TensorFlow.Redist-Linux-GPU
这里给出两个简单的示例,以介绍 Tensorflow.NET 的基本用法。如您所见,用 C# 编写代码就像用 Python 一样简单。
示例 - 在 Eager
模式下进行线性回归
using static Tensorflow.Binding;
using static Tensorflow.KerasApi;
using Tensorflow;
using Tensorflow.NumPy;
// 参数
var training_steps = 1000;
var learning_rate = 0.01f;
var display_step = 100;
// 样本数据
var X = np.array(3.3f, 4.4f, 5.5f, 6.71f, 6.93f, 4.168f, 9.779f, 6.182f, 7.59f, 2.167f,
7.042f, 10.791f, 5.313f, 7.997f, 5.654f, 9.27f, 3.1f);
var Y = np.array(1.7f, 2.76f, 2.09f, 3.19f, 1.694f, 1.573f, 3.366f, 2.596f, 2.53f, 1.221f,
2.827f, 3.465f, 1.65f, 2.904f, 2.42f, 2.94f, 1.3f);
var n_samples = X.shape[0];
// 为了演示,我们可以设置一个固定的初始值
var W = tf.Variable(-0.06f, name: "weight");
var b = tf.Variable(-0.73f, name: "bias");
var optimizer = keras.optimizers.SGD(learning_rate);
// 训练给定步数
foreach (var step in range(1, training_steps + 1))
{
// 运行优化以更新 W 和 b 的值
// 使用 GradientTape 进行自动微分
using var g = tf.GradientTape();
// 线性回归 (Wx + b)
var pred = W * X + b;
// 平均平方误差
var loss = tf.reduce_sum(tf.pow(pred - Y, 2)) / (2 * n_samples);
// should stop recording
// 计算梯度
var gradients = g.gradient(loss, (W, b));
// 根据梯度更新 W 和 b
optimizer.apply_gradients(zip(gradients, (W, b)));
if (step % display_step == 0)
{
pred = W * X + b;
loss = tf.reduce_sum(tf.pow(pred - Y, 2)) / (2 * n_samples);
print($"step: {step}, loss: {loss.numpy()}, W: {W.numpy()}, b: {b.numpy()}");
}
}
在 Jupyter Notebook 中运行此示例。
示例 - 在 Keras
功能性 API 中的简化版 ResNet
using static Tensorflow.Binding;
using static Tensorflow.KerasApi;
using Tensorflow;
using Tensorflow.NumPy;
var layers = keras.layers; //输入层 var inputs = keras.Input(shape: (32, 32, 3), name: "img"); //卷积层 var x = layers.Conv2D(32, 3, activation: "relu").Apply(inputs); x = layers.Conv2D(64, 3, activation: "relu").Apply(x); var block_1_output = layers.MaxPooling2D(3).Apply(x); x = layers.Conv2D(64, 3, activation: "relu", padding: "same").Apply(block_1_output); x = layers.Conv2D(64, 3, activation: "relu", padding: "same").Apply(x); var block_2_output = layers.Add().Apply(new Tensors(x, block_1_output)); x = layers.Conv2D(64, 3, activation: "relu", padding: "same").Apply(block_2_output); x = layers.Conv2D(64, 3, activation: "relu", padding: "same").Apply(x); var block_3_output = layers.Add().Apply(new Tensors(x, block_2_output)); x = layers.Conv2D(64, 3, activation: "relu").Apply(block_3_output); x = layers.GlobalAveragePooling2D().Apply(x); x = layers.Dense(256, activation: "relu").Apply(x); x = layers.Dropout(0.5f).Apply(x); //输出层 var outputs = layers.Dense(10).Apply(x); //构建Keras模型 var model = keras.Model(inputs, outputs, name: "toy_resnet"); model.summary(); //在TensorFlow静态图中编译Keras模型 model.compile(optimizer: keras.optimizers.RMSprop(1e-3f), loss: keras.losses.SparseCategoricalCrossentropy(from_logits: true), metrics: new[] { "acc" }); //准备数据集 var ((x_train, y_train), (x_test, y_test)) = keras.datasets.cifar10.load_data(); //标准化输入 x_train = x_train / 255.0f; //训练 model.fit(x_train[new Slice(0, 2000)], y_train[new Slice(0, 2000)], batch_size: 64, epochs: 10, validation_split: 0.2f); //保存模型 model.save("./toy_resnet_model");
有关线性回归的F#示例,请参见此处。
更多高级示例可以在TensorFlow.NET Examples找到。
版本关系
TensorFlow.NET 版本 | tensorflow 1.14, cuda 10.0 | tensorflow 1.15, cuda 10.0 | tensorflow 2.3, cuda 10.1 | tensorflow 2.4, cuda 11 | tensorflow 2.7, cuda 11 | tensorflow 2.10, cuda 11 |
---|---|---|---|---|---|---|
tf.net 0.10x, tf.keras 0.10 | x | |||||
tf.net 0.7x, tf.keras 0.7 | x | |||||
tf.net 0.4x, tf.keras 0.5 | x | |||||
tf.net 0.3x, tf.keras 0.4 | x | |||||
tf.net 0.2x | x | x | ||||
tf.net 0.15 | x | x | ||||
tf.net 0.14 | x |
tf.net 0.4x -> tf native 2.4
tf.net 0.6x -> tf native 2.6
tf.net 0.7x -> tf native 2.7
tf.net 0.10x -> tf native 2.10
...
贡献:
想为机器学习领域最热门的项目之一做贡献吗?想知道TensorFlow是如何神奇地创建计算图的吗?
我们感谢每一个微小的贡献!有适合初学者和专家的任务,如果每个人都解决一个小任务,贡献的总和将是巨大的。
您可以:
- 星标TensorFlow.NET或与他人分享
- 告诉我们与TensorFlow相比缺失的API
- 将TensorFlow单元测试从Python移植到C#或F#
- 将TensorFlow示例移植到C#或F#,并在遇到API或BUG的缺失部分时提出问题
- 调试一个被标记为忽略的单元测试,使其工作
- 调试一个尚未工作的示例并使其工作
- 帮助我们完成文档。
如何调试单元测试:
发现单元测试失败的最佳方法是同时在C#或F#和相应的Python中逐步执行它,看看执行流在哪里不同,或变量出现不同的值。好的Python IDE(如PyCharm)可以让你逐步进入TensorFlow库代码。
贡献者的Git知识
将SciSharp/TensorFlow.NET作为上游添加到本地仓库
git remote add upstream git@github.com:SciSharp/TensorFlow.NET.git
请确保您定期从上游拉取更新,保持您的分支最新。
git pull upstream master
支持
购买我们的书籍以使开源项目能持续发展:TensorFlow.NET实战
联系我们
关注我们:Twitter, Facebook, Medium, LinkedIn。
TensorFlow.NET是SciSharp STACK的一部分