{"id":19174991,"url":"https://github.com/losttech/gradient","last_synced_at":"2025-03-17T16:12:05.466Z","repository":{"id":65411290,"uuid":"160905085","full_name":"losttech/Gradient","owner":"losttech","description":"This repository serves as a public issue tracker and documentation host for Gradient, full TensorFlow binding for .NET","archived":false,"fork":false,"pushed_at":"2021-02-11T06:05:41.000Z","size":50,"stargazers_count":86,"open_issues_count":7,"forks_count":4,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-02T13:12:10.842Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/losttech.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-TECH-PREVIEW.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-08T04:50:48.000Z","updated_at":"2023-11-21T15:38:21.000Z","dependencies_parsed_at":"2023-01-22T06:45:38.110Z","dependency_job_id":null,"html_url":"https://github.com/losttech/Gradient","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FGradient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FGradient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FGradient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/losttech%2FGradient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/losttech","download_url":"https://codeload.github.com/losttech/Gradient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244066189,"owners_count":20392406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T10:20:17.263Z","updated_at":"2025-03-17T16:12:05.436Z","avatar_url":"https://github.com/losttech.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":":toc: macro\n:toc-title: \n:toclevels: 3\n:language: csharp\n\n# LostTech.TensorFlow (formerly Gradient)\nThis repository serves as a public issue tracker and documentation for LostTech.TensorFlow, full TensorFlow binding for .NET\n\n[link=https://www.nuget.org/packages/LostTech.TensorFlow/]\nimage::https://img.shields.io/nuget/v/LostTech.TensorFlow.svg[NuGet]\n\nLostTech.TensorFlow enables .NET developers to use the complete set of TensorFlow APIs from any .NET language.\n\nYou can find samples at https://github.com/losttech/Gradient-Samples\n\nFull API documentation is available at https://gradient.docs.losttech.software/\n\n[quote, Char-RNN trained on Shakespeare]\nHe shall speak not reverbering injurance.\n\n# Contents\ntoc::[]\n\n# Getting started\n## Supported platforms\nLostTech.TensorFlow is fully supported on Windows, MacOS, and Linux on AMD64/x64\narchitecture. It might work on other OS/CPU architecture combinations, but will\nonly be supported on the best effort basis.\n\n## Installation\n### Install Python + Tensorflow\nBefore installing LostTech.TensorFlow, you should ensure, that you have\nTensorFlow installed and working (or use \u003c\u003cusing_packaged_environment,packaged environment\u003e\u003e from NuGet):\n\n. Install Python 3.7 64-bit. If you have Visual Studio 2017+, it is possible to install it as a component. Otherwise, get one from https://www.python.org/downloads/ or your system's package manager\n. Install TensorFlow 1.15.0 (1.15.1+ release has a https://github.com/tensorflow/tensorflow/issues/36417[critical bug])\n using pip (https://www.tensorflow.org/install/[official instructions]):\n.. Find `python` executable in the installation directory (VS installs to: C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python36_64\\python.exe)\n.. Open command line to the directory, containing `python`\n.. Execute `.\\python -m pip install \"tensorflow-gpu==1.15.0\"` or `.\\python -m pip install \"tensorflow-cpu==1.15.0\"`.\nGPU acceleration requires matching CuDNN and CUDA 10 installed,\nsee https://www.tensorflow.org/install/gpu#older_versions_of_tensorflow[instructions].\n. Check the installation by launching `python`, and running [source,python]`import tensorflow`. It should succeed.\n\n### Add Nuget package to your project\n\nLostTech.TensorFlow packages are published on https://www.nuget.org/packages/LostTech.TensorFlow/[Nuget].\nNuget page lists the commands, necessary to install the package into your\nproject. For dotnet-based projects CLI command is\n\n[source,powershell]\n----\ndotnet add package LostTech.TensorFlow --pre\n----\n\nIf using the new package management features of `.csproj`, this could also be achieved by adding the following line to it:\n\n[source,xml]\n----\n\u003cPackageReference Include=\"LostTech.TensorFlow\" Version=\"1.15.0-RC1\" /\u003e\n----\n\nSee the example project file https://github.com/losttech/Gradient-Samples/blob/master/BasicMath/BasicMath.csproj[here].\n\n## First steps\n\n### Packages and Namespaces\nIn most cases, you will need to add `using tensorflow;` at the beginning of your\nfile. In many cases you will also need `using LostTech.TensorFlow;` and\n`using numpy;`.\n\n[source,csharp]\n----\nusing numpy;\nusing tensorflow;\nusing LostTech.TensorFlow;\n----\n\nCommercial users will also need to add a https://www.nuget.org/packages/LostTech.Gradient.License.Azure/[licensing package for Pay-As-You-Go]:\n[link=https://www.nuget.org/packages/LostTech.Gradient.License.Azure/]\nimage::https://img.shields.io/nuget/v/LostTech.Gradient.License.Azure.svg[NuGet]\n\nAnd configure the key from the https://lt-tf-lic-portal.azurewebsites.net/Home/Subscriptions[Subscriptions Page].\n\n[source,csharp]\n----\nusing LostTech.TensorFlow;\nusing LostTech.TensorFlow.Licensing;\nTensorFlowSetup.Instance.UseLicense(new AzureLicense(\"...Key Goes Here...\"));\nTensorFlowSetup.Instance.EnsureInitialized();\n----\n\n### Logging\nhttps://www.tensorflow.org/versions/r1.15/api_docs/python/tf/compat/v1/logging[TensorFlow logging]\nis separate from LostTech.TensorFlow logging. This section discusses the later.\n\nLostTech.TensorFlow core runtime library is https://www.nuget.org/packages/Gradient.Runtime/[Gradient.Runtime].\nTo configure runtime logging, set appropriate properties of https://gradient.docs.losttech.software/Runtime/v0.4.2/LostTech.Gradient/GradientLog.htm[`LostTech.Gradient.GradientLog`] static class, e.g.:\n[source,csharp]\nGradientLog.OutputWriter = Console.Out;\n\n### Selecting Python environment\nIf you want to use TensorFlow with non-default configuration (e.g. different versions instead of Python 3.7 + TensorFlow 1.15),\nuse one of `LostTech.Gradient.GradientEngine.UseEnvironment*` methods before accessing any TensorFlow methods to select the desired TensorFlow installation.\n\nWe also recommend to explicitly call `TensorFlowSetup.Instance.EnsureInitialized()`\nto be able to catch any problems with TensorFlow installation. This is especially important\nin production systems.\n\n### Using packaged environment\n[link=https://www.nuget.org/packages/LostTech.TensorFlow.Python/]\nimage::https://img.shields.io/nuget/v/LostTech.TensorFlow.Python.svg[NuGet]\n1. Install NuGet package https://www.nuget.org/packages/LostTech.TensorFlow.Python[LostTech.TensorFlow.Python]\n2. Deploy TensorFlow from the package and configure the engine to use it:\n\n[source,csharp]\n----\nvar pyEnv = LostTech.TensorFlow.PackagedTensorFlow.EnsureDeployed(DIRECTORY);\nGradientEngine.UseEnvironment(pyEnv);\n----\n\n### Old style TF\nPrior to the recent changes, the main way to use TensorFlow was to contstruct a computation graph, and then run it in a session. Most of the existing examples will use this mode.\n\n#### Constructing compute graph\n`Graph` creation methods are located in the `tf` class from `tensorflow` namespace. For example:\n\n[source,csharp]\n----\nvar a = tf.constant(5.0, name: \"a\");\nvar b = tf.constant(10.0, name: \"b\");\n\nvar sum = tf.add(a, b, name: \"sum\");\nvar div = tf.div(a, b, name: \"div\");\n----\n\n#### Running computation\nNext, you need to create a `Session` to run your graph one or multiple times. Sessions allocate CPU, GPU and memory resources, and hold the states of variables.\n\nNOTE: In GPU mode, TensorFlow will attempt to allocate all the GPU memory to itself at that stage,\nso ensure you don't have any other programs extensively using it, or https://stackoverflow.com/questions/34199233/how-to-prevent-tensorflow-from-allocating-the-totality-of-a-gpu-memory[turn down TensorFlow memory allocation]\n\nSince TensorFlow sessions hold unmanaged resources, they have to be used with `IDisposable` pattern:\n[source,csharp]\n----\nvar session = new Session();\nusing(session.StartUsing()) {\n    ...do something with the session...\n});\n----\n\nNow that you have a `Session` to work with, you can actually compute the values in the graph:\n\n[source,csharp]\n----\nvar session = new Session();\nusing(session.StartUsing()) {\n    Console.WriteLine($\"a = {session.run(a)}\");\n    Console.WriteLine($\"b = {session.run(b)}\");\n    Console.WriteLine($\"a + b = {session.run(sum)}\");\n    Console.WriteLine($\"a / b = {session.run(div)}\");\n};\n----\n\nThe full code for this example is available at our https://github.com/losttech/Gradient-Samples/tree/master/BasicMath[samples repository]\n\n# Porting Python code to LostTech.TensorFlow + C#\nIn most cases converting Python code, that uses TensorFlow, should be as easy as using C# syntax instead of Python one:\n\n * add `new` to class constructor calls: `Class()` -\u003e `new Class()`.\n\n__Its easy to spot class construction vs simple function calls in Python:\nby convention function names there start with a lower case letter like `min`,\nwhile in class names the first letter is capitalized: `Session` __\n\n * to pass named paramters, use `:` instead of `=`: `make_layer(kernel_bias=2.0)` -\u003e `make_layer(kernel_bias: 2.0)`\n * to get a subrange of a `Tensor` , use \u003c\u003ccsharp8\u003e\u003e syntax (if available): `tensor[1..-2]` -\u003e `tensor[1..^3]` (when using C# 8 ranges, note, that the right side in C# is *INCLUSIVE*, while in Python it is *EXCLUSIVE*). A single element can be addressed as usual: `tensor[1]`\n\n## Names of classes and functions\nGenerally, LostTech.TensorFlow follows TensorFlow https://www.tensorflow.org/versions/r1.15/api_docs/python/tf[Python API] naming.\nThere are, though, language-based differences:\n\n* in Python modules (roughly equivalent to namespaces) can directly contain functions. In .NET every function must be a part of some type. For that reason LostTech.TensorFlow exposes static classes, named after the innermost module name to contain module functions and properties (but not classes). For example, Python's `tensorflow.contrib.data` module has a correspoding C# class `tensorflow.contrib.data.data`. So an equivalent of Python's `tensorflow.contrib.data.group_by_window` would be `tensorflow.contrib.data.data.group_by_window`. This mostly applies to the unofficial APIs.\n* most of the official API's functions and properties (but *not* classes) are exposed via a special class `tensorflow.tf`. Combined with `using tensorflow;` this enables invoking TensorFlow functions as neatly as: `tf.placeholder(...)`, `tf.keras.activations.relu(...)`, etc\n\n__there is also a similar class__ `numpy.np` __for NumPy functions__\n\n* class names and namespaces are mostly the same as in Python API.\nE.g. https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/Session[`tf.Session`] is in `tensorflow` namespace,\nand can be instantiated via `new tensorflow.Session(...)` or simply `new Session(...)` with `using tensorflow;`\n\n* some APIs have multiple aliases, like https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/add[tf.add].\nOnly one of the aliases is exposed by LostTech.TensorFlow. Usually the shortest one.\n\n* in case of name conflicts (e.g. C# does not allow both `shape` property and `set_shape` method in the same class),\none of the conflicting names is exposed with suffix `$$_$$`. For example: `set_shape$$_$$`, which should be easy to find in IDE autocomplete list.\n\n* (very rare) due to the way LostTech.TensorFlow works, non-official classes, functions and properties might be exposed via unexpected namespaces.\nIDE should be able to help find classes (by suggesting to add an appropriate `using namespace;`). For functions and properties, one might try to find the class, corresponding to their containing module (see the example with `tensorflow.contrib.data` above, you could search for the `data` class). Another less convenient alternative is to use Visual Studio's Object Explorer.\n\n* (rare) some classes and functions, exposed by TensorFlow might only be exposed as function-typed properties.\nFor example, https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/ConfigProto[`ConfigProto`],\nthat is used to configure `tf.Session` does not have a correspoing class in LostTech.TensorFlow.\nTo create an instance of `ConfigProto`, you must call its constructor via `ConfigProto` property in [title=\"tensorflow.core.protobuf.config_pb2\"]`config_pb2` class: `config_pb2.ConfigProto.CreateInstance()`.\n\n## Parameter and return types\nLostTech.TensorFlow tries hard to expose statically-typed API, but the underlying TensorFlow code is inherently dynamic.\nIn many cases LostTech.TensorFlow over-generalizes or under-generalizes underlying parameter and return types.\n\nWhen the parameter type is over-generalized, it simply means you loose a hint as to what can actually be passed.\nLostTech.TensorFlow's parameter may be `IEnumerable\u003cobject\u003e`, but the function can reject anything except a `PythonSet\u003cint\u003e`.\nIn these cases you can either refer to the https://www.tensorflow.org/versions/r1.15/api_docs/python/tf[official documentation],\nor quickly try it, and see if the error you get explains what the function actually expects.\n\nFor convenience, any 1D .NET arrays are passed as instances of `PythonList\u003cT\u003e`\nby default. This also applies to enumerables produced by `System.Linq`.\nThis behavior can be turned off using `IsEnabled` properties in\nhttps://gradient.docs.losttech.software/Runtime/v0.4.2/LostTech.Gradient.Codecs/[LostTech.Gradient.Codecs].\n\n### Dynamic overloads\nTL;DR; when you can't pass something or get `InvalidCastException`, replace `tf.func_name(...)` -\u003e `tf.func_name_dyn(...)`,\nand `new Class(...)` -\u003e `Class.NewDyn(...)`.\n\nWhen the parameter or return type is under-generalized, you will not be able to use LostTech.TensorFlow's statically-typed API.\nA function parameter may say, that it only accepts `int` and `bool`, but you know from documentation/sample,\nthat you have to pass a `Tensor`. Another common example is when LostTech.TensorFlow thinks the parameter must be\nof a derived class, when a base class would actually also be ok. For example, parameter `cell` might be of type `LSTMCell`,\nbut actually you should be able to pass any `RNNCell`, where `class LSTMCell: RNNCell`.\nDo not try converting the value you want to pass to the expected type. It will not work.\nFor these cases LostTech.TensorFlow provides dynamic API alongside statically-typed one.\n\nEvery function from original API will have an untyped overload, whose name ends with `_dyn`.\nAll its parameters intentionally allow anything to be passed (type `object`).\nIt also returns a `dynamic` type.\n\nSame applies to properties. For each `SomeType property{get;set;}` there's a `dynamic property_dyn{get;set;}`.\n\nEvery class with constructors will have an untyped static factory method, named `NewDyn`,\nwhich allows you to call class constructor similar to untyped function overloads in the previos paragraph.\n\nPlease, report to this issue tracker, if you have to call dynamic overloads a lot to get your model running.\nWe will try to fix that in the next version.\n\nIn some cases even that is not enough. If you need to call a method or access a property of an instance of some class,\nand that method/property is not exposed by LostTech.TensorFlow, convert the instance to `dynamic`, and try to call it that way.\nSee https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic\n\n## Passing functions\nMany TensorFlow APIs accept functions as parameters.\nIf the parameter type is known to be a function, LostTech.TensorFlow will show\nit as `PythonFunctionContainer`[https://gradient.docs.losttech.software/Runtime/v0.4.2/LostTech.Gradient/PythonFunctionContainer.htm].\n\nThere are two ways to get an instance of it: pass TensorFlow functions back, or pass a .NET function.\n\n### Passing TensorFlow functions back to TensorFlow\nTL;DR; suffix your function with `_fn`.\n\nMost NN layers expect an `activation` argument, which specifies the neuron activation function.\nTensorFlow defines many activation functions one would want to use in both modern and old-style APIs.\nThe \"original\" one is called https://en.wikipedia.org/wiki/Sigmoid_function[sigmoid] as is available as `tf.sigmoid`.\nModern networks often use some variant of https://en.wikipedia.org/wiki/Rectifier_(neural_networks)[ReLU] (`tf.nn.relu`).\nYou can call both directly like this: `tf.sigmoid(tensor)`, but in most cases you need to pass them\nto `activation` parameter as `PythonFunctionContainer`.\n\nTo do that you can simply get a pre-wrapped instance by adding `_fn` suffix to the function name.\n\nFor example: `tf.layer.dense(activation: *tf.sigmoid_fn*)`.\n\n### Passing C# functions to TensorFlow\nTo get an instance of `PythonFunctionContainer` from a C# function, use static method `PythonFunctionContainer.Of\u003cT1, ..., TResult\u003e(func or lambda)`.\nYou will have to specify function argument types in place of `\u003cT1, ..., TResult\u003e`.\n\n## Python `with` blocks, C#'s `using`\nTL;DR; replace `with new Session(...) as sess: sess.do_stuff()`\n-\u003e\n[source,csharp]\n----\nvar session = new Session(...);\nusing (session.StartUsing()) {\n    session.do_stuff();\n}\n----\n\nYou can also use `new Session().UseSelf(sess =\u003e sess.DoStuff())`.\n\nTensorFlow API, being built on Python, use special *enter* and *exit* methods for the same purpose\n.NET has `IDisposable`. Problem is: in general they do not map directly to each other.\nFor that reason every LostTech.TensorFlow class, that declares those special methods in TensorFlow,\nalso exposes `.Use` and `.UseSelf` methods. In most cases it is easiest to use `.UseSelf(self =\u003e do_something(self))`\nas shown in the sample above. However, there might be rare special cases, when `.Use(context =\u003e do_something(context))`\nhas to be used. The difference is that `obj.UseSelf` always passes `obj` back to the lambda,\nwhile `obj.Use` might actually generate a new object of potentially completely different type.\n\nThink of `.Use` and `.UseSelf` as LostTech.TensorFlow's best attempt at reproducing `using(var session = new Session(...)) {}` statement.\n\n## Exceptions\nMost of TensorFlow exceptions have a counterpart either in LostTech.TensorFlow\nor in Gradient.Runtime[https://gradient.docs.losttech.software/Runtime/v0.4.2/LostTech.Gradient.Exceptions/].\n\nIf TensorFlow throws an exception, that has no counterpart, it will surface as\na generic `PythonException`[https://csharpdoc.hotexamples.com/class/Python.Runtime/PythonException].\n\n## NumPy\nSince most TensorFlow samples use NumPy, LostTech.TensorFlow includes a limited subset under `numpy` namespace.\nIt is shipped in a separate package: https://www.nuget.org/packages/LostTech.NumPy/[LostTech.NumPy].\n\n[link=https://www.nuget.org/packages/LostTech.NumPy/]\nimage::https://img.shields.io/nuget/v/LostTech.NumPy.svg[NuGet]\n\n## anchor:inheritance[]Custom layers and `Model` subclassing\n\nNOTE: When subclassing `tensorflow.keras.Model`, every layer, variable or tensor\nmust be explicitly tracked using `this.Track` method. See\nhttps://github.com/losttech/Gradient-Samples/blob/03aa035080d3a46fe6a4c8dcfd6e8f1b91a414a7/ResNetBlock/ResNetBlock.cs#L19[ResNetBlock sample].\n\nhttps://www.tensorflow.org/tutorials/customization/custom_layers[The official TensorFlow tutorial]\n\n\n\n## Recommendations\n* import both `tensorflow` and `numpy` namespaces:\n[source,csharp]\n----\nusing tensorflow;\nusing numpy;\n\ntf.placeholder(...);\nnp.array(...);\n----\n* if you extensively use some API set under `tf.`, use `using static tf.API_HERE;`\n[source,csharp]\n----\nusing static tf.keras;\n...\nvar model = models.load_model(...);\nnew Dense(kernel_regularizer: regularizers.l2(...));\n----\n* many LostTech.TensorFlow functions return `dynamic`. Whenever possible, immediately cast it to the concrete type.\nIt will help to maintain the code. Concrete type is always known at runtime\nand can be seen in the debugger, or accessed via `object.GetType()` method.\nMost methods in `tf.` usually return `Tensor`.\n[source,csharp]\n----\nTensor hidden = tf.layers.dense(input, hiddenSize, activation: tf.sigmoid_fn);\n----\n\n* avoid directly using classes in `Python.Runtime`.\nThey are LostTech.TensorFlow's implementation details, which might be changed\nin the future major versions.\n\n# Known limitations\n__This section may be outdated__\n\n## Unloading AppDomain is not supported\n\nLostTech.TensorFlow is incompatible with `AppDomain` unloading. An attempt to\nunload an `AppDomain` where TensorFlow was initialized will lead to a crash\nin native code.\n\nThis is a known problem with Unity editor, which means you can not use\nLostTech.TensorFlow within the editor. You must skip all TensorFlow code\nusing the https://docs.unity3d.com/ScriptReference/Application-isEditor.html[isEditor] check.\n\n# Tips and Tricks\n[#csharp8]\n## C# 8\nLostTech.TensorFlow supports the neat indexing feature of C# 8: if you are using Visual Studio 2019,\nyou can set appropriate language level like this in the project file: `\u003cLangVersion\u003e8.0\u003c/LangVersion\u003e`.\n\nThen you can access numpy arrays with the new syntax, for example: `arr[3..^4]`, which means \"take a range from element at index 3, that includes all elements until (and including) the element with index 4 (counting from the end of the array)\".\n\n# Blogs, Blog Posts \u0026 3rd-party Samples\n- https://habr.com/post/453232/[GPT-2: Writing billion songs with C# and Deep Learning]\n- https://habr.com/post/437174/[.NET, TensorFlow, and the windmills of Kaggle — the journey begins]\n- http://ml.blogs.losttech.software/Reinforcement-Learning-With-Unity-ML-Agents/[Reinforcement learning with Unity ML agents]\n- https://lostmsu.github.io/Not-CSharp/[Not C#] - training a convolutional network to recognize programming languages\n\n\n\n# What's new\n## Release Candidate:\n- replaced expiration with licenses\n- improved typing on many APIs\n- fixed inability to access static settings\n- strongly-typed wrappers for `Tensor`\n- enhanced `ndarray\u003cT\u003e`\n- improved exception handling and debugging\n- core runtime components include source and debug symbols\n- LINQ enumerables and 1D .NET arrays are now automatically converted to Python\nlists for compatibility with bad TensorFlow APIs (can be disabled)\n\n## Preview 7:\n- TensorFlow 1.15\n- strongly-typed accessors for `ndarray\u003cT\u003e`\n- arithmetic, bitwise and comparison operators on Tensors (note, now to check for null `is null` must be used instead of `== null`)\n- `StartUsing` extension on classes like `Session`, `variable_scope`, etc to allow `using (new variable_scope(...).StartUsing()) { ... }`\n- improved support for enums\n- prepackaged TensorFlow runtime on NuGet.org for easy installation:\nhttps://www.nuget.org/packages/LostTech.TensorFlow.Python[LostTech.TensorFlow.Python]\n- minimal wrapper for NumPy is released in a separate package (see dependencies)\n- runtime initialization moved to Gradient.Runtime\n- bugfixes: https://github.com/losttech/Gradient/milestone/3[see Milestone] + internally reported bugs\n- new sample: https://github.com/losttech/Gradient-Samples/tree/master/RL-MLAgents/[reinforcement learning with Unity ML agents]\nexplained in detail in http://ml.blogs.losttech.software/Reinforcement-Learning-With-Unity-ML-Agents/[a blog post]\n\n## Preview 6.x:\n- feature: ability to \u003c\u003cinheritance,inherit TensorFlow classes\u003e\u003e (for example, allows\n to create a custom Keras `Model`, `Callback`, `Layer`, etc)\n- new sample: https://github.com/losttech/Gradient-Samples/tree/master/ResNetBlock[ResNetBlock]\n- feature: TensorFlow classes are properly marshalled when passed back to you from TensorFlow\n- fixed: inability to add items to collections, belonging to TensorFlow classes\n- fixed: crash while enumerating collections without an explicit GIL lock\n- fixed: crash due to use-after-free of TensorFlow objects in marshalling layer\n- fixed: `PythonClassContainer\u003cT\u003e.Instance` failing for nested classes\n- fixed: `params object[]` were not passed correctly\n- minor: added `np.expand_dims`, reduced number of thrown and handled exceptions\n- expires in March 2020\n\n## Preview 5.1:\n- improved passing dictionaries\n- setup: optionally specify Conda environment via an environment variable\n- setup: fixed Conda environment autodectection on Linux\n- improved argument types in many places\n- Gradient warnings are now printed to Console.Error by default, instead of Console.Out\n- fixed crashes on dynamic interop and multithreaded enumeration\n- fixed some properties not being exposed https://github.com/losttech/Gradient/issues/4\n\n## Preview 5:\n- support for indexing `Tensor` objects via `dynamic`\n- allow using specific Python environment via `GradientSetup.UsePythonEnvironment`\n- numerous fixes in the interop layer\n- https://github.com/losttech/Gradient-Samples/tree/master/GPT-2[GPT-2 sample]\n\n## Preview 4:\n- MacOS and Ubuntu support (with others possibly working too) on .NET Core\n- documentation included for function and parameter tooltips\n- fixed inability to call static class methods\n\n## Preview 3\n- fixed inability to reenter TensorFlow from a callback\n\n## Preview 2:\n\n- dynamically typed overloads, that enable fallback for tricky signatures\n- a common interface for tf.Variable and tf.Tensor\n- enabled enumeration over TensorFlow collection types\n\n# FAQ\n## Why not TensorFlowSharp?\n|===\n| | TensorFlowSharp | LostTech.TensorFlow\n\n| Load TensorFlow models\n| *✓*\n| *✓*\n\n| Train existing models\n| *✓*\n| *✓*\n\n| Create new models with low-level API\n| *✓*\n| *✓*\n\n| Create new models with high-level API\n| ✗\n| *✓*\n\n| Dependencies\n| *TF*\n| TF\u0026nbsp;+ Python\n\n| TensorBoard integration\n| ✗\n| *✓*\n\n| Estimators\n| ✗\n| *✓*\n\n| Dataset manipulation via tf.data\n| ✗\n| *✓*\n\n| tf.contrib\n| ✗\n| *✓*\n\n| Commercial support\n| ✗\n| *✓*\n|===\n\n## Why not TensorFlow.NET?\n### Incomplete set of functions\nTensorFlow.NET does not provide full functionality of TensorFlow. As a result,\nhttps://github.com/SciSharp/TensorFlow.NET/issues/352[it is hard to implement]\nstate of the art algorithms for **computer vision (YOLOv3)** and\n**language processing (GPT and BERT)** using TensorFlow.NET, especially from\nscratch. We have complete LostTech.TensorFlow-based samples for both:\nhttps://github.com/losttech/YOLOv4[YOLOv4] and\nhttps://github.com/losttech/Gradient-Samples/tree/master/GPT-2[GPT-2]\nand https://github.com/losttech/Gradient-Samples/blob/master/README.md[many more].\n\n### Ghost APIs\nTensorFlow.NET goal is to be a reimplementation of TensorFlow in C#.\nHowever, as of August 2020 only a small set of APIs actually has\nimplementations. Many functions and classes are defined without bodies\nand do nothing. The state of specific APIs is not tracked,\nand that can create a lot of confusion. For example, there is an\n[line-through]#https://github.com/SciSharp/TensorFlow.NET/blob/master/src/TensorFlowNET.Core/Train/AdamOptimizer.cs[AdamOptimizer]# (they got AdamOptimizer since, but the problem is https://github.com/SciSharp/TensorFlow.NET/blob/c2138b20abc41b19a5e1d3568cdeed87bc1c7369/src/TensorFlowNET.Core/Train/GradientDescentOptimizer.cs#L38[systemic]) \nclass, but it does not actually have any implementation, apart from\nthe constructor, meaning it wont actually use Adam, or work at all.\n\n### Performance\nLostTech.TensorFlow uses official builds of TensorFlow provided by Google, which\nare well-optimized. As a result, in a https://github.com/losttech/Gradient-Perf/[simple comparison]\n(training a CNN) LostTech.TensorFlow is about 18% faster than\nTensorFlow.NET.\n\nWe also support TensorFlow builds, that use other accelerators, such as TPUs in\nGoogle cloud, or https://pypi.org/project/tensorflow-rocm[tensorflow-rocm] for\nAMD GPUs.\n\n# Credits\nTensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosttech%2Fgradient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flosttech%2Fgradient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flosttech%2Fgradient/lists"}