diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index fdf005901..1f011157e 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
-custom: ['https://bit.ly/2op1mu5']# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+custom: []# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/ISSUE_TEMPLATE/blank_issue.yml b/.github/ISSUE_TEMPLATE/blank_issue.yml
new file mode 100644
index 000000000..bbd855958
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/blank_issue.yml
@@ -0,0 +1,12 @@
+name: Blank Issue
+description: Submit an issue about Tensorflow.NET.
+labels: [Blank Issue]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Please describe the issue here.
+ placeholder: Description
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000..14e237951
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,48 @@
+name: BUG Report
+description: Report a BUG of Tensorflow.NET.
+title: "[BUG Report]: "
+labels: [bug-report]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ We welcome bug reports! Any unexpected behavior could be a BUG and this template help us gather the information to fix it.
+ - type: textarea
+ id: background
+ attributes:
+ label: Description
+ description: Please share a clear and concise description of the problem.
+ placeholder: Description
+ validations:
+ required: true
+ - type: textarea
+ id: repro-steps
+ attributes:
+ label: Reproduction Steps
+ description: |
+ Please include minimal steps to reproduce the problem if possible. E.g.: the smallest possible code snippet; or a small project, with steps to run it. It will greatly help us to locate the reason of the problem.
+ placeholder: Minimal Reproduction
+ validations:
+ required: false
+ - type: textarea
+ id: known-workarounds
+ attributes:
+ label: Known Workarounds
+ description: |
+ Please provide a description of any known workarounds.
+ placeholder: Known Workarounds
+ validations:
+ required: false
+ - type: textarea
+ id: configuration
+ attributes:
+ label: Configuration and Other Information
+ description: |
+ Please provide more information on your configuration:
+ * Which version of Tensorflow.NET is the code depending on?
+ * Which version of .NET runtime is the code running on?
+ * What is the OS?
+ * Any other information about this problem?
+ placeholder: Configuration
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/documention_issue.yml b/.github/ISSUE_TEMPLATE/documention_issue.yml
new file mode 100644
index 000000000..f8a04e40f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documention_issue.yml
@@ -0,0 +1,30 @@
+name: Documentation Issue
+description: Report an issue about Tensorflow.NET ducumention or require a documention.
+title: "[Documention Issue]: "
+labels: [Documention Issue]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Welcome to suggest to Tensorflow.NET documention! This template will help us gather the information we need to improve it.
+ - type: textarea
+ id: brief-description
+ attributes:
+ label: Brief Description
+ description: Please describe the problem or the requst for new documention here.
+ placeholder: Description
+ validations:
+ required: true
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives
+ description: |
+ Please provide some alternative information here, if any.
+ placeholder: Alternatives
+ validations:
+ required: false
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your contributing!
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 000000000..9ce3f1663
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,50 @@
+name: Feature Request
+description: Request/Propose a new feature of Tensorflow.NET.
+title: "[Feature Request]: "
+labels: [feature-request]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ We welcome feature proposal/request! This template will help us gather the information we need to implement the new feature.
+ - type: textarea
+ id: background
+ attributes:
+ label: Background and Feature Description
+ description: Please describe the purpose and value of the new feature here. If the feature is linked to a specific problem, please describe it or put the link here.
+ placeholder: Purpose
+ validations:
+ required: true
+ - type: textarea
+ id: api-proposal
+ attributes:
+ label: API Definition and Usage
+ description: |
+ Please tell us the new API related to the requested feature, if any.
+ placeholder: API declaration (no method bodies)
+ value: |
+ ```cs
+ public Tensor NewFunc(Tensor x, int y);
+
+ var result = NewFunc(input, index);
+ ```
+ validations:
+ required: false
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives
+ description: |
+ Please provide some alternative information of the feature, if any. For example, if you request a feature which depends on a specific device, please provide the device information.
+ placeholder: Alternatives
+ validations:
+ required: false
+ - type: textarea
+ id: risks
+ attributes:
+ label: Risks
+ description: |
+ Please mention any risks that to your knowledge the API proposal might entail, such as breaking changes, performance regressions, etc.
+ placeholder: Risks
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/performance_issue.yml b/.github/ISSUE_TEMPLATE/performance_issue.yml
new file mode 100644
index 000000000..cbe86d329
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/performance_issue.yml
@@ -0,0 +1,48 @@
+name: Performance Issue
+description: Submit an issue about performance problem or regression of Tensorflow.NET.
+title: "[Performance Issue]: "
+labels: [Performance Issue]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ We welcome issues about Tensorflow.NET performance! This template will help us gather the information we need to locate the problem improve the performance.
+ - type: textarea
+ id: brief-description
+ attributes:
+ label: Brief Description
+ description: Please give a brief description about the performance issue here.
+ placeholder: Description
+ validations:
+ required: true
+ - type: textarea
+ id: device-and-context
+ attributes:
+ label: Device and Context
+ description: |
+ Please describe the device and context you used when you encounter the performance problem/regression.
+ placeholder: Device and Context
+ validations:
+ required: true
+ - type: textarea
+ id: benchmark
+ attributes:
+ label: Benchmark
+ description: |
+ We will appreciate it if you'd like to provide benchmark comparison of the performance issue.
+ placeholder: Benchmark
+ validations:
+ required: false
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives
+ description: |
+ Please provide some alternative information of the performance issue here, if any. For example, we'll appreciate it if you'd like to provide the the code to reproduce the performance problem.
+ placeholder: Alternatives
+ validations:
+ required: false
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your contributing!
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
new file mode 100644
index 000000000..ca38be340
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -0,0 +1,30 @@
+name: Question
+description: Ask any question about Tensorflow.NET and discuss with community members.
+title: "[Question]: "
+labels: [Question]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Any question about Tensorflow.NET is welcomed! This template will help us get your point.
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Please describe your question here.
+ placeholder: Description
+ validations:
+ required: true
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives
+ description: |
+ Please provide some alternative information here, if any.
+ placeholder: Alternatives
+ validations:
+ required: false
+ - type: markdown
+ attributes:
+ value: |
+ We are always willing to answer your questions!
diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml
new file mode 100644
index 000000000..9fd34fc49
--- /dev/null
+++ b/.github/workflows/build_and_test.yml
@@ -0,0 +1,66 @@
+# This workflow will build a .NET project
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
+
+name: build_and_test
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+ types: ["opened", "reopened", "synchronize", "ready_for_review", "auto_merge_enabled"]
+
+jobs:
+ windows:
+
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET 6
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build CPU version
+ run: dotnet build --no-restore
+ - name: Test CPU version
+ run: dotnet test --no-build --verbosity normal
+ - name: uninstall redist cpu for unit tests
+ run: dotnet remove tools/Tensorflow.UnitTest.RedistHolder package SciSharp.TensorFlow.Redist
+ - name: install redist gpu for unit tests
+ run: dotnet add tools/Tensorflow.UnitTest.RedistHolder package SciSharp.TensorFlow.Redist-Windows-GPU
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build GPU version
+ run: dotnet build --no-restore
+# - name: Test GPU version
+# run: dotnet test --no-build --verbosity normal
+
+ linux:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build CPU version
+ run: dotnet build --no-restore
+ - name: Test CPU version
+ run: dotnet test --no-build --verbosity normal
+ - name: uninstall redist cpu for unit tests
+ run: dotnet remove tools/Tensorflow.UnitTest.RedistHolder package SciSharp.TensorFlow.Redist
+ - name: install redist gpu for unit tests
+ run: dotnet add tools/Tensorflow.UnitTest.RedistHolder package SciSharp.TensorFlow.Redist-Linux-GPU
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build GPU version
+ run: dotnet build --no-restore
+# - name: Test GPU version
+# run: dotnet test --no-build --verbosity normal
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..02601764c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,62 @@
+name: auto-release
+
+on:
+ workflow_run:
+ workflows: ["release-prepare"]
+ types:
+ - completed
+
+env:
+ MYGET_API_TOKEN: ${{ SECRETS.MYGET_API_KEY }}
+ GITHUB_TOKEN: ${{ SECRETS.RINNE_GITHUB_TOKEN }}
+
+jobs:
+ release_to_myget:
+ runs-on: windows-latest
+# needs: run-semantic-release
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET 6.0.x SDK
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+
+ - name: Check .NET info
+ run: dotnet --info
+
+ - name: Install dependencies
+ run: dotnet restore
+
+ - name: Build solution
+ run: dotnet build -c Release --no-restore
+
+ - name: Pack packages
+ run: |
+ git fetch --unshallow;
+ git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*";
+ git fetch origin;
+ $LastTag = git describe --tags;
+ $DroppedTag = ($LastTag).TrimStart('v');
+ echo "Last tag is: $DroppedTag";
+ $Suffix = "-nightly"
+ $Version = "${DroppedTag}${Suffix}";
+ echo "Publishing version: $Version";
+ dotnet pack ./src/TensorFlowNET.Core/Tensorflow.Binding.csproj -c Release -o packages /p:PackageVersion=$Version /p:Version=$Version;
+ dotnet pack ./src/TensorFlowNET.Keras/Tensorflow.Keras.csproj -c Release -o packages /p:PackageVersion=$Version /p:Version=$Version;
+ dotnet pack ./src/TensorflowNET.Hub/Tensorflow.Hub.csproj -c Release -o packages /p:PackageVersion=$Version /p:Version=$Version;
+
+ if($LastExitCode -ne 0)
+ {
+ Write-Warning -Message "Pack packages warming, last exit code is ${LastExitCode}."
+ $LastExitCode = 0;
+ }
+
+ - name: Upload packages artifacts
+ uses: actions/upload-artifact@v4.0.0
+ with:
+ name: "drop-ci-packages"
+ path: './packages'
+
+ - name: Push TensorFlow.NET to myget.org
+ run: dotnet nuget push .\packages\TensorFlow*.nupkg --source https://www.myget.org/F/scisharp/api/v3/index.json -k ${{ secrets.MYGET_API_KEY }} --skip-duplicate
diff --git a/.github/workflows/release_prepare.yml b/.github/workflows/release_prepare.yml
new file mode 100644
index 000000000..b21c6665c
--- /dev/null
+++ b/.github/workflows/release_prepare.yml
@@ -0,0 +1,46 @@
+name: release-prepare
+
+on:
+ pull_request:
+ branches:
+ - master
+ types: [ closed ]
+
+env:
+ MYGET_API_TOKEN: ${{ SECRETS.MYGET_API_KEY }}
+ GITHUB_TOKEN: ${{ SECRETS.RINNE_GITHUB_TOKEN }}
+
+jobs:
+ build:
+ if: contains(github.event.pull_request.labels.*.name, 'auto-release')
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET 6.0.x SDK
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+
+ - name: Check .NET info
+ run: dotnet --info
+
+ - name: Install dependencies
+ run: dotnet restore
+
+ - name: Build solution
+ run: dotnet build -c Release --no-restore
+
+# run-semantic-release:
+# runs-on: ubuntu-latest
+# needs: build
+
+# steps:
+# - name: Checkout
+# uses: actions/checkout@v2
+
+# - name: Run semantic-release
+# run: |
+# export PATH=$PATH:$(yarn global bin)
+# yarn global add semantic-release@17.4.3
+# semantic-release
\ No newline at end of file
diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml
new file mode 100644
index 000000000..db8c06a3e
--- /dev/null
+++ b/.github/workflows/semantic.yml
@@ -0,0 +1,17 @@
+name: Semantic
+
+on:
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ semantic-pull-request:
+ name: Semantic check
+ runs-on: windows-latest
+ steps:
+ - name: semantic-pull-request
+ uses: amannn/action-semantic-pull-request@v4
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ validateSingleCommit: true
diff --git a/README.md b/README.md
index f437ad8e1..75cad0aa7 100644
--- a/README.md
+++ b/README.md
@@ -1,68 +1,114 @@

-**TensorFlow.NET** (TF.NET) provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in C# which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework.
+**TensorFlow.NET** (TF.NET) provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in C# which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. TensorFlow.NET has built-in Keras high-level interface and is released as an independent package [TensorFlow.Keras](https://www.nuget.org/packages/TensorFlow.Keras/).
+[](https://discord.gg/qRVm82fKTS)
+[](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=sN9VVMwbWjs5L0ATpizKKxOcZdEPMrp8&authKey=RLDw41bLTrEyEgZZi%2FzT4pYk%2BwmEFgFcrhs8ZbkiVY7a4JFckzJefaYNW6Lk4yPX&noverify=0&group_code=985366726)
[](https://gitter.im/sci-sharp/community)
-[](https://ci.appveyor.com/project/Haiping-Chen/tensorflow-net)
-[](https://www.nuget.org/packages/TensorFlow.NET)
+[](https://github.com/SciSharp/TensorFlow.NET/actions/workflows/build_and_test.yml)
[](https://tensorflownet.readthedocs.io/en/latest/?badge=latest)
+[](https://www.nuget.org/packages/TensorFlow.NET)
+[](https://www.nuget.org/packages/TensorFlow.Keras)
+[](https://www.myget.org/feed/scisharp/package/nuget/Tensorflow.NET)
[](https://996.icu/#/en_US)
[](https://mybinder.org/v2/gh/javiercp/BinderTF.NET/master?urlpath=lab)
-*master branch is based on tensorflow 2.3 now, v0.15-tensorflow1.15 is from tensorflow1.15.*
+English | [中文](docs/README-CN.md)
+
+> [!IMPORTANT]
+> We're happy that our work on tensorflow.net has attracted many users. However, at this time, none of the main maintainers of this repo is available for new features and bug fix. We won't refuse PRs and will help to review them.
+>
+> If you would like to be a contributor or maintainer of tensorflow.net, we'd like to help you to start up.
+>
+> We feel sorry for that and we'll resume the maintaining for this project once one of us has bandwidth for it.
+>
+
+*master branch and v0.100.x is corresponding to tensorflow v2.10, v0.6x branch is from tensorflow v2.6, v0.15-tensorflow1.15 is from tensorflow1.15. Please add `https://www.myget.org/F/scisharp/api/v3/index.json` to nuget source to use nightly release.*

-### Why TensorFlow.NET ?
+## Why Tensorflow.NET ?
+
+`SciSharp STACK`'s mission is to bring popular data science technology into the .NET world and to provide .NET developers with a powerful Machine Learning tool set without reinventing the wheel. Since the APIs are kept as similar as possible you can immediately adapt any existing TensorFlow code in C# or F# with a zero learning curve. Take a look at a comparison picture and see how comfortably a TensorFlow/Python script translates into a C# program with TensorFlow.NET.
+
+
+
+SciSharp's philosophy allows a large number of machine learning code written in Python to be quickly migrated to .NET, enabling .NET developers to use cutting edge machine learning models and access a vast number of TensorFlow resources which would not be possible without this project.
+
+In comparison to other projects, like for instance [TensorFlowSharp](https://www.nuget.org/packages/TensorFlowSharp/) which only provide TensorFlow's low-level C++ API and can only run models that were built using Python, Tensorflow.NET makes it possible to build the pipeline of training and inference with pure C# and F#. Besides, Tensorflow.NET provides binding of Tensorflow.Keras to make it easy to transfer your code from python to .NET.
+
+[ML.NET](https://github.com/dotnet/machinelearning) also take Tensorflow.NET as one of the backends to train and infer your model, which provides better integration with .NET.
+
+## Documention
+
+Introduction and simple examples:[Tensorflow.NET Documents](https://scisharp.github.io/tensorflow-net-docs)
+
+Detailed documention:[The Definitive Guide to Tensorflow.NET](https://tensorflownet.readthedocs.io/en/latest/FrontCover.html)
-`SciSharp STACK`'s mission is to bring popular data science technology into the .NET world and to provide .NET developers with a powerful Machine Learning tool set without reinventing the wheel. Since the APIs are kept as similar as possible you can immediately adapt any existing Tensorflow code in C# with a zero learning curve. Take a look at a comparison picture and see how comfortably a Tensorflow/Python script translates into a C# program with TensorFlow.NET.
+Examples:[TensorFlow.NET Examples](https://github.com/SciSharp/TensorFlow.NET-Examples)
-
+Troubleshooting of running example or installation:[Tensorflow.NET FAQ](tensorflowlib/README.md)
-SciSharp's philosophy allows a large number of machine learning code written in Python to be quickly migrated to .NET, enabling .NET developers to use cutting edge machine learning models and access a vast number of Tensorflow resources which would not be possible without this project.
+## Usage
-In comparison to other projects, like for instance TensorFlowSharp which only provide Tensorflow's low-level C++ API and can only run models that were built using Python, Tensorflow.NET also implements Tensorflow's high level API where all the magic happens. This computation graph building layer is still under active development. Once it is completely implemented you can build new Machine Learning models in C#.
+### Installation
-### How to use
+You can search the package name in NuGet Manager, or use the commands below in package manager console.
-| TensorFlow | tf native1.14 | tf native 1.15 | tf native 2.3 |
-| ----------- | ------------- | -------------- | ------------- |
-| tf.net 0.20 | | x | x |
-| tf.net 0.15 | x | x | |
-| tf.net 0.14 | x | | |
+The installation contains two parts, the first is the main body:
-Install TF.NET and TensorFlow binary through NuGet.
```sh
-### install tensorflow C# binding
+### Install Tensorflow.NET
PM> Install-Package TensorFlow.NET
-### Install tensorflow binary
-### For CPU version
+### Install Tensorflow.Keras
+PM> Install-Package TensorFlow.Keras
+```
+
+The second part is the computing support part. Only one of the following packages is needed, depending on your device and system.
+
+```
+### CPU version for Windows and Linux
PM> Install-Package SciSharp.TensorFlow.Redist
-### For GPU version (CUDA and cuDNN are required)
+### CPU version for MacOS
+PM> Install-Package SciSharp.TensorFlow.Redist-OSX
+
+### GPU version for Windows (CUDA and cuDNN are required)
PM> Install-Package SciSharp.TensorFlow.Redist-Windows-GPU
+
+### GPU version for Linux (CUDA and cuDNN are required)
+PM> Install-Package SciSharp.TensorFlow.Redist-Linux-GPU
```
-Import TF.NET in your project.
-```cs
-using static Tensorflow.Binding;
-```
+Two simple examples are given here to introduce the basic usage of Tensorflow.NET. As you can see, it's easy to write C# code just like that in Python.
+
+### Example - Linear Regression in `Eager` mode
-Linear Regression:
+```csharp
+using static Tensorflow.Binding;
+using static Tensorflow.KerasApi;
+using Tensorflow;
+using Tensorflow.NumPy;
-```c#
// Parameters
-int training_steps = 1000;
-float learning_rate = 0.01f;
-int display_step = 100;
+var training_steps = 1000;
+var learning_rate = 0.01f;
+var display_step = 100;
+
+// Sample data
+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];
// We can set a fixed init value in order to demo
var W = tf.Variable(-0.06f, name: "weight");
var b = tf.Variable(-0.73f, name: "bias");
-var optimizer = tf.optimizers.SGD(learning_rate);
+var optimizer = keras.optimizers.SGD(learning_rate);
// Run training for the given number of steps.
foreach (var step in range(1, training_steps + 1))
@@ -92,29 +138,99 @@ foreach (var step in range(1, training_steps + 1))
Run this example in [Jupyter Notebook](https://github.com/SciSharp/SciSharpCube).
-Read the docs & book [The Definitive Guide to Tensorflow.NET](https://tensorflownet.readthedocs.io/en/latest/FrontCover.html).
+### Example - Toy version of `ResNet` in `Keras` functional API
+
+```csharp
+using static Tensorflow.Binding;
+using static Tensorflow.KerasApi;
+using Tensorflow;
+using Tensorflow.NumPy;
+
+var layers = keras.layers;
+// input layer
+var inputs = keras.Input(shape: (32, 32, 3), name: "img");
+// convolutional layer
+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);
+// output layer
+var outputs = layers.Dense(10).Apply(x);
+// build keras model
+var model = keras.Model(inputs, outputs, name: "toy_resnet");
+model.summary();
+// compile keras model in tensorflow static graph
+model.compile(optimizer: keras.optimizers.RMSprop(1e-3f),
+ loss: keras.losses.SparseCategoricalCrossentropy(from_logits: true),
+ metrics: new[] { "acc" });
+// prepare dataset
+var ((x_train, y_train), (x_test, y_test)) = keras.datasets.cifar10.load_data();
+// normalize the input
+x_train = x_train / 255.0f;
+// training
+model.fit(x_train[new Slice(0, 2000)], y_train[new Slice(0, 2000)],
+ batch_size: 64,
+ epochs: 10,
+ validation_split: 0.2f);
+// save the model
+model.save("./toy_resnet_model");
+```
+
+The F# example for linear regression is available [here](docs/Example-fsharp.md).
+
+More adcanced examples could be found in [TensorFlow.NET Examples](https://github.com/SciSharp/TensorFlow.NET-Examples).
+
+## Version Relationships
-There are many examples reside at [TensorFlow.NET Examples](https://github.com/SciSharp/TensorFlow.NET-Examples).
+| TensorFlow.NET Versions | 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 | | | | | |
-Troubleshooting of running example or installation, please refer [here](tensorflowlib/README.md).
-### Contribute:
+```
+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
+...
+```
-Feel like contributing to one of the hottest projects in the Machine Learning field? Want to know how Tensorflow magically creates the computational graph? We appreciate every contribution however small. There are tasks for novices to experts alike, if everyone tackles only a small task the sum of contributions will be huge.
+## Contribution:
+
+Feel like contributing to one of the hottest projects in the Machine Learning field? Want to know how Tensorflow magically creates the computational graph?
+
+We appreciate every contribution however small! There are tasks for novices to experts alike, if everyone tackles only a small task the sum of contributions will be huge.
You can:
-* Let everyone know about this project
-* Port Tensorflow unit tests from Python to C#
-* Port missing Tensorflow code from Python to C#
-* Port Tensorflow examples to C# and raise issues if you come accross missing parts of the API
-* Debug one of the unit tests that is marked as Ignored to get it to work
-* Debug one of the not yet working examples and get it to work
+- Star Tensorflow.NET or share it with others
+- Tell us about the missing APIs compared to Tensorflow
+- Port Tensorflow unit tests from Python to C# or F#
+- Port Tensorflow examples to C# or F# and raise issues if you come accross missing parts of the API or BUG
+- Debug one of the unit tests that is marked as Ignored to get it to work
+- Debug one of the not yet working examples and get it to work
+- Help us to complete the documentions.
+
-### How to debug unit tests:
+#### How to debug unit tests:
-The best way to find out why a unit test is failing is to single step it in C# and its pendant Python at the same time to see where the flow of execution digresses or where variables exhibit different values. Good Python IDEs like PyCharm let you single step into the tensorflow library code.
+The best way to find out why a unit test is failing is to single step it in C# or F# and its corresponding Python at the same time to see where the flow of execution digresses or where variables exhibit different values. Good Python IDEs like PyCharm let you single step into the tensorflow library code.
-### Git Knowhow for Contributors
+#### Git Knowhow for Contributors
Add SciSharp/TensorFlow.NET as upstream to your local repo ...
```git
@@ -126,22 +242,20 @@ Please make sure you keep your fork up to date by regularly pulling from upstrea
git pull upstream master
```
-### Contact
-
-Feel free to star or raise issue on [Github](https://github.com/SciSharp/TensorFlow.NET).
+### Support
+Buy our book to make open source project be sustainable [TensorFlow.NET实战](https://item.jd.com/13441549.html)
+
+
+
+
+
-Follow us on [Medium](https://medium.com/scisharp).
-
-Join our chat on [Gitter](https://gitter.im/sci-sharp/community).
-
-Scan QR code to join Tencent TIM group:
-
-
+### Contact
-WeChat Sponsor 微信打赏:
+Join our chat on [Discord](https://discord.gg/qRVm82fKTS) or [Gitter](https://gitter.im/sci-sharp/community).
-
+Follow us on [Twitter](https://twitter.com/ScisharpStack), [Facebook](https://www.facebook.com/scisharp.stack.9), [Medium](https://medium.com/scisharp), [LinkedIn](https://www.linkedin.com/company/scisharp-stack/).
TensorFlow.NET is a part of [SciSharp STACK](https://scisharp.github.io/SciSharp/)
-
\ No newline at end of file
+
diff --git a/TensorFlow.NET.sln b/TensorFlow.NET.sln
index c5e28fd35..e0c273568 100644
--- a/TensorFlow.NET.sln
+++ b/TensorFlow.NET.sln
@@ -1,29 +1,56 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29102.190
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33213.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Binding", "src\TensorFlowNET.Core\Tensorflow.Binding.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Benchmark", "src\TensorFlowNet.Benchmarks\Tensorflow.Benchmark.csproj", "{3A6EB896-604F-4E25-B677-B8103BCF3D2E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Binding.UnitTest", "test\TensorFlowNET.UnitTest\Tensorflow.Binding.UnitTest.csproj", "{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.UnitTest", "test\TensorFlowNET.UnitTest\Tensorflow.UnitTest.csproj", "{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras", "src\TensorFlowNET.Keras\Tensorflow.Keras.csproj", "{49D71826-C03D-4FA7-9BAC-22C1327E65CF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Console", "src\TensorFlowNET.Console\TensorFlowNET.Console.csproj", "{03F06299-3F4B-4449-A709-3A647657BC0C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Text", "src\TensorFlowNET.Text\Tensorflow.Text.csproj", "{1AB8108D-4FFE-4A16-88E7-328EAF686370}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras", "src\TensorFlowNET.Keras\Tensorflow.Keras.csproj", "{49D71826-C03D-4FA7-9BAC-22C1327E65CF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Recommenders", "src\TensorFlowNET.Recommenders\Tensorflow.Recommenders.csproj", "{F17AAECB-960A-4E18-A270-BAD776F0E55B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Native.UnitTest", "test\TensorFlowNET.Native.UnitTest\Tensorflow.Native.UnitTest.csproj", "{84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras.UnitTest", "test\TensorFlowNET.Keras.UnitTest\Tensorflow.Keras.UnitTest.csproj", "{79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Graph.UnitTest", "test\TensorFlowNET.Graph.UnitTest\TensorFlowNET.Graph.UnitTest.csproj", "{3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Hub", "src\TensorflowNET.Hub\Tensorflow.Hub.csproj", "{9738D16A-CFA0-405C-A7DF-D3D203B0CB18}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Hub.Unittest", "test\TensorflowNET.Hub.Unittest\Tensorflow.Hub.Unittest.csproj", "{7DEA8760-E401-4872-81F3-405F185A13A0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{01A1787F-A9BE-4221-84E8-6360DD010AB6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1B0918B9-65AD-4F34-A287-AF4597B27DBD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{E1A5D2B7-10AF-4876-85C0-7714EF274214}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.CodeGen", "tools\Tensorflow.CodeGen\Tensorflow.CodeGen.csproj", "{3D92142F-EEDB-469B-B03C-4E38728BFE4C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Redist.NativeLibrarySplitter", "tools\Tensorflow.Redist.NativeLibrarySplitter\Tensorflow.Redist.NativeLibrarySplitter.csproj", "{AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.UnitTest.RedistHolder", "tools\Tensorflow.UnitTest.RedistHolder\Tensorflow.UnitTest.RedistHolder.csproj", "{D24FCAA5-548C-4251-B226-A1B6535D0845}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Benchmark", "tools\TensorFlowNET.Benchmarks\Tensorflow.Benchmark.csproj", "{C23563DB-FE21-48E7-A411-87A109E4A899}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Console", "tools\TensorFlowNET.Console\Tensorflow.Console.csproj", "{1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlow.Kernel.UnitTest", "test\TensorFlow.Kernel.UnitTest\TensorFlow.Kernel.UnitTest.csproj", "{654A027D-1364-4729-880B-144DFE1FF5BB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tensorflow.UnitTest", "test\Tensorflow.UnitTest\Tensorflow.UnitTest.csproj", "{A73DF5A6-866E-4AED-9017-AA2EE86368C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
- Debug-Minimal|Any CPU = Debug-Minimal|Any CPU
- Debug-Minimal|x64 = Debug-Minimal|x64
- Debug-Minimal|x86 = Debug-Minimal|x86
- Publish|Any CPU = Publish|Any CPU
- Publish|x64 = Publish|x64
- Publish|x86 = Publish|x86
+ GPU|Any CPU = GPU|Any CPU
+ GPU|x64 = GPU|x64
+ GPU|x86 = GPU|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
@@ -35,124 +62,329 @@ Global
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|x64.Build.0 = Debug|x64
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|x86.ActiveCfg = Debug|Any CPU
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|x86.Build.0 = Debug|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x64.ActiveCfg = Debug|x64
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x64.Build.0 = Debug|x64
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug-Minimal|x86.Build.0 = Debug|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|Any CPU.ActiveCfg = Release|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|Any CPU.Build.0 = Release|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x64.ActiveCfg = Release|x64
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x64.Build.0 = Release|x64
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x86.ActiveCfg = Release|Any CPU
- {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Publish|x86.Build.0 = Release|Any CPU
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|Any CPU.ActiveCfg = GPU|Any CPU
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|Any CPU.Build.0 = GPU|Any CPU
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|x64.ActiveCfg = GPU|x64
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|x64.Build.0 = GPU|x64
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|x86.ActiveCfg = GPU|Any CPU
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.GPU|x86.Build.0 = GPU|Any CPU
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x64.ActiveCfg = Release|x64
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x64.Build.0 = Release|x64
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x86.ActiveCfg = Release|Any CPU
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|x86.Build.0 = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x64.ActiveCfg = Debug|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x64.Build.0 = Debug|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x86.ActiveCfg = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug|x86.Build.0 = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x64.ActiveCfg = Debug|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x64.Build.0 = Debug|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Debug-Minimal|x86.Build.0 = Debug|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|Any CPU.ActiveCfg = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|Any CPU.Build.0 = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x64.ActiveCfg = Release|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x64.Build.0 = Release|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x86.ActiveCfg = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Publish|x86.Build.0 = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|Any CPU.Build.0 = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x64.ActiveCfg = Release|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x64.Build.0 = Release|x64
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x86.ActiveCfg = Release|Any CPU
- {3A6EB896-604F-4E25-B677-B8103BCF3D2E}.Release|x86.Build.0 = Release|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x64.ActiveCfg = Debug|x64
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x64.Build.0 = Debug|x64
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x86.ActiveCfg = Debug|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug|x86.Build.0 = Debug|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x64.ActiveCfg = Debug|x64
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x64.Build.0 = Debug|x64
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Debug-Minimal|x86.Build.0 = Debug|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|Any CPU.ActiveCfg = Release|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|Any CPU.Build.0 = Release|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x64.ActiveCfg = Release|x64
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x64.Build.0 = Release|x64
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x86.ActiveCfg = Release|Any CPU
- {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Publish|x86.Build.0 = Release|Any CPU
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|x64.ActiveCfg = Release|x64
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|x64.Build.0 = Release|x64
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|x86.ActiveCfg = Release|Any CPU
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.GPU|x86.Build.0 = Release|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|Any CPU.Build.0 = Release|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.ActiveCfg = Release|x64
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.Build.0 = Release|x64
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.ActiveCfg = Release|Any CPU
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.Build.0 = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x64.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x64.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x86.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|x64.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug-Minimal|x86.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|Any CPU.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|x64.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|x64.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|x86.ActiveCfg = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Publish|x86.Build.0 = Debug|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|Any CPU.Build.0 = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|x64.ActiveCfg = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|x64.Build.0 = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|x86.ActiveCfg = Release|Any CPU
- {03F06299-3F4B-4449-A709-3A647657BC0C}.Release|x86.Build.0 = Release|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|x64.ActiveCfg = Debug|x64
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|x64.Build.0 = Debug|x64
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|x86.ActiveCfg = Debug|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug|x86.Build.0 = Debug|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|x64.ActiveCfg = Debug|x64
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|x64.Build.0 = Debug|x64
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Debug-Minimal|x86.Build.0 = Debug|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|Any CPU.ActiveCfg = Release|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|Any CPU.Build.0 = Release|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|x64.ActiveCfg = Debug|x64
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|x64.Build.0 = Debug|x64
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|x86.ActiveCfg = Release|Any CPU
- {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Publish|x86.Build.0 = Release|Any CPU
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|Any CPU.ActiveCfg = GPU|Any CPU
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|Any CPU.Build.0 = GPU|Any CPU
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|x64.ActiveCfg = GPU|x64
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|x64.Build.0 = GPU|x64
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|x86.ActiveCfg = GPU|Any CPU
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF}.GPU|x86.Build.0 = GPU|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|Any CPU.Build.0 = Release|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|x64.ActiveCfg = Release|x64
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|x64.Build.0 = Release|x64
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|x86.ActiveCfg = Release|Any CPU
{49D71826-C03D-4FA7-9BAC-22C1327E65CF}.Release|x86.Build.0 = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|x64.ActiveCfg = Debug|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|x64.Build.0 = Debug|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Debug|x86.Build.0 = Debug|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|x64.ActiveCfg = Release|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|x64.Build.0 = Release|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|x86.ActiveCfg = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.GPU|x86.Build.0 = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|x64.ActiveCfg = Release|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|x64.Build.0 = Release|x64
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|x86.ActiveCfg = Release|Any CPU
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370}.Release|x86.Build.0 = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|x64.ActiveCfg = Debug|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|x64.Build.0 = Debug|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Debug|x86.Build.0 = Debug|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|x64.ActiveCfg = Release|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|x64.Build.0 = Release|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|x86.ActiveCfg = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.GPU|x86.Build.0 = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|x64.ActiveCfg = Release|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|x64.Build.0 = Release|x64
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|x86.ActiveCfg = Release|Any CPU
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B}.Release|x86.Build.0 = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|x64.ActiveCfg = Debug|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|x64.Build.0 = Debug|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Debug|x86.Build.0 = Debug|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|x64.ActiveCfg = Release|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|x64.Build.0 = Release|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|x86.ActiveCfg = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.GPU|x86.Build.0 = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|x64.ActiveCfg = Release|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|x64.Build.0 = Release|x64
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|x86.ActiveCfg = Release|Any CPU
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3}.Release|x86.Build.0 = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|x64.ActiveCfg = Debug|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|x64.Build.0 = Debug|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Debug|x86.Build.0 = Debug|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|x64.ActiveCfg = Release|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|x64.Build.0 = Release|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|x86.ActiveCfg = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.GPU|x86.Build.0 = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|x64.ActiveCfg = Release|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|x64.Build.0 = Release|x64
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|x86.ActiveCfg = Release|Any CPU
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA}.Release|x86.Build.0 = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|x64.ActiveCfg = Debug|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|x64.Build.0 = Debug|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Debug|x86.Build.0 = Debug|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|Any CPU.ActiveCfg = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|Any CPU.Build.0 = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|x64.ActiveCfg = Release|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|x64.Build.0 = Release|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|x86.ActiveCfg = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.GPU|x86.Build.0 = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|x64.ActiveCfg = Release|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|x64.Build.0 = Release|x64
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|x86.ActiveCfg = Release|Any CPU
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3}.Release|x86.Build.0 = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|x64.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Debug|x86.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|x64.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.GPU|x86.Build.0 = Debug|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|x64.ActiveCfg = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|x64.Build.0 = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|x86.ActiveCfg = Release|Any CPU
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18}.Release|x86.Build.0 = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|x64.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Debug|x86.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|x64.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.GPU|x86.Build.0 = Debug|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|x64.ActiveCfg = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|x64.Build.0 = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|x86.ActiveCfg = Release|Any CPU
+ {7DEA8760-E401-4872-81F3-405F185A13A0}.Release|x86.Build.0 = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Debug|x86.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|x64.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.GPU|x86.Build.0 = Debug|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|x64.Build.0 = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C}.Release|x86.Build.0 = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Debug|x86.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|x64.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.GPU|x86.Build.0 = Debug|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|x64.Build.0 = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C}.Release|x86.Build.0 = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|x64.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Debug|x86.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|x64.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.GPU|x86.Build.0 = Debug|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|x64.ActiveCfg = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|x64.Build.0 = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|x86.ActiveCfg = Release|Any CPU
+ {D24FCAA5-548C-4251-B226-A1B6535D0845}.Release|x86.Build.0 = Release|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|x64.ActiveCfg = Debug|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|x64.Build.0 = Debug|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Debug|x86.Build.0 = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|x64.ActiveCfg = Debug|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|x64.Build.0 = Debug|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.GPU|x86.Build.0 = Debug|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|x64.ActiveCfg = Release|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|x64.Build.0 = Release|x64
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|x86.ActiveCfg = Release|Any CPU
+ {C23563DB-FE21-48E7-A411-87A109E4A899}.Release|x86.Build.0 = Release|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|x64.ActiveCfg = Debug|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|x64.Build.0 = Debug|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Debug|x86.Build.0 = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|x64.ActiveCfg = Debug|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|x64.Build.0 = Debug|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.GPU|x86.Build.0 = Debug|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|x64.ActiveCfg = Release|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|x64.Build.0 = Release|x64
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|x86.ActiveCfg = Release|Any CPU
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0}.Release|x86.Build.0 = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|x64.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Debug|x86.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|x64.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.GPU|x86.Build.0 = Debug|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|x64.ActiveCfg = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|x64.Build.0 = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|x86.ActiveCfg = Release|Any CPU
+ {654A027D-1364-4729-880B-144DFE1FF5BB}.Release|x86.Build.0 = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|x64.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Debug|x86.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|Any CPU.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|Any CPU.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|x64.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|x64.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|x86.ActiveCfg = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.GPU|x86.Build.0 = Debug|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|x64.ActiveCfg = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|x64.Build.0 = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|x86.ActiveCfg = Release|Any CPU
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {FD682AC0-7B2D-45D3-8B0D-C6D678B04144} = {01A1787F-A9BE-4221-84E8-6360DD010AB6}
+ {23C28035-2FCE-41F3-9A12-E73CE8A5AE32} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {49D71826-C03D-4FA7-9BAC-22C1327E65CF} = {01A1787F-A9BE-4221-84E8-6360DD010AB6}
+ {1AB8108D-4FFE-4A16-88E7-328EAF686370} = {01A1787F-A9BE-4221-84E8-6360DD010AB6}
+ {F17AAECB-960A-4E18-A270-BAD776F0E55B} = {01A1787F-A9BE-4221-84E8-6360DD010AB6}
+ {84CA35F8-99FC-408E-8DF3-5AA175E5EFD3} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {79EB56DF-E29E-4AE2-A7D9-FE403FD919BA} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {3F5388FF-FBB4-462B-8F6F-829FFBAEB8A3} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {9738D16A-CFA0-405C-A7DF-D3D203B0CB18} = {01A1787F-A9BE-4221-84E8-6360DD010AB6}
+ {7DEA8760-E401-4872-81F3-405F185A13A0} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {3D92142F-EEDB-469B-B03C-4E38728BFE4C} = {E1A5D2B7-10AF-4876-85C0-7714EF274214}
+ {AB131FA7-B7C3-4ABF-ABDE-E059C72A613C} = {E1A5D2B7-10AF-4876-85C0-7714EF274214}
+ {D24FCAA5-548C-4251-B226-A1B6535D0845} = {E1A5D2B7-10AF-4876-85C0-7714EF274214}
+ {C23563DB-FE21-48E7-A411-87A109E4A899} = {E1A5D2B7-10AF-4876-85C0-7714EF274214}
+ {1DC32255-BA1F-4D6D-A9C9-5BD5ED71CAA0} = {E1A5D2B7-10AF-4876-85C0-7714EF274214}
+ {654A027D-1364-4729-880B-144DFE1FF5BB} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ {A73DF5A6-866E-4AED-9017-AA2EE86368C4} = {1B0918B9-65AD-4F34-A287-AF4597B27DBD}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2DEAD3CC-486B-4918-A607-50B0DE7B114A}
EndGlobalSection
diff --git a/data/img001.bmp b/data/img001.bmp
new file mode 100644
index 000000000..d149d76f1
Binary files /dev/null and b/data/img001.bmp differ
diff --git a/docs/Example-fsharp.md b/docs/Example-fsharp.md
new file mode 100644
index 000000000..578543454
--- /dev/null
+++ b/docs/Example-fsharp.md
@@ -0,0 +1,55 @@
+Linear Regression in `Eager` mode:
+
+```fsharp
+#r "nuget: TensorFlow.Net"
+#r "nuget: TensorFlow.Keras"
+#r "nuget: SciSharp.TensorFlow.Redist"
+
+open Tensorflow
+open Tensorflow.NumPy
+open type Tensorflow.Binding
+open type Tensorflow.KerasApi
+
+let tf = New()
+tf.enable_eager_execution()
+
+// Parameters
+let training_steps = 1000
+let learning_rate = 0.01f
+let display_step = 100
+
+// Sample data
+let train_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)
+let train_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)
+let n_samples = train_X.shape.[0]
+
+// We can set a fixed init value in order to demo
+let W = tf.Variable(-0.06f,name = "weight")
+let b = tf.Variable(-0.73f, name = "bias")
+let optimizer = keras.optimizers.SGD(learning_rate)
+
+// Run training for the given number of steps.
+for step = 1 to (training_steps + 1) do
+ // Run the optimization to update W and b values.
+ // Wrap computation inside a GradientTape for automatic differentiation.
+ use g = tf.GradientTape()
+ // Linear regression (Wx + b).
+ let pred = W * train_X + b
+ // Mean square error.
+ let loss = tf.reduce_sum(tf.pow(pred - train_Y,2)) / (2 * n_samples)
+ // should stop recording
+ // compute gradients
+ let gradients = g.gradient(loss,struct (W,b))
+
+ // Update W and b following gradients.
+ optimizer.apply_gradients(zip(gradients, struct (W,b)))
+
+ if (step % display_step) = 0 then
+ let pred = W * train_X + b
+ let loss = tf.reduce_sum(tf.pow(pred-train_Y,2)) / (2 * n_samples)
+ printfn $"step: {step}, loss: {loss.numpy()}, W: {W.numpy()}, b: {b.numpy()}"
+```
\ No newline at end of file
diff --git a/docs/README-CN.md b/docs/README-CN.md
new file mode 100644
index 000000000..9776b0fb8
--- /dev/null
+++ b/docs/README-CN.md
@@ -0,0 +1,228 @@
+
+
+**Tensorflow.NET**是AI框架[TensorFlow](https://www.tensorflow.org/)在.NET平台上的实现,支持C#和F#,可以用来搭建深度学习模型并进行训练和推理,并内置了Numpy API,可以用来进行其它科学计算。
+
+Tensorflow.NET并非对于Python的简单封装,而是基于C API的pure C#实现,因此使用时无需额外的环境,可以很方便地用NuGet直接安装使用。并且dotnet团队提供的[ML.NET](https://github.com/dotnet/machinelearning)也依赖于Tensorflow.NET,支持调用Tensorflow.NET进行训练和推理,可以很方便地融入.NET生态。
+
+与tensorflow相同,Tensorflow.NET也内置了Keras这一高级API,只要在安装Tensorflow.NET的同时安装Tensorflow.Keras就可以使用,Keras支持以模块化的方式调用模型,给模型的搭建提供了极大的便利。
+
+[](https://gitter.im/sci-sharp/community)
+[](https://ci.appveyor.com/project/Haiping-Chen/tensorflow-net)
+[](https://www.nuget.org/packages/TensorFlow.NET)
+[](https://tensorflownet.readthedocs.io/en/latest/?badge=latest)
+[](https://996.icu/#/en_US)
+[](https://mybinder.org/v2/gh/javiercp/BinderTF.NET/master?urlpath=lab)
+
+中文 | [English](https://github.com/SciSharp/TensorFlow.NET#readme)
+
+*当前主分支与Tensorflow2.10版本相对应,支持Eager Mode,同时也支持v1的静态图。*
+
+
+
+
+## Why Tensorflow.NET?
+
+`SciSharp STACK`开源社区的目标是构建.NET平台下易用的科学计算库,而Tensorflow.NET就是其中最具代表性的仓库之一。在深度学习领域Python是主流,无论是初学者还是资深开发者,模型的搭建和训练都常常使用Python写就的AI框架,比如tensorflow。但在实际应用深度学习模型的时候,又可能希望用到.NET生态,亦或只是因为.NET是自己最熟悉的领域,这时候Tensorflow.NET就有显著的优点,因为它不仅可以和.NET生态很好地贴合,其API还使得开发者很容易将Python代码迁移过来。下面的对比就是很好的例子,Python代码和C#代码有着高度相似的API,这会使得迁移的时候无需做过多修改。
+
+
+
+除了高度相似的API外,Tensorflow.NET与tensorflow也已经打通数据通道,tensorflow训练并保存的模型可以在Tensorflow.NET中直接读取并继续训练或推理,反之Tensorflow.NET保存的模型也可以在tensorflow中读取,这大大方便了模型的训练和部署。
+
+与其它类似的库比如[TensorFlowSharp](https://www.nuget.org/packages/TensorFlowSharp/)相比,Tensorflow.NET的实现更加完全,提供了更多的高级API,使用起来更为方便,更新也更加迅速。
+
+
+## 文档
+
+基本介绍与简单用例:[Tensorflow.NET Documents](https://scisharp.github.io/tensorflow-net-docs)
+
+详细文档:[The Definitive Guide to Tensorflow.NET](https://tensorflownet.readthedocs.io/en/latest/FrontCover.html)
+
+例程:[TensorFlow.NET Examples](https://github.com/SciSharp/TensorFlow.NET-Examples)
+
+运行例程常见问题:[Tensorflow.NET FAQ](tensorflowlib/README.md)
+
+## 安装与使用
+
+安装可以在NuGet包管理器中搜索包名安装,也可以用下面命令行的方式。
+
+安装分为两个部分,第一部分是Tensorflow.NET的主体:
+
+```sh
+### 安装Tensorflow.NET
+PM> Install-Package TensorFlow.NET
+
+### 安装Tensorflow.Keras
+PM> Install-Package TensorFlow.Keras
+```
+
+第二部分是计算支持部分,只需要根据自己的设备和系统选择下面之一即可:
+
+```
+### CPU版本,支持Windows、Linux和Mac
+PM> Install-Package SciSharp.TensorFlow.Redist
+
+### 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 Examples]中查看。
+
+### 简单例子(使用Eager Mode进行线性回归)
+
+```csharp
+using static Tensorflow.Binding;
+using static Tensorflow.KerasApi;
+using Tensorflow;
+using Tensorflow.NumPy;
+
+// Parameters
+var training_steps = 1000;
+var learning_rate = 0.01f;
+var display_step = 100;
+
+// Sample data
+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];
+
+// We can set a fixed init value in order to demo
+var W = tf.Variable(-0.06f, name: "weight");
+var b = tf.Variable(-0.73f, name: "bias");
+var optimizer = keras.optimizers.SGD(learning_rate);
+
+// Run training for the given number of steps.
+foreach (var step in range(1, training_steps + 1))
+{
+ // Run the optimization to update W and b values.
+ // Wrap computation inside a GradientTape for automatic differentiation.
+ using var g = tf.GradientTape();
+ // Linear regression (Wx + b).
+ var pred = W * X + b;
+ // Mean square error.
+ var loss = tf.reduce_sum(tf.pow(pred - Y, 2)) / (2 * n_samples);
+ // should stop recording
+ // Compute gradients.
+ var gradients = g.gradient(loss, (W, b));
+
+ // Update W and b following gradients.
+ 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 Example](https://github.com/SciSharp/SciSharpCube)进行运行.
+
+### 简单例子(使用Keras搭建Resnet)
+
+```csharp
+using static Tensorflow.Binding;
+using static Tensorflow.KerasApi;
+using Tensorflow;
+using Tensorflow.NumPy;
+
+var layers = keras.layers;
+// input layer
+var inputs = keras.Input(shape: (32, 32, 3), name: "img");
+// convolutional layer
+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);
+// output layer
+var outputs = layers.Dense(10).Apply(x);
+// build keras model
+var model = keras.Model(inputs, outputs, name: "toy_resnet");
+model.summary();
+// compile keras model in tensorflow static graph
+model.compile(optimizer: keras.optimizers.RMSprop(1e-3f),
+ loss: keras.losses.SparseCategoricalCrossentropy(from_logits: true),
+ metrics: new[] { "acc" });
+// prepare dataset
+var ((x_train, y_train), (x_test, y_test)) = keras.datasets.cifar10.load_data();
+// normalize the input
+x_train = x_train / 255.0f;
+// training
+model.fit(x_train[new Slice(0, 2000)], y_train[new Slice(0, 2000)],
+ batch_size: 64,
+ epochs: 10,
+ validation_split: 0.2f);
+// save the model
+model.save("./toy_resnet_model");
+```
+
+此外,Tensorflow.NET也支持用F#搭建上述模型进行训练和推理。
+
+## Tensorflow.NET版本对应关系
+
+| TensorFlow.NET Versions | 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.NET与Tensorflow.Keras版本存在一一对应关系,请安装与Tensorflow.NET对应的Tensorflow.Keras版本。
+
+## 参与我们的开发:
+
+我们欢迎任何人的任何形式的贡献!无论是文档中的错误纠正,新特性提议,还是BUG修复等等,都会使得Tensorflow.NET项目越来越好,Tensorflow.NET的全体开发者也会积极帮助解决您提出的问题。
+
+下面任何一种形式都可以帮助Tensorflow.NET越来越好:
+
+* Star和分享Tensorflow.NET项目
+* 为Tensorflow.NET添加更多的用例
+* 在issue中告知我们Tensorflow.NET目前相比tensorflow缺少的API或者没有对齐的特性
+* 在issue中提出Tensorflow.NET存在的BUG或者可以改进的地方
+* 在待办事项清单中选择一个进行或者解决某个issue
+* 帮助我们完善文档,这也十分重要
+
+
+## 支持我们
+我们推出了[TensorFlow.NET实战](https://item.jd.com/13441549.html)这本书,包含了Tensorflow.NET主要开发者编写的讲解与实战例程,欢迎您的购买,希望这本书可以给您带来帮助。
+
+
+
+
+
+
+## 联系我们
+
+可以在 [Twitter](https://twitter.com/ScisharpStack), [Facebook](https://www.facebook.com/scisharp.stack.9), [Medium](https://medium.com/scisharp), [LinkedIn](https://www.linkedin.com/company/scisharp-stack/)中关注我们,也可以在[Gitter](https://gitter.im/sci-sharp/community)中与项目开发者以及其它使用者进行沟通交流,也欢迎在仓库中提起issue。
+
+TensorFlow.NET is a part of [SciSharp STACK](https://scisharp.github.io/SciSharp/)
+
+
diff --git a/docs/RELEASE.md b/docs/RELEASE.md
new file mode 100644
index 000000000..62a1be238
--- /dev/null
+++ b/docs/RELEASE.md
@@ -0,0 +1,44 @@
+# Release Notes
+
+**Thanks to our Contributors!**
+
+This release contains contributions from many people at SciSharp as well as the external contributors.
+
+**Release Date 02/06/2021**
+
+### TensorFlow.Binding v0.33.0
+
+* Improve memory usage
+* Fix minor bugs
+
+### TensorFlow.Keras v0.4.0
+
+* Add Subtract layer
+
+* Add model.load_weights and model.save_weights
+
+* Fix memory leak issue
+
+* Support to build YOLOv3 object detection model
+
+
+
+**Release Date 01/09/2021**
+
+### TensorFlow.Binding v0.32.0
+
+* Fix input `dtype` for `MapDataset`.
+* Fix `image_dataset_from_directory` function.
+* Fix `tf.transpose`.
+* Add `array_ops.where_v2`, `array_ops.select_v2`, `array_ops.softplus`.
+* Add `dataset.dataset_cardinality`.
+
+### TensorFlow.Keras v0.3.0
+
+* Fix `weight` init value for `double` type in `compute_weighted_loss`.
+* Add `MeanSquaredError `, `MeanAbsolutePercentageError `, `MeanAbsoluteError` and `MeanSquaredLogarithmicError` loss functions.
+* `Sequential` model API works.
+* Add `ShellProgressBar` to show training progress better.
+
+
+
diff --git a/docs/TIM.jpg b/docs/TIM.jpg
deleted file mode 100644
index a436aa301..000000000
Binary files a/docs/TIM.jpg and /dev/null differ
diff --git a/docs/source/LinearRegression.md b/docs/source/LinearRegression.md
index 81a6dbc4c..8033625c3 100644
--- a/docs/source/LinearRegression.md
+++ b/docs/source/LinearRegression.md
@@ -82,4 +82,4 @@ When we visualize the graph in TensorBoard:

-The full example is [here](https://github.com/SciSharp/TensorFlow.NET/blob/master/test/TensorFlowNET.Examples/BasicModels/LinearRegression.cs).
+The full example is [here](https://github.com/SciSharp/TensorFlow.NET-Examples/blob/master/src/TensorFlowNET.Examples/BasicModels/LinearRegression.cs).
diff --git a/docs/source/LogisticRegression.md b/docs/source/LogisticRegression.md
index 42cda8983..ddf75f846 100644
--- a/docs/source/LogisticRegression.md
+++ b/docs/source/LogisticRegression.md
@@ -13,4 +13,4 @@ The dependent variable of logistics regression can be two-category or multi-cate
Softmax regression allows us to handle  where K is the number of classes.
-The full example is [here](https://github.com/SciSharp/TensorFlow.NET/blob/master/test/TensorFlowNET.Examples/BasicModels/LogisticRegression.cs).
+The full example is [here](https://github.com/SciSharp/TensorFlow.NET-Examples/blob/master/src/TensorFlowNET.Examples/BasicModels/LogisticRegression.cs).
diff --git a/docs/source/NearestNeighbor.md b/docs/source/NearestNeighbor.md
index 861181aae..94e300df6 100644
--- a/docs/source/NearestNeighbor.md
+++ b/docs/source/NearestNeighbor.md
@@ -2,4 +2,4 @@
The nearest neighbour algorithm was one of the first algorithms used to solve the travelling salesman problem. In it, the salesman starts at a random city and repeatedly visits the nearest city until all have been visited. It quickly yields a short tour, but usually not the optimal one.
-The full example is [here](https://github.com/SciSharp/TensorFlow.NET/blob/master/test/TensorFlowNET.Examples/BasicModels/NearestNeighbor.cs).
\ No newline at end of file
+The full example is [here](https://github.com/SciSharp/TensorFlow.NET-Examples/blob/master/src/TensorFlowNET.Examples/BasicModels/NearestNeighbor.cs).
\ No newline at end of file
diff --git a/src/SciSharp.TensorFlow.Redist/README.md b/src/SciSharp.TensorFlow.Redist/README.md
index 26eec870d..4002aa21d 100644
--- a/src/SciSharp.TensorFlow.Redist/README.md
+++ b/src/SciSharp.TensorFlow.Redist/README.md
@@ -22,11 +22,19 @@ https://www.nuget.org/packages/SciSharp.TensorFlow.Redist
Related merged [commits](https://github.com/SciSharp/TensorFlow.NET/commit/854a5ba61ad0e400623821236bd117cc24c6cb77).
+
+
+#### Download pre-build package
+
+[Mac OSX CPU](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-darwin-x86_64-2.10.0.tar.gz), [Linux CPU](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-2.10.0.tar.gz), [Linux GPU](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-linux-x86_64-2.10.0.tar.gz), [Windows CPU](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-2.10.0.zip), [Windows GPU](https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-windows-x86_64-2.10.0.zip)
+
+
+
#### Pack and Deploy ####
On Windows, the tar command does not support extracting archives with symlinks. So when `dotnet pack` runs on Windows it will only package the Windows binaries.
1. Run `dotnet pack SciSharp.TensorFlow.Redist.nupkgproj` under `src/SciSharp.TensorFlow.Redist` directory in Linux.
-2. Run `dotnet nuget push SciSharp.TensorFlow.Redist.2.3.1.nupkg -k APIKEY -s https://api.nuget.org/v3/index.json -t 600`
+2. Run `dotnet nuget push SciSharp.TensorFlow.Redist.2.10.0.nupkg -k APIKEY -s https://api.nuget.org/v3/index.json -t 600`
diff --git a/src/TensorFlowNET.Console/MemoryMonitor.cs b/src/TensorFlowNET.Console/MemoryMonitor.cs
deleted file mode 100644
index 311488af5..000000000
--- a/src/TensorFlowNET.Console/MemoryMonitor.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Diagnostics;
-using static Tensorflow.Binding;
-
-namespace Tensorflow
-{
- public class MemoryMonitor
- {
- public void WarmUp()
- {
- print($"tensorflow native version: v{tf.VERSION}");
- }
-
- public void Execute(int epoch, int iterate, Action process)
- {
- /*GC.Collect();
- GC.WaitForPendingFinalizers();
- GC.Collect();*/
-
- print($"{process.Method.Name} started...");
- for (int i = 0; i < epoch; i++)
- {
- var initialMemory = Process.GetCurrentProcess().PrivateMemorySize64;// GC.GetTotalMemory(true);
- process(iterate);
- var finalMemory = Process.GetCurrentProcess().PrivateMemorySize64; //GC.GetTotalMemory(true);
- print($"Epoch {i}: {Format(finalMemory - initialMemory)}.");
- }
-
- GC.Collect();
- GC.WaitForPendingFinalizers();
- GC.Collect();
-
- print($"Total {process.Method.Name} usage {Format(Process.GetCurrentProcess().PrivateMemorySize64)}");
- }
-
- private string Format(long usage)
- {
- if (usage < 0)
- return $"-{Format(0 - usage)}";
-
- if (usage <= 1024 && usage >= 0)
- return $"{usage} Bytes";
- else if (usage > 1024 && usage <= 1024 * 1024)
- return $"{usage / 1024} KB";
- else
- return $"{usage / 1024 / 1024} MB";
- }
- }
-}
diff --git a/src/TensorFlowNET.Console/MemoryTestingCases.cs b/src/TensorFlowNET.Console/MemoryTestingCases.cs
deleted file mode 100644
index 731ef4d51..000000000
--- a/src/TensorFlowNET.Console/MemoryTestingCases.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using NumSharp;
-using System;
-using static Tensorflow.Binding;
-
-namespace Tensorflow
-{
- class MemoryTestingCases
- {
- ///
- ///
- ///
- public Action Constant
- => (iterate) =>
- {
- for (int i = 0; i < iterate; i++)
- {
- var tensor = tf.constant(3112.0f);
- }
- };
-
- public Action Constant2x3
- => (iterate) =>
- {
- var nd = np.array(new byte[,]
- {
- {1, 2, 3},
- {4, 5, 6}
- });
- for (int i = 0; i < iterate; i++)
- {
- var tensor = tf.constant(nd);
- var data = tensor.numpy();
- }
- };
-
- public Action Variable
- => (iterate) =>
- {
- for (int i = 0; i < iterate; i++)
- {
- var tensor = tf.Variable(3112.0f);
- }
- };
-
- public Action MathAdd
- => (iterate) =>
- {
- var x = tf.constant(3112.0f);
- var y = tf.constant(3112.0f);
-
- for (int i = 0; i < iterate; i++)
- {
- var z = x + y;
- }
- };
-
- public Action Gradient
- => (iterate) =>
- {
- for (int i = 0; i < iterate; i++)
- {
- var w = tf.constant(3112.0f);
- using var tape = tf.GradientTape();
- tape.watch(w);
- var loss = w * w;
- var grad = tape.gradient(loss, w);
- }
- };
- }
-}
diff --git a/src/TensorFlowNET.Console/Program.cs b/src/TensorFlowNET.Console/Program.cs
deleted file mode 100644
index 7b91e6ad1..000000000
--- a/src/TensorFlowNET.Console/Program.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Tensorflow
-{
- class Program
- {
- static void Main(string[] args)
- {
- // boot .net core 10.5M.
- var mm = new MemoryMonitor();
- // warm up tensorflow.net 28.5M.
- mm.WarmUp();
- var cases = new MemoryTestingCases();
-
- int batchSize = 1000;
-
- // explaination of constant
- mm.Execute(10, 100 * batchSize, cases.Constant2x3);
-
- // 1 million float tensor 68M.
- mm.Execute(10, 100 * batchSize, cases.Constant);
-
- // 100K float variable 84M.
- mm.Execute(10, 10 * batchSize, cases.Variable);
-
- // 1 million math add 39M.
- mm.Execute(10, 100 * batchSize, cases.MathAdd);
-
- // 100K gradient 44M.
- mm.Execute(10, 10 * batchSize, cases.Gradient);
-
- // 95M
- Console.WriteLine("Finished.");
- Console.ReadLine();
- }
- }
-}
diff --git a/src/TensorFlowNET.Console/TensorFlowNET.Console.csproj b/src/TensorFlowNET.Console/TensorFlowNET.Console.csproj
deleted file mode 100644
index 6cc631f42..000000000
--- a/src/TensorFlowNET.Console/TensorFlowNET.Console.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
- Tensorflow
- Tensorflow
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/TensorFlowNET.Core/APIs/c_api.cs b/src/TensorFlowNET.Core/APIs/c_api.cs
index 10f678e0a..a91b86827 100644
--- a/src/TensorFlowNET.Core/APIs/c_api.cs
+++ b/src/TensorFlowNET.Core/APIs/c_api.cs
@@ -16,6 +16,7 @@ limitations under the License.
using System;
using System.Runtime.InteropServices;
+using static Tensorflow.CppShapeInferenceResult.Types;
namespace Tensorflow
{
@@ -50,6 +51,35 @@ public static string StringPiece(IntPtr handle)
return handle == IntPtr.Zero ? String.Empty : Marshal.PtrToStringAnsi(handle);
}
+ public unsafe static byte[] ByteStringPiece(Buffer? handle)
+ {
+ if (handle is null)
+ {
+ return new byte[0];
+ }
+ var data = handle.ToArray();
+ return data;
+ }
+
+ public unsafe static byte[] ByteStringPieceFromNativeString(IntPtr handle)
+ {
+ if (handle == IntPtr.Zero)
+ {
+ return new byte[0];
+ }
+
+ byte* str_data = (byte*)handle.ToPointer();
+ List bytes = new List();
+ byte current = 255;
+ while (current != ((byte)'\0'))
+ {
+ current = *(str_data++);
+ bytes.Add(current);
+ }
+ var data = bytes.ToArray();
+ return data;
+ }
+
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void Deallocator(IntPtr data, IntPtr size, ref DeallocatorArgs args);
diff --git a/src/TensorFlowNET.Core/APIs/c_api.customize.cs b/src/TensorFlowNET.Core/APIs/c_api.customize.cs
new file mode 100644
index 000000000..bee4897ee
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/c_api.customize.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Tensorflow
+{
+ public partial class c_api
+ {
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_SetAttr(SafeGraphHandle graph, IntPtr op, string attr_name, SafeBufferHandle attr_value_proto, SafeStatusHandle status);
+ [DllImport(TensorFlowLibName)]
+ public static extern SafeBufferHandle TF_GetHandleShapeAndType(SafeGraphHandle c_graph, TF_Output output);
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_SetHandleShapeAndType(SafeGraphHandle c_graph, TF_Output output, byte[] data, long proto_len, SafeStatusHandle status);
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/c_api_lite.cs b/src/TensorFlowNET.Core/APIs/c_api_lite.cs
new file mode 100644
index 000000000..5a437d261
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/c_api_lite.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using Tensorflow.Lite;
+
+namespace Tensorflow
+{
+ public class c_api_lite
+ {
+ public const string TensorFlowLibName = "tensorflowlite_c";
+
+ public static string StringPiece(IntPtr handle)
+ {
+ return handle == IntPtr.Zero ? String.Empty : Marshal.PtrToStringAnsi(handle);
+ }
+
+ [DllImport(TensorFlowLibName)]
+ public static extern IntPtr TfLiteVersion();
+
+ [DllImport(TensorFlowLibName)]
+ public static extern SafeTfLiteModelHandle TfLiteModelCreateFromFile(string model_path);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TfLiteModelDelete(IntPtr model);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern SafeTfLiteInterpreterOptionsHandle TfLiteInterpreterOptionsCreate();
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TfLiteInterpreterOptionsDelete(IntPtr options);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TfLiteInterpreterOptionsSetNumThreads(SafeTfLiteInterpreterOptionsHandle options, int num_threads);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern SafeTfLiteInterpreterHandle TfLiteInterpreterCreate(SafeTfLiteModelHandle model, SafeTfLiteInterpreterOptionsHandle optional_options);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TfLiteInterpreterDelete(IntPtr interpreter);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteStatus TfLiteInterpreterAllocateTensors(SafeTfLiteInterpreterHandle interpreter);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern int TfLiteInterpreterGetInputTensorCount(SafeTfLiteInterpreterHandle interpreter);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern int TfLiteInterpreterGetOutputTensorCount(SafeTfLiteInterpreterHandle interpreter);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteStatus TfLiteInterpreterResizeInputTensor(SafeTfLiteInterpreterHandle interpreter,
+ int input_index, int[] input_dims, int input_dims_size);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteTensor TfLiteInterpreterGetInputTensor(SafeTfLiteInterpreterHandle interpreter, int input_index);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteDataType TfLiteTensorType(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern int TfLiteTensorNumDims(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern int TfLiteTensorDim(TfLiteTensor tensor, int dim_index);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern int TfLiteTensorByteSize(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern IntPtr TfLiteTensorData(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern IntPtr TfLiteTensorName(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteQuantizationParams TfLiteTensorQuantizationParams(TfLiteTensor tensor);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteStatus TfLiteTensorCopyFromBuffer(TfLiteTensor tensor, IntPtr input_data, int input_data_size);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteStatus TfLiteInterpreterInvoke(SafeTfLiteInterpreterHandle interpreter);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern IntPtr TfLiteInterpreterGetOutputTensor(SafeTfLiteInterpreterHandle interpreter, int output_index);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern TfLiteStatus TfLiteTensorCopyToBuffer(TfLiteTensor output_tensor, IntPtr output_data, int output_data_size);
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.array.cs b/src/TensorFlowNET.Core/APIs/tf.array.cs
index a87e041e3..b529cd319 100644
--- a/src/TensorFlowNET.Core/APIs/tf.array.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.array.cs
@@ -14,11 +14,12 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
-using NumSharp;
+using Tensorflow.NumPy;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using static Tensorflow.Binding;
+using Tensorflow.Operations;
namespace Tensorflow
{
@@ -43,7 +44,8 @@ public partial class tensorflow
///
///
public Tensor batch_to_space_nd(T input, int[] block_shape, int[,] crops, string name = null)
- => gen_array_ops.batch_to_space_nd(input, block_shape, crops, name: name);
+ => gen_array_ops.batch_to_space_nd(ops.convert_to_tensor(input), ops.convert_to_tensor(block_shape),
+ ops.convert_to_tensor(crops), name: name);
///
/// Apply boolean mask to tensor.
@@ -65,7 +67,7 @@ public Tensor boolean_mask(T1 tensor, T2 mask, string name = "boolean_ma
///
///
///
- public Tensor broadcast_to(Tensor input, TensorShape shape, string name = null)
+ public Tensor broadcast_to(Tensor input, Shape shape, string name = null)
=> gen_array_ops.broadcast_to(input, shape, name: name);
public Tensor check_numerics(Tensor tensor, string message, string name = null)
@@ -78,19 +80,18 @@ public Tensor check_numerics(Tensor tensor, string message, string name = null)
///
///
/// A `Tensor` resulting from concatenation of the input tensors.
- public Tensor concat(IList values, int axis, string name = "concat")
+ public Tensor concat(IEnumerable values, int axis, string name = "concat")
{
- if (values.Count == 1)
+ if (values.Count() == 1)
{
return tf_with(ops.name_scope(name), scope =>
{
var tensor = ops.convert_to_tensor(axis, name: "concat_dim", dtype: dtypes.int32);
- Debug.Assert(tensor.TensorShape.ndim == 0);
- return identity(values[0], name: scope);
+ Debug.Assert(tensor.shape.ndim == 0);
+ return identity(values.First(), name: scope);
});
}
-
- return gen_array_ops.concat_v2(values.ToArray(), axis, name: name);
+ return array_ops.concat(values.ToArray(), axis, name: name);
}
///
@@ -99,13 +100,12 @@ public Tensor concat(IList values, int axis, string name = "concat")
///
///
///
- ///
///
/// A `Tensor` with the same data as `input`, but its shape has an additional
/// dimension of size 1 added.
///
- public Tensor expand_dims(Tensor input, int axis = -1, string name = null, int dim = -1)
- => array_ops.expand_dims(input, axis, name, dim);
+ public Tensor expand_dims(Tensor input, int axis = -1, string name = null)
+ => array_ops.expand_dims(input, axis, name);
///
/// Creates a tensor filled with a scalar value.
@@ -115,7 +115,10 @@ public Tensor expand_dims(Tensor input, int axis = -1, string name = null, int d
///
///
public Tensor fill(Tensor dims, T value, string name = null)
- => gen_array_ops.fill(dims, value, name: name);
+ => gen_array_ops.fill(dims, ops.convert_to_tensor(value), name: name);
+
+ public Tensor fill(Shape dims, T value, string name = null)
+ => array_ops.fill(dims, value, name: name);
///
/// Return a tensor with the same shape and contents as input.
@@ -135,7 +138,17 @@ public Tensor identity(Tensor input, string name = null)
///
///
public Tensor gather(Tensor @params, Tensor indices, string name = null, int axis = 0)
- => array_ops.gather(@params, indices, name: name, axis: axis);
+ => array_ops.gather(@params, indices, name: name, axis: ops.convert_to_tensor(axis));
+
+ ///
+ /// Gather slices from `params` into a Tensor with shape specified by `indices`.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor gather_nd(Tensor @params, Tensor indices, string name = null)
+ => gen_array_ops.gather_nd(@params, indices, name: name);
///
/// Return the elements, either from `x` or `y`, depending on the `condition`.
@@ -152,21 +165,24 @@ public Tensor where(Tensor condition, Tx x, Ty y, string name = null)
///
///
///
- public Tensor transpose(T1 a, int[] perm = null, string name = "transpose", bool conjugate = false)
+ public Tensor transpose(T1 a, Axis perm = null, string name = "transpose", bool conjugate = false)
=> array_ops.transpose(a, perm, name, conjugate);
///
/// Reverses specific dimensions of a tensor.
///
///
- ///
+ /// The indices of the dimensions to reverse. Must be in the range [-rank(tensor), rank(tensor)).
///
///
- public Tensor reverse(Tensor tensor, int[] axis, string name = null)
- => gen_array_ops.reverse(tensor, axis, name: name);
-
- public Tensor reverse(Tensor tensor, Tensor axis, string name = null)
- => gen_array_ops.reverse(tensor, axis, name: name);
+ public Tensor reverse(Tensor tensor, Axis axis, string name = null)
+ {
+ if (axis.IsScalar)
+ {
+ axis = new Axis(axis.axis);
+ }
+ return array_ops.reverse(tensor, axis, name: name);
+ }
///
/// Returns the rank of a tensor.
@@ -186,7 +202,11 @@ public Tensor rank(Tensor input, string name = null)
/// A name for the operation (optional).
/// A `Tensor` the same type as `input`.
public Tensor slice(Tensor input, Tb[] begin, Ts[] size, string name = null)
- => array_ops.slice(input, begin, size, name: name);
+ => array_ops.slice(input, begin.Select(x => ops.convert_to_tensor(x)).ToArray(),
+ size.Select(x => ops.convert_to_tensor(x)).ToArray(), name: name);
+
+ public Tensor squeeze(Tensor input, int axis, string name = null, int squeeze_dims = -1)
+ => array_ops.squeeze(input, new[] { axis }, name);
public Tensor squeeze(Tensor input, int[] axis = null, string name = null, int squeeze_dims = -1)
=> array_ops.squeeze(input, axis, name);
@@ -215,6 +235,9 @@ public Tensor stack(object values, int axis = 0, string name = "stack")
public Tensor ones_like(Tensor tensor, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool optimize = true)
=> array_ops.ones_like(tensor, dtype: dtype, name: name, optimize: optimize);
+ public Tensor ones_like(NDArray nd, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool optimize = true)
+ => array_ops.ones_like(nd, dtype: dtype, name: name, optimize: optimize);
+
public Tensor one_hot(Tensor indices, int depth,
Tensor on_value = null,
Tensor off_value = null,
@@ -240,13 +263,13 @@ public Tensor pad(Tensor tensor, Tensor paddings, string mode = "CONSTANT", stri
///
/// A `Tensor`. The default value to produce when output is not fed.
///
- /// A `tf.TensorShape` or list of `int`s. The (possibly partial) shape of
+ /// A `tf.Shape` or list of `int`s. The (possibly partial) shape of
/// the tensor.
///
/// A name for the operation (optional).
/// A `Tensor`. Has the same type as `input`.
public Tensor placeholder_with_default(T input, int[] shape, string name = null)
- => gen_array_ops.placeholder_with_default(input, shape, name: name);
+ => gen_array_ops.placeholder_with_default(ops.convert_to_tensor(input), shape, name: name);
///
/// Returns the shape of a tensor.
@@ -290,6 +313,9 @@ public Tensor[] unstack(Tensor value, int? num = null, int axis = 0, string name
public Tensor zeros_like(Tensor tensor, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool optimize = true)
=> array_ops.zeros_like(tensor, dtype: dtype, name: name, optimize: optimize);
+ public Tensor zeros_like(NDArray nd, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, bool optimize = true)
+ => array_ops.zeros_like(nd, dtype: dtype, name: name, optimize: optimize);
+
///
/// Stops gradient computation.
///
@@ -298,5 +324,27 @@ public Tensor zeros_like(Tensor tensor, TF_DataType dtype = TF_DataType.DtInvali
///
public Tensor stop_gradient(Tensor x, string name = null)
=> gen_array_ops.stop_gradient(x, name: name);
+
+ public TensorArray TensorArray(TF_DataType dtype, int size = 0, bool dynamic_size = false,
+ bool clear_after_read = true, Shape? element_shape = null, bool colocate_with_first_write_call = true,
+ bool infer_shape = true)
+ => tf.executing_eagerly() ?
+ new _EagerTensorArray(dtype, size: constant_op.constant(size), dynamic_size: dynamic_size,
+ clear_after_read: clear_after_read, element_shape: element_shape, infer_shape: infer_shape,
+ colocate_with_first_write_call: colocate_with_first_write_call) :
+ new _GraphTensorArray(dtype, size: constant_op.constant(size), dynamic_size: dynamic_size,
+ clear_after_read: clear_after_read, element_shape: element_shape, infer_shape: infer_shape,
+ colocate_with_first_write_call: colocate_with_first_write_call);
+
+ public TensorArray TensorArray(TF_DataType dtype, Tensor size, bool dynamic_size = false,
+ bool clear_after_read = true, Shape? element_shape = null, bool colocate_with_first_write_call = true,
+ bool infer_shape = true)
+ => tf.executing_eagerly() ?
+ new _EagerTensorArray(dtype, size: size, dynamic_size: dynamic_size,
+ clear_after_read: clear_after_read, element_shape: element_shape, infer_shape: infer_shape,
+ colocate_with_first_write_call: colocate_with_first_write_call) :
+ new _GraphTensorArray(dtype, size: size, dynamic_size: dynamic_size,
+ clear_after_read: clear_after_read, element_shape: element_shape, infer_shape: infer_shape,
+ colocate_with_first_write_call: colocate_with_first_write_call);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.audio.cs b/src/TensorFlowNET.Core/APIs/tf.audio.cs
new file mode 100644
index 000000000..573b11ec3
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/tf.audio.cs
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ Copyright 2021 Haiping Chen. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+******************************************************************************/
+
+using System.Collections.Generic;
+using Tensorflow.IO;
+
+namespace Tensorflow
+{
+ public partial class tensorflow
+ {
+ public AudioAPI audio { get; } = new AudioAPI();
+
+ public class AudioAPI
+ {
+ audio_ops audio_ops = new audio_ops();
+
+ public Tensors decode_wav(Tensor contents, int desired_channels = -1, int desired_samples = -1, string name = null)
+ => audio_ops.decode_wav(contents,
+ desired_channels: desired_channels,
+ desired_samples: desired_samples,
+ name: name);
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.compat.cs b/src/TensorFlowNET.Core/APIs/tf.compat.cs
index 4d979eb55..8a30badd9 100644
--- a/src/TensorFlowNET.Core/APIs/tf.compat.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.compat.cs
@@ -14,6 +14,9 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using Google.Protobuf;
+using System.Text;
+
namespace Tensorflow
{
public partial class tensorflow
@@ -23,6 +26,43 @@ public partial class tensorflow
public class CompatApi
{
public CompatV1Api v1 { get; } = new CompatV1Api();
+
+ internal string as_text(string bytes_or_text, Encoding? encoding = null)
+ {
+ if(encoding is null) encoding = Encoding.UTF8;
+ return bytes_or_text;
+ }
+ internal string as_text(byte[] bytes_or_text, Encoding? encoding = null)
+ {
+ if(encoding is null) encoding = Encoding.UTF8;
+ return encoding.GetString(bytes_or_text);
+ }
+
+ internal string as_str(string bytes_or_text, Encoding? encoding = null)
+ {
+ return as_text(bytes_or_text, encoding);
+ }
+ internal string as_str(byte[] bytes_or_text, Encoding? encoding = null)
+ {
+ return as_text(bytes_or_text, encoding);
+ }
+
+ public ByteString as_bytes(ByteString bytes, Encoding encoding = null)
+ {
+ return bytes;
+ }
+ public ByteString as_bytes(byte[] bytes, Encoding encoding = null)
+ {
+ return ByteString.CopyFrom(bytes);
+ }
+ public ByteString as_bytes(string text, Encoding encoding = null)
+ {
+ if(encoding is null)
+ {
+ encoding = Encoding.UTF8;
+ }
+ return ByteString.CopyFrom(encoding.GetBytes(text));
+ }
}
public bool executing_eagerly()
diff --git a/src/TensorFlowNET.Core/APIs/tf.compat.v1.cs b/src/TensorFlowNET.Core/APIs/tf.compat.v1.cs
index e5dc6a409..982e7ccce 100644
--- a/src/TensorFlowNET.Core/APIs/tf.compat.v1.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.compat.v1.cs
@@ -25,7 +25,7 @@ public void disable_eager_execution()
=> tf.Context.graph_mode();
public IVariableV1 get_variable(string name,
- TensorShape shape = null,
+ Shape shape = null,
TF_DataType dtype = TF_DataType.DtInvalid,
object initializer = null, // IInitializer or Tensor
bool? trainable = null,
@@ -47,5 +47,14 @@ public IVariableV1 get_variable(string name,
trainable: trainable,
collections: collections);
}
+
+ public Operation global_variables_initializer()
+ {
+ var g = variables.global_variables();
+ return variables.variables_initializer(g.ToArray());
+ }
+
+ public Session Session()
+ => new Session().as_default();
}
}
diff --git a/src/TensorFlowNET.Keras/Initializers.cs b/src/TensorFlowNET.Core/APIs/tf.config.cs
similarity index 66%
rename from src/TensorFlowNET.Keras/Initializers.cs
rename to src/TensorFlowNET.Core/APIs/tf.config.cs
index b432cc97c..3c30ffb48 100644
--- a/src/TensorFlowNET.Keras/Initializers.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.config.cs
@@ -14,20 +14,19 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
-using Tensorflow.Operations.Initializers;
+using Tensorflow.Contexts;
+using Tensorflow.Framework;
-namespace Tensorflow.Keras
+namespace Tensorflow
{
- public class Initializers
+ public partial class tensorflow
{
///
- /// He normal initializer.
+ /// Public API for tf.debugging namespace
+ /// https://www.tensorflow.org/api_docs/python/tf/debugging
+ /// More debugging instructions
+ /// https://developer.ibm.com/technologies/artificial-intelligence/tutorials/debug-tensorflow/
///
- ///
- ///
- public IInitializer he_normal(int? seed = null)
- {
- return new VarianceScaling(factor: 2.0f, mode: "fan_in", seed: seed);
- }
+ public ConfigImpl config => new ConfigImpl();
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.control_flow.cs b/src/TensorFlowNET.Core/APIs/tf.control_flow.cs
index 239487e05..cd5a71e50 100644
--- a/src/TensorFlowNET.Core/APIs/tf.control_flow.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.control_flow.cs
@@ -46,10 +46,10 @@ public Tensor while_loop(Func cond,
Tensor loop_vars,
int parallel_iterations = 10)
{
- Func cond1 = x
+ Func cond1 = x
=> cond(x[0]);
- Func body1 = x
+ Func body1 = x
=> new[] { body(x[0]) };
var results = control_flow_ops.while_loop(cond1,
@@ -58,9 +58,9 @@ public Tensor while_loop(Func cond,
return results[0];
}
- public Tensor[] while_loop(Func cond,
- Func body,
- Tensor[] loop_vars,
+ public Tensor[] while_loop(Func cond,
+ Func body,
+ Tensors loop_vars,
int parallel_iterations = 10,
string name = null)
=> control_flow_ops.while_loop(cond, body, loop_vars,
diff --git a/src/TensorFlowNET.Core/APIs/tf.data.cs b/src/TensorFlowNET.Core/APIs/tf.data.cs
index 7fe7fcf98..6c41a8393 100644
--- a/src/TensorFlowNET.Core/APIs/tf.data.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.data.cs
@@ -22,6 +22,9 @@ public partial class tensorflow
public class DataOps
{
+ public int AUTOTUNE = -1;
+ public int INFINITE_CARDINALITY = -1;
+ public int UNKNOWN_CARDINALITY = -2;
public DatasetManager Dataset { get; } = new DatasetManager();
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.debugging.cs b/src/TensorFlowNET.Core/APIs/tf.debugging.cs
index 1a9c7b461..b3b3529e4 100644
--- a/src/TensorFlowNET.Core/APIs/tf.debugging.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.debugging.cs
@@ -14,41 +14,22 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using Tensorflow.Debugging;
+using static Tensorflow.Binding;
+
namespace Tensorflow
{
public partial class tensorflow
{
///
- /// Assert the condition `x == y` holds element-wise.
+ /// Public API for tf.debugging namespace
+ /// https://www.tensorflow.org/api_docs/python/tf/debugging
+ /// More debugging instructions
+ /// https://developer.ibm.com/technologies/artificial-intelligence/tutorials/debug-tensorflow/
///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public Tensor assert_equal(T1 t1,
- T2 t2,
- object[] data = null,
- string message = null,
- string name = null)
- => check_ops.assert_equal(t1,
- t2,
- data: data,
- message: message,
- name: name);
+ public DebugImpl debugging => new DebugImpl();
- public Tensor assert_greater_equal(Tensor x,
- Tensor y,
- object[] data = null,
- string message = null,
- string name = null)
- => check_ops.assert_greater_equal(x,
- y,
- data: data,
- message: message,
- name: name);
+ public void print(Tensor input)
+ => tf.logging.print_v2(input);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.gradients.cs b/src/TensorFlowNET.Core/APIs/tf.gradients.cs
index b5724aaa0..d722cb143 100644
--- a/src/TensorFlowNET.Core/APIs/tf.gradients.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.gradients.cs
@@ -14,22 +14,32 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using System.Collections.Generic;
using Tensorflow.Gradients;
namespace Tensorflow
{
public partial class tensorflow
{
+ GradientTape _tapeSet;
+
///
/// Record operations for automatic differentiation.
///
///
///
- ///
+ /// Tape set
public GradientTape GradientTape(bool persistent = false,
bool watch_accessed_variables = true)
- => new GradientTape(persistent: persistent,
+ {
+ var tape = _tapeSet.PushTape(persistent: persistent,
watch_accessed_variables: watch_accessed_variables);
+ tape.StartRecord();
+ return _tapeSet;
+ }
+
+ public Stack GetTapeSet()
+ => _tapeSet.GetTapeSet();
public Tensor[] gradients(Tensor[] ys,
Tensor[] xs,
diff --git a/src/TensorFlowNET.Core/APIs/tf.graph.cs b/src/TensorFlowNET.Core/APIs/tf.graph.cs
index 7c0e75853..c1b033aee 100644
--- a/src/TensorFlowNET.Core/APIs/tf.graph.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.graph.cs
@@ -20,25 +20,18 @@ namespace Tensorflow
{
public partial class tensorflow
{
- public graph_util_impl graph_util => new graph_util_impl();
- public GraphTransformer graph_transforms => new GraphTransformer();
+ public graph_util_impl graph_util { get; } = new graph_util_impl();
+ public GraphTransformer graph_transforms { get; } = new GraphTransformer();
public GraphKeys GraphKeys { get; } = new GraphKeys();
public void reset_default_graph()
=> ops.reset_default_graph();
public Graph get_default_graph()
- {
- return ops.get_default_graph();
- }
+ => ops.get_default_graph();
- ///
- /// Equivalent to but does not create a new graph if it there is none.
- ///
public Graph peak_default_graph()
- {
- return ops.default_graph_stack.peak_controller();
- }
+ => ops.peak_default_graph();
///
/// Creates a new graph.
diff --git a/src/TensorFlowNET.Core/APIs/tf.image.cs b/src/TensorFlowNET.Core/APIs/tf.image.cs
index 34cb4be77..41ef52967 100644
--- a/src/TensorFlowNET.Core/APIs/tf.image.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.image.cs
@@ -14,6 +14,10 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using OneOf.Types;
+using System;
+using System.Buffers.Text;
+using Tensorflow.Contexts;
using static Tensorflow.Binding;
namespace Tensorflow
@@ -58,9 +62,13 @@ public Tensor resize_images(Tensor images, Tensor size, string method = ResizeMe
string name = null)
=> image_ops_impl.resize_images(images, size, method, preserve_aspect_ratio, antialias, name);
- public Tensor resize_images_v2(Tensor images, TensorShape size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
+ public Tensor resize_images_v2(Tensor images, Shape size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
string name = null)
- => image_ops_impl.resize_images(images, tf.constant(size.dims), method, preserve_aspect_ratio, antialias, name);
+ => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name);
+
+ public Tensor resize_images_v2(Tensor images, Tensor size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
+ string name = null)
+ => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name);
public Tensor resize_images_with_pad(Tensor image, int target_height, int target_width, string method, bool antialias)
=> image_ops_impl.resize_images_with_pad(image, target_height, target_width, method, antialias);
@@ -158,17 +166,108 @@ public Tensor ssim_multiscale(Tensor img1, Tensor img2, float max_val, float[] p
public Tensor sobel_edges(Tensor image)
=> image_ops_impl.sobel_edges(image);
- public Tensor decode_jpeg(Tensor contents,
- int channels = 0,
- int ratio = 1,
- bool fancy_upscaling = true,
- bool try_recover_truncated = false,
- int acceptable_fraction = 1,
- string dct_method = "",
- string name = null)
- => gen_image_ops.decode_jpeg(contents, channels: channels, ratio: ratio,
- fancy_upscaling: fancy_upscaling, try_recover_truncated: try_recover_truncated,
- acceptable_fraction: acceptable_fraction, dct_method: dct_method);
+ ///
+ /// Adjust contrast of RGB or grayscale images.
+ ///
+ /// Images to adjust. At least 3-D.
+ ///
+ /// A float multiplier for adjusting contrast.
+ /// The contrast-adjusted image or images.
+ public Tensor adjust_contrast(Tensor images, float contrast_factor, string name = null)
+ => gen_image_ops.adjust_contrastv2(images, contrast_factor, name);
+
+ ///
+ /// Adjust hue of RGB images.
+ ///
+ /// RGB image or images. The size of the last dimension must be 3.
+ /// float. How much to add to the hue channel.
+ /// A name for this operation (optional).
+ /// Adjusted image(s), same shape and DType as `image`.
+ /// if `delta` is not in the interval of `[-1, 1]`.
+ public Tensor adjust_hue(Tensor images, float delta, string name = null)
+ {
+ if (tf.Context.executing_eagerly())
+ {
+ if (delta < -1f || delta > 1f)
+ throw new ValueError("delta must be in the interval [-1, 1]");
+ }
+ return gen_image_ops.adjust_hue(images, delta, name: name);
+ }
+
+ ///
+ /// Adjust saturation of RGB images.
+ ///
+ /// RGB image or images. The size of the last dimension must be 3.
+ /// float. Factor to multiply the saturation by.
+ /// A name for this operation (optional).
+ /// Adjusted image(s), same shape and DType as `image`.
+ public Tensor adjust_saturation(Tensor image, float saturation_factor, string name = null)
+ => gen_image_ops.adjust_saturation(image, saturation_factor, name);
+
+ ///
+ /// Greedily selects a subset of bounding boxes in descending order of score.
+ ///
+ ///
+ /// A 4-D float `Tensor` of shape `[batch_size, num_boxes, q, 4]`. If `q`
+ /// is 1 then same boxes are used for all classes otherwise, if `q` is equal
+ /// to number of classes, class-specific boxes are used.
+ ///
+ ///
+ /// A 3-D float `Tensor` of shape `[batch_size, num_boxes, num_classes]`
+ /// representing a single score corresponding to each box(each row of boxes).
+ ///
+ ///
+ /// A scalar integer `Tensor` representing the
+ /// maximum number of boxes to be selected by non-max suppression per class
+ ///
+ ///
+ /// A int32 scalar representing maximum number of boxes retained
+ /// over all classes.Note that setting this value to a large number may
+ /// result in OOM error depending on the system workload.
+ ///
+ ///
+ /// A float representing the threshold for deciding whether boxes
+ /// overlap too much with respect to IOU.
+ ///
+ ///
+ /// A float representing the threshold for deciding when to
+ /// remove boxes based on score.
+ ///
+ ///
+ /// If false, the output nmsed boxes, scores and classes are
+ /// padded/clipped to `max_total_size`. If true, the output nmsed boxes, scores and classes are padded to be of length `max_size_per_class`*`num_classes`,
+ /// unless it exceeds `max_total_size` in which case it is clipped to `max_total_size`. Defaults to false.
+ ///
+ ///
+ /// If true, the coordinates of output nmsed boxes will be clipped
+ /// to[0, 1]. If false, output the box coordinates as it is. Defaults to true.
+ ///
+ ///
+ /// 'nmsed_boxes': A [batch_size, max_detections, 4] float32 tensor containing the non-max suppressed boxes.
+ /// 'nmsed_scores': A [batch_size, max_detections] float32 tensor containing the scores for the boxes.
+ /// 'nmsed_classes': A [batch_size, max_detections] float32 tensor containing the class for boxes.
+ /// 'valid_detections': A [batch_size] int32 tensor indicating the number of
+ /// valid detections per batch item. Only the top valid_detections[i] entries
+ /// in nms_boxes[i], nms_scores[i] and nms_class[i] are valid. The rest of the
+ /// entries are zero paddings.
+ ///
+ public (Tensor, Tensor, Tensor, Tensor) combined_non_max_suppression(
+ Tensor boxes,
+ Tensor scores,
+ int max_output_size_per_class,
+ int max_total_size,
+ float iou_threshold,
+ float score_threshold,
+ bool pad_per_class = false,
+ bool clip_boxes = true)
+ {
+ var iou_threshold_t = ops.convert_to_tensor(iou_threshold, TF_DataType.TF_FLOAT, name: "iou_threshold");
+ var score_threshold_t = ops.convert_to_tensor(score_threshold, TF_DataType.TF_FLOAT, name: "score_threshold");
+ var max_total_size_t = ops.convert_to_tensor(max_total_size);
+ var max_output_size_per_class_t = ops.convert_to_tensor(max_output_size_per_class);
+ return gen_image_ops.combined_non_max_suppression(boxes, scores, max_output_size_per_class_t, max_total_size_t,
+ iou_threshold_t, score_threshold_t, pad_per_class, clip_boxes);
+ }
///
/// Extracts crops from the input image tensor and resizes them using bilinear sampling or nearest neighbor sampling (possibly with aspect ratio change) to a common output size specified by crop_size. This is more general than the crop_to_bounding_box op which extracts a fixed size slice from the input image and does not allow resizing or aspect ratio change.
@@ -183,7 +282,19 @@ public Tensor decode_jpeg(Tensor contents,
/// A name for the operation (optional).
/// A 4-D tensor of shape [num_boxes, crop_height, crop_width, depth].
public Tensor crop_and_resize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size, string method = "bilinear", float extrapolation_value = 0f, string name = null) =>
- image_ops_impl.crop_and_resize(image, boxes, box_ind, crop_size, method, extrapolation_value, name);
+ gen_image_ops.crop_and_resize(image, boxes, box_ind, crop_size, method, extrapolation_value, name);
+
+ public Tensor decode_jpeg(Tensor contents,
+ int channels = 0,
+ int ratio = 1,
+ bool fancy_upscaling = true,
+ bool try_recover_truncated = false,
+ int acceptable_fraction = 1,
+ string dct_method = "",
+ string name = null)
+ => gen_image_ops.decode_jpeg(contents, channels: channels, ratio: ratio,
+ fancy_upscaling: fancy_upscaling, try_recover_truncated: try_recover_truncated,
+ acceptable_fraction: acceptable_fraction, dct_method: dct_method);
public Tensor extract_glimpse(Tensor input, Tensor size, Tensor offsets, bool centered = true, bool normalized = true,
bool uniform_noise = true, string name = null)
@@ -206,7 +317,10 @@ public Tensor extract_glimpse(Tensor input, Tensor size, Tensor offsets, bool ce
=> image_ops_impl.non_max_suppression_padded(boxes, scores, max_output_size, iou_threshold, score_threshold, pad_to_max_output_size,
name, sorted_input, canonicalized_coordinates, tile_size);
- public Tensor resize(Tensor image, TensorShape size, string method = ResizeMethod.BILINEAR)
+ public Tensor resize(Tensor image, Shape size, string method = ResizeMethod.BILINEAR)
+ => image_ops_impl.resize_images_v2(image, size, method: method);
+
+ public Tensor resize(Tensor image, Tensor size, string method = ResizeMethod.BILINEAR)
=> image_ops_impl.resize_images_v2(image, size, method: method);
public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, bool half_pixel_centers = false, string name = null)
@@ -225,6 +339,13 @@ public Tensor decode_image(Tensor contents, int channels = 0, TF_DataType dtype
=> image_ops_impl.decode_image(contents, channels: channels, dtype: dtype,
name: name, expand_animations: expand_animations);
+ public Tensor encode_png(Tensor contents, string name = null)
+ => image_ops_impl.encode_png(contents, name: name);
+
+ public Tensor encode_jpeg(Tensor contents, string name = null)
+ => image_ops_impl.encode_jpeg(contents, name: name);
+
+
///
/// Convenience function to check if the 'contents' encodes a JPEG image.
///
diff --git a/src/TensorFlowNET.Core/APIs/tf.init.cs b/src/TensorFlowNET.Core/APIs/tf.init.cs
index b5ebc469f..8635f6620 100644
--- a/src/TensorFlowNET.Core/APIs/tf.init.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.init.cs
@@ -76,13 +76,13 @@ public IInitializer random_normal_initializer(float mean = 0.0f,
///
///
public IInitializer variance_scaling_initializer(float factor = 1.0f,
- string mode = "FAN_IN",
- bool uniform = false,
+ string mode = "fan_in",
+ string distribution = "truncated_normal",
int? seed = null,
TF_DataType dtype = TF_DataType.TF_FLOAT) => new VarianceScaling(
- factor: factor,
+ scale: factor,
mode: mode,
- uniform: uniform,
+ distribution: distribution,
seed: seed,
dtype: dtype);
@@ -96,7 +96,7 @@ public IInitializer random_normal_initializer(float mean = 0.0f,
seed: seed,
dtype: dtype);
- public IInitializer zeros_initializer(TensorShape shape = null,
+ public IInitializer zeros_initializer(Shape shape = null,
TF_DataType dtype = TF_DataType.TF_FLOAT) => new Zeros(shape: shape,
dtype: dtype);
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.io.cs b/src/TensorFlowNET.Core/APIs/tf.io.cs
index 25d9cfe80..ea1e44b28 100644
--- a/src/TensorFlowNET.Core/APIs/tf.io.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.io.cs
@@ -16,6 +16,7 @@ limitations under the License.
using System.Collections.Generic;
using Tensorflow.IO;
+using Tensorflow.Operations;
namespace Tensorflow
{
@@ -26,9 +27,11 @@ public partial class tensorflow
public class IoApi
{
io_ops ops;
+ public GFile gfile;
public IoApi()
{
ops = new io_ops();
+ gfile = new GFile();
}
public Tensor read_file(string filename, string name = null)
@@ -44,6 +47,12 @@ public Operation save_v2(Tensor prefix, string[] tensor_names,
public Tensor[] restore_v2(Tensor prefix, string[] tensor_names,
string[] shape_and_slices, TF_DataType[] dtypes, string name = null)
=> ops.restore_v2(prefix, tensor_names, shape_and_slices, dtypes, name: name);
+
+ public Operation write_file(string filename, Tensor conentes, string name = null)
+ => write_file(Tensorflow.ops.convert_to_tensor(filename, TF_DataType.TF_STRING), conentes, name);
+
+ public Operation write_file(Tensor filename, Tensor conentes, string name = null)
+ => gen_ops.write_file(filename, conentes, name);
}
public GFile gfile = new GFile();
@@ -52,6 +61,6 @@ public ITensorOrOperation[] import_graph_def(GraphDef graph_def,
Dictionary input_map = null,
string[] return_elements = null,
string name = null,
- OpList producer_op_list = null) => importer.import_graph_def(graph_def, input_map, return_elements, name, producer_op_list);
+ OpList producer_op_list = null) => importer.import_graph_def(graph_def, input_map, return_elements, name: name, producer_op_list: producer_op_list);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.linalg.cs b/src/TensorFlowNET.Core/APIs/tf.linalg.cs
index bf8c358c2..32f64ec35 100644
--- a/src/TensorFlowNET.Core/APIs/tf.linalg.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.linalg.cs
@@ -13,6 +13,8 @@ You may obtain a copy of the License at
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************/
+using Tensorflow.NumPy;
+using static Tensorflow.Binding;
namespace Tensorflow
{
@@ -24,10 +26,13 @@ public class LinalgApi
{
linalg_ops ops = new linalg_ops();
+ public Tensor einsum(string equation, Tensors inputs, string name = null)
+ => math_ops.einsum(equation, inputs, name: name);
+
public Tensor eye(int num_rows,
int num_columns = -1,
- TensorShape batch_shape = null,
- TF_DataType dtype = TF_DataType.TF_FLOAT,
+ Shape batch_shape = null,
+ TF_DataType dtype = TF_DataType.TF_DOUBLE,
string name = null)
=> ops.eye(num_rows, num_columns: num_columns, batch_shape: batch_shape, dtype: dtype, name: name);
@@ -37,17 +42,70 @@ public Tensor diag(Tensor diagonal, string name = null)
public Tensor matmul(Tensor a, Tensor b)
=> math_ops.matmul(a, b);
- public Tensor batch_matmul(Tensor x, Tensor y)
- => gen_math_ops.batch_mat_mul(x, y);
+ public Tensor norm(Tensor a, string ord = "euclidean", Axis axis = null, string name = null)
+ => ops.norm(a, ord: ord, axis: axis, name: name);
+
+ public Tensor batch_matmul(Tensor x, Tensor y, bool adj_x = false, bool adj_y = false, string name = null)
+ => math_ops.batch_matmul(x, y, adj_x: adj_x, adj_y: adj_y, name: name);
+
+ public Tensor inv(Tensor input, bool adjoint = false, string name = null)
+ => ops.matrix_inverse(input, adjoint: adjoint, name: name);
+
+ public Tensor global_norm(Tensor[] t_list, string name = null)
+ => clip_ops.global_norm(t_list, name: name);
+
+ public Tensor l2_normalize(Tensor x,
+ int axis = 0,
+ float epsilon = 1e-12f,
+ string name = null)
+ => nn_impl.l2_normalize(x, axis: axis, epsilon: constant_op.constant(epsilon), name: name);
+
+ public Tensor lstsq(Tensor matrix, Tensor rhs,
+ NDArray l2_regularizer = null, bool fast = true, string name = null)
+ => ops.matrix_solve_ls(matrix, rhs, l2_regularizer: l2_regularizer, fast: fast, name: name);
+
+ public Tensors qr(Tensor input, bool full_matrices = true, string name = null)
+ => ops.qr(input, full_matrices: full_matrices, name: name);
+
+ public Tensor tensor_diag_part(Tensor input, string name = null)
+ => gen_array_ops.diag_part(input, name: name);
+
+ public Tensor tensordot(Tensor x, Tensor y, NDArray axes, string name = null)
+ => math_ops.tensordot(x, y, axes, name: name);
}
public Tensor diag(Tensor diagonal, string name = null)
=> gen_array_ops.diag(diagonal, name: name);
- public Tensor matmul(Tensor a, Tensor b)
- => math_ops.matmul(a, b);
+ public Tensor matmul(Tensor a, Tensor b, bool transpose_a = false, bool transpose_b = false)
+ => math_ops.matmul(a, b, transpose_a: transpose_a, transpose_b: transpose_b);
- public Tensor batch_matmul(Tensor x, Tensor y)
- => gen_math_ops.batch_mat_mul(x, y);
+ ///
+ /// Multiply slices of the two matrices "x" and "y".
+ ///
+ ///
+ /// The `BatchMatMul` operation is embedded into the
+ /// `MatMul` operation on the DLL side. However the expected
+ /// attributes are not the same, hence we need to expose this
+ /// method to have the right args list on the `_apply_op_helper`
+ /// function.
+ ///
+ /// For each rank > 2 the first rank - 2 dimensions are considered
+ /// as fixed, and have to be consistent across the two matrices. A
+ /// common matrix multiplication is then applied over the residual
+ /// 2 dimensions.
+ ///
+ /// e.g.
+ /// x is (3, 6, 12); y is (3, 12, 6)
+ /// batch_matmul(x, y) ==> (3, 6, 6)
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor batch_matmul(Tensor x, Tensor y, bool adj_x = false, bool adj_y = false, string name = null)
+ => math_ops.batch_matmul(x, y, adj_x: adj_x, adj_y: adj_y, name: name);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.exp.cs b/src/TensorFlowNET.Core/APIs/tf.logging.cs
similarity index 82%
rename from src/TensorFlowNET.Core/APIs/tf.exp.cs
rename to src/TensorFlowNET.Core/APIs/tf.logging.cs
index 56ea1898e..0e10c1610 100644
--- a/src/TensorFlowNET.Core/APIs/tf.exp.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.logging.cs
@@ -1,5 +1,5 @@
/*****************************************************************************
- Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.
+ Copyright 2021 Haiping Chen. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@ namespace Tensorflow
{
public partial class tensorflow
{
- public Tensor exp(Tensor x,
- string name = null) => gen_math_ops.exp(x, name);
-
+ public logging_ops logging => new logging_ops();
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.math.cs b/src/TensorFlowNET.Core/APIs/tf.math.cs
index 9a405b491..da54a9dd7 100644
--- a/src/TensorFlowNET.Core/APIs/tf.math.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.math.cs
@@ -1,5 +1,5 @@
/*****************************************************************************
- Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.
+ Copyright 2023 The TensorFlow.NET Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,6 +14,9 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using Tensorflow.NumPy;
+using Tensorflow.Operations;
+
namespace Tensorflow
{
public partial class tensorflow
@@ -21,8 +24,96 @@ public partial class tensorflow
public MathApi math { get; } = new MathApi();
public class MathApi
{
+ public Tensor argmax(Tensor input, Axis axis = null, string name = null, int? dimension = null, TF_DataType output_type = TF_DataType.TF_INT64)
+ => gen_math_ops.arg_max(input, axis, name: name, output_type: output_type);
+
+ public Tensor count_nonzero(Tensor input, Axis? axis = null, bool? keepdims = null, TF_DataType dtype = TF_DataType.TF_INT64, string name = null)
+ => math_ops.count_nonzero_v2(input, axis: axis, keepdims: keepdims ?? false, dtype: dtype);
public Tensor log(Tensor x, string name = null)
=> gen_math_ops.log(x, name);
+
+ ///
+ /// Computes the Gauss error function of `x` element-wise.
+ ///
+ ///
+ ///
+ ///
+ public Tensor erf(Tensor x, string name = null)
+ => math_ops.erf(x, name);
+
+ public Tensor multiply(Tensor x, Tensor y, string name = null)
+ => math_ops.multiply(x, y, name: name);
+ public Tensor divide_no_nan(Tensor a, Tensor b, string name = null)
+ => math_ops.div_no_nan(a, b);
+
+ ///
+ /// Computes the Euclidean norm of elements across dimensions of a tensor.
+ ///
+ /// The tensor to reduce. Should have numeric type.
+ /// The dimensions to reduce. If `None` (the default), reduces all dimensions.Must be in the range `[-rank(input_tensor), rank(input_tensor))`
+ /// If true, retains reduced dimensions with length 1.
+ /// A name for the operation (optional).
+ /// The reduced tensor, of the same dtype as the input_tensor.
+ public Tensor reduce_euclidean_norm(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
+ => math_ops.reduce_euclidean_norm(input_tensor, axis: axis, keepdims: keepdims, name);
+
+ public Tensor square(Tensor x, string name = null)
+ => math_ops.square(x, name: name);
+
+ public Tensor sum(Tensor x, Axis? axis = null, string name = null)
+ => math_ops.reduce_sum(x, axis: axis, name: name);
+
+ public Tensor softplus(Tensor features, string name = null)
+ => nn_ops.softplus(features, name: name);
+
+ public Tensor tanh(Tensor x, string name = null)
+ => math_ops.tanh(x, name: name);
+
+ ///
+ /// Finds values and indices of the `k` largest entries for the last dimension.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensors top_k(Tensor input, int k, bool sorted = true, string name = null)
+ => nn_ops.top_kv2(input, k, sorted: sorted, name: name);
+
+ public Tensor in_top_k(Tensor predictions, Tensor targets, int k, string name = "InTopK")
+ => nn_ops.in_top_k(predictions, targets, k, name);
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor bincount(Tensor arr, Tensor weights = null,
+ Tensor minlength = null,
+ Tensor maxlength = null,
+ TF_DataType dtype = TF_DataType.TF_INT32,
+ string name = null,
+ Shape axis = null,
+ bool binary_output = false)
+ => math_ops.bincount(arr, weights: weights, minlength: minlength, maxlength: maxlength,
+ dtype: dtype, name: name, axis: axis, binary_output: binary_output);
+
+ public Tensor real(Tensor x, string name = null)
+ => gen_ops.real(x, x.dtype.real_dtype(), name);
+ public Tensor imag(Tensor x, string name = null)
+ => gen_ops.imag(x, x.dtype.real_dtype(), name);
+
+ public Tensor conj(Tensor x, string name = null)
+ => gen_ops.conj(x, name);
+ public Tensor angle(Tensor x, string name = null)
+ => gen_ops.angle(x, x.dtype.real_dtype(), name);
}
public Tensor abs(Tensor x, string name = null)
@@ -50,7 +141,7 @@ public Tensor add(Tensor a, Tensor b, string name = null)
=> gen_math_ops.add(a, b, name: name);
public Tensor add(Tx a, Ty b, string name = null)
- => gen_math_ops.add(a, b, name: name);
+ => gen_math_ops.add(ops.convert_to_tensor(a), ops.convert_to_tensor(b), name: name);
///
/// Adds all input tensors element-wise.
@@ -71,10 +162,10 @@ public Tensor atan(Tensor x, string name = null)
=> gen_math_ops.atan(x, name);
public Tensor arg_max(Tensor input, int dimension, TF_DataType output_type = TF_DataType.TF_INT64, string name = null)
- => gen_math_ops.arg_max(input, dimension, output_type: output_type, name: name);
+ => gen_math_ops.arg_max(input, ops.convert_to_tensor(dimension), output_type: output_type, name: name);
public Tensor arg_min(Tensor input, int dimension, TF_DataType output_type = TF_DataType.TF_INT64, string name = null)
- => gen_math_ops.arg_min(input, dimension, output_type: output_type, name: name);
+ => gen_math_ops.arg_min(input, ops.convert_to_tensor(dimension), output_type: output_type, name: name);
public Tensor is_finite(Tensor input, string name = null)
=> gen_math_ops.is_finite(input, name);
@@ -118,6 +209,9 @@ public Tensor sinh(Tensor x, string name = null)
public Tensor cos(Tensor x, string name = null)
=> gen_math_ops.cos(x, name);
+ public Tensor cos(float x, string name = null)
+ => gen_math_ops.cos(ops.convert_to_tensor(x), name);
+
///
/// Computes hyperbolic cosine of x element-wise.
///
@@ -152,7 +246,7 @@ public Tensor floor(Tensor x, string name = null)
///
///
public Tensor greater(Tx x, Ty y, string name = null)
- => gen_math_ops.greater(x, y, name);
+ => gen_math_ops.greater(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name);
///
/// Returns the truth value of (x >= y) element-wise.
@@ -164,7 +258,7 @@ public Tensor greater(Tx x, Ty y, string name = null)
///
///
public Tensor greater_equal(Tx x, Ty y, string name = null)
- => gen_math_ops.greater_equal(x, y, name);
+ => gen_math_ops.greater_equal(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name);
///
/// Returns the truth value of (x < y) element-wise.
@@ -176,7 +270,7 @@ public Tensor greater_equal(Tx x, Ty y, string name = null)
///
///
public Tensor less(Tx x, Ty y, string name = null)
- => gen_math_ops.less(x, y, name);
+ => gen_math_ops.less(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name);
///
/// Computes the log of the absolute value of `Gamma(x)` element-wise.
@@ -197,7 +291,7 @@ public Tensor lgamma(Tensor x, string name = null)
///
///
public Tensor less_equal(Tx x, Ty y, string name = null)
- => gen_math_ops.less_equal(x, y, name);
+ => gen_math_ops.less_equal(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name);
///
/// Computes natural logarithm of (1 + x) element-wise.
@@ -208,8 +302,8 @@ public Tensor less_equal(Tx x, Ty y, string name = null)
public Tensor log1p(Tensor x, string name = null)
=> gen_math_ops.log1p(x, name);
- public Tensor logical_and(Tensor x, Tensor y, string name = null)
- => gen_math_ops.logical_and(x, y, name);
+ public Tensor logical_and(T x, T y, string name = null)
+ => gen_math_ops.logical_and(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name);
public Tensor logical_not(Tensor x, string name = null)
=> gen_math_ops.logical_not(x, name);
@@ -218,7 +312,10 @@ public Tensor logical_or(Tensor x, Tensor y, string name = null)
=> gen_math_ops.logical_or(x, y, name);
public Tensor logical_xor(Tensor x, Tensor y, string name = "LogicalXor")
- => gen_math_ops.logical_xor(x, y, name);
+ {
+ return gen_math_ops.logical_and(gen_math_ops.logical_or(x, y),
+ gen_math_ops.logical_not(gen_math_ops.logical_and(x, y)), name);
+ }
///
/// Clips tensor values to a specified min and max.
@@ -229,7 +326,7 @@ public Tensor logical_xor(Tensor x, Tensor y, string name = "LogicalXor")
///
///
public Tensor _clip_by_value(Tensor t, Tensor clip_value_min, Tensor clip_value_max, string name = null)
- => gen_math_ops._clip_by_value(t, clip_value_min, clip_value_max);
+ => gen_math_ops.clip_by_value(t, clip_value_min, clip_value_max);
///
/// Clips tensor values to a specified min and max.
@@ -262,13 +359,13 @@ public Tensor clip_by_value(Tensor t, T1 clip_value_min, T2 clip_value_m
=> clip_ops.clip_by_value(t, clip_value_min, clip_value_max, name);
public Tensor sub(Tx a, Ty b, string name = null)
- => gen_math_ops.sub(a, b, name: name);
+ => gen_math_ops.sub(ops.convert_to_tensor(a), ops.convert_to_tensor(b), name: name);
public Tensor divide(Tensor a, Tensor b)
=> a / b;
public Tensor sqrt(Tensor a, string name = null)
- => gen_math_ops.sqrt(a, name);
+ => math_ops.sqrt(a, name);
public Tensor sign(Tensor a, string name = null)
=> gen_math_ops.sign(a, name);
@@ -290,7 +387,7 @@ public Tensor log(Tensor x, string name = null)
=> gen_math_ops.log(x, name);
public Tensor equal(Tensor x, Tensor y, string name = null)
- => gen_math_ops.equal(x, y, name);
+ => gen_math_ops.equal(x, y, name: name);
///
/// Computes arctangent of `y/x` element-wise, respecting signs of the arguments.
@@ -313,7 +410,7 @@ public Tensor atan2(Tensor y, Tensor x, string name = null)
///
///
public Tensor max(Tx input, Ty axis, bool keep_dims = false, string name = null)
- => gen_math_ops._max(input, axis, keep_dims: keep_dims, name: name);
+ => gen_math_ops.max(ops.convert_to_tensor(input), ops.convert_to_tensor(axis), keep_dims: keep_dims, name: name);
///
/// Computes the minimum of elements across dimensions of a tensor.
@@ -326,7 +423,7 @@ public Tensor max(Tx input, Ty axis, bool keep_dims = false, string name
///
///
public Tensor min(Tx input, Ty axis, bool keep_dims = false, string name = null)
- => gen_math_ops._min(input, axis, keep_dims: keep_dims, name: name);
+ => gen_math_ops.min(ops.convert_to_tensor(input), ops.convert_to_tensor(axis), keep_dims: keep_dims, name: name);
///
/// Returns the max of x and y (i.e. x > y ? x : y) element-wise.
@@ -338,7 +435,7 @@ public Tensor min(Tx input, Ty axis, bool keep_dims = false, string name
///
///
public Tensor maximum(T1 x, T2 y, string name = null)
- => gen_math_ops.maximum(x, y, name: name);
+ => gen_math_ops.maximum(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name: name);
///
/// Returns the min of x and y (i.e. x < y ? x : y) element-wise.
@@ -350,7 +447,7 @@ public Tensor maximum(T1 x, T2 y, string name = null)
///
///
public Tensor minimum(T1 x, T2 y, string name = null)
- => gen_math_ops.minimum(x, y, name: name);
+ => gen_math_ops.minimum(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name: name);
public Tensor multiply(Tensor x, Tensor y, string name = null)
=> gen_math_ops.mul(x, y, name: name);
@@ -365,8 +462,19 @@ public Tensor multiply(Tensor x, Tensor y, string name = null)
///
///
public Tensor multiply(Tx x, Ty y, string name = null)
- => gen_math_ops.mul(x, y, name: name);
-
+ => gen_math_ops.mul(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name: name);
+ ///
+ /// return scalar product
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor dot_prod(Tx x, Ty y, NDArray axes, string name = null)
+ => math_ops.tensordot(convert_to_tensor(x), convert_to_tensor(y), axes, name: name);
public Tensor negative(Tensor x, string name = null)
=> gen_math_ops.neg(x, name);
@@ -416,7 +524,7 @@ public Tensor floordiv(Tensor x, Tensor y, string name = null)
public static Tensor truediv(Tensor x, Tensor y, string name = null)
=> math_ops.truediv(x, y, name: name);
- public Tensor range(object start, object limit = null, object delta = null, TF_DataType dtype = TF_DataType.DtInvalid, string name = "range")
+ public Tensor range(object start, object limit = null, object delta = null, TF_DataType? dtype = null, string name = "range")
=> math_ops.range(start, limit: limit, delta: delta, dtype: dtype, name: name);
public Tensor real(Tensor input, string name = null)
@@ -430,12 +538,9 @@ public Tensor real(Tensor input, string name = null)
/// If true, retains reduced dimensions with length 1.
///
/// The reduced tensor.
- public Tensor reduce_any(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_any(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_any(input_tensor, axis: axis, keepdims: keepdims, name: name);
- public Tensor reduce_any(Tensor input_tensor, int axis = 0, bool keepdims = false, string name = null)
- => math_ops.reduce_any(input_tensor, axis: new[] { axis }, keepdims: keepdims, name: name);
-
///
/// Computes the "logical and" of elements across dimensions of a tensor.
///
@@ -444,7 +549,7 @@ public Tensor reduce_any(Tensor input_tensor, int axis = 0, bool keepdims = fals
///
///
/// The reduced tensor.
- public Tensor reduce_all(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_all(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_all(input_tensor, axis: axis, keepdims: keepdims, name: name);
///
@@ -455,43 +560,24 @@ public Tensor reduce_all(Tensor input_tensor, int[] axis = null, bool keepdims =
///
///
///
- public Tensor reduce_prod(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_prod(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_prod(input_tensor, axis: axis, keepdims: keepdims, name: name);
- ///
- /// Computes the sum of elements across dimensions of a tensor.
- ///
- ///
- ///
- ///
- ///
- ///
- public Tensor reduce_sum(Tensor[] input_tensors, int? axis = null, bool keepdims = false, string name = null)
- => math_ops.reduce_sum(input_tensors, axis: axis, keepdims: keepdims, name: name);
-
///
/// Computes the sum of elements across dimensions of a tensor.
///
///
///
///
- public Tensor reduce_sum(Tensor input, int? axis = null, int? reduction_indices = null,
+ public Tensor reduce_sum(Tensor input, Axis? axis = null, Axis? reduction_indices = null,
bool keepdims = false, string name = null)
{
- if (!axis.HasValue && reduction_indices.HasValue && !keepdims)
- return math_ops.reduce_sum(input, reduction_indices.Value);
- else if (axis.HasValue && !reduction_indices.HasValue && !keepdims)
- return math_ops.reduce_sum(input, axis.Value);
- else if (axis.HasValue && !reduction_indices.HasValue && keepdims)
- return math_ops.reduce_sum(input, keepdims: keepdims, axis: axis.Value, name: name);
+ if (keepdims)
+ return math_ops.reduce_sum(input, axis: constant_op.constant(axis ?? reduction_indices), keepdims: keepdims, name: name);
else
- return math_ops.reduce_sum(input, keepdims: keepdims, name: name);
+ return math_ops.reduce_sum(input, axis: constant_op.constant(axis ?? reduction_indices));
}
- public Tensor reduce_sum(Tensor input, TensorShape axis, int? reduction_indices = null,
- bool keepdims = false, string name = null)
- => math_ops.reduce_sum(input, axis, keepdims: keepdims, name: name);
-
///
/// Computes the maximum of elements across dimensions of a tensor.
///
@@ -500,51 +586,43 @@ public Tensor reduce_sum(Tensor input, TensorShape axis, int? reduction_indices
///
///
///
- public Tensor reduce_max(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
- => math_ops.reduce_max(input_tensor, axis, keepdims, name);
-
- public Tensor reduce_max(Tensor input_tensor, int axis, bool keepdims = false, string name = null)
+ public Tensor reduce_max(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_max(input_tensor, axis, keepdims, name);
- public Tensor reduce_min(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_min(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_min(input_tensor, axis, keepdims, name);
- public Tensor reduce_std(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_std(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_std(input_tensor, axis, keepdims, name);
- public Tensor reduce_variance(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null)
+ public Tensor reduce_variance(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null)
=> math_ops.reduce_variance(input_tensor, axis, keepdims, name);
public Tensor sigmoid(T x, string name = null)
=> math_ops.sigmoid(x, name: name);
public Tensor sum(Tensor input, int axis, bool keep_dims = false, string name = null)
- => gen_math_ops._sum(input, axis, keep_dims: keep_dims, name: name);
-
- public Tensor reduce_mean(Tensor input_tensors, int axis, bool keepdims = false, string name = null)
- => math_ops.reduce_mean(input_tensors, axis: new[] { axis }, keepdims: keepdims, name: name);
+ => gen_math_ops.sum(input, ops.convert_to_tensor(axis), keep_dims: keep_dims, name: name);
- public Tensor reduce_mean(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null, int? reduction_indices = null)
+ public Tensor reduce_mean(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null, int? reduction_indices = null)
=> math_ops.reduce_mean(input_tensor, axis: axis, keepdims: keepdims, name: name, reduction_indices: reduction_indices);
- public Tensor reduce_mean(Tensor[] input_tensors, int? axis = null, bool keepdims = false, string name = null)
- => math_ops.reduce_mean(input_tensors, axis: axis, keepdims: keepdims, name: name);
-
public Tensor round(Tensor x, string name = null)
=> gen_math_ops.round(x, name: name);
- public Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null)
+ public Tensor cast(Tensor x, TF_DataType dtype, string name = null)
=> math_ops.cast(x, dtype, name);
public Tensor cumsum(Tensor x, int axis = 0, bool exclusive = false, bool reverse = false, string name = null)
=> math_ops.cumsum(x, axis: axis, exclusive: exclusive, reverse: reverse, name: name);
- public Tensor argmax(Tensor input, int axis = -1, string name = null, int? dimension = null, TF_DataType output_type = TF_DataType.TF_INT64)
- => gen_math_ops.arg_max(input, axis, name: name, output_type: output_type);
-
public Tensor square(Tensor x, string name = null)
=> gen_math_ops.square(x, name: name);
public Tensor squared_difference(Tensor x, Tensor y, string name = null)
=> gen_math_ops.squared_difference(x: x, y: y, name: name);
+ public Tensor complex(Tensor real, Tensor imag, Tensorflow.TF_DataType? dtype = null,
+ string name = null) => gen_ops.complex(real, imag, dtype, name);
+ public Tensor exp(Tensor x,
+ string name = null) => gen_math_ops.exp(x, name);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.nn.cs b/src/TensorFlowNET.Core/APIs/tf.nn.cs
index f0c156fa8..112c48628 100644
--- a/src/TensorFlowNET.Core/APIs/tf.nn.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.nn.cs
@@ -14,6 +14,7 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using System.Xml.Linq;
using Tensorflow.Operations;
using Tensorflow.Operations.Activation;
using static Tensorflow.Binding;
@@ -26,24 +27,11 @@ public partial class tensorflow
public class nn_internal
{
- public Tensor conv2d(Tensor input, IVariableV1 filter, int[] strides, string padding, bool use_cudnn_on_gpu = true,
+ public Tensor conv2d(Tensor input, Tensor filter, int[] strides, string padding, bool use_cudnn_on_gpu = true,
string data_format = "NHWC", int[] dilations = null, string name = null)
{
- var parameters = new Conv2dParams
- {
- Input = input,
- Filter = filter.AsTensor(),
- Strides = strides,
- Padding = padding,
- UseCudnnOnGpu = use_cudnn_on_gpu,
- DataFormat = data_format,
- Name = name
- };
-
- if (dilations != null)
- parameters.Dilations = dilations;
-
- return gen_nn_ops.conv2d(parameters);
+ return gen_nn_ops.conv2d(input, filter, strides, padding, use_cudnn_on_gpu,
+ data_format: data_format, dilations: dilations, name: name);
}
public Tensor[] ctc_greedy_decoder(Tensor inputs, Tensor sequence_length, bool merge_repeated = true, string name = null)
@@ -89,7 +77,7 @@ public Tensor elu(Tensor features, string name = null)
=> gen_nn_ops.elu(features, name: name);
public (Tensor, Tensor) moments(Tensor x,
- int[] axes,
+ Axis axes,
string name = null,
bool keep_dims = false) => nn_impl.moments(x,
axes,
@@ -113,29 +101,56 @@ public Tensor embedding_lookup(Tensor @params,
name: name);
public IActivation relu() => new relu();
+
+
public IActivation swish() => new swish();
public IActivation tanh() => new tanh();
public IActivation softmax() => new softmax();
public Tensor tanh(Tensor x, string name = null)
- => gen_nn_ops.tanh(x, name);
+ => gen_math_ops.tanh(x, name);
public Tensor relu(Tensor features, string name = null)
=> gen_nn_ops.relu(features, name);
+ public Tensor relu6(Tensor features, string name = null)
+ => gen_nn_ops.relu6(features, name);
+
public Tensor[] fused_batch_norm(Tensor x,
- IVariableV1 scale,
- IVariableV1 offset,
+ Tensor scale,
+ Tensor offset,
Tensor mean = null,
Tensor variance = null,
float epsilon = 0.001f,
string data_format = "NHWC",
bool is_training = true,
- string name = null) => nn_impl.fused_batch_norm(x, scale, offset, mean, variance,
+ string name = null,
+ float exponential_avg_factor = 1.0f) => nn_impl.fused_batch_norm(x, scale, offset, mean, variance,
epsilon: epsilon,
data_format: data_format,
is_training: is_training,
- name: name);
+ name: name,
+ exponential_avg_factor: exponential_avg_factor);
+
+ ///
+ /// Normalizes a tensor by `mean` and `variance`, and applies (optionally) a`scale` \\(\gamma\\) to it, as well as an `offset` \\(\beta\\).
+ ///
+ /// A floating point tensor.
+ /// A mean `Tensor`.
+ /// A variance `Tensor`.
+ /// An offset `Tensor`, often denoted \\(\beta\\) in equations, or NULL. If present, will be added to the normalized tensor.
+ /// A scale `Tensor`, often denoted \\(\gamma\\) in equations, or NULL. If present, the scale is applied to the normalized tensor.
+ /// A small float number to avoid dividing by 0.
+ /// A name for this operation.
+ /// the normalized, scaled, offset tensor.
+ public Tensor batch_normalization(Tensor x,
+ Tensor mean,
+ Tensor variance,
+ Tensor offset,
+ Tensor scale,
+ float variance_epsilon,
+ string name = null) => nn_impl.batch_normalization(x, mean, variance, offset, scale, variance_epsilon, name);
+
public Tensor max_pool(Tensor value, int[] ksize, int[] strides, string padding, string data_format = "NHWC", string name = null)
=> nn_ops.max_pool(value, ksize, strides, padding, data_format: data_format, name: name);
@@ -144,17 +159,20 @@ public Tensor in_top_k(Tensor predictions, Tensor targets, int k, string name =
=> nn_ops.in_top_k(predictions, targets, k, name);
public Tensor[] top_k(Tensor input, int k = 1, bool sorted = true, string name = null)
- => gen_nn_ops.top_kv2(input, k: k, sorted: sorted, name: name);
+ => gen_nn_ops.top_kv2(input, k: ops.convert_to_tensor(k), sorted: sorted, name: name);
public Tensor bias_add(Tensor value, IVariableV1 bias, string data_format = null, string name = null)
{
return tf_with(ops.name_scope(name, "BiasAdd", new { value, bias }), scope =>
{
name = scope;
- return gen_nn_ops.bias_add(value, bias.AsTensor(), data_format: data_format, name: name);
+ return gen_nn_ops.bias_add(value, ops.convert_to_tensor(bias), data_format: data_format, name: name);
});
}
+ public Tensor l2_loss(Tensor t, string name = null)
+ => nn_ops.l2_loss(t, name: name);
+
///
/// Local Response Normalization.
///
@@ -167,7 +185,7 @@ public Tensor bias_add(Tensor value, IVariableV1 bias, string data_format = null
///
public Tensor lrn(Tensor input, int depth_radius = 5, int bias = 1,
int alpha = 1, float beta = 0.5f, string name = null)
- => gen_nn_ops.local_response_normalization(input, depth_radius: depth_radius, bias: bias,
+ => gen_nn_ops.lrn(input, depth_radius: depth_radius, bias: bias,
alpha: alpha, beta: beta, name: name);
public Tensor leaky_relu(Tensor features, float alpha = 0.2f, string name = null)
diff --git a/src/TensorFlowNET.Core/APIs/tf.numpy.cs b/src/TensorFlowNET.Core/APIs/tf.numpy.cs
new file mode 100644
index 000000000..392ba915f
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/tf.numpy.cs
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ Copyright 2021 Haiping Chen. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+******************************************************************************/
+
+using Tensorflow.NumPy;
+
+namespace Tensorflow
+{
+ public partial class tensorflow
+ {
+ ///
+ /// NumPy API on TensorFlow
+ /// https://www.tensorflow.org/api_docs/python/tf/experimental/numpy
+ ///
+ public NumPyImpl numpy => new NumPyImpl();
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.ops.cs b/src/TensorFlowNET.Core/APIs/tf.ops.cs
index 4308ff914..ebf35e3f9 100644
--- a/src/TensorFlowNET.Core/APIs/tf.ops.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.ops.cs
@@ -27,8 +27,8 @@ public void add_to_collection(string name, T value)
public void add_to_collections(List names, T value)
=> get_default_graph().add_to_collections(names, value);
- public Tensor assign(Tensor @ref, object value, bool validate_shape = true, bool use_locking = true, string name = null)
- => state_ops.assign(@ref, value, validate_shape, use_locking, name);
+ public (Tensors, Tensor) clip_by_global_norm(Tensor[] t_list, float clip_norm, Tensor use_norm = null, string name = null)
+ => clip_ops.clip_by_global_norm(t_list, clip_norm, use_norm: use_norm, name: name);
public Tensor assign(IVariableV1 @ref, object value, bool validate_shape = true, bool use_locking = true, string name = null)
=> state_ops.assign(@ref, value, validate_shape, use_locking, name);
@@ -44,7 +44,7 @@ public List get_collection(string key, string scope = "")
/// When eager execution is enabled, code inside an init_scope block runs with
/// eager execution enabled even when tracing a `tf.function`.
///
- public void init_scope()
+ public ops.NameScope init_scope()
=> ops.init_scope();
///
diff --git a/src/TensorFlowNET.Core/APIs/tf.queue.cs b/src/TensorFlowNET.Core/APIs/tf.queue.cs
index e32588134..a4757890e 100644
--- a/src/TensorFlowNET.Core/APIs/tf.queue.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.queue.cs
@@ -32,7 +32,7 @@ public partial class tensorflow
///
public PaddingFIFOQueue PaddingFIFOQueue(int capacity,
TF_DataType[] dtypes,
- TensorShape[] shapes,
+ Shape[] shapes,
string[] names = null,
string shared_name = null,
string name = "padding_fifo_queue")
@@ -45,7 +45,7 @@ public PaddingFIFOQueue PaddingFIFOQueue(int capacity,
public PaddingFIFOQueue PaddingFIFOQueue(int capacity,
TF_DataType dtype,
- TensorShape shape,
+ Shape shape,
string shared_name = null,
string name = "padding_fifo_queue")
=> new PaddingFIFOQueue(capacity,
@@ -66,7 +66,7 @@ public PaddingFIFOQueue PaddingFIFOQueue(int capacity,
///
public FIFOQueue FIFOQueue(int capacity,
TF_DataType[] dtypes,
- TensorShape[] shapes = null,
+ Shape[] shapes = null,
string[] names = null,
string shared_name = null,
string name = "fifo_queue")
@@ -79,12 +79,12 @@ public FIFOQueue FIFOQueue(int capacity,
public FIFOQueue FIFOQueue(int capacity,
TF_DataType dtype,
- TensorShape shape = null,
+ Shape shape = null,
string shared_name = null,
string name = "fifo_queue")
=> new FIFOQueue(capacity,
new[] { dtype },
- new[] { shape ?? new TensorShape() },
+ new[] { shape ?? Shape.Null },
shared_name: shared_name,
name: name);
@@ -99,26 +99,26 @@ public FIFOQueue FIFOQueue(int capacity,
///
public PriorityQueue PriorityQueue(int capacity,
TF_DataType dtype,
- TensorShape shape = null,
+ Shape shape = null,
string shared_name = null,
string name = "priority_queue")
=> new PriorityQueue(capacity,
new[] { dtype },
- new[] { shape ?? new TensorShape() },
+ new[] { shape ?? Shape.Null },
shared_name: shared_name,
name: name);
public RandomShuffleQueue RandomShuffleQueue(int capacity,
int min_after_dequeue,
TF_DataType dtype,
- TensorShape shape = null,
+ Shape shape = null,
int? seed = null,
string shared_name = null,
string name = "random_shuffle_queue")
=> new RandomShuffleQueue(capacity,
min_after_dequeue: min_after_dequeue,
new[] { dtype },
- new[] { shape ?? new TensorShape() },
+ new[] { shape ?? Shape.Null },
seed: seed,
shared_name: shared_name,
name: name);
diff --git a/src/TensorFlowNET.Core/APIs/tf.random.cs b/src/TensorFlowNET.Core/APIs/tf.random.cs
index bd74c8fdf..4f4962840 100644
--- a/src/TensorFlowNET.Core/APIs/tf.random.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.random.cs
@@ -32,13 +32,19 @@ public class Random
///
///
///
- public Tensor normal(TensorShape shape,
+ public Tensor normal(Shape shape,
float mean = 0.0f,
float stddev = 1.0f,
TF_DataType dtype = TF_DataType.TF_FLOAT,
int? seed = null,
string name = null) => random_ops.random_normal(shape, mean, stddev, dtype, seed, name);
+ public Tensor stateless_normal(Shape shape,
+ float mean = 0.0f,
+ float stddev = 1.0f,
+ TF_DataType dtype = TF_DataType.TF_FLOAT,
+ string name = null) => stateless_random_ops.stateless_random_normal(shape, mean, stddev, dtype, name: name);
+
///
/// Outputs random values from a truncated normal distribution.
///
@@ -49,7 +55,7 @@ public Tensor normal(TensorShape shape,
///
///
///
- public Tensor truncated_normal(TensorShape shape,
+ public Tensor truncated_normal(Shape shape,
float mean = 0.0f,
float stddev = 1.0f,
TF_DataType dtype = TF_DataType.TF_FLOAT,
@@ -62,16 +68,30 @@ public Tensor categorical(
int? seed = null,
string name = null,
TF_DataType output_dtype = TF_DataType.DtInvalid) => random_ops.multinomial(logits, num_samples, seed: seed, name: name, output_dtype: output_dtype);
+
+ public Tensor uniform(Shape shape,
+ float minval = 0,
+ float maxval = 1,
+ TF_DataType dtype = TF_DataType.TF_FLOAT,
+ int? seed = null,
+ string name = null)
+ {
+ if (dtype.is_integer())
+ return random_ops.random_uniform_int(shape, (int)minval, (int)maxval, seed, name);
+ else
+ return random_ops.random_uniform(shape, minval, maxval, dtype, seed, name);
+ }
}
- public Tensor random_uniform(TensorShape shape,
+ public Tensor random_uniform(Shape shape,
float minval = 0,
float maxval = 1,
TF_DataType dtype = TF_DataType.TF_FLOAT,
int? seed = null,
- string name = null) => random_ops.random_uniform(shape, minval, maxval, dtype, seed, name);
+ string name = null)
+ => random.uniform(shape, minval: minval, maxval: maxval, dtype: dtype, seed: seed, name: name);
- public Tensor truncated_normal(TensorShape shape,
+ public Tensor truncated_normal(Shape shape,
float mean = 0.0f,
float stddev = 1.0f,
TF_DataType dtype = TF_DataType.TF_FLOAT,
@@ -93,7 +113,12 @@ public Tensor random_shuffle(Tensor value, int? seed = null, string name = null)
=> random_ops.random_shuffle(value, seed: seed, name: name);
public void set_random_seed(int seed)
- => ops.get_default_graph().seed = seed;
+ {
+ if (executing_eagerly())
+ Context.set_global_seed(seed);
+ else
+ ops.get_default_graph().seed = seed;
+ }
public Tensor multinomial(Tensor logits, int num_samples, int? seed = null,
string name = null, TF_DataType output_dtype = TF_DataType.DtInvalid)
diff --git a/src/TensorFlowNET.Core/APIs/tf.reduce_logsumexp.cs b/src/TensorFlowNET.Core/APIs/tf.reduce_logsumexp.cs
index 325f06339..41f0ec45d 100644
--- a/src/TensorFlowNET.Core/APIs/tf.reduce_logsumexp.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.reduce_logsumexp.cs
@@ -19,7 +19,7 @@ namespace Tensorflow
public partial class tensorflow
{
public Tensor reduce_logsumexp(Tensor input_tensor,
- int[] axis = null,
+ Axis? axis = null,
bool keepdims = false,
string name = null) => math_ops.reduce_logsumexp(input_tensor, axis, keepdims, name);
diff --git a/src/TensorFlowNET.Core/APIs/tf.reshape.cs b/src/TensorFlowNET.Core/APIs/tf.reshape.cs
index 3952b82c4..102a81323 100644
--- a/src/TensorFlowNET.Core/APIs/tf.reshape.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.reshape.cs
@@ -19,15 +19,18 @@ namespace Tensorflow
public partial class tensorflow
{
public Tensor reshape(Tensor tensor,
- TensorShape shape,
- string name = null) => gen_array_ops.reshape(tensor, shape, name);
+ Shape shape,
+ string name = null)
+ => gen_array_ops.reshape(tensor, shape, name);
public Tensor reshape(Tensor tensor,
- Tensor[] shape,
- string name = null) => gen_array_ops.reshape(tensor, shape, name);
+ Tensor shape,
+ string name = null)
+ => gen_array_ops.reshape(tensor, shape, name);
public Tensor reshape(Tensor tensor,
- Tensor shape,
- string name = null) => gen_array_ops.reshape(tensor, shape, name);
+ object[] shape,
+ string name = null)
+ => array_ops.reshape(tensor, shape, name);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.saved_model.cs b/src/TensorFlowNET.Core/APIs/tf.saved_model.cs
new file mode 100644
index 000000000..ef6251ca8
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/tf.saved_model.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tensorflow.Train;
+
+namespace Tensorflow
+{
+ public partial class tensorflow
+ {
+ public SavedModelAPI saved_model { get; } = new SavedModelAPI();
+ }
+
+ public class SavedModelAPI
+ {
+ public Trackable load(string export_dir, LoadOptions? options = null)
+ {
+ return Loader.load(export_dir, options);
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.signal.cs b/src/TensorFlowNET.Core/APIs/tf.signal.cs
new file mode 100644
index 000000000..2471124c5
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/tf.signal.cs
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ Copyright 2023 Konstantin Balashov All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+******************************************************************************/
+
+using Tensorflow.Operations;
+
+namespace Tensorflow
+{
+ public partial class tensorflow
+ {
+ public SignalApi signal { get; } = new SignalApi();
+ public class SignalApi
+ {
+ public Tensor fft(Tensor input, string name = null)
+ => gen_ops.f_f_t(input, name: name);
+ public Tensor ifft(Tensor input, string name = null)
+ => gen_ops.i_f_f_t(input, name: name);
+ public Tensor fft2d(Tensor input, string name = null)
+ => gen_ops.f_f_t2d(input, name: name);
+ public Tensor ifft2d(Tensor input, string name = null)
+ => gen_ops.i_f_f_t2d(input, name: name);
+ public Tensor fft3d(Tensor input, string name = null)
+ => gen_ops.f_f_t3d(input, name: name);
+ public Tensor ifft3d(Tensor input, string name = null)
+ => gen_ops.i_f_f_t3d(input, name: name);
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.sparse.cs b/src/TensorFlowNET.Core/APIs/tf.sparse.cs
index 11f6a55d5..f124f6105 100644
--- a/src/TensorFlowNET.Core/APIs/tf.sparse.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.sparse.cs
@@ -14,17 +14,18 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using System;
using Tensorflow.Framework;
namespace Tensorflow
{
public partial class tensorflow
{
- public SparseTensor SparseTensor(long[,] indices, T[] values, long[] dense_shape)
- => new SparseTensor(indices, values, dense_shape);
+ public SparseTensor SparseTensor(long[,] indices, Array values, long[] dense_shape)
+ => new SparseTensor(indices, values, dense_shape);
- public Tensor sparse_tensor_to_dense(SparseTensor sp_input,
- T default_value = default,
+ public Tensor sparse_tensor_to_dense(SparseTensor sp_input,
+ Array default_value = default,
bool validate_indices = true,
string name = null)
=> gen_sparse_ops.sparse_to_dense(sp_input.indices,
@@ -46,7 +47,7 @@ public Tensor sparse_tensor_to_dense(SparseTensor sp_input,
///
/// Dense `Tensor` of shape `output_shape`. Has the same type as `sparse_values`.
public Tensor sparse_to_dense(Tensor sparse_indices,
- TensorShape output_shape,
+ Shape output_shape,
T sparse_values,
T default_value = default,
bool validate_indices = true,
diff --git a/src/TensorFlowNET.Core/APIs/tf.strings.cs b/src/TensorFlowNET.Core/APIs/tf.strings.cs
index be0cf7651..ecaf775d0 100644
--- a/src/TensorFlowNET.Core/APIs/tf.strings.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.strings.cs
@@ -14,6 +14,8 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using static Tensorflow.Binding;
+
namespace Tensorflow
{
public partial class tensorflow
@@ -24,6 +26,30 @@ public class StringsApi
{
string_ops ops = new string_ops();
+ ///
+ /// Converts all uppercase characters into their respective lowercase replacements.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor lower(Tensor input, string encoding = "", string name = null)
+ => ops.lower(input: input, encoding: encoding, name: name);
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor regex_replace(Tensor input, string pattern, string rewrite,
+ bool replace_global = true, string name = null)
+ => ops.regex_replace(input, pattern, rewrite,
+ replace_global: replace_global, name: name);
+
///
/// Return substrings from `Tensor` of strings.
///
@@ -40,6 +66,30 @@ public Tensor substr(Tensor input, int pos, int len,
public Tensor substr(string input, int pos, int len,
string name = null, string @uint = "BYTE")
=> ops.substr(input, pos, len, @uint: @uint, name: name);
+
+ ///
+ /// String lengths of `input`.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor string_length(Tensor input, string name = null, string unit = "BYTE")
+ => ops.string_length(input, name: name, unit: unit);
+
+ public Tensor format(string template, Tensor[] inputs, string placeholder = "{}", int summarize = 3, string name = null)
+ => ops.string_format(inputs, template: template, placeholder: placeholder, summarize: summarize, name: name);
+
+ public RaggedTensor split(Tensor input, char sep = ' ', int maxsplit = -1, string name = null)
+ => ops.string_split_v2(input, sep: sep.ToString(), maxsplit : maxsplit, name : name);
+
+ public (RaggedTensor, RaggedTensor) unicode_decode_with_offsets(Tensor input, string input_encoding,
+ string errors = "replace", int replacement_char = 0xFFFD,
+ bool replace_control_characters = false, string name = null)
+ => ops.unicode_decode_with_offsets(input, input_encoding, errors,
+ replacement_char: replacement_char,
+ replace_control_characters: replace_control_characters,
+ name: name);
}
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.tensor.cs b/src/TensorFlowNET.Core/APIs/tf.tensor.cs
index a0dac3c70..b03168ab3 100644
--- a/src/TensorFlowNET.Core/APIs/tf.tensor.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.tensor.cs
@@ -14,12 +14,14 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
+using Tensorflow.Operations;
+
namespace Tensorflow
{
public partial class tensorflow
{
public Tensor convert_to_tensor(object value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, TF_DataType preferred_dtype = TF_DataType.DtInvalid)
- => ops.convert_to_tensor(value, dtype, name, preferred_dtype);
+ => ops.convert_to_tensor(value, dtype, name, preferred_dtype: preferred_dtype);
public Tensor strided_slice(Tensor input, Tensor begin, Tensor end, Tensor strides = null,
int begin_mask = 0,
@@ -44,10 +46,10 @@ public Tensor strided_slice(Tensor input, T[] begin, T[] end, T[] strides = n
int ellipsis_mask = 0,
int new_axis_mask = 0,
int shrink_axis_mask = 0,
- string name = null) => gen_array_ops.strided_slice(input: input,
- begin: begin,
- end: end,
- strides: strides,
+ string name = null) => array_ops.strided_slice(input,
+ begin: ops.convert_to_tensor(begin),
+ end: ops.convert_to_tensor(end),
+ strides: ops.convert_to_tensor(strides),
begin_mask: begin_mask,
end_mask: end_mask,
ellipsis_mask: ellipsis_mask,
@@ -66,18 +68,30 @@ public Tensor strided_slice(Tensor input, T[] begin, T[] end, T[] strides = n
/// A name for the operation (optional)
/// if num_or_size_splits is a scalar returns num_or_size_splits Tensor objects;
/// if num_or_size_splits is a 1-D Tensor returns num_or_size_splits.get_shape[0] Tensor objects resulting from splitting value.
- public Tensor[] split(Tensor value, int num_split, Tensor axis, string name = null)
+ public Tensor[] split(Tensor value, int num_split, Axis axis, string name = null)
=> array_ops.split(
value: value,
- num_split: num_split,
+ num_or_size_splits: num_split,
axis: axis,
name: name);
- public Tensor[] split(Tensor value, int num_split, int axis, string name = null)
+ public Tensor[] split(Tensor value, int[] num_split, Axis axis, string name = null)
=> array_ops.split(
value: value,
- num_split: num_split,
+ num_or_size_splits: num_split,
axis: axis,
name: name);
+
+ //public Tensor[] split(Tensor value, int num_split, Axis axis, string name = null)
+ // => array_ops.split(
+ // value: value,
+ // num_or_size_splits: num_split,
+ // axis: axis,
+ // name: name);
+
+ public Tensor ensure_shape(Tensor x, Shape shape, string name = null)
+ {
+ return gen_ops.ensure_shape(x, shape, name);
+ }
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.tile.cs b/src/TensorFlowNET.Core/APIs/tf.tile.cs
index 71717e9cf..a3b497e8a 100644
--- a/src/TensorFlowNET.Core/APIs/tf.tile.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.tile.cs
@@ -13,13 +13,22 @@ You may obtain a copy of the License at
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************/
+using static Tensorflow.Binding;
namespace Tensorflow
{
public partial class tensorflow
{
- public Tensor tile(Tensor input,
- T multiples,
- string name = null) => gen_array_ops.tile(input, multiples, name);
+ public Tensor tile(Tensor input, Tensor multiples, string name = null)
+ => gen_array_ops.tile(input, multiples, name);
+
+ public Tensor tile(Tensor input, object[] multiples, string name = null)
+ => array_ops.tile(input, constant_op.constant(shape_utils.from_object_array(multiples).dims), name);
+
+ public Tensor tile(Tensor input, Shape multiples, string name = null)
+ {
+ var multiples_tensor = constant_op.constant(multiples);
+ return gen_array_ops.tile(input, multiples_tensor, name);
+ }
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.variable.cs b/src/TensorFlowNET.Core/APIs/tf.variable.cs
index c730e805c..9ce864bd8 100644
--- a/src/TensorFlowNET.Core/APIs/tf.variable.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.variable.cs
@@ -37,10 +37,7 @@ public Operation variables_initializer(IVariableV1[] var_list, string name = "in
=> variables.variables_initializer(var_list, name: name);
public Operation global_variables_initializer()
- {
- var g = variables.global_variables();
- return variables.variables_initializer(g.ToArray());
- }
+ => tf.compat.v1.global_variables_initializer();
///
/// Returns all variables created with `trainable=True`.
diff --git a/src/TensorFlowNET.Core/Attributes/c_api.ops.cs b/src/TensorFlowNET.Core/Attributes/c_api.ops.cs
index 1476d4d38..ba6f653a1 100644
--- a/src/TensorFlowNET.Core/Attributes/c_api.ops.cs
+++ b/src/TensorFlowNET.Core/Attributes/c_api.ops.cs
@@ -57,11 +57,26 @@ public partial class c_api
[DllImport(TensorFlowLibName)]
public static extern int TF_OperationGetAttrValueProto(IntPtr oper, string attr_name, SafeBufferHandle output_attr_value, SafeStatusHandle status);
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_OperationGetAttrType(IntPtr oper, string attr_name, IntPtr value, SafeStatusHandle status);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_OperationGetAttrInt(IntPtr oper, string attr_name, IntPtr value, SafeStatusHandle status);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_OperationGetAttrFloat(IntPtr oper, string attr_name, IntPtr value, SafeStatusHandle status);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_OperationGetAttrBool(IntPtr oper, string attr_name, IntPtr value, SafeStatusHandle status);
+
+ [DllImport(TensorFlowLibName)]
+ public static extern void TF_OperationGetAttrShape(IntPtr oper, string attr_name, long[] value, int num_dims, SafeStatusHandle status);
+
[DllImport(TensorFlowLibName)]
public static extern void TF_SetAttrBool(IntPtr desc, string attr_name, bool value);
[DllImport(TensorFlowLibName)]
- public static extern void TF_SetAttrValueProto(IntPtr desc, string attr_name, IntPtr proto, uint proto_len, SafeStatusHandle status);
+ public static extern void TF_SetAttrValueProto(IntPtr desc, string attr_name, byte[] proto, ulong proto_len, SafeStatusHandle status);
///
/// Set `num_dims` to -1 to represent "unknown rank".
@@ -99,7 +114,7 @@ public partial class c_api
public static extern void TF_SetAttrStringList(IntPtr desc, string attr_name, IntPtr[] values, uint[] lengths, int num_values);
[DllImport(TensorFlowLibName)]
- public static extern void TF_SetAttrTensor(IntPtr desc, string attr_name, IntPtr value, SafeStatusHandle status);
+ public static extern void TF_SetAttrTensor(IntPtr desc, string attr_name, SafeTensorHandle value, SafeStatusHandle status);
[DllImport(TensorFlowLibName)]
public static extern void TF_SetAttrType(IntPtr desc, string attr_name, TF_DataType value);
diff --git a/src/TensorFlowNET.Core/Binding.Util.cs b/src/TensorFlowNET.Core/Binding.Util.cs
index 0411227f5..99ed5c1f3 100644
--- a/src/TensorFlowNET.Core/Binding.Util.cs
+++ b/src/TensorFlowNET.Core/Binding.Util.cs
@@ -14,14 +14,15 @@ You may obtain a copy of the License at
limitations under the License.
******************************************************************************/
-using NumSharp;
-using NumSharp.Utilities;
+using Tensorflow.NumPy;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
+using System.IO;
using System.Linq;
+using Tensorflow.Operations;
namespace Tensorflow
{
@@ -46,6 +47,15 @@ public static void Update(this IList list, T element)
}
}
+ public static void difference_update(this IList list, IList list2)
+ {
+ foreach(var el in list2)
+ {
+ if (list.Contains(el))
+ list.Remove(el);
+ }
+ }
+
public static void add(this IList list, T element)
=> list.Add(element);
@@ -80,39 +90,44 @@ private static string _tostring(object obj)
switch (obj)
{
case NDArray nd:
- return nd.ToString(false);
- case Array arr:
+ return nd.ToString();
+ /*case Array arr:
if (arr.Rank != 1 || arr.GetType().GetElementType()?.IsArray == true)
arr = Arrays.Flatten(arr);
var objs = toObjectArray(arr);
- return $"[{string.Join(", ", objs.Select(_tostring))}]";
+ return $"[{string.Join(", ", objs.Select(_tostring))}]";*/
default:
return obj?.ToString() ?? "null";
}
+ }
- object[] toObjectArray(Array arr)
+ private static TextWriter _writer = Console.Out;
+
+ public static TextWriter tf_output_redirect {
+ set
{
- var len = arr.LongLength;
- var ret = new object[len];
- for (long i = 0; i < len; i++)
+ if(_writer != null)
{
- ret[i] = arr.GetValue(i);
+ _writer.Flush();
+ if (_writer is StringWriter sw)
+ sw.GetStringBuilder().Clear();
}
- return ret;
+ _writer = value;
}
+ get => _writer ?? Console.Out;
}
public static void print(object obj)
{
- Console.WriteLine(_tostring(obj));
+ tf_output_redirect.WriteLine(_tostring(obj));
}
public static void print(string format, params object[] objects)
{
if (!format.Contains("{}"))
{
- Console.WriteLine(format + " " + string.Join(" ", objects.Select(x => x.ToString())));
+ tf_output_redirect.WriteLine(format + " " + string.Join(" ", objects.Select(x => x.ToString())));
return;
}
@@ -121,30 +136,42 @@ public static void print(string format, params object[] objects)
}
- Console.WriteLine(format);
+ tf_output_redirect.WriteLine(format);
}
public static int len(object a)
{
switch (a)
{
+ case Tensor tensor:
+ return (int)tensor.shape[0];
+ case Tensors arr:
+ return arr.Length;
case Array arr:
return arr.Length;
case IList arr:
return arr.Count;
case ICollection arr:
return arr.Count;
- case NDArray ndArray:
- return ndArray.ndim == 0 ? 1 : ndArray.shape[0];
case IEnumerable enumerable:
return enumerable.OfType