| @@ -5,14 +5,8 @@ VisualStudioVersion = 16.0.29102.190 | |||
| MinimumVisualStudioVersion = 10.0.40219.1 | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "test\TensorFlowNET.UnitTest\TensorFlowNET.UnitTest.csproj", "{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "test\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj", "{1FE60088-157C-4140-91AB-E96B915E4BAE}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" | |||
| EndProject | |||
| Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "TensorFlowNET.Examples.FSharp", "test\TensorFlowNET.Examples.FSharp\TensorFlowNET.Examples.FSharp.fsproj", "{62BC3801-F0D3-44A9-A0AC-712F40C8F961}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowBenchmark", "src\TensorFlowNet.Benchmarks\TensorFlowBenchmark.csproj", "{68861442-971A-4196-876E-C9330F0B3C54}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowHub", "src\TensorFlowHub\TensorFlowHub.csproj", "{8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowText", "src\TensorFlowText\TensorFlowText.csproj", "{B598E5D5-BD2D-4191-8532-F2FBAC31AB81}" | |||
| @@ -31,22 +25,10 @@ Global | |||
| {029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {1FE60088-157C-4140-91AB-E96B915E4BAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {1FE60088-157C-4140-91AB-E96B915E4BAE}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {1FE60088-157C-4140-91AB-E96B915E4BAE}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {1FE60088-157C-4140-91AB-E96B915E4BAE}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|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 | |||
| {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {62BC3801-F0D3-44A9-A0AC-712F40C8F961}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {68861442-971A-4196-876E-C9330F0B3C54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {68861442-971A-4196-876E-C9330F0B3C54}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {68861442-971A-4196-876E-C9330F0B3C54}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {68861442-971A-4196-876E-C9330F0B3C54}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| @@ -1,45 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| namespace TensorFlowNET.Visualization.Controllers | |||
| { | |||
| [Route("api/[controller]")] | |||
| [ApiController] | |||
| public class ValuesController : ControllerBase | |||
| { | |||
| // GET api/values | |||
| [HttpGet] | |||
| public ActionResult<IEnumerable<string>> Get() | |||
| { | |||
| return new string[] { "value1", "value2" }; | |||
| } | |||
| // GET api/values/5 | |||
| [HttpGet("{id}")] | |||
| public ActionResult<string> Get(int id) | |||
| { | |||
| return "value"; | |||
| } | |||
| // POST api/values | |||
| [HttpPost] | |||
| public void Post([FromBody] string value) | |||
| { | |||
| } | |||
| // PUT api/values/5 | |||
| [HttpPut("{id}")] | |||
| public void Put(int id, [FromBody] string value) | |||
| { | |||
| } | |||
| // DELETE api/values/5 | |||
| [HttpDelete("{id}")] | |||
| public void Delete(int id) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -1,24 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.Logging; | |||
| namespace TensorFlowNET.Visualization | |||
| { | |||
| public class Program | |||
| { | |||
| public static void Main(string[] args) | |||
| { | |||
| CreateWebHostBuilder(args).Build().Run(); | |||
| } | |||
| public static IWebHostBuilder CreateWebHostBuilder(string[] args) => | |||
| WebHost.CreateDefaultBuilder(args) | |||
| .UseStartup<Startup>(); | |||
| } | |||
| } | |||
| @@ -1,41 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore.Builder; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using Microsoft.Extensions.Logging; | |||
| using Microsoft.Extensions.Options; | |||
| namespace TensorFlowNET.Visualization | |||
| { | |||
| public class Startup | |||
| { | |||
| public Startup(IConfiguration configuration) | |||
| { | |||
| Configuration = configuration; | |||
| } | |||
| public IConfiguration Configuration { get; } | |||
| // This method gets called by the runtime. Use this method to add services to the container. | |||
| public void ConfigureServices(IServiceCollection services) | |||
| { | |||
| services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); | |||
| } | |||
| // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||
| public void Configure(IApplicationBuilder app, IHostingEnvironment env) | |||
| { | |||
| if (env.IsDevelopment()) | |||
| { | |||
| app.UseDeveloperExceptionPage(); | |||
| } | |||
| app.UseMvc(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||
| <PropertyGroup> | |||
| <TargetFramework>netcoreapp2.1</TargetFramework> | |||
| <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Microsoft.AspNetCore.App" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,9 +0,0 @@ | |||
| { | |||
| "Logging": { | |||
| "LogLevel": { | |||
| "Default": "Debug", | |||
| "System": "Information", | |||
| "Microsoft": "Information" | |||
| } | |||
| } | |||
| } | |||
| @@ -1,8 +0,0 @@ | |||
| { | |||
| "Logging": { | |||
| "LogLevel": { | |||
| "Default": "Warning" | |||
| } | |||
| }, | |||
| "AllowedHosts": "*" | |||
| } | |||
| @@ -1,29 +0,0 @@ | |||
| using System; | |||
| using System.Reflection; | |||
| using BenchmarkDotNet.Configs; | |||
| using BenchmarkDotNet.Running; | |||
| namespace TensorFlowBenchmark | |||
| { | |||
| class Program | |||
| { | |||
| static void Main(string[] args) | |||
| { | |||
| if (args?.Length > 0) | |||
| { | |||
| for (int i = 0; i < args.Length; i++) | |||
| { | |||
| string name = $"TensorFlowBenchmark.{args[i]}"; | |||
| var type = Type.GetType(name); | |||
| BenchmarkRunner.Run(type); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(args, ManualConfig.Create(DefaultConfig.Instance).With(ConfigOptions.DisableOptimizationsValidator)); | |||
| } | |||
| Console.ReadLine(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,88 +0,0 @@ | |||
| using System; | |||
| using BenchmarkDotNet.Attributes; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowBenchmark | |||
| { | |||
| [SimpleJob(launchCount: 1, warmupCount: 2, targetCount: 10)] | |||
| [MinColumn, MaxColumn, MeanColumn, MedianColumn] | |||
| public class TensorBenchmark | |||
| { | |||
| private double[] data; | |||
| [GlobalSetup] | |||
| public void Setup() | |||
| { | |||
| data = new double[100]; | |||
| } | |||
| [Benchmark] | |||
| public void ScalarTensor() | |||
| { | |||
| var g = new Graph(); | |||
| for (int i = 0; i < 100; i++) | |||
| { | |||
| using (var tensor = new Tensor(17.0)) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| [Benchmark] | |||
| public unsafe void TensorFromFixedPtr() | |||
| { | |||
| var g = new Graph(); | |||
| for (int i = 0; i < 100; i++) | |||
| { | |||
| fixed (double* ptr = &data[0]) | |||
| { | |||
| using (var t = new Tensor((IntPtr)ptr, new long[] { data.Length }, tf.float64, 8 * data.Length)) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| } | |||
| [Benchmark] | |||
| public void TensorFromArray() | |||
| { | |||
| var g=new Graph(); | |||
| for (int i = 0; i < 100; i++) | |||
| { | |||
| using (var tensor = new Tensor(data)) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| [Benchmark] | |||
| public void TensorFromNDArray() | |||
| { | |||
| var g = new Graph(); | |||
| for (int i = 0; i < 1000; i++) | |||
| { | |||
| using (var tensor = new Tensor(new NDArray(data))) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| //[Benchmark] | |||
| //public void Constant() | |||
| //{ | |||
| // for (int i = 0; i < 100; i++) | |||
| // { | |||
| // //var tensor = new Tensor(new NDArray(data)); | |||
| // var c = tf.constant(42.0); | |||
| // } | |||
| //} | |||
| } | |||
| } | |||
| @@ -1,33 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <OutputType>Exe</OutputType> | |||
| <TargetFramework>netcoreapp3.0</TargetFramework> | |||
| <NoWin32Manifest>true</NoWin32Manifest> | |||
| <AssemblyName>TensorFlowBenchmark</AssemblyName> | |||
| <RootNamespace>TensorFlowBenchmark</RootNamespace> | |||
| <LangVersion>7.3</LangVersion> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <None Remove="tensorflow.dll" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="BenchmarkDotNet" Version="0.11.5" /> | |||
| <PackageReference Include="SciSharp.TensorFlow.Redist" Version="1.14.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,20 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <OutputType>Exe</OutputType> | |||
| <TargetFramework>netcoreapp2.2</TargetFramework> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <None Remove="tensorflow.dll" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="BenchmarkDotNet" Version="0.11.5" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,76 +0,0 @@ | |||
| using System; | |||
| using System.Runtime.CompilerServices; | |||
| using System.Runtime.InteropServices; | |||
| using BenchmarkDotNet.Attributes; | |||
| using Google.Protobuf.WellKnownTypes; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowBenchmark.Unmanaged | |||
| { | |||
| public struct UnmanagedStruct | |||
| { | |||
| public int a; | |||
| public long b; | |||
| public UnmanagedStruct(int _) | |||
| { | |||
| a = 2; | |||
| b = 3; | |||
| } | |||
| } | |||
| [SimpleJob(launchCount: 1, warmupCount: 2, targetCount: 10)] | |||
| [MinColumn, MaxColumn, MeanColumn, MedianColumn] | |||
| public unsafe class StructCastBenchmark | |||
| { | |||
| private static void EnsureIsUnmanaged<T>(T _) where T : unmanaged | |||
| { } | |||
| static StructCastBenchmark() //if UnmanagedStruct is not unmanaged struct then this will fail to compile. | |||
| => EnsureIsUnmanaged(new UnmanagedStruct()); | |||
| private IntPtr data; | |||
| private void* dataptr; | |||
| [GlobalSetup] | |||
| public void Setup() | |||
| { | |||
| data = Marshal.AllocHGlobal(Marshal.SizeOf<UnmanagedStruct>()); | |||
| dataptr = data.ToPointer(); | |||
| } | |||
| [Benchmark, MethodImpl(MethodImplOptions.NoOptimization)] | |||
| public void Marshal_PtrToStructure() | |||
| { | |||
| UnmanagedStruct _; | |||
| for (int i = 0; i < 10000; i++) | |||
| { | |||
| _ = Marshal.PtrToStructure<UnmanagedStruct>(data); | |||
| } | |||
| } | |||
| [Benchmark, MethodImpl(MethodImplOptions.NoOptimization)] | |||
| public void PointerCast() | |||
| { | |||
| var dptr = dataptr; | |||
| UnmanagedStruct _; | |||
| for (int i = 0; i < 10000; i++) | |||
| { | |||
| _ = *(UnmanagedStruct*) dptr; | |||
| } | |||
| } | |||
| [Benchmark, MethodImpl(MethodImplOptions.NoOptimization)] | |||
| public void Unsafe_Read() | |||
| { | |||
| var dptr = dataptr; | |||
| UnmanagedStruct _; | |||
| for (int i = 0; i < 10000; i++) | |||
| { | |||
| _ = Unsafe.Read<UnmanagedStruct>(dptr); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,104 +0,0 @@ | |||
| module FunctionApproximation | |||
| //reduced example from https://github.com/tirthajyoti/Machine-Learning-with-Python/blob/master/Function%20Approximation%20by%20Neural%20Network/Function%20approximation%20by%20linear%20model%20and%20deep%20network.ipynb | |||
| open NumSharp | |||
| open Tensorflow | |||
| open System | |||
| let run()= | |||
| let N_points = 75 // Number of points for constructing function | |||
| let x_min = 1.0 // Min of the range of x (feature) | |||
| let x_max = 15.0 // Max of the range of x (feature) | |||
| let noise_mean = 0.0 // Mean of the Gaussian noise adder | |||
| let noise_sd = 10.0 // Std.Dev of the Gaussian noise adder | |||
| let linspace points = [| for i in 0 .. (points - 1) -> x_min + (x_max - x_min)/(float)points * (float)i |] | |||
| let func_trans(xAr:float []) = | |||
| xAr | |||
| |>Array.map (fun (x:float) -> (20.0 * x+3.0 * System.Math.Pow(x,2.0)+0.1 * System.Math.Pow(x,3.0))*sin(x)*exp(-0.1*x)) | |||
| let X_raw = linspace N_points | |||
| let Y_raw = func_trans(X_raw) | |||
| let X_mtr = Array2D.init X_raw.Length 1 (fun i j -> X_raw.[i]) | |||
| let X = np.array(X_mtr) | |||
| let noise_x = np.random.normal(noise_mean,noise_sd,N_points) | |||
| let y = np.array(Y_raw)+noise_x | |||
| let X_train = X | |||
| let y_train = y | |||
| let learning_rate = 0.00001 | |||
| let training_epochs = 35000 | |||
| let n_input = 1 // Number of features | |||
| let n_output = 1 // Regression output is a number only | |||
| let n_hidden_layer_1 = 25 // Hidden layer 1 | |||
| let n_hidden_layer_2 = 25 // Hidden layer 2 | |||
| let tf = Binding.New<tensorflow>() | |||
| let x = tf.placeholder(tf.float64, new TensorShape(N_points,n_input)) | |||
| let y = tf.placeholder(tf.float64, new TensorShape(n_output)) | |||
| let weights = dict[ | |||
| "hidden_layer_1", tf.Variable(tf.random_normal([|n_input; n_hidden_layer_1|],dtype=tf.float64)) | |||
| "hidden_layer_2", tf.Variable(tf.random_normal([|n_hidden_layer_1; n_hidden_layer_2|],dtype=tf.float64)) | |||
| "out", tf.Variable(tf.random_normal([|n_hidden_layer_2; n_output|],dtype=tf.float64)) | |||
| ] | |||
| let biases = dict[ | |||
| "hidden_layer_1", tf.Variable(tf.random_normal([|n_hidden_layer_1|],dtype=tf.float64)) | |||
| "hidden_layer_2", tf.Variable(tf.random_normal([|n_hidden_layer_2|],dtype=tf.float64)) | |||
| "out", tf.Variable(tf.random_normal([|n_output|],dtype=tf.float64)) | |||
| ] | |||
| // Hidden layer with RELU activation | |||
| let layer_1 = tf.add(tf.matmul(x, weights.["hidden_layer_1"]._AsTensor()),biases.["hidden_layer_1"]) | |||
| let layer_1 = tf.nn.relu(layer_1) | |||
| let layer_2 = tf.add(tf.matmul(layer_1, weights.["hidden_layer_2"]._AsTensor()),biases.["hidden_layer_2"]) | |||
| let layer_2 = tf.nn.relu(layer_2) | |||
| // Output layer with linear activation | |||
| let ops = tf.add(tf.matmul(layer_2, weights.["out"]._AsTensor()), biases.["out"]) | |||
| // Define loss and optimizer | |||
| let cost = tf.reduce_mean(tf.square(tf.squeeze(ops)-y)) | |||
| let gs = tf.Variable(1, trainable= false, name= "global_step") | |||
| let optimizer = tf.train.GradientDescentOptimizer(learning_rate=(float32)learning_rate).minimize(cost,global_step = gs) | |||
| let init = tf.global_variables_initializer() | |||
| Tensorflow.Binding.``tf_with``(tf.Session(), fun (sess:Session) -> | |||
| sess.run(init) |> ignore | |||
| // Loop over epochs | |||
| for epoch in [0..training_epochs] do | |||
| // Run optimization process (backprop) and cost function (to get loss value) | |||
| let result=sess.run([|optimizer:>ITensorOrOperation; gs._AsTensor():>ITensorOrOperation; cost:>ITensorOrOperation|], new FeedItem(x, X_train), new FeedItem(y, y_train)) | |||
| let loss_value = (double) result.[2]; | |||
| let step = (int) result.[1]; | |||
| if epoch % 1000 = 0 then | |||
| sprintf "Step %d loss: %f" step loss_value |> Console.WriteLine | |||
| let w=sess.run(weights |> Array.ofSeq |> Array.map (fun pair -> pair.Value)) | |||
| let b = sess.run(biases |> Array.ofSeq |> Array.map (fun pair -> pair.Value)) | |||
| let yhat=sess.run([|ops:>ITensorOrOperation|],new FeedItem(x,X_train)) | |||
| for i in [0..(N_points-1)] do | |||
| sprintf "pred %f real: %f" ((double)(yhat.[0].[i].[0])) ((double)Y_raw.[i]) |> Console.WriteLine | |||
| ) | |||
| @@ -1,8 +0,0 @@ | |||
| // Learn more about F# at http://fsharp.org | |||
| open System | |||
| [<EntryPoint>] | |||
| let main argv = | |||
| FunctionApproximation.run() | |||
| 0 // return an integer exit code | |||
| @@ -1,21 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <OutputType>Exe</OutputType> | |||
| <TargetFramework>netcoreapp2.2</TargetFramework> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Compile Include="FunctionApproximation.fs" /> | |||
| <Compile Include="Program.fs" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="SciSharp.TensorFlow.Redist" Version="1.14.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1 +0,0 @@ | |||
| | |||
| @@ -1,73 +0,0 @@ | |||
| using System; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Basic introduction to TensorFlow's Eager API. | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/1_Introduction/basic_eager_api.py | |||
| /// </summary> | |||
| public class BasicEagerApi : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public string Name => "Basic Eager"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| private Tensor a, b, c, d; | |||
| public bool Run() | |||
| { | |||
| // Set Eager API | |||
| Console.WriteLine("Setting Eager mode..."); | |||
| tf.enable_eager_execution(); | |||
| // Define constant tensors | |||
| Console.WriteLine("Define constant tensors"); | |||
| a = tf.constant(2); | |||
| Console.WriteLine($"a = {a}"); | |||
| b = tf.constant(3); | |||
| Console.WriteLine($"b = {b}"); | |||
| // Run the operation without the need for tf.Session | |||
| Console.WriteLine("Running operations, without tf.Session"); | |||
| c = a + b; | |||
| Console.WriteLine($"a + b = {c}"); | |||
| d = a * b; | |||
| Console.WriteLine($"a * b = {d}"); | |||
| // Full compatibility with Numpy | |||
| return true; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,185 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Implement K-Means algorithm with TensorFlow.NET, and apply it to classify | |||
| /// handwritten digit images. | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/kmeans.py | |||
| /// </summary> | |||
| public class KMeansClustering : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public string Name => "K-means Clustering"; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public int? train_size = null; | |||
| public int validation_size = 5000; | |||
| public int? test_size = null; | |||
| public int batch_size = 1024; // The number of samples per batch | |||
| Datasets<MnistDataSet> mnist; | |||
| NDArray full_data_x; | |||
| int num_steps = 20; // Total steps to train | |||
| int k = 25; // The number of clusters | |||
| int num_classes = 10; // The 10 digits | |||
| int num_features = 784; // Each image is 28x28 pixels | |||
| float accuray_test = 0f; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = ImportGraph(); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| Train(sess); | |||
| } | |||
| return accuray_test > 0.70; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| var loader = new MnistModelLoader(); | |||
| var setting = new ModelLoadSetting | |||
| { | |||
| TrainDir = ".resources/mnist", | |||
| OneHot = true, | |||
| TrainSize = train_size, | |||
| ValidationSize = validation_size, | |||
| TestSize = test_size, | |||
| ShowProgressInConsole = true | |||
| }; | |||
| mnist = loader.LoadAsync(setting).Result; | |||
| full_data_x = mnist.Train.Data; | |||
| // download graph meta data | |||
| string url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/graph/kmeans.meta"; | |||
| loader.DownloadAsync(url, ".resources/graph", "kmeans.meta").Wait(); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| tf.train.import_meta_graph(".resources/graph/kmeans.meta"); | |||
| return graph; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| var graph = tf.Graph(); | |||
| // Input images | |||
| Tensor X = graph.get_operation_by_name("Placeholder"); // tf.placeholder(tf.float32, shape: new TensorShape(-1, num_features)); | |||
| // Labels (for assigning a label to a centroid and testing) | |||
| Tensor Y = graph.get_operation_by_name("Placeholder_1"); // tf.placeholder(tf.float32, shape: new TensorShape(-1, num_classes)); | |||
| // K-Means Parameters | |||
| //var kmeans = new KMeans(X, k, distance_metric: KMeans.COSINE_DISTANCE, use_mini_batch: true); | |||
| // Build KMeans graph | |||
| //var training_graph = kmeans.training_graph(); | |||
| var init_vars = tf.global_variables_initializer(); | |||
| Tensor init_op = graph.get_operation_by_name("cond/Merge"); | |||
| var train_op = graph.get_operation_by_name("group_deps"); | |||
| Tensor avg_distance = graph.get_operation_by_name("Mean"); | |||
| Tensor cluster_idx = graph.get_operation_by_name("Squeeze_1"); | |||
| NDArray result = null; | |||
| sess.run(init_vars, new FeedItem(X, full_data_x)); | |||
| sess.run(init_op, new FeedItem(X, full_data_x)); | |||
| // Training | |||
| var sw = new Stopwatch(); | |||
| foreach (var i in range(1, num_steps + 1)) | |||
| { | |||
| sw.Restart(); | |||
| result = sess.run(new ITensorOrOperation[] { train_op, avg_distance, cluster_idx }, new FeedItem(X, full_data_x)); | |||
| sw.Stop(); | |||
| if (i % 4 == 0 || i == 1) | |||
| print($"Step {i}, Avg Distance: {result[1]} Elapse: {sw.ElapsedMilliseconds}ms"); | |||
| } | |||
| var idx = result[2].Data<int>(); | |||
| // Assign a label to each centroid | |||
| // Count total number of labels per centroid, using the label of each training | |||
| // sample to their closest centroid (given by 'idx') | |||
| var counts = np.zeros((k, num_classes), np.float32); | |||
| sw.Start(); | |||
| foreach (var i in range(idx.Count)) | |||
| { | |||
| var x = mnist.Train.Labels[i]; | |||
| counts[idx[i]] += x; | |||
| } | |||
| sw.Stop(); | |||
| print($"Assign a label to each centroid took {sw.ElapsedMilliseconds}ms"); | |||
| // Assign the most frequent label to the centroid | |||
| var labels_map_array = np.argmax(counts, 1); | |||
| var labels_map = tf.convert_to_tensor(labels_map_array); | |||
| // Evaluation ops | |||
| // Lookup: centroid_id -> label | |||
| var cluster_label = tf.nn.embedding_lookup(labels_map, cluster_idx); | |||
| // Compute accuracy | |||
| var correct_prediction = tf.equal(cluster_label, tf.cast(tf.argmax(Y, 1), tf.int32)); | |||
| var cast = tf.cast(correct_prediction, tf.float32); | |||
| var accuracy_op = tf.reduce_mean(cast); | |||
| // Test Model | |||
| var (test_x, test_y) = (mnist.Test.Data, mnist.Test.Labels); | |||
| result = sess.run(accuracy_op, new FeedItem(X, test_x), new FeedItem(Y, test_y)); | |||
| accuray_test = result; | |||
| print($"Test Accuracy: {accuray_test}"); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,145 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// A linear regression learning algorithm example using TensorFlow library. | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/linear_regression.py | |||
| /// </summary> | |||
| public class LinearRegression : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Linear Regression"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public int training_epochs = 1000; | |||
| // Parameters | |||
| float learning_rate = 0.01f; | |||
| int display_step = 50; | |||
| NumPyRandom rng = np.random; | |||
| NDArray train_X, train_Y; | |||
| int n_samples; | |||
| public bool Run() | |||
| { | |||
| // Training Data | |||
| PrepareData(); | |||
| // tf Graph Input | |||
| var X = tf.placeholder(tf.float32); | |||
| var Y = tf.placeholder(tf.float32); | |||
| // Set model weights | |||
| // We can set a fixed init value in order to debug | |||
| // var rnd1 = rng.randn<float>(); | |||
| // var rnd2 = rng.randn<float>(); | |||
| var W = tf.Variable(-0.06f, name: "weight"); | |||
| var b = tf.Variable(-0.73f, name: "bias"); | |||
| // Construct a linear model | |||
| var pred = tf.add(tf.multiply(X, W), b); | |||
| // Mean squared error | |||
| var cost = tf.reduce_sum(tf.pow(pred - Y, 2.0f)) / (2.0f * n_samples); | |||
| // Gradient descent | |||
| // Note, minimize() knows to modify W and b because Variable objects are trainable=True by default | |||
| var optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost); | |||
| // Initialize the variables (i.e. assign their default value) | |||
| var init = tf.global_variables_initializer(); | |||
| // Start training | |||
| using (var sess = tf.Session()) | |||
| { | |||
| // Run the initializer | |||
| sess.run(init); | |||
| // Fit all training data | |||
| for (int epoch = 0; epoch < training_epochs; epoch++) | |||
| { | |||
| foreach (var (x, y) in zip<float>(train_X, train_Y)) | |||
| sess.run(optimizer, (X, x), (Y, y)); | |||
| // Display logs per epoch step | |||
| if ((epoch + 1) % display_step == 0) | |||
| { | |||
| var c = sess.run(cost, (X, train_X), (Y, train_Y)); | |||
| Console.WriteLine($"Epoch: {epoch + 1} cost={c} " + $"W={sess.run(W)} b={sess.run(b)}"); | |||
| } | |||
| } | |||
| Console.WriteLine("Optimization Finished!"); | |||
| var training_cost = sess.run(cost, (X, train_X), (Y, train_Y)); | |||
| Console.WriteLine($"Training cost={training_cost} W={sess.run(W)} b={sess.run(b)}"); | |||
| // Testing example | |||
| var test_X = np.array(6.83f, 4.668f, 8.9f, 7.91f, 5.7f, 8.7f, 3.1f, 2.1f); | |||
| var test_Y = np.array(1.84f, 2.273f, 3.2f, 2.831f, 2.92f, 3.24f, 1.35f, 1.03f); | |||
| Console.WriteLine("Testing... (Mean square loss Comparison)"); | |||
| var testing_cost = sess.run(tf.reduce_sum(tf.pow(pred - Y, 2.0f)) / (2.0f * test_X.shape[0]), | |||
| (X, test_X), (Y, test_Y)); | |||
| Console.WriteLine($"Testing cost={testing_cost}"); | |||
| var diff = Math.Abs((float)training_cost - (float)testing_cost); | |||
| Console.WriteLine($"Absolute mean square loss difference: {diff}"); | |||
| return diff < 0.01; | |||
| } | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| 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); | |||
| 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); | |||
| n_samples = train_X.shape[0]; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,190 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// A logistic regression learning algorithm example using TensorFlow library. | |||
| /// This example is using the MNIST database of handwritten digits | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/logistic_regression.py | |||
| /// </summary> | |||
| public class LogisticRegression : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Logistic Regression"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public int training_epochs = 10; | |||
| public int? train_size = null; | |||
| public int validation_size = 5000; | |||
| public int? test_size = null; | |||
| public int batch_size = 100; | |||
| private float learning_rate = 0.01f; | |||
| private int display_step = 1; | |||
| Datasets<MnistDataSet> mnist; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| // tf Graph Input | |||
| var x = tf.placeholder(tf.float32, new TensorShape(-1, 784)); // mnist data image of shape 28*28=784 | |||
| var y = tf.placeholder(tf.float32, new TensorShape(-1, 10)); // 0-9 digits recognition => 10 classes | |||
| // Set model weights | |||
| var W = tf.Variable(tf.zeros(new Shape(784, 10))); | |||
| var b = tf.Variable(tf.zeros(new Shape(10))); | |||
| // Construct model | |||
| var pred = tf.nn.softmax(tf.matmul(x, W) + b); // Softmax | |||
| // Minimize error using cross entropy | |||
| var cost = tf.reduce_mean(-tf.reduce_sum(y * tf.log(pred), reduction_indices: 1)); | |||
| // Gradient Descent | |||
| var optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost); | |||
| // Initialize the variables (i.e. assign their default value) | |||
| var init = tf.global_variables_initializer(); | |||
| var sw = new Stopwatch(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| // Run the initializer | |||
| sess.run(init); | |||
| // Training cycle | |||
| foreach (var epoch in range(training_epochs)) | |||
| { | |||
| sw.Start(); | |||
| var avg_cost = 0.0f; | |||
| var total_batch = mnist.Train.NumOfExamples / batch_size; | |||
| // Loop over all batches | |||
| foreach (var i in range(total_batch)) | |||
| { | |||
| var (batch_xs, batch_ys) = mnist.Train.GetNextBatch(batch_size); | |||
| // Run optimization op (backprop) and cost op (to get loss value) | |||
| (_, float c) = sess.run((optimizer, cost), | |||
| (x, batch_xs), | |||
| (y, batch_ys)); | |||
| // Compute average loss | |||
| avg_cost += c / total_batch; | |||
| } | |||
| sw.Stop(); | |||
| // Display logs per epoch step | |||
| if ((epoch + 1) % display_step == 0) | |||
| print($"Epoch: {(epoch + 1):D4} Cost: {avg_cost:G9} Elapse: {sw.ElapsedMilliseconds}ms"); | |||
| sw.Reset(); | |||
| } | |||
| print("Optimization Finished!"); | |||
| // SaveModel(sess); | |||
| // Test model | |||
| var correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)); | |||
| // Calculate accuracy | |||
| var accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)); | |||
| float acc = accuracy.eval(sess, (x, mnist.Test.Data), (y, mnist.Test.Labels)); | |||
| print($"Accuracy: {acc:F4}"); | |||
| return acc > 0.9; | |||
| } | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| mnist = MnistModelLoader.LoadAsync(".resources/mnist", oneHot: true, trainSize: train_size, validationSize: validation_size, testSize: test_size, showProgressInConsole: true).Result; | |||
| } | |||
| public void SaveModel(Session sess) | |||
| { | |||
| var saver = tf.train.Saver(); | |||
| var save_path = saver.save(sess, ".resources/logistic_regression/model.ckpt"); | |||
| tf.train.write_graph(sess.graph, ".resources/logistic_regression", "model.pbtxt", as_text: true); | |||
| FreezeGraph.freeze_graph(input_graph: ".resources/logistic_regression/model.pbtxt", | |||
| input_saver: "", | |||
| input_binary: false, | |||
| input_checkpoint: ".resources/logistic_regression/model.ckpt", | |||
| output_node_names: "Softmax", | |||
| restore_op_name: "save/restore_all", | |||
| filename_tensor_name: "save/Const:0", | |||
| output_graph: ".resources/logistic_regression/model.pb", | |||
| clear_devices: true, | |||
| initializer_nodes: ""); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| graph.Import(Path.Join(".resources/logistic_regression", "model.pb")); | |||
| // restoring the model | |||
| // var saver = tf.train.import_meta_graph("logistic_regression/tensorflowModel.ckpt.meta"); | |||
| // saver.restore(sess, tf.train.latest_checkpoint('logistic_regression')); | |||
| var pred = graph.OperationByName("Softmax"); | |||
| var output = pred.outputs[0]; | |||
| var x = graph.OperationByName("Placeholder"); | |||
| var input = x.outputs[0]; | |||
| // predict | |||
| var (batch_xs, batch_ys) = mnist.Train.GetNextBatch(10); | |||
| var results = sess.run(output, new FeedItem(input, batch_xs[np.arange(1)])); | |||
| if (results[0].argmax() == (batch_ys[0] as NDArray).argmax()) | |||
| print("predicted OK!"); | |||
| else | |||
| throw new ValueError("predict error, should be 90% accuracy"); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,221 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using System.Collections.Generic; | |||
| using Tensorflow; | |||
| using NumSharp; | |||
| using static Tensorflow.Binding; | |||
| using System.IO; | |||
| using TensorFlowNET.Examples.Utility; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// https://github.com/nicolov/naive_bayes_tensorflow | |||
| /// </summary> | |||
| public class NaiveBayesClassifier : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Naive Bayes Classifier"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public NDArray X, y; | |||
| public Normal dist { get; set; } | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| fit(X, y); | |||
| // Create a regular grid and classify each point | |||
| float x_min = X.amin(0).Data<float>()[0] - 0.5f; | |||
| float y_min = X.amin(0).Data<float>()[1] - 0.5f; | |||
| float x_max = X.amax(0).Data<float>()[1] + 0.5f; | |||
| float y_max = X.amax(0).Data<float>()[1] + 0.5f; | |||
| var (xx, yy) = np.meshgrid(np.linspace(x_min, x_max, 30), np.linspace(y_min, y_max, 30)); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| //var samples = np.vstack<float>(xx.ravel(), yy.ravel()); | |||
| //samples = np.transpose(samples); | |||
| var array = np.Load<double[,]>(Path.Join("nb", "nb_example.npy")); | |||
| var samples = np.array(array).astype(np.float32); | |||
| var Z = sess.run(predict(samples)); | |||
| } | |||
| return true; | |||
| } | |||
| public void fit(NDArray X, NDArray y) | |||
| { | |||
| var unique_y = np.unique(y); | |||
| var dic = new Dictionary<int, List<List<float>>>(); | |||
| // Init uy in dic | |||
| foreach (int uy in unique_y.Data<int>()) | |||
| { | |||
| dic.Add(uy, new List<List<float>>()); | |||
| } | |||
| // Separate training points by class | |||
| // Shape : nb_classes * nb_samples * nb_features | |||
| int maxCount = 0; | |||
| for (int i = 0; i < y.size; i++) | |||
| { | |||
| var curClass = y[i]; | |||
| var l = dic[curClass]; | |||
| var pair = new List<float>(); | |||
| pair.Add(X[i,0]); | |||
| pair.Add(X[i, 1]); | |||
| l.Add(pair); | |||
| if (l.Count > maxCount) | |||
| { | |||
| maxCount = l.Count; | |||
| } | |||
| dic[curClass] = l; | |||
| } | |||
| float[,,] points = new float[dic.Count, maxCount, X.shape[1]]; | |||
| foreach (KeyValuePair<int, List<List<float>>> kv in dic) | |||
| { | |||
| int j = (int) kv.Key; | |||
| for (int i = 0; i < maxCount; i++) | |||
| { | |||
| for (int k = 0; k < X.shape[1]; k++) | |||
| { | |||
| points[j, i, k] = kv.Value[i][k]; | |||
| } | |||
| } | |||
| } | |||
| var points_by_class = np.array(points); | |||
| // estimate mean and variance for each class / feature | |||
| // shape : nb_classes * nb_features | |||
| var cons = tf.constant(points_by_class); | |||
| var tup = tf.nn.moments(cons, new int[]{1}); | |||
| var mean = tup.Item1; | |||
| var variance = tup.Item2; | |||
| // Create a 3x2 univariate normal distribution with the | |||
| // Known mean and variance | |||
| var dist = tf.distributions.Normal(mean, tf.sqrt(variance)); | |||
| this.dist = dist; | |||
| } | |||
| public Tensor predict(NDArray X) | |||
| { | |||
| if (dist == null) | |||
| { | |||
| throw new ArgumentNullException("cant not find the model (normal distribution)!"); | |||
| } | |||
| int nb_classes = (int) dist.scale().shape[0]; | |||
| int nb_features = (int)dist.scale().shape[1]; | |||
| // Conditional probabilities log P(x|c) with shape | |||
| // (nb_samples, nb_classes) | |||
| var t1= ops.convert_to_tensor(X, TF_DataType.TF_FLOAT); | |||
| var t2 = ops.convert_to_tensor(new int[] { 1, nb_classes }); | |||
| Tensor tile = tf.tile(t1, t2); | |||
| var t3 = ops.convert_to_tensor(new int[] { -1, nb_classes, nb_features }); | |||
| Tensor r = tf.reshape(tile, t3); | |||
| var cond_probs = tf.reduce_sum(dist.log_prob(r), 2); | |||
| // uniform priors | |||
| float[] tem = new float[nb_classes]; | |||
| for (int i = 0; i < tem.Length; i++) | |||
| { | |||
| tem[i] = 1.0f / nb_classes; | |||
| } | |||
| var priors = np.log(np.array<float>(tem)); | |||
| // posterior log probability, log P(c) + log P(x|c) | |||
| var joint_likelihood = tf.add(ops.convert_to_tensor(priors, TF_DataType.TF_FLOAT), cond_probs); | |||
| // normalize to get (log)-probabilities | |||
| var norm_factor = tf.reduce_logsumexp(joint_likelihood, new int[] { 1 }, keepdims: true); | |||
| var log_prob = joint_likelihood - norm_factor; | |||
| // exp to get the actual probabilities | |||
| return tf.exp(log_prob); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| #region Training data | |||
| X = np.array(new float[,] { | |||
| {5.1f, 3.5f}, {4.9f, 3.0f}, {4.7f, 3.2f}, {4.6f, 3.1f}, {5.0f, 3.6f}, {5.4f, 3.9f}, | |||
| {4.6f, 3.4f}, {5.0f, 3.4f}, {4.4f, 2.9f}, {4.9f, 3.1f}, {5.4f, 3.7f}, {4.8f, 3.4f}, | |||
| {4.8f, 3.0f}, {4.3f, 3.0f}, {5.8f, 4.0f}, {5.7f, 4.4f}, {5.4f, 3.9f}, {5.1f, 3.5f}, | |||
| {5.7f, 3.8f}, {5.1f, 3.8f}, {5.4f, 3.4f}, {5.1f, 3.7f}, {5.1f, 3.3f}, {4.8f, 3.4f}, | |||
| {5.0f, 3.0f}, {5.0f, 3.4f}, {5.2f, 3.5f}, {5.2f, 3.4f}, {4.7f, 3.2f}, {4.8f, 3.1f}, | |||
| {5.4f, 3.4f}, {5.2f, 4.1f}, {5.5f, 4.2f}, {4.9f, 3.1f}, {5.0f, 3.2f}, {5.5f, 3.5f}, | |||
| {4.9f, 3.6f}, {4.4f, 3.0f}, {5.1f, 3.4f}, {5.0f, 3.5f}, {4.5f, 2.3f}, {4.4f, 3.2f}, | |||
| {5.0f, 3.5f}, {5.1f, 3.8f}, {4.8f, 3.0f}, {5.1f, 3.8f}, {4.6f, 3.2f}, {5.3f, 3.7f}, | |||
| {5.0f, 3.3f}, {7.0f, 3.2f}, {6.4f, 3.2f}, {6.9f, 3.1f}, {5.5f, 2.3f}, {6.5f, 2.8f}, | |||
| {5.7f, 2.8f}, {6.3f, 3.3f}, {4.9f, 2.4f}, {6.6f, 2.9f}, {5.2f, 2.7f}, {5.0f, 2.0f}, | |||
| {5.9f, 3.0f}, {6.0f, 2.2f}, {6.1f, 2.9f}, {5.6f, 2.9f}, {6.7f, 3.1f}, {5.6f, 3.0f}, | |||
| {5.8f, 2.7f}, {6.2f, 2.2f}, {5.6f, 2.5f}, {5.9f, 3.0f}, {6.1f, 2.8f}, {6.3f, 2.5f}, | |||
| {6.1f, 2.8f}, {6.4f, 2.9f}, {6.6f, 3.0f}, {6.8f, 2.8f}, {6.7f, 3.0f}, {6.0f, 2.9f}, | |||
| {5.7f, 2.6f}, {5.5f, 2.4f}, {5.5f, 2.4f}, {5.8f, 2.7f}, {6.0f, 2.7f}, {5.4f, 3.0f}, | |||
| {6.0f, 3.4f}, {6.7f, 3.1f}, {6.3f, 2.3f}, {5.6f, 3.0f}, {5.5f, 2.5f}, {5.5f, 2.6f}, | |||
| {6.1f, 3.0f}, {5.8f, 2.6f}, {5.0f, 2.3f}, {5.6f, 2.7f}, {5.7f, 3.0f}, {5.7f, 2.9f}, | |||
| {6.2f, 2.9f}, {5.1f, 2.5f}, {5.7f, 2.8f}, {6.3f, 3.3f}, {5.8f, 2.7f}, {7.1f, 3.0f}, | |||
| {6.3f, 2.9f}, {6.5f, 3.0f}, {7.6f, 3.0f}, {4.9f, 2.5f}, {7.3f, 2.9f}, {6.7f, 2.5f}, | |||
| {7.2f, 3.6f}, {6.5f, 3.2f}, {6.4f, 2.7f}, {6.8f, 3.0f}, {5.7f, 2.5f}, {5.8f, 2.8f}, | |||
| {6.4f, 3.2f}, {6.5f, 3.0f}, {7.7f, 3.8f}, {7.7f, 2.6f}, {6.0f, 2.2f}, {6.9f, 3.2f}, | |||
| {5.6f, 2.8f}, {7.7f, 2.8f}, {6.3f, 2.7f}, {6.7f, 3.3f}, {7.2f, 3.2f}, {6.2f, 2.8f}, | |||
| {6.1f, 3.0f}, {6.4f, 2.8f}, {7.2f, 3.0f}, {7.4f, 2.8f}, {7.9f, 3.8f}, {6.4f, 2.8f}, | |||
| {6.3f, 2.8f}, {6.1f, 2.6f}, {7.7f, 3.0f}, {6.3f, 3.4f}, {6.4f, 3.1f}, {6.0f, 3.0f}, | |||
| {6.9f, 3.1f}, {6.7f, 3.1f}, {6.9f, 3.1f}, {5.8f, 2.7f}, {6.8f, 3.2f}, {6.7f, 3.3f}, | |||
| {6.7f, 3.0f}, {6.3f, 2.5f}, {6.5f, 3.0f}, {6.2f, 3.4f}, {5.9f, 3.0f}, {5.8f, 3.0f}}); | |||
| y = np.array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); | |||
| string url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/data/nb_example.npy"; | |||
| Web.Download(url, "nb", "nb_example.npy"); | |||
| #endregion | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,118 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// A nearest neighbor learning algorithm example | |||
| /// This example is using the MNIST database of handwritten digits | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/nearest_neighbor.py | |||
| /// </summary> | |||
| public class NearestNeighbor : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Nearest Neighbor"; | |||
| Datasets<MnistDataSet> mnist; | |||
| NDArray Xtr, Ytr, Xte, Yte; | |||
| public int? TrainSize = null; | |||
| public int ValidationSize = 5000; | |||
| public int? TestSize = null; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public bool Run() | |||
| { | |||
| // tf Graph Input | |||
| var xtr = tf.placeholder(tf.float32, new TensorShape(-1, 784)); | |||
| var xte = tf.placeholder(tf.float32, new TensorShape(784)); | |||
| // Nearest Neighbor calculation using L1 Distance | |||
| // Calculate L1 Distance | |||
| var distance = tf.reduce_sum(tf.abs(tf.add(xtr, tf.negative(xte))), reduction_indices: 1); | |||
| // Prediction: Get min distance index (Nearest neighbor) | |||
| var pred = tf.arg_min(distance, 0); | |||
| float accuracy = 0f; | |||
| // Initialize the variables (i.e. assign their default value) | |||
| var init = tf.global_variables_initializer(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| // Run the initializer | |||
| sess.run(init); | |||
| PrepareData(); | |||
| foreach(int i in range(Xte.shape[0])) | |||
| { | |||
| // Get nearest neighbor | |||
| long nn_index = sess.run(pred, (xtr, Xtr), (xte, Xte[i])); | |||
| // Get nearest neighbor class label and compare it to its true label | |||
| int index = (int)nn_index; | |||
| if (i % 10 == 0 || i == 0) | |||
| print($"Test {i} Prediction: {np.argmax(Ytr[index])} True Class: {np.argmax(Yte[i])}"); | |||
| // Calculate accuracy | |||
| if (np.argmax(Ytr[index]) == np.argmax(Yte[i])) | |||
| accuracy += 1f/ Xte.shape[0]; | |||
| } | |||
| print($"Accuracy: {accuracy}"); | |||
| } | |||
| return accuracy > 0.8; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| mnist = MnistModelLoader.LoadAsync(".resources/mnist", oneHot: true, trainSize: TrainSize, validationSize: ValidationSize, testSize: TestSize, showProgressInConsole: true).Result; | |||
| // In this example, we limit mnist data | |||
| (Xtr, Ytr) = mnist.Train.GetNextBatch(TrainSize == null ? 5000 : TrainSize.Value / 100); // 5000 for training (nn candidates) | |||
| (Xte, Yte) = mnist.Test.GetNextBatch(TestSize == null ? 200 : TestSize.Value / 100); // 200 for testing | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,187 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Basic Operations example using TensorFlow library. | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/1_Introduction/basic_operations.py | |||
| /// </summary> | |||
| public class BasicOperations : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Basic Operations"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| private Session sess; | |||
| public bool Run() | |||
| { | |||
| // Basic constant operations | |||
| // The value returned by the constructor represents the output | |||
| // of the Constant op. | |||
| var a = tf.constant(2); | |||
| var b = tf.constant(3); | |||
| // Launch the default graph. | |||
| using (sess = tf.Session()) | |||
| { | |||
| Console.WriteLine("a=2, b=3"); | |||
| Console.WriteLine($"Addition with constants: {sess.run(a + b)}"); | |||
| Console.WriteLine($"Multiplication with constants: {sess.run(a * b)}"); | |||
| } | |||
| // Basic Operations with variable as graph input | |||
| // The value returned by the constructor represents the output | |||
| // of the Variable op. (define as input when running session) | |||
| // tf Graph input | |||
| a = tf.placeholder(tf.int16); | |||
| b = tf.placeholder(tf.int16); | |||
| // Define some operations | |||
| var add = tf.add(a, b); | |||
| var mul = tf.multiply(a, b); | |||
| // Launch the default graph. | |||
| using(sess = tf.Session()) | |||
| { | |||
| var feed_dict = new FeedItem[] | |||
| { | |||
| new FeedItem(a, (short)2), | |||
| new FeedItem(b, (short)3) | |||
| }; | |||
| // Run every operation with variable input | |||
| Console.WriteLine($"Addition with variables: {sess.run(add, feed_dict)}"); | |||
| Console.WriteLine($"Multiplication with variables: {sess.run(mul, feed_dict)}"); | |||
| } | |||
| // ---------------- | |||
| // More in details: | |||
| // Matrix Multiplication from TensorFlow official tutorial | |||
| // Create a Constant op that produces a 1x2 matrix. The op is | |||
| // added as a node to the default graph. | |||
| // | |||
| // The value returned by the constructor represents the output | |||
| // of the Constant op. | |||
| var nd1 = np.array(3, 3).reshape(1, 2); | |||
| var matrix1 = tf.constant(nd1); | |||
| // Create another Constant that produces a 2x1 matrix. | |||
| var nd2 = np.array(2, 2).reshape(2, 1); | |||
| var matrix2 = tf.constant(nd2); | |||
| // Create a Matmul op that takes 'matrix1' and 'matrix2' as inputs. | |||
| // The returned value, 'product', represents the result of the matrix | |||
| // multiplication. | |||
| var product = tf.matmul(matrix1, matrix2); | |||
| // To run the matmul op we call the session 'run()' method, passing 'product' | |||
| // which represents the output of the matmul op. This indicates to the call | |||
| // that we want to get the output of the matmul op back. | |||
| // | |||
| // All inputs needed by the op are run automatically by the session. They | |||
| // typically are run in parallel. | |||
| // | |||
| // The call 'run(product)' thus causes the execution of threes ops in the | |||
| // graph: the two constants and matmul. | |||
| // | |||
| // The output of the op is returned in 'result' as a numpy `ndarray` object. | |||
| using (sess = tf.Session()) | |||
| { | |||
| var result = sess.run(product); | |||
| Console.WriteLine(result.ToString()); // ==> [[ 12.]] | |||
| }; | |||
| // `BatchMatMul` is actually embedded into the `MatMul` operation on the tf.dll side. Every time we ask | |||
| // for a multiplication between matrices with rank > 2, the first rank - 2 dimensions are checked to be consistent | |||
| // across the two matrices and a common matrix multiplication is done on the residual 2 dimensions. | |||
| // | |||
| // np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]).reshape(3, 3, 3) | |||
| // array([[[1, 2, 3], | |||
| // [4, 5, 6], | |||
| // [7, 8, 9]], | |||
| // | |||
| // [[1, 2, 3], | |||
| // [4, 5, 6], | |||
| // [7, 8, 9]], | |||
| // | |||
| // [[1, 2, 3], | |||
| // [4, 5, 6], | |||
| // [7, 8, 9]]]) | |||
| var firstTensor = tf.convert_to_tensor( | |||
| np.reshape( | |||
| np.array<float>(1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9), | |||
| 3, 3, 3)); | |||
| // | |||
| // np.array([0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0]).reshape(3,3,2) | |||
| // array([[[0, 1], | |||
| // [0, 1], | |||
| // [0, 1]], | |||
| // | |||
| // [[0, 1], | |||
| // [0, 0], | |||
| // [1, 0]], | |||
| // | |||
| // [[1, 0], | |||
| // [1, 0], | |||
| // [1, 0]]]) | |||
| var secondTensor = tf.convert_to_tensor( | |||
| np.reshape( | |||
| np.array<float>(0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0), | |||
| 3, 3, 2)); | |||
| var batchMul = tf.batch_matmul(firstTensor, secondTensor); | |||
| var checkTensor = np.array<float>(0, 6, 0, 15, 0, 24, 3, 1, 6, 4, 9, 7, 6, 0, 15, 0, 24, 0); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| var result = sess.run(batchMul); | |||
| Console.WriteLine(result.ToString()); | |||
| // | |||
| // ==> array([[[0, 6], | |||
| // [0, 15], | |||
| // [0, 24]], | |||
| // | |||
| // [[ 3, 1], | |||
| // [ 6, 4], | |||
| // [ 9, 7]], | |||
| // | |||
| // [[ 6, 0], | |||
| // [15, 0], | |||
| // [24, 0]]]) | |||
| return np.reshape(result, 18) | |||
| .array_equal(checkTensor); | |||
| } | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,66 +0,0 @@ | |||
| using System; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Simple hello world using TensorFlow | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/1_Introduction/helloworld.py | |||
| /// </summary> | |||
| public class HelloWorld : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Hello World"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public bool Run() | |||
| { | |||
| /* Create a Constant op | |||
| The op is added as a node to the default graph. | |||
| The value returned by the constructor represents the output | |||
| of the Constant op. */ | |||
| var str = "Hello, TensorFlow.NET!"; | |||
| var hello = tf.constant(str); | |||
| // Start tf session | |||
| using (var sess = tf.Session()) | |||
| { | |||
| // Run the op | |||
| var result = sess.run(hello); | |||
| Console.WriteLine(result.ToString()); | |||
| return result.ToString().Equals(str); | |||
| } | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,59 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Interface of Example project | |||
| /// All example should implement IExample so the entry program will find it. | |||
| /// </summary> | |||
| public interface IExample | |||
| { | |||
| /// <summary> | |||
| /// True to run example | |||
| /// </summary> | |||
| bool Enabled { get; set; } | |||
| /// <summary> | |||
| /// Set true to import the computation graph instead of building it. | |||
| /// </summary> | |||
| bool IsImportingGraph { get; set; } | |||
| string Name { get; } | |||
| bool Run(); | |||
| /// <summary> | |||
| /// Build dataflow graph, train and predict | |||
| /// </summary> | |||
| /// <returns></returns> | |||
| void Train(Session sess); | |||
| void Test(Session sess); | |||
| void Predict(Session sess); | |||
| Graph ImportGraph(); | |||
| Graph BuildGraph(); | |||
| /// <summary> | |||
| /// Prepare dataset | |||
| /// </summary> | |||
| void PrepareData(); | |||
| } | |||
| } | |||
| @@ -1,73 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using TensorFlowDatasets; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// https://www.tensorflow.org/tutorials/images/deep_cnn | |||
| /// </summary> | |||
| public class CIFAR10_CNN : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "CIFAR-10 CNN"; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| return true; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| var tfds = new DatasetBuilder(); | |||
| tfds.download_and_prepare(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,338 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Convolutional Neural Network classifier for Hand Written Digits | |||
| /// CNN architecture with two convolutional layers, followed by two fully-connected layers at the end. | |||
| /// Use Stochastic Gradient Descent (SGD) optimizer. | |||
| /// http://www.easy-tf.com/tf-tutorials/convolutional-neural-nets-cnns/cnn1 | |||
| /// </summary> | |||
| public class DigitRecognitionCNN : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "MNIST CNN"; | |||
| string logs_path = "logs"; | |||
| const int img_h = 28, img_w = 28; // MNIST images are 28x28 | |||
| int n_classes = 10; // Number of classes, one class per digit | |||
| int n_channels = 1; | |||
| // Hyper-parameters | |||
| int epochs = 5; // accuracy > 98% | |||
| int batch_size = 100; | |||
| float learning_rate = 0.001f; | |||
| Datasets<MnistDataSet> mnist; | |||
| // Network configuration | |||
| // 1st Convolutional Layer | |||
| int filter_size1 = 5; // Convolution filters are 5 x 5 pixels. | |||
| int num_filters1 = 16; // There are 16 of these filters. | |||
| int stride1 = 1; // The stride of the sliding window | |||
| // 2nd Convolutional Layer | |||
| int filter_size2 = 5; // Convolution filters are 5 x 5 pixels. | |||
| int num_filters2 = 32;// There are 32 of these filters. | |||
| int stride2 = 1; // The stride of the sliding window | |||
| // Fully-connected layer. | |||
| int h1 = 128; // Number of neurons in fully-connected layer. | |||
| Tensor x, y; | |||
| Tensor loss, accuracy, cls_prediction; | |||
| Operation optimizer; | |||
| int display_freq = 100; | |||
| float accuracy_test = 0f; | |||
| float loss_test = 1f; | |||
| NDArray x_train, y_train; | |||
| NDArray x_valid, y_valid; | |||
| NDArray x_test, y_test; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| BuildGraph(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| Train(sess); | |||
| Test(sess); | |||
| } | |||
| return loss_test < 0.05 && accuracy_test > 0.98; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| tf_with(tf.name_scope("Input"), delegate | |||
| { | |||
| // Placeholders for inputs (x) and outputs(y) | |||
| x = tf.placeholder(tf.float32, shape: (-1, img_h, img_w, n_channels), name: "X"); | |||
| y = tf.placeholder(tf.float32, shape: (-1, n_classes), name: "Y"); | |||
| }); | |||
| var conv1 = conv_layer(x, filter_size1, num_filters1, stride1, name: "conv1"); | |||
| var pool1 = max_pool(conv1, ksize: 2, stride: 2, name: "pool1"); | |||
| var conv2 = conv_layer(pool1, filter_size2, num_filters2, stride2, name: "conv2"); | |||
| var pool2 = max_pool(conv2, ksize: 2, stride: 2, name: "pool2"); | |||
| var layer_flat = flatten_layer(pool2); | |||
| var fc1 = fc_layer(layer_flat, h1, "FC1", use_relu: true); | |||
| var output_logits = fc_layer(fc1, n_classes, "OUT", use_relu: false); | |||
| tf_with(tf.variable_scope("Train"), delegate | |||
| { | |||
| tf_with(tf.variable_scope("Loss"), delegate | |||
| { | |||
| loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels: y, logits: output_logits), name: "loss"); | |||
| }); | |||
| tf_with(tf.variable_scope("Optimizer"), delegate | |||
| { | |||
| optimizer = tf.train.AdamOptimizer(learning_rate: learning_rate, name: "Adam-op").minimize(loss); | |||
| }); | |||
| tf_with(tf.variable_scope("Accuracy"), delegate | |||
| { | |||
| var correct_prediction = tf.equal(tf.argmax(output_logits, 1), tf.argmax(y, 1), name: "correct_pred"); | |||
| accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name: "accuracy"); | |||
| }); | |||
| tf_with(tf.variable_scope("Prediction"), delegate | |||
| { | |||
| cls_prediction = tf.argmax(output_logits, axis: 1, name: "predictions"); | |||
| }); | |||
| }); | |||
| return graph; | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| // Number of training iterations in each epoch | |||
| var num_tr_iter = y_train.shape[0] / batch_size; | |||
| var init = tf.global_variables_initializer(); | |||
| sess.run(init); | |||
| float loss_val = 100.0f; | |||
| float accuracy_val = 0f; | |||
| var sw = new Stopwatch(); | |||
| sw.Start(); | |||
| foreach (var epoch in range(epochs)) | |||
| { | |||
| print($"Training epoch: {epoch + 1}"); | |||
| // Randomly shuffle the training data at the beginning of each epoch | |||
| (x_train, y_train) = mnist.Randomize(x_train, y_train); | |||
| foreach (var iteration in range(num_tr_iter)) | |||
| { | |||
| var start = iteration * batch_size; | |||
| var end = (iteration + 1) * batch_size; | |||
| var (x_batch, y_batch) = mnist.GetNextBatch(x_train, y_train, start, end); | |||
| // Run optimization op (backprop) | |||
| sess.run(optimizer, (x, x_batch), (y, y_batch)); | |||
| if (iteration % display_freq == 0) | |||
| { | |||
| // Calculate and display the batch loss and accuracy | |||
| var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||
| loss_val = result[0]; | |||
| accuracy_val = result[1]; | |||
| print($"iter {iteration.ToString("000")}: Loss={loss_val.ToString("0.0000")}, Training Accuracy={accuracy_val.ToString("P")} {sw.ElapsedMilliseconds}ms"); | |||
| sw.Restart(); | |||
| } | |||
| } | |||
| // Run validation after every epoch | |||
| (loss_val, accuracy_val) = sess.run((loss, accuracy), (x, x_valid), (y, y_valid)); | |||
| print("---------------------------------------------------------"); | |||
| print($"Epoch: {epoch + 1}, validation loss: {loss_val.ToString("0.0000")}, validation accuracy: {accuracy_val.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| (loss_test, accuracy_test) = sess.run((loss, accuracy), (x, x_test), (y, y_test)); | |||
| print("---------------------------------------------------------"); | |||
| print($"Test loss: {loss_test.ToString("0.0000")}, test accuracy: {accuracy_test.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| /// <summary> | |||
| /// Create a 2D convolution layer | |||
| /// </summary> | |||
| /// <param name="x">input from previous layer</param> | |||
| /// <param name="filter_size">size of each filter</param> | |||
| /// <param name="num_filters">number of filters(or output feature maps)</param> | |||
| /// <param name="stride">filter stride</param> | |||
| /// <param name="name">layer name</param> | |||
| /// <returns>The output array</returns> | |||
| private Tensor conv_layer(Tensor x, int filter_size, int num_filters, int stride, string name) | |||
| { | |||
| return tf_with(tf.variable_scope(name), delegate { | |||
| var num_in_channel = x.shape[x.NDims - 1]; | |||
| var shape = new[] { filter_size, filter_size, num_in_channel, num_filters }; | |||
| var W = weight_variable("W", shape); | |||
| // var tf.summary.histogram("weight", W); | |||
| var b = bias_variable("b", new[] { num_filters }); | |||
| // tf.summary.histogram("bias", b); | |||
| var layer = tf.nn.conv2d(x, W, | |||
| strides: new[] { 1, stride, stride, 1 }, | |||
| padding: "SAME"); | |||
| layer += b; | |||
| return tf.nn.relu(layer); | |||
| }); | |||
| } | |||
| /// <summary> | |||
| /// Create a max pooling layer | |||
| /// </summary> | |||
| /// <param name="x">input to max-pooling layer</param> | |||
| /// <param name="ksize">size of the max-pooling filter</param> | |||
| /// <param name="stride">stride of the max-pooling filter</param> | |||
| /// <param name="name">layer name</param> | |||
| /// <returns>The output array</returns> | |||
| private Tensor max_pool(Tensor x, int ksize, int stride, string name) | |||
| { | |||
| return tf.nn.max_pool(x, | |||
| ksize: new[] { 1, ksize, ksize, 1 }, | |||
| strides: new[] { 1, stride, stride, 1 }, | |||
| padding: "SAME", | |||
| name: name); | |||
| } | |||
| /// <summary> | |||
| /// Flattens the output of the convolutional layer to be fed into fully-connected layer | |||
| /// </summary> | |||
| /// <param name="layer">input array</param> | |||
| /// <returns>flattened array</returns> | |||
| private Tensor flatten_layer(Tensor layer) | |||
| { | |||
| return tf_with(tf.variable_scope("Flatten_layer"), delegate | |||
| { | |||
| var layer_shape = layer.TensorShape; | |||
| var num_features = layer_shape[new Slice(1, 4)].size; | |||
| var layer_flat = tf.reshape(layer, new[] { -1, num_features }); | |||
| return layer_flat; | |||
| }); | |||
| } | |||
| /// <summary> | |||
| /// Create a weight variable with appropriate initialization | |||
| /// </summary> | |||
| /// <param name="name"></param> | |||
| /// <param name="shape"></param> | |||
| /// <returns></returns> | |||
| private RefVariable weight_variable(string name, int[] shape) | |||
| { | |||
| var initer = tf.truncated_normal_initializer(stddev: 0.01f); | |||
| return tf.get_variable(name, | |||
| dtype: tf.float32, | |||
| shape: shape, | |||
| initializer: initer); | |||
| } | |||
| /// <summary> | |||
| /// Create a bias variable with appropriate initialization | |||
| /// </summary> | |||
| /// <param name="name"></param> | |||
| /// <param name="shape"></param> | |||
| /// <returns></returns> | |||
| private RefVariable bias_variable(string name, int[] shape) | |||
| { | |||
| var initial = tf.constant(0f, shape: shape, dtype: tf.float32); | |||
| return tf.get_variable(name, | |||
| dtype: tf.float32, | |||
| initializer: initial); | |||
| } | |||
| /// <summary> | |||
| /// Create a fully-connected layer | |||
| /// </summary> | |||
| /// <param name="x">input from previous layer</param> | |||
| /// <param name="num_units">number of hidden units in the fully-connected layer</param> | |||
| /// <param name="name">layer name</param> | |||
| /// <param name="use_relu">boolean to add ReLU non-linearity (or not)</param> | |||
| /// <returns>The output array</returns> | |||
| private Tensor fc_layer(Tensor x, int num_units, string name, bool use_relu = true) | |||
| { | |||
| return tf_with(tf.variable_scope(name), delegate | |||
| { | |||
| var in_dim = x.shape[1]; | |||
| var W = weight_variable("W_" + name, shape: new[] { in_dim, num_units }); | |||
| var b = bias_variable("b_" + name, new[] { num_units }); | |||
| var layer = tf.matmul(x, W) + b; | |||
| if (use_relu) | |||
| layer = tf.nn.relu(layer); | |||
| return layer; | |||
| }); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| mnist = MnistModelLoader.LoadAsync(".resources/mnist", oneHot: true, showProgressInConsole: true).Result; | |||
| (x_train, y_train) = Reformat(mnist.Train.Data, mnist.Train.Labels); | |||
| (x_valid, y_valid) = Reformat(mnist.Validation.Data, mnist.Validation.Labels); | |||
| (x_test, y_test) = Reformat(mnist.Test.Data, mnist.Test.Labels); | |||
| print("Size of:"); | |||
| print($"- Training-set:\t\t{len(mnist.Train.Data)}"); | |||
| print($"- Validation-set:\t{len(mnist.Validation.Data)}"); | |||
| } | |||
| /// <summary> | |||
| /// Reformats the data to the format acceptable for convolutional layers | |||
| /// </summary> | |||
| /// <param name="x"></param> | |||
| /// <param name="y"></param> | |||
| /// <returns></returns> | |||
| private (NDArray, NDArray) Reformat(NDArray x, NDArray y) | |||
| { | |||
| var (img_size, num_ch, num_class) = (np.sqrt(x.shape[1]).astype(np.int32), 1, len(np.unique(np.argmax(y, 1)))); | |||
| var dataset = x.reshape(x.shape[0], img_size, img_size, num_ch).astype(np.float32); | |||
| //y[0] = np.arange(num_class) == y[0]; | |||
| //var labels = (np.arange(num_class) == y.reshape(y.shape[0], 1, y.shape[1])).astype(np.float32); | |||
| return (dataset, y); | |||
| } | |||
| public Graph ImportGraph() => throw new NotImplementedException(); | |||
| public void Predict(Session sess) => throw new NotImplementedException(); | |||
| } | |||
| } | |||
| @@ -1,182 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Neural Network classifier for Hand Written Digits | |||
| /// Sample Neural Network architecture with two layers implemented for classifying MNIST digits. | |||
| /// Use Stochastic Gradient Descent (SGD) optimizer. | |||
| /// http://www.easy-tf.com/tf-tutorials/neural-networks | |||
| /// </summary> | |||
| public class DigitRecognitionNN : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "Digits Recognition Neural Network"; | |||
| const int img_h = 28; | |||
| const int img_w = 28; | |||
| int img_size_flat = img_h * img_w; // 784, the total number of pixels | |||
| int n_classes = 10; // Number of classes, one class per digit | |||
| // Hyper-parameters | |||
| int epochs = 10; | |||
| int batch_size = 100; | |||
| float learning_rate = 0.001f; | |||
| int h1 = 200; // number of nodes in the 1st hidden layer | |||
| Datasets<MnistDataSet> mnist; | |||
| Tensor x, y; | |||
| Tensor loss, accuracy; | |||
| Operation optimizer; | |||
| int display_freq = 100; | |||
| float accuracy_test = 0f; | |||
| float loss_test = 1f; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| BuildGraph(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| Train(sess); | |||
| Test(sess); | |||
| }; | |||
| return loss_test < 0.09 && accuracy_test > 0.95; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| // Placeholders for inputs (x) and outputs(y) | |||
| x = tf.placeholder(tf.float32, shape: (-1, img_size_flat), name: "X"); | |||
| y = tf.placeholder(tf.float32, shape: (-1, n_classes), name: "Y"); | |||
| // Create a fully-connected layer with h1 nodes as hidden layer | |||
| var fc1 = fc_layer(x, h1, "FC1", use_relu: true); | |||
| // Create a fully-connected layer with n_classes nodes as output layer | |||
| var output_logits = fc_layer(fc1, n_classes, "OUT", use_relu: false); | |||
| // Define the loss function, optimizer, and accuracy | |||
| var logits = tf.nn.softmax_cross_entropy_with_logits(labels: y, logits: output_logits); | |||
| loss = tf.reduce_mean(logits, name: "loss"); | |||
| optimizer = tf.train.AdamOptimizer(learning_rate: learning_rate, name: "Adam-op").minimize(loss); | |||
| var correct_prediction = tf.equal(tf.argmax(output_logits, 1), tf.argmax(y, 1), name: "correct_pred"); | |||
| accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name: "accuracy"); | |||
| // Network predictions | |||
| var cls_prediction = tf.argmax(output_logits, axis: 1, name: "predictions"); | |||
| return graph; | |||
| } | |||
| private Tensor fc_layer(Tensor x, int num_units, string name, bool use_relu = true) | |||
| { | |||
| var in_dim = x.shape[1]; | |||
| var initer = tf.truncated_normal_initializer(stddev: 0.01f); | |||
| var W = tf.get_variable("W_" + name, | |||
| dtype: tf.float32, | |||
| shape: (in_dim, num_units), | |||
| initializer: initer); | |||
| var initial = tf.constant(0f, num_units); | |||
| var b = tf.get_variable("b_" + name, | |||
| dtype: tf.float32, | |||
| initializer: initial); | |||
| var layer = tf.matmul(x, W) + b; | |||
| if (use_relu) | |||
| layer = tf.nn.relu(layer); | |||
| return layer; | |||
| } | |||
| public Graph ImportGraph() => throw new NotImplementedException(); | |||
| public void Predict(Session sess) => throw new NotImplementedException(); | |||
| public void PrepareData() | |||
| { | |||
| mnist = MnistModelLoader.LoadAsync(".resources/mnist", oneHot: true, showProgressInConsole: true).Result; | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| // Number of training iterations in each epoch | |||
| var num_tr_iter = mnist.Train.Labels.shape[0] / batch_size; | |||
| var init = tf.global_variables_initializer(); | |||
| sess.run(init); | |||
| float loss_val = 100.0f; | |||
| float accuracy_val = 0f; | |||
| var sw = new Stopwatch(); | |||
| sw.Start(); | |||
| foreach (var epoch in range(epochs)) | |||
| { | |||
| print($"Training epoch: {epoch + 1}"); | |||
| // Randomly shuffle the training data at the beginning of each epoch | |||
| var (x_train, y_train) = mnist.Randomize(mnist.Train.Data, mnist.Train.Labels); | |||
| foreach (var iteration in range(num_tr_iter)) | |||
| { | |||
| var start = iteration * batch_size; | |||
| var end = (iteration + 1) * batch_size; | |||
| var (x_batch, y_batch) = mnist.GetNextBatch(x_train, y_train, start, end); | |||
| // Run optimization op (backprop) | |||
| sess.run(optimizer, (x, x_batch), (y, y_batch)); | |||
| if (iteration % display_freq == 0) | |||
| { | |||
| // Calculate and display the batch loss and accuracy | |||
| (loss_val, accuracy_val) = sess.run((loss, accuracy), (x, x_batch), (y, y_batch)); | |||
| print($"iter {iteration.ToString("000")}: Loss={loss_val.ToString("0.0000")}, Training Accuracy={accuracy_val.ToString("P")} {sw.ElapsedMilliseconds}ms"); | |||
| sw.Restart(); | |||
| } | |||
| } | |||
| // Run validation after every epoch | |||
| (loss_val, accuracy_val) = sess.run((loss, accuracy), (x, mnist.Validation.Data), (y, mnist.Validation.Labels)); | |||
| print("---------------------------------------------------------"); | |||
| print($"Epoch: {epoch + 1}, validation loss: {loss_val.ToString("0.0000")}, validation accuracy: {accuracy_val.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| (loss_test, accuracy_test) = sess.run((loss, accuracy), (x, mnist.Test.Data), (y, mnist.Test.Labels)); | |||
| print("---------------------------------------------------------"); | |||
| print($"Test loss: {loss_test.ToString("0.0000")}, test accuracy: {accuracy_test.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,161 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using Tensorflow; | |||
| using Tensorflow.Hub; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Recurrent Neural Network for handwritten digits MNIST. | |||
| /// https://medium.com/machine-learning-algorithms/mnist-using-recurrent-neural-network-2d070a5915a2 | |||
| /// </summary> | |||
| public class DigitRecognitionRNN : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "MNIST RNN"; | |||
| string logs_path = "logs"; | |||
| // Hyper-parameters | |||
| int n_neurons = 128; | |||
| float learning_rate = 0.001f; | |||
| int batch_size = 128; | |||
| int epochs = 10; | |||
| int n_steps = 28; | |||
| int n_inputs = 28; | |||
| int n_outputs = 10; | |||
| Datasets<MnistDataSet> mnist; | |||
| Tensor x, y; | |||
| Tensor loss, accuracy, cls_prediction; | |||
| Operation optimizer; | |||
| int display_freq = 100; | |||
| float accuracy_test = 0f; | |||
| float loss_test = 1f; | |||
| NDArray x_train, y_train; | |||
| NDArray x_valid, y_valid; | |||
| NDArray x_test, y_test; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| BuildGraph(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| Train(sess); | |||
| Test(sess); | |||
| } | |||
| return loss_test < 0.09 && accuracy_test > 0.95; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| var X = tf.placeholder(tf.float32, new[] { -1, n_steps, n_inputs }); | |||
| var y = tf.placeholder(tf.int32, new[] { -1 }); | |||
| var cell = tf.nn.rnn_cell.BasicRNNCell(num_units: n_neurons); | |||
| var (output, state) = tf.nn.dynamic_rnn(cell, X, dtype: tf.float32); | |||
| return graph; | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| // Number of training iterations in each epoch | |||
| var num_tr_iter = y_train.shape[0] / batch_size; | |||
| var init = tf.global_variables_initializer(); | |||
| sess.run(init); | |||
| float loss_val = 100.0f; | |||
| float accuracy_val = 0f; | |||
| foreach (var epoch in range(epochs)) | |||
| { | |||
| print($"Training epoch: {epoch + 1}"); | |||
| // Randomly shuffle the training data at the beginning of each epoch | |||
| (x_train, y_train) = mnist.Randomize(x_train, y_train); | |||
| foreach (var iteration in range(num_tr_iter)) | |||
| { | |||
| var start = iteration * batch_size; | |||
| var end = (iteration + 1) * batch_size; | |||
| var (x_batch, y_batch) = mnist.GetNextBatch(x_train, y_train, start, end); | |||
| // Run optimization op (backprop) | |||
| sess.run(optimizer, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||
| if (iteration % display_freq == 0) | |||
| { | |||
| // Calculate and display the batch loss and accuracy | |||
| var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_batch), new FeedItem(y, y_batch)); | |||
| loss_val = result[0]; | |||
| accuracy_val = result[1]; | |||
| print($"iter {iteration.ToString("000")}: Loss={loss_val.ToString("0.0000")}, Training Accuracy={accuracy_val.ToString("P")}"); | |||
| } | |||
| } | |||
| // Run validation after every epoch | |||
| var results1 = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_valid), new FeedItem(y, y_valid)); | |||
| loss_val = results1[0]; | |||
| accuracy_val = results1[1]; | |||
| print("---------------------------------------------------------"); | |||
| print($"Epoch: {epoch + 1}, validation loss: {loss_val.ToString("0.0000")}, validation accuracy: {accuracy_val.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| var result = sess.run(new[] { loss, accuracy }, new FeedItem(x, x_test), new FeedItem(y, y_test)); | |||
| loss_test = result[0]; | |||
| accuracy_test = result[1]; | |||
| print("---------------------------------------------------------"); | |||
| print($"Test loss: {loss_test.ToString("0.0000")}, test accuracy: {accuracy_test.ToString("P")}"); | |||
| print("---------------------------------------------------------"); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| mnist = MnistModelLoader.LoadAsync(".resources/mnist", oneHot: true, showProgressInConsole: true).Result; | |||
| (x_train, y_train) = (mnist.Train.Data, mnist.Train.Labels); | |||
| (x_valid, y_valid) = (mnist.Validation.Data, mnist.Validation.Labels); | |||
| (x_test, y_test) = (mnist.Test.Data, mnist.Test.Labels); | |||
| print("Size of:"); | |||
| print($"- Training-set:\t\t{len(mnist.Train.Data)}"); | |||
| print($"- Validation-set:\t{len(mnist.Validation.Data)}"); | |||
| print($"- Test-set:\t\t{len(mnist.Test.Data)}"); | |||
| } | |||
| public Graph ImportGraph() => throw new NotImplementedException(); | |||
| public void Predict(Session sess) => throw new NotImplementedException(); | |||
| } | |||
| } | |||
| @@ -1,84 +0,0 @@ | |||
| using System; | |||
| using System.IO; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// This example removes the background from an input image. | |||
| /// | |||
| /// https://github.com/susheelsk/image-background-removal | |||
| /// </summary> | |||
| public class ImageBackgroundRemoval : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public string Name => "Image Background Removal"; | |||
| string dataDir = "deeplabv3"; | |||
| string modelDir = "deeplabv3_mnv2_pascal_train_aug"; | |||
| string modelName = "frozen_inference_graph.pb"; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| // import GraphDef from pb file | |||
| var graph = new Graph().as_default(); | |||
| graph.Import(Path.Join(dataDir, modelDir, modelName)); | |||
| Tensor output = graph.OperationByName("SemanticPredictions"); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| // Runs inference on a single image. | |||
| sess.run(output, new FeedItem(output, "[np.asarray(resized_image)]")); | |||
| } | |||
| return false; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // get mobile_net_model file | |||
| string fileName = "deeplabv3_mnv2_pascal_train_aug_2018_01_29.tar.gz"; | |||
| string url = $"http://download.tensorflow.org/models/{fileName}"; | |||
| Web.Download(url, dataDir, fileName); | |||
| Compress.ExtractTGZ(Path.Join(dataDir, fileName), dataDir); | |||
| // xception_model, better accuracy | |||
| /*fileName = "deeplabv3_pascal_train_aug_2018_01_04.tar.gz"; | |||
| url = $"http://download.tensorflow.org/models/{fileName}"; | |||
| Web.Download(url, modelDir, fileName); | |||
| Compress.ExtractTGZ(Path.Join(modelDir, fileName), modelDir);*/ | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,140 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using Console = Colorful.Console; | |||
| using Tensorflow; | |||
| using System.Drawing; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Inception v3 is a widely-used image recognition model | |||
| /// that has been shown to attain greater than 78.1% accuracy on the ImageNet dataset. | |||
| /// The model is the culmination of many ideas developed by multiple researchers over the years. | |||
| /// </summary> | |||
| public class ImageRecognitionInception : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Image Recognition Inception"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| string dir = "ImageRecognitionInception"; | |||
| string pbFile = "tensorflow_inception_graph.pb"; | |||
| string labelFile = "imagenet_comp_graph_label_strings.txt"; | |||
| List<NDArray> file_ndarrays = new List<NDArray>(); | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = new Graph(); | |||
| //import GraphDef from pb file | |||
| graph.Import(Path.Join(dir, pbFile)); | |||
| var input_name = "input"; | |||
| var output_name = "output"; | |||
| var input_operation = graph.OperationByName(input_name); | |||
| var output_operation = graph.OperationByName(output_name); | |||
| var labels = File.ReadAllLines(Path.Join(dir, labelFile)); | |||
| var result_labels = new List<string>(); | |||
| var sw = new Stopwatch(); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| foreach (var nd in file_ndarrays) | |||
| { | |||
| sw.Restart(); | |||
| var results = sess.run(output_operation.outputs[0], (input_operation.outputs[0], nd)); | |||
| results = np.squeeze(results); | |||
| int idx = np.argmax(results); | |||
| Console.WriteLine($"{labels[idx]} {results[idx]} in {sw.ElapsedMilliseconds}ms", Color.Tan); | |||
| result_labels.Add(labels[idx]); | |||
| } | |||
| } | |||
| return result_labels.Contains("military uniform"); | |||
| } | |||
| private NDArray ReadTensorFromImageFile(string file_name, | |||
| int input_height = 224, | |||
| int input_width = 224, | |||
| int input_mean = 117, | |||
| int input_std = 1) | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| var file_reader = tf.read_file(file_name, "file_reader"); | |||
| var decodeJpeg = tf.image.decode_jpeg(file_reader, channels: 3, name: "DecodeJpeg"); | |||
| var cast = tf.cast(decodeJpeg, tf.float32); | |||
| var dims_expander = tf.expand_dims(cast, 0); | |||
| var resize = tf.constant(new int[] { input_height, input_width }); | |||
| var bilinear = tf.image.resize_bilinear(dims_expander, resize); | |||
| var sub = tf.subtract(bilinear, new float[] { input_mean }); | |||
| var normalized = tf.divide(sub, new float[] { input_std }); | |||
| using (var sess = tf.Session(graph)) | |||
| return sess.run(normalized); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| Directory.CreateDirectory(dir); | |||
| // get model file | |||
| string url = "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip"; | |||
| Utility.Web.Download(url, dir, "inception5h.zip"); | |||
| Utility.Compress.UnZip(Path.Join(dir, "inception5h.zip"), dir); | |||
| // download sample picture | |||
| Directory.CreateDirectory(Path.Join(dir, "img")); | |||
| url = $"https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/examples/label_image/data/grace_hopper.jpg"; | |||
| Utility.Web.Download(url, Path.Join(dir, "img"), "grace_hopper.jpg"); | |||
| url = $"https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/data/shasta-daisy.jpg"; | |||
| Utility.Web.Download(url, Path.Join(dir, "img"), "shasta-daisy.jpg"); | |||
| // load image file | |||
| var files = Directory.GetFiles(Path.Join(dir, "img")); | |||
| for (int i = 0; i < files.Length; i++) | |||
| { | |||
| var nd = ReadTensorFromImageFile(files[i]); | |||
| file_ndarrays.Add(nd); | |||
| } | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,133 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Inception Architecture for Computer Vision | |||
| /// Port from tensorflow\examples\label_image\label_image.py | |||
| /// </summary> | |||
| public class InceptionArchGoogLeNet : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public string Name => "Inception Arch GoogLeNet"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| string dir = "label_image_data"; | |||
| string pbFile = "inception_v3_2016_08_28_frozen.pb"; | |||
| string labelFile = "imagenet_slim_labels.txt"; | |||
| string picFile = "grace_hopper.jpg"; | |||
| int input_height = 299; | |||
| int input_width = 299; | |||
| int input_mean = 0; | |||
| int input_std = 255; | |||
| string input_name = "import/input"; | |||
| string output_name = "import/InceptionV3/Predictions/Reshape_1"; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var labels = File.ReadAllLines(Path.Join(dir, labelFile)); | |||
| var nd = ReadTensorFromImageFile(Path.Join(dir, picFile), | |||
| input_height: input_height, | |||
| input_width: input_width, | |||
| input_mean: input_mean, | |||
| input_std: input_std); | |||
| var graph = new Graph(); | |||
| graph.Import(Path.Join(dir, pbFile)); | |||
| var input_operation = graph.get_operation_by_name(input_name); | |||
| var output_operation = graph.get_operation_by_name(output_name); | |||
| NDArray results; | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| results = sess.run(output_operation.outputs[0], | |||
| new FeedItem(input_operation.outputs[0], nd)); | |||
| } | |||
| results = np.squeeze(results); | |||
| var argsort = results.argsort<float>(); | |||
| var top_k = argsort.Data<float>() | |||
| .Skip(results.size - 5) | |||
| .Reverse() | |||
| .ToArray(); | |||
| foreach (float idx in top_k) | |||
| Console.WriteLine($"{picFile}: {idx} {labels[(int)idx]}, {results[(int)idx]}"); | |||
| return true; | |||
| } | |||
| private NDArray ReadTensorFromImageFile(string file_name, | |||
| int input_height = 299, | |||
| int input_width = 299, | |||
| int input_mean = 0, | |||
| int input_std = 255) | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| var file_reader = tf.read_file(file_name, "file_reader"); | |||
| var image_reader = tf.image.decode_jpeg(file_reader, channels: 3, name: "jpeg_reader"); | |||
| var caster = tf.cast(image_reader, tf.float32); | |||
| var dims_expander = tf.expand_dims(caster, 0); | |||
| var resize = tf.constant(new int[] { input_height, input_width }); | |||
| var bilinear = tf.image.resize_bilinear(dims_expander, resize); | |||
| var sub = tf.subtract(bilinear, new float[] { input_mean }); | |||
| var normalized = tf.divide(sub, new float[] { input_std }); | |||
| using (var sess = tf.Session(graph)) | |||
| return sess.run(normalized); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| Directory.CreateDirectory(dir); | |||
| // get model file | |||
| string url = "https://storage.googleapis.com/download.tensorflow.org/models/inception_v3_2016_08_28_frozen.pb.tar.gz"; | |||
| Utility.Web.Download(url, dir, $"{pbFile}.tar.gz"); | |||
| Utility.Compress.ExtractTGZ(Path.Join(dir, $"{pbFile}.tar.gz"), dir); | |||
| // download sample picture | |||
| string pic = "grace_hopper.jpg"; | |||
| url = $"https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/examples/label_image/data/{pic}"; | |||
| Utility.Web.Download(url, dir, pic); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,175 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.IO; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using System.Drawing; | |||
| using System.Drawing.Drawing2D; | |||
| using System.Linq; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| public class ObjectDetection : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Object Detection"; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public float MIN_SCORE = 0.5f; | |||
| string modelDir = "ssd_mobilenet_v1_coco_2018_01_28"; | |||
| string imageDir = "images"; | |||
| string pbFile = "frozen_inference_graph.pb"; | |||
| string labelFile = "mscoco_label_map.pbtxt"; | |||
| string picFile = "input.jpg"; | |||
| NDArray imgArr; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| // read in the input image | |||
| imgArr = ReadTensorFromImageFile(Path.Join(imageDir, "input.jpg")); | |||
| var graph = IsImportingGraph ? ImportGraph() : BuildGraph(); | |||
| using (var sess = tf.Session(graph)) | |||
| Predict(sess); | |||
| return true; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| graph.Import(Path.Join(modelDir, pbFile)); | |||
| return graph; | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| var graph = tf.get_default_graph(); | |||
| Tensor tensorNum = graph.OperationByName("num_detections"); | |||
| Tensor tensorBoxes = graph.OperationByName("detection_boxes"); | |||
| Tensor tensorScores = graph.OperationByName("detection_scores"); | |||
| Tensor tensorClasses = graph.OperationByName("detection_classes"); | |||
| Tensor imgTensor = graph.OperationByName("image_tensor"); | |||
| Tensor[] outTensorArr = new Tensor[] { tensorNum, tensorBoxes, tensorScores, tensorClasses }; | |||
| var results = sess.run(outTensorArr, new FeedItem(imgTensor, imgArr)); | |||
| buildOutputImage(results); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // get model file | |||
| string url = "http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz"; | |||
| Web.Download(url, modelDir, "ssd_mobilenet_v1_coco.tar.gz"); | |||
| Compress.ExtractTGZ(Path.Join(modelDir, "ssd_mobilenet_v1_coco.tar.gz"), "./"); | |||
| // download sample picture | |||
| url = $"https://github.com/tensorflow/models/raw/master/research/object_detection/test_images/image2.jpg"; | |||
| Web.Download(url, imageDir, "input.jpg"); | |||
| // download the pbtxt file | |||
| url = $"https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_label_map.pbtxt"; | |||
| Web.Download(url, modelDir, "mscoco_label_map.pbtxt"); | |||
| } | |||
| private NDArray ReadTensorFromImageFile(string file_name) | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| var file_reader = tf.read_file(file_name, "file_reader"); | |||
| var decodeJpeg = tf.image.decode_jpeg(file_reader, channels: 3, name: "DecodeJpeg"); | |||
| var casted = tf.cast(decodeJpeg, TF_DataType.TF_UINT8); | |||
| var dims_expander = tf.expand_dims(casted, 0); | |||
| using (var sess = tf.Session(graph)) | |||
| return sess.run(dims_expander); | |||
| } | |||
| private void buildOutputImage(NDArray[] resultArr) | |||
| { | |||
| // get pbtxt items | |||
| PbtxtItems pbTxtItems = PbtxtParser.ParsePbtxtFile(Path.Join(modelDir, "mscoco_label_map.pbtxt")); | |||
| // get bitmap | |||
| Bitmap bitmap = new Bitmap(Path.Join(imageDir, "input.jpg")); | |||
| var scores = resultArr[2].AsIterator<float>(); | |||
| var boxes = resultArr[1].GetData<float>(); | |||
| var id = np.squeeze(resultArr[3]).GetData<float>(); | |||
| for (int i=0; i< scores.size; i++) | |||
| { | |||
| float score = scores.MoveNext(); | |||
| if (score > MIN_SCORE) | |||
| { | |||
| float top = boxes[i * 4] * bitmap.Height; | |||
| float left = boxes[i * 4 + 1] * bitmap.Width; | |||
| float bottom = boxes[i * 4 + 2] * bitmap.Height; | |||
| float right = boxes[i * 4 + 3] * bitmap.Width; | |||
| Rectangle rect = new Rectangle() | |||
| { | |||
| X = (int)left, | |||
| Y = (int)top, | |||
| Width = (int)(right - left), | |||
| Height = (int)(bottom - top) | |||
| }; | |||
| string name = pbTxtItems.items.Where(w => w.id == id[i]).Select(s=>s.display_name).FirstOrDefault(); | |||
| drawObjectOnBitmap(bitmap, rect, score, name); | |||
| } | |||
| } | |||
| string path = Path.Join(imageDir, "output.jpg"); | |||
| bitmap.Save(path); | |||
| Console.WriteLine($"Processed image is saved as {path}"); | |||
| } | |||
| private void drawObjectOnBitmap(Bitmap bmp, Rectangle rect, float score, string name) | |||
| { | |||
| using (Graphics graphic = Graphics.FromImage(bmp)) | |||
| { | |||
| graphic.SmoothingMode = SmoothingMode.AntiAlias; | |||
| using (Pen pen = new Pen(Color.Red, 2)) | |||
| { | |||
| graphic.DrawRectangle(pen, rect); | |||
| Point p = new Point(rect.Right + 5, rect.Top + 5); | |||
| string text = string.Format("{0}:{1}%", name, (int)(score * 100)); | |||
| graphic.DrawString(text, new Font("Verdana", 8), Brushes.Red, p); | |||
| } | |||
| } | |||
| } | |||
| public Graph BuildGraph() => throw new NotImplementedException(); | |||
| public void Train(Session sess) => throw new NotImplementedException(); | |||
| public void Test(Session sess) => throw new NotImplementedException(); | |||
| } | |||
| } | |||
| @@ -1,88 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using Tensorflow.Contrib.Train; | |||
| using Tensorflow.Estimators; | |||
| using Tensorflow.Models.ObjectDetection; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.ObjectDetection | |||
| { | |||
| public class Main : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public string Name => "Object Detection API"; | |||
| ModelLib model_lib = new ModelLib(); | |||
| string model_dir = "D:/Projects/PythonLab/tf-models/research/object_detection/models/model"; | |||
| string pipeline_config_path = "ObjectDetection/Models/faster_rcnn_resnet101_voc07.config"; | |||
| int num_train_steps = 50; | |||
| int sample_1_of_n_eval_examples = 1; | |||
| int sample_1_of_n_eval_on_train_examples = 5; | |||
| public bool Run() | |||
| { | |||
| var config = tf.estimator.RunConfig(model_dir: model_dir); | |||
| var train_and_eval_dict = model_lib.create_estimator_and_inputs(run_config: config, | |||
| hparams: new HParams(true), | |||
| pipeline_config_path: pipeline_config_path, | |||
| train_steps: num_train_steps, | |||
| sample_1_of_n_eval_examples: sample_1_of_n_eval_examples, | |||
| sample_1_of_n_eval_on_train_examples: sample_1_of_n_eval_on_train_examples); | |||
| var estimator = train_and_eval_dict.estimator; | |||
| var train_input_fn = train_and_eval_dict.train_input_fn; | |||
| var eval_input_fns = train_and_eval_dict.eval_input_fns; | |||
| var eval_on_train_input_fn = train_and_eval_dict.eval_on_train_input_fn; | |||
| var predict_input_fn = train_and_eval_dict.predict_input_fn; | |||
| var train_steps = train_and_eval_dict.train_steps; | |||
| var (train_spec, eval_specs) = model_lib.create_train_and_eval_specs(train_input_fn, | |||
| eval_input_fns, | |||
| eval_on_train_input_fn, | |||
| predict_input_fn, | |||
| train_steps, | |||
| eval_on_train_data: false); | |||
| // Currently only a single Eval Spec is allowed. | |||
| tf.estimator.train_and_evaluate(estimator, train_spec, eval_specs[0]); | |||
| return true; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| void IExample.Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,791 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 Google.Protobuf; | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// In this tutorial, we will reuse the feature extraction capabilities from powerful image classifiers trained on ImageNet | |||
| /// and simply train a new classification layer on top. Transfer learning is a technique that shortcuts much of this | |||
| /// by taking a piece of a model that has already been trained on a related task and reusing it in a new model. | |||
| /// | |||
| /// https://www.tensorflow.org/hub/tutorials/image_retraining | |||
| /// </summary> | |||
| public class RetrainImageClassifier : IExample | |||
| { | |||
| public int Priority => 16; | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public string Name => "Retrain Image Classifier"; | |||
| const string data_dir = "retrain_images"; | |||
| string summaries_dir = Path.Join(data_dir, "retrain_logs"); | |||
| string image_dir = Path.Join(data_dir, "flower_photos"); | |||
| string bottleneck_dir = Path.Join(data_dir, "bottleneck"); | |||
| string output_graph = Path.Join(data_dir, "output_graph.pb"); | |||
| string output_labels = Path.Join(data_dir, "output_labels.txt"); | |||
| // The location where variable checkpoints will be stored. | |||
| string CHECKPOINT_NAME = Path.Join(data_dir, "_retrain_checkpoint"); | |||
| string tfhub_module = "https://tfhub.dev/google/imagenet/inception_v3/feature_vector/3"; | |||
| string input_tensor_name = "Placeholder"; | |||
| string final_tensor_name = "Score"; | |||
| float testing_percentage = 0.1f; | |||
| float validation_percentage = 0.1f; | |||
| float learning_rate = 0.01f; | |||
| Tensor resized_image_tensor; | |||
| Dictionary<string, Dictionary<string, string[]>> image_lists; | |||
| int how_many_training_steps = 100; | |||
| int eval_step_interval = 10; | |||
| int train_batch_size = 100; | |||
| int test_batch_size = -1; | |||
| int validation_batch_size = 100; | |||
| int intermediate_store_frequency = 0; | |||
| int class_count = 0; | |||
| const int MAX_NUM_IMAGES_PER_CLASS = 134217727; | |||
| Operation train_step; | |||
| Tensor final_tensor; | |||
| Tensor bottleneck_input; | |||
| Tensor cross_entropy; | |||
| Tensor ground_truth_input; | |||
| Tensor bottleneck_tensor; | |||
| bool wants_quantization; | |||
| float test_accuracy; | |||
| NDArray predictions; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| #region For debug purpose | |||
| // predict images | |||
| // Predict(null); | |||
| // load saved pb and test new images. | |||
| // Test(null); | |||
| #endregion | |||
| var graph = IsImportingGraph ? ImportGraph() : BuildGraph(); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| Train(sess); | |||
| } | |||
| return test_accuracy > 0.75f; | |||
| } | |||
| /// <summary> | |||
| /// Runs a final evaluation on an eval graph using the test data set. | |||
| /// </summary> | |||
| /// <param name="train_session"></param> | |||
| /// <param name="module_spec"></param> | |||
| /// <param name="class_count"></param> | |||
| /// <param name="image_lists"></param> | |||
| /// <param name="jpeg_data_tensor"></param> | |||
| /// <param name="decoded_image_tensor"></param> | |||
| /// <param name="resized_image_tensor"></param> | |||
| /// <param name="bottleneck_tensor"></param> | |||
| private (float, NDArray) run_final_eval(Session train_session, object module_spec, int class_count, | |||
| Dictionary<string, Dictionary<string, string[]>> image_lists, | |||
| Tensor jpeg_data_tensor, Tensor decoded_image_tensor, | |||
| Tensor resized_image_tensor, Tensor bottleneck_tensor) | |||
| { | |||
| var (test_bottlenecks, test_ground_truth, test_filenames) = get_random_cached_bottlenecks(train_session, image_lists, | |||
| test_batch_size, "testing", bottleneck_dir, image_dir, jpeg_data_tensor, | |||
| decoded_image_tensor, resized_image_tensor, bottleneck_tensor, tfhub_module); | |||
| var (eval_session, _, bottleneck_input, ground_truth_input, evaluation_step, | |||
| prediction) = build_eval_session(class_count); | |||
| (float accuracy, NDArray prediction1) = eval_session.run((evaluation_step, prediction), | |||
| (bottleneck_input, test_bottlenecks), | |||
| (ground_truth_input, test_ground_truth)); | |||
| print($"final test accuracy: {(accuracy * 100).ToString("G4")}% (N={len(test_bottlenecks)})"); | |||
| return (accuracy, prediction1); | |||
| } | |||
| private (Session, Tensor, Tensor, Tensor, Tensor, Tensor) | |||
| build_eval_session(int class_count) | |||
| { | |||
| // If quantized, we need to create the correct eval graph for exporting. | |||
| var (eval_graph, bottleneck_tensor, resized_input_tensor, wants_quantization) = create_module_graph(); | |||
| var eval_sess = tf.Session(graph: eval_graph); | |||
| Tensor evaluation_step = null; | |||
| Tensor prediction = null; | |||
| var graph = eval_graph.as_default(); | |||
| // Add the new layer for exporting. | |||
| var (_, _, bottleneck_input, ground_truth_input, final_tensor) = | |||
| add_final_retrain_ops(class_count, final_tensor_name, bottleneck_tensor, | |||
| wants_quantization, is_training: false); | |||
| // Now we need to restore the values from the training graph to the eval | |||
| // graph. | |||
| tf.train.Saver().restore(eval_sess, CHECKPOINT_NAME); | |||
| (evaluation_step, prediction) = add_evaluation_step(final_tensor, | |||
| ground_truth_input); | |||
| return (eval_sess, resized_input_tensor, bottleneck_input, ground_truth_input, | |||
| evaluation_step, prediction); | |||
| } | |||
| /// <summary> | |||
| /// Adds a new softmax and fully-connected layer for training and eval. | |||
| /// | |||
| /// We need to retrain the top layer to identify our new classes, so this function | |||
| /// adds the right operations to the graph, along with some variables to hold the | |||
| /// weights, and then sets up all the gradients for the backward pass. | |||
| /// | |||
| /// The set up for the softmax and fully-connected layers is based on: | |||
| /// https://www.tensorflow.org/tutorials/mnist/beginners/index.html | |||
| /// </summary> | |||
| /// <param name="class_count"></param> | |||
| /// <param name="final_tensor_name"></param> | |||
| /// <param name="bottleneck_tensor"></param> | |||
| /// <param name="quantize_layer"></param> | |||
| /// <param name="is_training"></param> | |||
| /// <returns></returns> | |||
| private (Operation, Tensor, Tensor, Tensor, Tensor) add_final_retrain_ops(int class_count, string final_tensor_name, | |||
| Tensor bottleneck_tensor, bool quantize_layer, bool is_training) | |||
| { | |||
| var (batch_size, bottleneck_tensor_size) = (bottleneck_tensor.TensorShape.dims[0], bottleneck_tensor.TensorShape.dims[1]); | |||
| tf_with(tf.name_scope("input"), scope => | |||
| { | |||
| bottleneck_input = tf.placeholder_with_default( | |||
| bottleneck_tensor, | |||
| shape: bottleneck_tensor.TensorShape.dims, | |||
| name: "BottleneckInputPlaceholder"); | |||
| ground_truth_input = tf.placeholder(tf.int64, new TensorShape(batch_size), name: "GroundTruthInput"); | |||
| }); | |||
| // Organizing the following ops so they are easier to see in TensorBoard. | |||
| string layer_name = "final_retrain_ops"; | |||
| Tensor logits = null; | |||
| tf_with(tf.name_scope(layer_name), scope => | |||
| { | |||
| RefVariable layer_weights = null; | |||
| tf_with(tf.name_scope("weights"), delegate | |||
| { | |||
| var initial_value = tf.truncated_normal(new int[] { bottleneck_tensor_size, class_count }, stddev: 0.001f); | |||
| layer_weights = tf.Variable(initial_value, name: "final_weights"); | |||
| variable_summaries(layer_weights); | |||
| }); | |||
| RefVariable layer_biases = null; | |||
| tf_with(tf.name_scope("biases"), delegate | |||
| { | |||
| layer_biases = tf.Variable(tf.zeros(new TensorShape(class_count)), name: "final_biases"); | |||
| variable_summaries(layer_biases); | |||
| }); | |||
| tf_with(tf.name_scope("Wx_plus_b"), delegate | |||
| { | |||
| logits = tf.matmul(bottleneck_input, layer_weights) + layer_biases; | |||
| tf.summary.histogram("pre_activations", logits); | |||
| }); | |||
| }); | |||
| final_tensor = tf.nn.softmax(logits, name: final_tensor_name); | |||
| // The tf.contrib.quantize functions rewrite the graph in place for | |||
| // quantization. The imported model graph has already been rewritten, so upon | |||
| // calling these rewrites, only the newly added final layer will be | |||
| // transformed. | |||
| if (quantize_layer) | |||
| { | |||
| throw new NotImplementedException("quantize_layer"); | |||
| /*if (is_training) | |||
| tf.contrib.quantize.create_training_graph(); | |||
| else | |||
| tf.contrib.quantize.create_eval_graph();*/ | |||
| } | |||
| tf.summary.histogram("activations", final_tensor); | |||
| // If this is an eval graph, we don't need to add loss ops or an optimizer. | |||
| if (!is_training) | |||
| return (null, null, bottleneck_input, ground_truth_input, final_tensor); | |||
| Tensor cross_entropy_mean = null; | |||
| tf_with(tf.name_scope("cross_entropy"), delegate | |||
| { | |||
| cross_entropy_mean = tf.losses.sparse_softmax_cross_entropy( | |||
| labels: ground_truth_input, logits: logits); | |||
| }); | |||
| tf.summary.scalar("cross_entropy", cross_entropy_mean); | |||
| tf_with(tf.name_scope("train"), delegate | |||
| { | |||
| var optimizer = tf.train.GradientDescentOptimizer(learning_rate); | |||
| train_step = optimizer.minimize(cross_entropy_mean); | |||
| }); | |||
| return (train_step, cross_entropy_mean, bottleneck_input, ground_truth_input, | |||
| final_tensor); | |||
| } | |||
| private void variable_summaries(RefVariable var) | |||
| { | |||
| tf_with(tf.name_scope("summaries"), delegate | |||
| { | |||
| var mean = tf.reduce_mean(var); | |||
| tf.summary.scalar("mean", mean); | |||
| Tensor stddev = null; | |||
| tf_with(tf.name_scope("stddev"), delegate | |||
| { | |||
| stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean))); | |||
| }); | |||
| tf.summary.scalar("stddev", stddev); | |||
| tf.summary.scalar("max", tf.reduce_max(var)); | |||
| tf.summary.scalar("min", tf.reduce_min(var)); | |||
| tf.summary.histogram("histogram", var); | |||
| }); | |||
| } | |||
| private (Graph, Tensor, Tensor, bool) create_module_graph() | |||
| { | |||
| var (height, width) = (299, 299); | |||
| var graph = tf.Graph().as_default(); | |||
| tf.train.import_meta_graph("graph/InceptionV3.meta"); | |||
| Tensor resized_input_tensor = graph.OperationByName(input_tensor_name); //tf.placeholder(tf.float32, new TensorShape(-1, height, width, 3)); | |||
| // var m = hub.Module(module_spec); | |||
| Tensor bottleneck_tensor = graph.OperationByName("module_apply_default/hub_output/feature_vector/SpatialSqueeze");// m(resized_input_tensor); | |||
| var wants_quantization = false; | |||
| return (graph, bottleneck_tensor, resized_input_tensor, wants_quantization); | |||
| } | |||
| private (NDArray, long[], string[]) get_random_cached_bottlenecks(Session sess, Dictionary<string, Dictionary<string, string[]>> image_lists, | |||
| int how_many, string category, string bottleneck_dir, string image_dir, | |||
| Tensor jpeg_data_tensor, Tensor decoded_image_tensor, Tensor resized_input_tensor, | |||
| Tensor bottleneck_tensor, string module_name) | |||
| { | |||
| var bottlenecks = new List<float[]>(); | |||
| var ground_truths = new List<long>(); | |||
| var filenames = new List<string>(); | |||
| class_count = image_lists.Keys.Count; | |||
| if (how_many >= 0) | |||
| { | |||
| // Retrieve a random sample of bottlenecks. | |||
| foreach (var unused_i in range(how_many)) | |||
| { | |||
| int label_index = new Random().Next(class_count); | |||
| string label_name = image_lists.Keys.ToArray()[label_index]; | |||
| int image_index = new Random().Next(MAX_NUM_IMAGES_PER_CLASS); | |||
| string image_name = get_image_path(image_lists, label_name, image_index, | |||
| image_dir, category); | |||
| var bottleneck = get_or_create_bottleneck( | |||
| sess, image_lists, label_name, image_index, image_dir, category, | |||
| bottleneck_dir, jpeg_data_tensor, decoded_image_tensor, | |||
| resized_input_tensor, bottleneck_tensor, module_name); | |||
| bottlenecks.Add(bottleneck); | |||
| ground_truths.Add(label_index); | |||
| filenames.Add(image_name); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| // Retrieve all bottlenecks. | |||
| foreach (var (label_index, label_name) in enumerate(image_lists.Keys.ToArray())) | |||
| { | |||
| foreach (var (image_index, image_name) in enumerate(image_lists[label_name][category])) | |||
| { | |||
| var bottleneck = get_or_create_bottleneck( | |||
| sess, image_lists, label_name, image_index, image_dir, category, | |||
| bottleneck_dir, jpeg_data_tensor, decoded_image_tensor, | |||
| resized_input_tensor, bottleneck_tensor, module_name); | |||
| bottlenecks.Add(bottleneck); | |||
| ground_truths.Add(label_index); | |||
| filenames.Add(image_name); | |||
| } | |||
| } | |||
| } | |||
| return (bottlenecks.ToArray(), ground_truths.ToArray(), filenames.ToArray()); | |||
| } | |||
| /// <summary> | |||
| /// Inserts the operations we need to evaluate the accuracy of our results. | |||
| /// </summary> | |||
| /// <param name="result_tensor"></param> | |||
| /// <param name="ground_truth_tensor"></param> | |||
| /// <returns></returns> | |||
| private (Tensor, Tensor) add_evaluation_step(Tensor result_tensor, Tensor ground_truth_tensor) | |||
| { | |||
| Tensor evaluation_step = null, correct_prediction = null, prediction = null; | |||
| tf_with(tf.name_scope("accuracy"), scope => | |||
| { | |||
| tf_with(tf.name_scope("correct_prediction"), delegate | |||
| { | |||
| prediction = tf.argmax(result_tensor, 1); | |||
| correct_prediction = tf.equal(prediction, ground_truth_tensor); | |||
| }); | |||
| tf_with(tf.name_scope("accuracy"), delegate | |||
| { | |||
| evaluation_step = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)); | |||
| }); | |||
| }); | |||
| tf.summary.scalar("accuracy", evaluation_step); | |||
| return (evaluation_step, prediction); | |||
| } | |||
| /// <summary> | |||
| /// Ensures all the training, testing, and validation bottlenecks are cached. | |||
| /// </summary> | |||
| /// <param name="sess"></param> | |||
| /// <param name="image_lists"></param> | |||
| /// <param name="image_dir"></param> | |||
| /// <param name="bottleneck_dir"></param> | |||
| /// <param name="jpeg_data_tensor"></param> | |||
| /// <param name="decoded_image_tensor"></param> | |||
| /// <param name="resized_image_tensor"></param> | |||
| /// <param name="bottleneck_tensor"></param> | |||
| /// <param name="tfhub_module"></param> | |||
| private void cache_bottlenecks(Session sess, Dictionary<string, Dictionary<string, string[]>> image_lists, | |||
| string image_dir, string bottleneck_dir, Tensor jpeg_data_tensor, Tensor decoded_image_tensor, | |||
| Tensor resized_input_tensor, Tensor bottleneck_tensor, string module_name) | |||
| { | |||
| int how_many_bottlenecks = 0; | |||
| var kvs = image_lists.ToArray(); | |||
| var categories = new string[] {"training", "testing", "validation"}; | |||
| Parallel.For(0, kvs.Length, i => | |||
| { | |||
| var (label_name, label_lists) = kvs[i]; | |||
| Parallel.For(0, categories.Length, j => | |||
| { | |||
| var category = categories[j]; | |||
| var category_list = label_lists[category]; | |||
| foreach (var (index, unused_base_name) in enumerate(category_list)) | |||
| { | |||
| get_or_create_bottleneck(sess, image_lists, label_name, index, image_dir, category, | |||
| bottleneck_dir, jpeg_data_tensor, decoded_image_tensor, | |||
| resized_input_tensor, bottleneck_tensor, module_name); | |||
| how_many_bottlenecks++; | |||
| if (how_many_bottlenecks % 300 == 0) | |||
| print($"{how_many_bottlenecks} bottleneck files created."); | |||
| } | |||
| }); | |||
| }); | |||
| } | |||
| private float[] get_or_create_bottleneck(Session sess, Dictionary<string, Dictionary<string, string[]>> image_lists, | |||
| string label_name, int index, string image_dir, string category, string bottleneck_dir, | |||
| Tensor jpeg_data_tensor, Tensor decoded_image_tensor, Tensor resized_input_tensor, | |||
| Tensor bottleneck_tensor, string module_name) | |||
| { | |||
| var label_lists = image_lists[label_name]; | |||
| var sub_dir_path = Path.Join(bottleneck_dir, label_name); | |||
| Directory.CreateDirectory(sub_dir_path); | |||
| string bottleneck_path = get_bottleneck_path(image_lists, label_name, index, | |||
| bottleneck_dir, category, module_name); | |||
| if (!File.Exists(bottleneck_path)) | |||
| create_bottleneck_file(bottleneck_path, image_lists, label_name, index, | |||
| image_dir, category, sess, jpeg_data_tensor, | |||
| decoded_image_tensor, resized_input_tensor, | |||
| bottleneck_tensor); | |||
| var bottleneck_string = File.ReadAllText(bottleneck_path); | |||
| var bottleneck_values = Array.ConvertAll(bottleneck_string.Split(','), x => float.Parse(x)); | |||
| return bottleneck_values; | |||
| } | |||
| private void create_bottleneck_file(string bottleneck_path, Dictionary<string, Dictionary<string, string[]>> image_lists, | |||
| string label_name, int index, string image_dir, string category, Session sess, | |||
| Tensor jpeg_data_tensor, Tensor decoded_image_tensor, Tensor resized_input_tensor, Tensor bottleneck_tensor) | |||
| { | |||
| // Create a single bottleneck file. | |||
| print("Creating bottleneck at " + bottleneck_path); | |||
| var image_path = get_image_path(image_lists, label_name, index, image_dir, category); | |||
| if (!File.Exists(image_path)) | |||
| print($"File does not exist {image_path}"); | |||
| var image_data = File.ReadAllBytes(image_path); | |||
| var bottleneck_values = run_bottleneck_on_image( | |||
| sess, image_data, jpeg_data_tensor, decoded_image_tensor, | |||
| resized_input_tensor, bottleneck_tensor); | |||
| var values = bottleneck_values.Data<float>(); | |||
| var bottleneck_string = string.Join(",", values); | |||
| File.WriteAllText(bottleneck_path, bottleneck_string); | |||
| } | |||
| /// <summary> | |||
| /// Runs inference on an image to extract the 'bottleneck' summary layer. | |||
| /// </summary> | |||
| /// <param name="sess">Current active TensorFlow Session.</param> | |||
| /// <param name="image_data">Data of raw JPEG data.</param> | |||
| /// <param name="image_data_tensor">Input data layer in the graph.</param> | |||
| /// <param name="decoded_image_tensor">Output of initial image resizing and preprocessing.</param> | |||
| /// <param name="resized_input_tensor">The input node of the recognition graph.</param> | |||
| /// <param name="bottleneck_tensor">Layer before the final softmax.</param> | |||
| /// <returns></returns> | |||
| private NDArray run_bottleneck_on_image(Session sess, byte[] image_data, Tensor image_data_tensor, | |||
| Tensor decoded_image_tensor, Tensor resized_input_tensor, Tensor bottleneck_tensor) | |||
| { | |||
| // First decode the JPEG image, resize it, and rescale the pixel values. | |||
| var resized_input_values = sess.run(decoded_image_tensor, new FeedItem(image_data_tensor, new Tensor(image_data, TF_DataType.TF_STRING))); | |||
| // Then run it through the recognition network. | |||
| var bottleneck_values = sess.run(bottleneck_tensor, new FeedItem(resized_input_tensor, resized_input_values))[0]; | |||
| bottleneck_values = np.squeeze(bottleneck_values); | |||
| return bottleneck_values; | |||
| } | |||
| private string get_bottleneck_path(Dictionary<string, Dictionary<string, string[]>> image_lists, string label_name, int index, | |||
| string bottleneck_dir, string category, string module_name) | |||
| { | |||
| module_name = (module_name.Replace("://", "~") // URL scheme. | |||
| .Replace('/', '~') // URL and Unix paths. | |||
| .Replace(':', '~').Replace('\\', '~')); // Windows paths. | |||
| return get_image_path(image_lists, label_name, index, bottleneck_dir, | |||
| category) + "_" + module_name + ".txt"; | |||
| } | |||
| private string get_image_path(Dictionary<string, Dictionary<string, string[]>> image_lists, string label_name, | |||
| int index, string image_dir, string category) | |||
| { | |||
| if (!image_lists.ContainsKey(label_name)) | |||
| print($"Label does not exist {label_name}"); | |||
| var label_lists = image_lists[label_name]; | |||
| if (!label_lists.ContainsKey(category)) | |||
| print($"Category does not exist {category}"); | |||
| var category_list = label_lists[category]; | |||
| if (category_list.Length == 0) | |||
| print($"Label {label_name} has no images in the category {category}."); | |||
| var mod_index = index % len(category_list); | |||
| var base_name = category_list[mod_index].Split(Path.DirectorySeparatorChar).Last(); | |||
| var sub_dir = label_name; | |||
| var full_path = Path.Join(image_dir, sub_dir, base_name); | |||
| return full_path; | |||
| } | |||
| /// <summary> | |||
| /// Saves an graph to file, creating a valid quantized one if necessary. | |||
| /// </summary> | |||
| /// <param name="graph_file_name"></param> | |||
| /// <param name="class_count"></param> | |||
| private void save_graph_to_file(string graph_file_name, int class_count) | |||
| { | |||
| var (sess, _, _, _, _, _) = build_eval_session(class_count); | |||
| var graph = sess.graph; | |||
| var output_graph_def = tf.graph_util.convert_variables_to_constants( | |||
| sess, graph.as_graph_def(), new string[] { final_tensor_name }); | |||
| File.WriteAllBytes(graph_file_name, output_graph_def.ToByteArray()); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // get a set of images to teach the network about the new classes | |||
| string fileName = "flower_photos.tgz"; | |||
| string url = $"http://download.tensorflow.org/example_images/{fileName}"; | |||
| Web.Download(url, data_dir, fileName); | |||
| Compress.ExtractTGZ(Path.Join(data_dir, fileName), data_dir); | |||
| // download graph meta data | |||
| url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/graph/InceptionV3.meta"; | |||
| Web.Download(url, "graph", "InceptionV3.meta"); | |||
| // download variables.data checkpoint file. | |||
| url = "https://github.com/SciSharp/TensorFlow.NET/raw/master/data/tfhub_modules.zip"; | |||
| Web.Download(url, data_dir, "tfhub_modules.zip"); | |||
| Compress.UnZip(Path.Join(data_dir, "tfhub_modules.zip"), "tfhub_modules"); | |||
| // Prepare necessary directories that can be used during training | |||
| Directory.CreateDirectory(summaries_dir); | |||
| Directory.CreateDirectory(bottleneck_dir); | |||
| // Look at the folder structure, and create lists of all the images. | |||
| image_lists = create_image_lists(); | |||
| class_count = len(image_lists); | |||
| if (class_count == 0) | |||
| print($"No valid folders of images found at {image_dir}"); | |||
| if (class_count == 1) | |||
| print("Only one valid folder of images found at " + | |||
| image_dir + | |||
| " - multiple classes are needed for classification."); | |||
| } | |||
| private (Tensor, Tensor) add_jpeg_decoding() | |||
| { | |||
| // height, width, depth | |||
| var input_dim = (299, 299, 3); | |||
| var jpeg_data = tf.placeholder(tf.@string, name: "DecodeJPGInput"); | |||
| var decoded_image = tf.image.decode_jpeg(jpeg_data, channels: input_dim.Item3); | |||
| // Convert from full range of uint8 to range [0,1] of float32. | |||
| var decoded_image_as_float = tf.image.convert_image_dtype(decoded_image, tf.float32); | |||
| var decoded_image_4d = tf.expand_dims(decoded_image_as_float, 0); | |||
| var resize_shape = tf.stack(new int[] { input_dim.Item1, input_dim.Item2 }); | |||
| var resize_shape_as_int = tf.cast(resize_shape, dtype: tf.int32); | |||
| var resized_image = tf.image.resize_bilinear(decoded_image_4d, resize_shape_as_int); | |||
| return (jpeg_data, resized_image); | |||
| } | |||
| /// <summary> | |||
| /// Builds a list of training images from the file system. | |||
| /// </summary> | |||
| private Dictionary<string, Dictionary<string, string[]>> create_image_lists() | |||
| { | |||
| var sub_dirs = tf.gfile.Walk(image_dir) | |||
| .Select(x => x.Item1) | |||
| .OrderBy(x => x) | |||
| .ToArray(); | |||
| var result = new Dictionary<string, Dictionary<string, string[]>>(); | |||
| foreach (var sub_dir in sub_dirs) | |||
| { | |||
| var dir_name = sub_dir.Split(Path.DirectorySeparatorChar).Last(); | |||
| print($"Looking for images in '{dir_name}'"); | |||
| var file_list = Directory.GetFiles(sub_dir); | |||
| if (len(file_list) < 20) | |||
| print($"WARNING: Folder has less than 20 images, which may cause issues."); | |||
| var label_name = dir_name.ToLower(); | |||
| result[label_name] = new Dictionary<string, string[]>(); | |||
| int testing_count = (int)Math.Floor(file_list.Length * testing_percentage); | |||
| int validation_count = (int)Math.Floor(file_list.Length * validation_percentage); | |||
| result[label_name]["testing"] = file_list.Take(testing_count).ToArray(); | |||
| result[label_name]["validation"] = file_list.Skip(testing_count).Take(validation_count).ToArray(); | |||
| result[label_name]["training"] = file_list.Skip(testing_count + validation_count).ToArray(); | |||
| } | |||
| return result; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| Graph graph; | |||
| // Set up the pre-trained graph. | |||
| (graph, bottleneck_tensor, resized_image_tensor, wants_quantization) = | |||
| create_module_graph(); | |||
| // Add the new layer that we'll be training. | |||
| (train_step, cross_entropy, bottleneck_input, | |||
| ground_truth_input, final_tensor) = add_final_retrain_ops( | |||
| class_count, final_tensor_name, bottleneck_tensor, | |||
| wants_quantization, is_training: true); | |||
| return graph; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| var sw = new Stopwatch(); | |||
| // Initialize all weights: for the module to their pretrained values, | |||
| // and for the newly added retraining layer to random initial values. | |||
| var init = tf.global_variables_initializer(); | |||
| sess.run(init); | |||
| var (jpeg_data_tensor, decoded_image_tensor) = add_jpeg_decoding(); | |||
| // We'll make sure we've calculated the 'bottleneck' image summaries and | |||
| // cached them on disk. | |||
| cache_bottlenecks(sess, image_lists, image_dir, | |||
| bottleneck_dir, jpeg_data_tensor, | |||
| decoded_image_tensor, resized_image_tensor, | |||
| bottleneck_tensor, tfhub_module); | |||
| // Create the operations we need to evaluate the accuracy of our new layer. | |||
| var (evaluation_step, _) = add_evaluation_step(final_tensor, ground_truth_input); | |||
| // Merge all the summaries and write them out to the summaries_dir | |||
| var merged = tf.summary.merge_all(); | |||
| var train_writer = tf.summary.FileWriter(summaries_dir + "/train", sess.graph); | |||
| var validation_writer = tf.summary.FileWriter(summaries_dir + "/validation", sess.graph); | |||
| // Create a train saver that is used to restore values into an eval graph | |||
| // when exporting models. | |||
| var train_saver = tf.train.Saver(); | |||
| train_saver.save(sess, CHECKPOINT_NAME); | |||
| sw.Restart(); | |||
| for (int i = 0; i < how_many_training_steps; i++) | |||
| { | |||
| var (train_bottlenecks, train_ground_truth, _) = get_random_cached_bottlenecks( | |||
| sess, image_lists, train_batch_size, "training", | |||
| bottleneck_dir, image_dir, jpeg_data_tensor, | |||
| decoded_image_tensor, resized_image_tensor, bottleneck_tensor, | |||
| tfhub_module); | |||
| // Feed the bottlenecks and ground truth into the graph, and run a training | |||
| // step. Capture training summaries for TensorBoard with the `merged` op. | |||
| var results = sess.run( | |||
| new ITensorOrOperation[] { merged, train_step }, | |||
| new FeedItem(bottleneck_input, train_bottlenecks), | |||
| new FeedItem(ground_truth_input, train_ground_truth)); | |||
| var train_summary = results[0]; | |||
| // TODO | |||
| // train_writer.add_summary(train_summary, i); | |||
| // Every so often, print out how well the graph is training. | |||
| bool is_last_step = (i + 1 == how_many_training_steps); | |||
| if ((i % eval_step_interval) == 0 || is_last_step) | |||
| { | |||
| (float train_accuracy, float cross_entropy_value) = sess.run((evaluation_step, cross_entropy), | |||
| (bottleneck_input, train_bottlenecks), | |||
| (ground_truth_input, train_ground_truth)); | |||
| print($"{DateTime.Now}: Step {i + 1}: Train accuracy = {train_accuracy * 100}%, Cross entropy = {cross_entropy_value.ToString("G4")}"); | |||
| var (validation_bottlenecks, validation_ground_truth, _) = get_random_cached_bottlenecks( | |||
| sess, image_lists, validation_batch_size, "validation", | |||
| bottleneck_dir, image_dir, jpeg_data_tensor, | |||
| decoded_image_tensor, resized_image_tensor, bottleneck_tensor, | |||
| tfhub_module); | |||
| // Run a validation step and capture training summaries for TensorBoard | |||
| // with the `merged` op. | |||
| (_, float validation_accuracy) = sess.run((merged, evaluation_step), | |||
| (bottleneck_input, validation_bottlenecks), | |||
| (ground_truth_input, validation_ground_truth)); | |||
| // validation_writer.add_summary(validation_summary, i); | |||
| print($"{DateTime.Now}: Step {i + 1}: Validation accuracy = {validation_accuracy * 100}% (N={len(validation_bottlenecks)}) {sw.ElapsedMilliseconds}ms"); | |||
| sw.Restart(); | |||
| } | |||
| // Store intermediate results | |||
| int intermediate_frequency = intermediate_store_frequency; | |||
| if (intermediate_frequency > 0 && i % intermediate_frequency == 0 && i > 0) | |||
| { | |||
| } | |||
| } | |||
| // After training is complete, force one last save of the train checkpoint. | |||
| train_saver.save(sess, CHECKPOINT_NAME); | |||
| // We've completed all our training, so run a final test evaluation on | |||
| // some new images we haven't used before. | |||
| (test_accuracy, predictions) = run_final_eval(sess, null, class_count, image_lists, | |||
| jpeg_data_tensor, decoded_image_tensor, resized_image_tensor, | |||
| bottleneck_tensor); | |||
| // Write out the trained graph and labels with the weights stored as | |||
| // constants. | |||
| print($"Save final result to : {output_graph}"); | |||
| save_graph_to_file(output_graph, class_count); | |||
| File.WriteAllText(output_labels, string.Join("\n", image_lists.Keys)); | |||
| } | |||
| /// <summary> | |||
| /// Prediction | |||
| /// labels mapping, it's from output_lables.txt | |||
| /// 0 - daisy | |||
| /// 1 - dandelion | |||
| /// 2 - roses | |||
| /// 3 - sunflowers | |||
| /// 4 - tulips | |||
| /// </summary> | |||
| /// <param name="sess_"></param> | |||
| public void Predict(Session sess_) | |||
| { | |||
| if (!File.Exists(output_graph)) | |||
| return; | |||
| var labels = File.ReadAllLines(output_labels); | |||
| // predict image | |||
| var img_path = Path.Join(image_dir, "daisy", "5547758_eea9edfd54_n.jpg"); | |||
| var fileBytes = ReadTensorFromImageFile(img_path); | |||
| // import graph and variables | |||
| var graph = new Graph(); | |||
| graph.Import(output_graph, ""); | |||
| Tensor input = graph.OperationByName(input_tensor_name); | |||
| Tensor output = graph.OperationByName(final_tensor_name); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| var result = sess.run(output, (input, fileBytes)); | |||
| var prob = np.squeeze(result); | |||
| var idx = np.argmax(prob); | |||
| print($"Prediction result: [{labels[idx]} {prob[idx]}] for {img_path}."); | |||
| } | |||
| } | |||
| private NDArray ReadTensorFromImageFile(string file_name, | |||
| int input_height = 299, | |||
| int input_width = 299, | |||
| int input_mean = 0, | |||
| int input_std = 255) | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| var file_reader = tf.read_file(file_name, "file_reader"); | |||
| var image_reader = tf.image.decode_jpeg(file_reader, channels: 3, name: "jpeg_reader"); | |||
| var caster = tf.cast(image_reader, tf.float32); | |||
| var dims_expander = tf.expand_dims(caster, 0); | |||
| var resize = tf.constant(new int[] { input_height, input_width }); | |||
| var bilinear = tf.image.resize_bilinear(dims_expander, resize); | |||
| var sub = tf.subtract(bilinear, new float[] { input_mean }); | |||
| var normalized = tf.divide(sub, new float[] { input_std }); | |||
| using (var sess = tf.Session(graph)) | |||
| return sess.run(normalized); | |||
| } | |||
| public void Test(Session sess_) | |||
| { | |||
| if (!File.Exists(output_graph)) | |||
| return; | |||
| var graph = new Graph(); | |||
| graph.Import(output_graph); | |||
| var (jpeg_data_tensor, decoded_image_tensor) = add_jpeg_decoding(); | |||
| tf_with(tf.Session(graph), sess => | |||
| { | |||
| (test_accuracy, predictions) = run_final_eval(sess, null, class_count, image_lists, | |||
| jpeg_data_tensor, decoded_image_tensor, resized_image_tensor, | |||
| bottleneck_tensor); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,54 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| public class Dataset | |||
| { | |||
| string annot_path; | |||
| int[] input_sizes; | |||
| int batch_size; | |||
| bool data_aug; | |||
| int[] train_input_sizes; | |||
| NDArray strides; | |||
| NDArray anchors; | |||
| Dictionary<int, string> classes; | |||
| int num_classes; | |||
| int anchor_per_scale; | |||
| int max_bbox_per_scale; | |||
| string[] annotations; | |||
| int num_samples; | |||
| int batch_count; | |||
| public int Length = 0; | |||
| public Dataset(string dataset_type, Config cfg) | |||
| { | |||
| annot_path = dataset_type == "train" ? cfg.TRAIN.ANNOT_PATH : cfg.TEST.ANNOT_PATH; | |||
| input_sizes = dataset_type == "train" ? cfg.TRAIN.INPUT_SIZE : cfg.TEST.INPUT_SIZE; | |||
| batch_size = dataset_type == "train" ? cfg.TRAIN.BATCH_SIZE : cfg.TEST.BATCH_SIZE; | |||
| data_aug = dataset_type == "train" ? cfg.TRAIN.DATA_AUG : cfg.TEST.DATA_AUG; | |||
| train_input_sizes = cfg.TRAIN.INPUT_SIZE; | |||
| strides = np.array(cfg.YOLO.STRIDES); | |||
| classes = Utils.read_class_names(cfg.YOLO.CLASSES); | |||
| num_classes = classes.Count; | |||
| anchors = np.array(Utils.get_anchors(cfg.YOLO.ANCHORS)); | |||
| anchor_per_scale = cfg.YOLO.ANCHOR_PER_SCALE; | |||
| max_bbox_per_scale = 150; | |||
| annotations = load_annotations(); | |||
| num_samples = len(annotations); | |||
| batch_count = 0; | |||
| } | |||
| string[] load_annotations() | |||
| { | |||
| return File.ReadAllLines(annot_path); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,243 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| /// <summary> | |||
| /// Implementation of YOLO v3 object detector in Tensorflow | |||
| /// https://github.com/YunYang1994/tensorflow-yolov3 | |||
| /// </summary> | |||
| public class Main : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "YOLOv3"; | |||
| #region args | |||
| Dictionary<int, string> classes; | |||
| int num_classes; | |||
| float learn_rate_init; | |||
| float learn_rate_end; | |||
| int first_stage_epochs; | |||
| int second_stage_epochs; | |||
| int warmup_periods; | |||
| string time; | |||
| float moving_ave_decay; | |||
| int max_bbox_per_scale; | |||
| int steps_per_period; | |||
| Dataset trainset, testset; | |||
| Config cfg; | |||
| Tensor input_data; | |||
| Tensor label_sbbox; | |||
| Tensor label_mbbox; | |||
| Tensor label_lbbox; | |||
| Tensor true_sbboxes; | |||
| Tensor true_mbboxes; | |||
| Tensor true_lbboxes; | |||
| Tensor trainable; | |||
| Session sess; | |||
| YOLOv3 model; | |||
| VariableV1[] net_var; | |||
| Tensor giou_loss, conf_loss, prob_loss; | |||
| RefVariable global_step; | |||
| Tensor learn_rate; | |||
| Tensor loss; | |||
| List<RefVariable> first_stage_trainable_var_list; | |||
| Operation train_op_with_frozen_variables; | |||
| Operation train_op_with_all_variables; | |||
| Saver loader; | |||
| Saver saver; | |||
| #endregion | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = IsImportingGraph ? ImportGraph() : BuildGraph(); | |||
| var options = new SessionOptions(); | |||
| options.SetConfig(new ConfigProto { AllowSoftPlacement = true }); | |||
| using (var sess = tf.Session(graph, opts: options)) | |||
| { | |||
| Train(sess); | |||
| } | |||
| return true; | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| sess.run(tf.global_variables_initializer()); | |||
| print($"=> Restoring weights from: {cfg.TRAIN.INITIAL_WEIGHT} ... "); | |||
| loader.restore(sess, cfg.TRAIN.INITIAL_WEIGHT); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| var graph = new Graph().as_default(); | |||
| tf_with(tf.name_scope("define_input"), scope => | |||
| { | |||
| input_data = tf.placeholder(dtype: tf.float32, name: "input_data"); | |||
| label_sbbox = tf.placeholder(dtype: tf.float32, name: "label_sbbox"); | |||
| label_mbbox = tf.placeholder(dtype: tf.float32, name: "label_mbbox"); | |||
| label_lbbox = tf.placeholder(dtype: tf.float32, name: "label_lbbox"); | |||
| true_sbboxes = tf.placeholder(dtype: tf.float32, name: "sbboxes"); | |||
| true_mbboxes = tf.placeholder(dtype: tf.float32, name: "mbboxes"); | |||
| true_lbboxes = tf.placeholder(dtype: tf.float32, name: "lbboxes"); | |||
| trainable = tf.placeholder(dtype: tf.@bool, name: "training"); | |||
| }); | |||
| tf_with(tf.name_scope("define_loss"), scope => | |||
| { | |||
| model = new YOLOv3(cfg, input_data, trainable); | |||
| net_var = tf.global_variables(); | |||
| (giou_loss, conf_loss, prob_loss) = model.compute_loss( | |||
| label_sbbox, label_mbbox, label_lbbox, | |||
| true_sbboxes, true_mbboxes, true_lbboxes); | |||
| loss = giou_loss + conf_loss + prob_loss; | |||
| }); | |||
| Tensor global_step_update = null; | |||
| tf_with(tf.name_scope("learn_rate"), scope => | |||
| { | |||
| global_step = tf.Variable(1.0, dtype: tf.float64, trainable: false, name: "global_step"); | |||
| var warmup_steps = tf.constant(warmup_periods * steps_per_period, | |||
| dtype: tf.float64, name: "warmup_steps"); | |||
| var train_steps = tf.constant((first_stage_epochs + second_stage_epochs) * steps_per_period, | |||
| dtype: tf.float64, name: "train_steps"); | |||
| learn_rate = tf.cond( | |||
| pred: global_step < warmup_steps, | |||
| true_fn: delegate | |||
| { | |||
| return global_step / warmup_steps * learn_rate_init; | |||
| }, | |||
| false_fn: delegate | |||
| { | |||
| return learn_rate_end + 0.5 * (learn_rate_init - learn_rate_end) * | |||
| (1 + tf.cos( | |||
| (global_step - warmup_steps) / (train_steps - warmup_steps) * Math.PI)); | |||
| } | |||
| ); | |||
| global_step_update = tf.assign_add(global_step, 1.0f); | |||
| }); | |||
| Operation moving_ave = null; | |||
| tf_with(tf.name_scope("define_weight_decay"), scope => | |||
| { | |||
| var emv = tf.train.ExponentialMovingAverage(moving_ave_decay); | |||
| var vars = tf.trainable_variables().Select(x => (RefVariable)x).ToArray(); | |||
| moving_ave = emv.apply(vars); | |||
| }); | |||
| tf_with(tf.name_scope("define_first_stage_train"), scope => | |||
| { | |||
| first_stage_trainable_var_list = new List<RefVariable>(); | |||
| foreach (var var in tf.trainable_variables()) | |||
| { | |||
| var var_name = var.op.name; | |||
| var var_name_mess = var_name.Split('/'); | |||
| if (new[] { "conv_sbbox", "conv_mbbox", "conv_lbbox" }.Contains(var_name_mess[0])) | |||
| first_stage_trainable_var_list.Add(var as RefVariable); | |||
| } | |||
| var adam = tf.train.AdamOptimizer(learn_rate); | |||
| var first_stage_optimizer = adam.minimize(loss, var_list: first_stage_trainable_var_list); | |||
| tf_with(tf.control_dependencies(tf.get_collection<Operation>(tf.GraphKeys.UPDATE_OPS).ToArray()), delegate | |||
| { | |||
| tf_with(tf.control_dependencies(new ITensorOrOperation[] { first_stage_optimizer, global_step_update }), delegate | |||
| { | |||
| tf_with(tf.control_dependencies(new[] { moving_ave }), delegate | |||
| { | |||
| train_op_with_frozen_variables = tf.no_op(); | |||
| }); | |||
| }); | |||
| }); | |||
| }); | |||
| tf_with(tf.name_scope("define_second_stage_train"), delegate | |||
| { | |||
| var second_stage_trainable_var_list = tf.trainable_variables().Select(x => x as RefVariable).ToList(); | |||
| var adam = tf.train.AdamOptimizer(learn_rate); | |||
| var second_stage_optimizer = adam.minimize(loss, var_list: second_stage_trainable_var_list); | |||
| tf_with(tf.control_dependencies(tf.get_collection<Operation>(tf.GraphKeys.UPDATE_OPS).ToArray()), delegate | |||
| { | |||
| tf_with(tf.control_dependencies(new ITensorOrOperation[] { second_stage_optimizer, global_step_update }), delegate | |||
| { | |||
| tf_with(tf.control_dependencies(new[] { moving_ave }), delegate | |||
| { | |||
| train_op_with_all_variables = tf.no_op(); | |||
| }); | |||
| }); | |||
| }); | |||
| }); | |||
| tf_with(tf.name_scope("loader_and_saver"), delegate | |||
| { | |||
| loader = tf.train.Saver(net_var); | |||
| saver = tf.train.Saver(tf.global_variables(), max_to_keep: 10); | |||
| }); | |||
| tf_with(tf.name_scope("summary"), delegate | |||
| { | |||
| tf.summary.scalar("learn_rate", learn_rate); | |||
| tf.summary.scalar("giou_loss", giou_loss); | |||
| tf.summary.scalar("conf_loss", conf_loss); | |||
| tf.summary.scalar("prob_loss", prob_loss); | |||
| tf.summary.scalar("total_loss", loss); | |||
| }); | |||
| return graph; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| cfg = new Config(Name); | |||
| string dataDir = Path.Combine(Name, "data"); | |||
| Directory.CreateDirectory(dataDir); | |||
| classes = Utils.read_class_names(cfg.YOLO.CLASSES); | |||
| num_classes = classes.Count; | |||
| learn_rate_init = cfg.TRAIN.LEARN_RATE_INIT; | |||
| learn_rate_end = cfg.TRAIN.LEARN_RATE_END; | |||
| first_stage_epochs = cfg.TRAIN.FISRT_STAGE_EPOCHS; | |||
| second_stage_epochs = cfg.TRAIN.SECOND_STAGE_EPOCHS; | |||
| warmup_periods = cfg.TRAIN.WARMUP_EPOCHS; | |||
| DateTime now = DateTime.Now; | |||
| time = $"{now.Year}-{now.Month}-{now.Day}-{now.Hour}-{now.Minute}-{now.Minute}"; | |||
| moving_ave_decay = cfg.YOLO.MOVING_AVE_DECAY; | |||
| max_bbox_per_scale = 150; | |||
| trainset = new Dataset("train", cfg); | |||
| testset = new Dataset("test", cfg); | |||
| steps_per_period = trainset.Length; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,27 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Text; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| class Utils | |||
| { | |||
| public static Dictionary<int, string> read_class_names(string file) | |||
| { | |||
| var classes = new Dictionary<int, string>(); | |||
| foreach (var line in File.ReadAllLines(file)) | |||
| classes[classes.Count] = line; | |||
| return classes; | |||
| } | |||
| public static NDArray get_anchors(string file) | |||
| { | |||
| return np.array(File.ReadAllText(file).Split(',') | |||
| .Select(x => float.Parse(x)) | |||
| .ToArray()).reshape(3, 3, 2); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,291 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| public class YOLOv3 | |||
| { | |||
| Config cfg; | |||
| Tensor trainable; | |||
| Tensor input_data; | |||
| Dictionary<int, string> classes; | |||
| int num_class; | |||
| NDArray strides; | |||
| NDArray anchors; | |||
| int anchor_per_scale; | |||
| float iou_loss_thresh; | |||
| string upsample_method; | |||
| Tensor conv_lbbox; | |||
| Tensor conv_mbbox; | |||
| Tensor conv_sbbox; | |||
| Tensor pred_sbbox; | |||
| Tensor pred_mbbox; | |||
| Tensor pred_lbbox; | |||
| public YOLOv3(Config cfg_, Tensor input_data_, Tensor trainable_) | |||
| { | |||
| cfg = cfg_; | |||
| input_data = input_data_; | |||
| trainable = trainable_; | |||
| classes = Utils.read_class_names(cfg.YOLO.CLASSES); | |||
| num_class = len(classes); | |||
| strides = np.array(cfg.YOLO.STRIDES); | |||
| anchors = Utils.get_anchors(cfg.YOLO.ANCHORS); | |||
| anchor_per_scale = cfg.YOLO.ANCHOR_PER_SCALE; | |||
| iou_loss_thresh = cfg.YOLO.IOU_LOSS_THRESH; | |||
| upsample_method = cfg.YOLO.UPSAMPLE_METHOD; | |||
| (conv_lbbox, conv_mbbox, conv_sbbox) = __build_nework(input_data); | |||
| tf_with(tf.variable_scope("pred_sbbox"), scope => | |||
| { | |||
| pred_sbbox = decode(conv_sbbox, anchors[0], strides[0]); | |||
| }); | |||
| tf_with(tf.variable_scope("pred_mbbox"), scope => | |||
| { | |||
| pred_mbbox = decode(conv_mbbox, anchors[1], strides[1]); | |||
| }); | |||
| tf_with(tf.variable_scope("pred_lbbox"), scope => | |||
| { | |||
| pred_lbbox = decode(conv_lbbox, anchors[2], strides[2]); | |||
| }); | |||
| } | |||
| private (Tensor, Tensor, Tensor) __build_nework(Tensor input_data) | |||
| { | |||
| Tensor route_1, route_2; | |||
| (route_1, route_2, input_data) = backbone.darknet53(input_data, trainable); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 1024, 512 }, trainable, "conv52"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 512, 1024 }, trainable, "conv53"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 1024, 512 }, trainable, "conv54"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 512, 1024 }, trainable, "conv55"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 1024, 512 }, trainable, "conv56"); | |||
| var conv_lobj_branch = common.convolutional(input_data, new[] { 3, 3, 512, 1024 }, trainable, name: "conv_lobj_branch"); | |||
| var conv_lbbox = common.convolutional(conv_lobj_branch, new[] { 1, 1, 1024, 3 * (num_class + 5) }, | |||
| trainable: trainable, name: "conv_lbbox", activate: false, bn: false); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 512, 256 }, trainable, "conv57"); | |||
| input_data = common.upsample(input_data, name: "upsample0", method: upsample_method); | |||
| tf_with(tf.variable_scope("route_1"), delegate | |||
| { | |||
| input_data = tf.concat(new[] { input_data, route_2 }, axis: -1); | |||
| }); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 768, 256 }, trainable, "conv58"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 256, 512 }, trainable, "conv59"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 512, 256 }, trainable, "conv60"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 256, 512 }, trainable, "conv61"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 512, 256 }, trainable, "conv62"); | |||
| var conv_mobj_branch = common.convolutional(input_data, new[] { 3, 3, 256, 512 }, trainable, name: "conv_mobj_branch"); | |||
| conv_mbbox = common.convolutional(conv_mobj_branch, new[] { 1, 1, 512, 3 * (num_class + 5) }, | |||
| trainable: trainable, name: "conv_mbbox", activate: false, bn: false); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 256, 128 }, trainable, "conv63"); | |||
| input_data = common.upsample(input_data, name: "upsample1", method: upsample_method); | |||
| tf_with(tf.variable_scope("route_2"), delegate | |||
| { | |||
| input_data = tf.concat(new[] { input_data, route_1 }, axis: -1); | |||
| }); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 384, 128 }, trainable, "conv64"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 128, 256 }, trainable, "conv65"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 256, 128 }, trainable, "conv66"); | |||
| input_data = common.convolutional(input_data, new[] { 3, 3, 128, 256 }, trainable, "conv67"); | |||
| input_data = common.convolutional(input_data, new[] { 1, 1, 256, 128 }, trainable, "conv68"); | |||
| var conv_sobj_branch = common.convolutional(input_data, new[] { 3, 3, 128, 256 }, trainable, name: "conv_sobj_branch"); | |||
| conv_sbbox = common.convolutional(conv_sobj_branch, new[] { 1, 1, 256, 3 * (num_class + 5) }, | |||
| trainable: trainable, name: "conv_sbbox", activate: false, bn: false); | |||
| return (conv_lbbox, conv_mbbox, conv_sbbox); | |||
| } | |||
| private Tensor decode(Tensor conv_output, NDArray anchors, int stride) | |||
| { | |||
| var conv_shape = tf.shape(conv_output); | |||
| var batch_size = conv_shape[0]; | |||
| var output_size = conv_shape[1]; | |||
| anchor_per_scale = len(anchors); | |||
| conv_output = tf.reshape(conv_output, new object[] { batch_size, output_size, output_size, anchor_per_scale, 5 + num_class }); | |||
| var conv_raw_dxdy = conv_output[":", ":", ":", ":", "0:2"]; | |||
| var conv_raw_dwdh = conv_output[":", ":", ":", ":", "2:4"]; | |||
| var conv_raw_conf = conv_output[":", ":", ":", ":", "4:5"]; | |||
| var conv_raw_prob = conv_output[":", ":", ":", ":", "5:"]; | |||
| var y = tf.tile(tf.range(output_size, dtype: tf.int32)[":", tf.newaxis], new object[] { 1, output_size }); | |||
| var x = tf.tile(tf.range(output_size, dtype: tf.int32)[tf.newaxis, ":"], new object[] { output_size, 1 }); | |||
| var xy_grid = tf.concat(new[] { x[":", ":", tf.newaxis], y[":", ":", tf.newaxis] }, axis: -1); | |||
| xy_grid = tf.tile(xy_grid[tf.newaxis, ":", ":", tf.newaxis, ":"], new object[] { batch_size, 1, 1, anchor_per_scale, 1 }); | |||
| xy_grid = tf.cast(xy_grid, tf.float32); | |||
| var pred_xy = (tf.sigmoid(conv_raw_dxdy) + xy_grid) * stride; | |||
| var pred_wh = (tf.exp(conv_raw_dwdh) * anchors) * stride; | |||
| var pred_xywh = tf.concat(new[] { pred_xy, pred_wh }, axis: -1); | |||
| var pred_conf = tf.sigmoid(conv_raw_conf); | |||
| var pred_prob = tf.sigmoid(conv_raw_prob); | |||
| return tf.concat(new[] { pred_xywh, pred_conf, pred_prob }, axis: -1); | |||
| } | |||
| public (Tensor, Tensor, Tensor) compute_loss(Tensor label_sbbox, Tensor label_mbbox, Tensor label_lbbox, | |||
| Tensor true_sbbox, Tensor true_mbbox, Tensor true_lbbox) | |||
| { | |||
| Tensor giou_loss = null, conf_loss = null, prob_loss = null; | |||
| (Tensor, Tensor, Tensor) loss_sbbox = (null, null, null); | |||
| (Tensor, Tensor, Tensor) loss_mbbox = (null, null, null); | |||
| (Tensor, Tensor, Tensor) loss_lbbox = (null, null, null); | |||
| tf_with(tf.name_scope("smaller_box_loss"), delegate | |||
| { | |||
| loss_sbbox = loss_layer(conv_sbbox, pred_sbbox, label_sbbox, true_sbbox, | |||
| anchors: anchors[0], stride: strides[0]); | |||
| }); | |||
| tf_with(tf.name_scope("medium_box_loss"), delegate | |||
| { | |||
| loss_mbbox = loss_layer(conv_mbbox, pred_mbbox, label_mbbox, true_mbbox, | |||
| anchors: anchors[1], stride: strides[1]); | |||
| }); | |||
| tf_with(tf.name_scope("bigger_box_loss"), delegate | |||
| { | |||
| loss_lbbox = loss_layer(conv_lbbox, pred_lbbox, label_lbbox, true_lbbox, | |||
| anchors: anchors[2], stride: strides[2]); | |||
| }); | |||
| tf_with(tf.name_scope("giou_loss"), delegate | |||
| { | |||
| giou_loss = loss_sbbox.Item1 + loss_mbbox.Item1 + loss_lbbox.Item1; | |||
| }); | |||
| tf_with(tf.name_scope("conf_loss"), delegate | |||
| { | |||
| conf_loss = loss_sbbox.Item2 + loss_mbbox.Item2 + loss_lbbox.Item2; | |||
| }); | |||
| tf_with(tf.name_scope("prob_loss"), delegate | |||
| { | |||
| prob_loss = loss_sbbox.Item3 + loss_mbbox.Item3 + loss_lbbox.Item3; | |||
| }); | |||
| return (giou_loss, conf_loss, prob_loss); | |||
| } | |||
| public (Tensor, Tensor, Tensor) loss_layer(Tensor conv, Tensor pred, Tensor label, Tensor bboxes, NDArray anchors, int stride) | |||
| { | |||
| var conv_shape = tf.shape(conv); | |||
| var batch_size = conv_shape[0]; | |||
| var output_size = conv_shape[1]; | |||
| var input_size = stride * output_size; | |||
| conv = tf.reshape(conv, new object[] {batch_size, output_size, output_size, | |||
| anchor_per_scale, 5 + num_class }); | |||
| var conv_raw_conf = conv[":", ":", ":", ":", "4:5"]; | |||
| var conv_raw_prob = conv[":", ":", ":", ":", "5:"]; | |||
| var pred_xywh = pred[":", ":", ":", ":", "0:4"]; | |||
| var pred_conf = pred[":", ":", ":", ":", "4:5"]; | |||
| var label_xywh = label[":", ":", ":", ":", "0:4"]; | |||
| var respond_bbox = label[":", ":", ":", ":", "4:5"]; | |||
| var label_prob = label[":", ":", ":", ":", "5:"]; | |||
| var giou = tf.expand_dims(bbox_giou(pred_xywh, label_xywh), axis: -1); | |||
| input_size = tf.cast(input_size, tf.float32); | |||
| var bbox_loss_scale = 2.0 - 1.0 * label_xywh[":", ":", ":", ":", "2:3"] * label_xywh[":", ":", ":", ":", "3:4"] / (tf.sqrt(input_size)); | |||
| var giou_loss = respond_bbox * bbox_loss_scale * (1 - giou); | |||
| var iou = bbox_iou(pred_xywh[":", ":", ":", ":", tf.newaxis, ":"], bboxes[":", tf.newaxis, tf.newaxis, tf.newaxis, ":", ":"]); | |||
| var max_iou = tf.expand_dims(tf.reduce_max(iou, axis: new[] { -1 }), axis: -1); | |||
| var respond_bgd = (1.0 - respond_bbox) * tf.cast(max_iou < iou_loss_thresh, tf.float32); | |||
| var conf_focal = focal(respond_bbox, pred_conf); | |||
| var conf_loss = conf_focal * ( | |||
| respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits(labels: respond_bbox, logits: conv_raw_conf) + | |||
| respond_bgd * tf.nn.sigmoid_cross_entropy_with_logits(labels: respond_bbox, logits: conv_raw_conf)); | |||
| var prob_loss = respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits(labels: label_prob, logits: conv_raw_prob); | |||
| giou_loss = tf.reduce_mean(tf.reduce_sum(giou_loss, axis: new[] { 1, 2, 3, 4 })); | |||
| conf_loss = tf.reduce_mean(tf.reduce_sum(conf_loss, axis: new[] { 1, 2, 3, 4 })); | |||
| prob_loss = tf.reduce_mean(tf.reduce_sum(prob_loss, axis: new[] { 1, 2, 3, 4 })); | |||
| return (giou_loss, conf_loss, prob_loss); | |||
| } | |||
| public Tensor focal(Tensor target, Tensor actual, int alpha = 1, int gamma = 2) | |||
| { | |||
| var focal_loss = alpha * tf.pow(tf.abs(target - actual), gamma); | |||
| return focal_loss; | |||
| } | |||
| public Tensor bbox_giou(Tensor boxes1, Tensor boxes2) | |||
| { | |||
| boxes1 = tf.concat(new[] { boxes1["...", ":2"] - boxes1["...", "2:"] * 0.5, | |||
| boxes1["...", ":2"] + boxes1["...", "2:"] * 0.5}, axis: -1); | |||
| boxes2 = tf.concat(new[] { boxes2["...", ":2"] - boxes2["...", "2:"] * 0.5, | |||
| boxes2["...", ":2"] + boxes2["...", "2:"] * 0.5}, axis: -1); | |||
| boxes1 = tf.concat(new[] { tf.minimum(boxes1["...", ":2"], boxes1["...", "2:"]), | |||
| tf.maximum(boxes1["...", ":2"], boxes1["...", "2:"])}, axis: -1); | |||
| boxes2 = tf.concat(new[] { tf.minimum(boxes2["...", ":2"], boxes2["...", "2:"]), | |||
| tf.maximum(boxes2["...", ":2"], boxes2["...", "2:"])}, axis: -1); | |||
| var boxes1_area = (boxes1["...", "2"] - boxes1["...", "0"]) * (boxes1["...", "3"] - boxes1["...", "1"]); | |||
| var boxes2_area = (boxes2["...", "2"] - boxes2["...", "0"]) * (boxes2["...", "3"] - boxes2["...", "1"]); | |||
| var left_up = tf.maximum(boxes1["...", ":2"], boxes2["...", ":2"]); | |||
| var right_down = tf.minimum(boxes1["...", "2:"], boxes2["...", "2:"]); | |||
| var inter_section = tf.maximum(right_down - left_up, 0.0f); | |||
| var inter_area = inter_section["...", "0"] * inter_section["...", "1"]; | |||
| var union_area = boxes1_area + boxes2_area - inter_area; | |||
| var iou = inter_area / union_area; | |||
| var enclose_left_up = tf.minimum(boxes1["...", ":2"], boxes2["...", ":2"]); | |||
| var enclose_right_down = tf.maximum(boxes1["...", "2:"], boxes2["...", "2:"]); | |||
| var enclose = tf.maximum(enclose_right_down - enclose_left_up, 0.0); | |||
| var enclose_area = enclose["...", "0"] * enclose["...", "1"]; | |||
| var giou = iou - 1.0 * (enclose_area - union_area) / enclose_area; | |||
| return giou; | |||
| } | |||
| public Tensor bbox_iou(Tensor boxes1, Tensor boxes2) | |||
| { | |||
| var boxes1_area = boxes1["...", "2"] * boxes1["...", "3"]; | |||
| var boxes2_area = boxes2["...", "2"] * boxes2["...", "3"]; | |||
| boxes1 = tf.concat(new[] { boxes1["...", ":2"] - boxes1["...", "2:"] * 0.5, | |||
| boxes1["...", ":2"] + boxes1["...", "2:"] * 0.5}, axis: -1); | |||
| boxes2 = tf.concat(new[] { boxes2["...", ":2"] - boxes2["...", "2:"] * 0.5, | |||
| boxes2["...", ":2"] + boxes2["...", "2:"] * 0.5}, axis: -1); | |||
| var left_up = tf.maximum(boxes1["...", ":2"], boxes2["...", ":2"]); | |||
| var right_down = tf.minimum(boxes1["...", "2:"], boxes2["...", "2:"]); | |||
| var inter_section = tf.maximum(right_down - left_up, 0.0); | |||
| var inter_area = inter_section["...", "0"] * inter_section["...", "1"]; | |||
| var union_area = boxes1_area + boxes2_area - inter_area; | |||
| var iou = 1.0 * inter_area / union_area; | |||
| return iou; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,51 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| class backbone | |||
| { | |||
| public static (Tensor, Tensor, Tensor) darknet53(Tensor input_data, Tensor trainable) | |||
| { | |||
| return tf_with(tf.variable_scope("darknet"), scope => | |||
| { | |||
| input_data = common.convolutional(input_data, filters_shape: new int[] { 3, 3, 3, 32 }, trainable: trainable, name: "conv0"); | |||
| input_data = common.convolutional(input_data, filters_shape: new int[] { 3, 3, 32, 64 }, trainable: trainable, name: "conv1", downsample: true); | |||
| foreach (var i in range(1)) | |||
| input_data = common.residual_block(input_data, 64, 32, 64, trainable: trainable, name: $"residual{i + 0}"); | |||
| input_data = common.convolutional(input_data, filters_shape: new[] { 3, 3, 64, 128 }, | |||
| trainable: trainable, name: "conv4", downsample: true); | |||
| foreach (var i in range(2)) | |||
| input_data = common.residual_block(input_data, 128, 64, 128, trainable: trainable, name: $"residual{i + 1}"); | |||
| input_data = common.convolutional(input_data, filters_shape: new[] { 3, 3, 128, 256 }, | |||
| trainable: trainable, name: "conv9", downsample: true); | |||
| foreach (var i in range(8)) | |||
| input_data = common.residual_block(input_data, 256, 128, 256, trainable: trainable, name: $"residual{i + 3}"); | |||
| var route_1 = input_data; | |||
| input_data = common.convolutional(input_data, filters_shape: new int[] { 3, 3, 256, 512 }, | |||
| trainable: trainable, name: "conv26", downsample: true); | |||
| foreach (var i in range(8)) | |||
| input_data = common.residual_block(input_data, 512, 256, 512, trainable: trainable, name: $"residual{i + 11}"); | |||
| var route_2 = input_data; | |||
| input_data = common.convolutional(input_data, filters_shape: new[] { 3, 3, 512, 1024 }, | |||
| trainable: trainable, name: "conv43", downsample: true); | |||
| foreach (var i in range(4)) | |||
| input_data = common.residual_block(input_data, 1024, 512, 1024, trainable: trainable, name: $"residual{i + 19}"); | |||
| return (route_1, route_2, input_data); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,100 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| class common | |||
| { | |||
| public static Tensor convolutional(Tensor input_data, int[] filters_shape, Tensor trainable, | |||
| string name, bool downsample = false, bool activate = true, | |||
| bool bn = true) | |||
| { | |||
| return tf_with(tf.variable_scope(name), scope => | |||
| { | |||
| int[] strides; | |||
| string padding; | |||
| if (downsample) | |||
| { | |||
| (int pad_h, int pad_w) = ((int)Math.Floor((filters_shape[0] - 2) / 2.0f) + 1, (int)Math.Floor((filters_shape[1] - 2) / 2.0f) + 1); | |||
| var paddings = tf.constant(new int[,] { { 0, 0 }, { pad_h, pad_h }, { pad_w, pad_w }, { 0, 0 } }); | |||
| input_data = tf.pad(input_data, paddings, "CONSTANT"); | |||
| strides = new[] { 1, 2, 2, 1 }; | |||
| padding = "VALID"; | |||
| } | |||
| else | |||
| { | |||
| strides = new int[] { 1, 1, 1, 1 }; | |||
| padding = "SAME"; | |||
| } | |||
| var weight = tf.get_variable(name: "weight", dtype: tf.float32, trainable: true, | |||
| shape: filters_shape, initializer: tf.random_normal_initializer(stddev: 0.01f)); | |||
| var conv = tf.nn.conv2d(input: input_data, filter: weight, strides: strides, padding: padding); | |||
| if (bn) | |||
| { | |||
| conv = tf.layers.batch_normalization(conv, beta_initializer: tf.zeros_initializer, | |||
| gamma_initializer: tf.ones_initializer, | |||
| moving_mean_initializer: tf.zeros_initializer, | |||
| moving_variance_initializer: tf.ones_initializer, training: trainable); | |||
| } | |||
| else | |||
| { | |||
| var bias = tf.get_variable(name: "bias", shape: filters_shape.Last(), trainable: true, | |||
| dtype: tf.float32, initializer: tf.constant_initializer(0.0f)); | |||
| conv = tf.nn.bias_add(conv, bias); | |||
| } | |||
| if (activate) | |||
| conv = tf.nn.leaky_relu(conv, alpha: 0.1f); | |||
| return conv; | |||
| }); | |||
| } | |||
| public static Tensor upsample(Tensor input_data, string name, string method = "deconv") | |||
| { | |||
| Debug.Assert(new[] { "resize", "deconv" }.Contains(method)); | |||
| Tensor output = null; | |||
| if (method == "resize") | |||
| { | |||
| tf_with(tf.variable_scope(name), delegate | |||
| { | |||
| var input_shape = tf.shape(input_data); | |||
| output = tf.image.resize_nearest_neighbor(input_data, new Tensor[] { input_shape[1] * 2, input_shape[2] * 2 }); | |||
| }); | |||
| } | |||
| else if(method == "deconv") | |||
| { | |||
| throw new NotImplementedException("upsample.deconv"); | |||
| } | |||
| return output; | |||
| } | |||
| public static Tensor residual_block(Tensor input_data, int input_channel, int filter_num1, | |||
| int filter_num2, Tensor trainable, string name) | |||
| { | |||
| var short_cut = input_data; | |||
| return tf_with(tf.variable_scope(name), scope => | |||
| { | |||
| input_data = convolutional(input_data, filters_shape: new int[] { 1, 1, input_channel, filter_num1 }, | |||
| trainable: trainable, name: "conv1"); | |||
| input_data = convolutional(input_data, filters_shape: new int[] { 3, 3, filter_num1, filter_num2 }, | |||
| trainable: trainable, name: "conv2"); | |||
| var residual_output = input_data + short_cut; | |||
| return residual_output; | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,94 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Text; | |||
| namespace TensorFlowNET.Examples.ImageProcessing.YOLO | |||
| { | |||
| public class Config | |||
| { | |||
| public YoloConfig YOLO; | |||
| public TrainConfig TRAIN; | |||
| public TestConfig TEST; | |||
| public Config(string root) | |||
| { | |||
| YOLO = new YoloConfig(root); | |||
| TRAIN = new TrainConfig(root); | |||
| TEST = new TestConfig(root); | |||
| } | |||
| public class YoloConfig | |||
| { | |||
| string _root; | |||
| public string CLASSES; | |||
| public string ANCHORS; | |||
| public float MOVING_AVE_DECAY = 0.9995f; | |||
| public int[] STRIDES = new int[] { 8, 16, 32 }; | |||
| public int ANCHOR_PER_SCALE = 3; | |||
| public float IOU_LOSS_THRESH = 0.5f; | |||
| public string UPSAMPLE_METHOD = "resize"; | |||
| public string ORIGINAL_WEIGHT; | |||
| public string DEMO_WEIGHT; | |||
| public YoloConfig(string root) | |||
| { | |||
| _root = root; | |||
| CLASSES = Path.Combine(_root, "data", "classes", "coco.names"); | |||
| ANCHORS = Path.Combine(_root, "data", "anchors", "basline_anchors.txt"); | |||
| ORIGINAL_WEIGHT = Path.Combine(_root, "checkpoint", "yolov3_coco.ckpt"); | |||
| DEMO_WEIGHT = Path.Combine(_root, "checkpoint", "yolov3_coco_demo.ckpt"); | |||
| } | |||
| } | |||
| public class TrainConfig | |||
| { | |||
| string _root; | |||
| public int BATCH_SIZE = 6; | |||
| public int[] INPUT_SIZE = new int[] { 320, 352, 384, 416, 448, 480, 512, 544, 576, 608 }; | |||
| public bool DATA_AUG = true; | |||
| public float LEARN_RATE_INIT = 1e-4f; | |||
| public float LEARN_RATE_END = 1e-6f; | |||
| public int WARMUP_EPOCHS = 2; | |||
| public int FISRT_STAGE_EPOCHS = 20; | |||
| public int SECOND_STAGE_EPOCHS = 30; | |||
| public string INITIAL_WEIGHT; | |||
| public string ANNOT_PATH; | |||
| public TrainConfig(string root) | |||
| { | |||
| _root = root; | |||
| INITIAL_WEIGHT = Path.Combine(_root, "checkpoint", "yolov3_coco_demo.ckpt"); | |||
| ANNOT_PATH = Path.Combine(_root, "data", "dataset", "voc_train.txt"); | |||
| } | |||
| } | |||
| public class TestConfig | |||
| { | |||
| string _root; | |||
| public int BATCH_SIZE = 2; | |||
| public int[] INPUT_SIZE = new int[] { 544 }; | |||
| public bool DATA_AUG = false; | |||
| public bool WRITE_IMAGE = true; | |||
| public string WRITE_IMAGE_PATH; | |||
| public string WEIGHT_FILE; | |||
| public bool WRITE_IMAGE_SHOW_LABEL = true; | |||
| public bool SHOW_LABEL = true; | |||
| public int SECOND_STAGE_EPOCHS = 30; | |||
| public float SCORE_THRESHOLD = 0.3f; | |||
| public float IOU_THRESHOLD = 0.45f; | |||
| public string ANNOT_PATH; | |||
| public TestConfig(string root) | |||
| { | |||
| _root = root; | |||
| ANNOT_PATH = Path.Combine(_root, "data", "dataset", "voc_test.txt"); | |||
| WRITE_IMAGE_PATH = Path.Combine(_root, "data", "detection"); | |||
| WEIGHT_FILE = Path.Combine(_root, "checkpoint", "yolov3_test_loss=9.2099.ckpt-5"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,99 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using Tensorflow; | |||
| using Keras.Layers; | |||
| using NumSharp; | |||
| using Keras; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| public class Keras : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "Keras"; | |||
| public bool Run() | |||
| { | |||
| Console.WriteLine("================================== Keras =================================="); | |||
| #region data | |||
| var batch_size = 1000; | |||
| var (X, Y) = XOR(batch_size); | |||
| //var (X, Y, batch_size) = (np.array(new float[,]{{1, 0 },{1, 1 },{0, 0 },{0, 1 }}), np.array(new int[] { 0, 1, 1, 0 }), 4); | |||
| #endregion | |||
| #region features | |||
| var (features, labels) = (new Tensor(X), new Tensor(Y)); | |||
| var num_steps = 10000; | |||
| #endregion | |||
| #region model | |||
| var m = new Model(); | |||
| //m.Add(new Dense(8, name: "Hidden", activation: tf.nn.relu())).Add(new Dense(1, name:"Output")); | |||
| m.Add( | |||
| new ILayer[] { | |||
| new Dense(8, name: "Hidden_1", activation: tf.nn.relu()), | |||
| new Dense(1, name: "Output") | |||
| }); | |||
| m.train(num_steps, (X, Y)); | |||
| #endregion | |||
| return true; | |||
| } | |||
| static (NDArray, NDArray) XOR(int samples) | |||
| { | |||
| var X = new List<float[]>(); | |||
| var Y = new List<float>(); | |||
| var r = new Random(); | |||
| for (int i = 0; i < samples; i++) | |||
| { | |||
| var x1 = (float)r.Next(0, 2); | |||
| var x2 = (float)r.Next(0, 2); | |||
| var y = 0.0f; | |||
| if (x1 == x2) | |||
| y = 1.0f; | |||
| X.Add(new float[] { x1, x2 }); | |||
| Y.Add(y); | |||
| } | |||
| return (np.array(X.ToArray()), np.array(Y.ToArray())); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,153 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// How to optimise your input pipeline with queues and multi-threading | |||
| /// https://blog.metaflow.fr/tensorflow-how-to-optimise-your-input-pipeline-with-queues-and-multi-threading-e7c3874157e0 | |||
| /// </summary> | |||
| public class FullyConnected : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } | |||
| public string Name => "Fully Connected Neural Network"; | |||
| Tensor input = null; | |||
| Tensor x_inputs_data = null; | |||
| Tensor y_inputs_data = null; | |||
| Tensor accuracy = null; | |||
| Tensor y_true = null; | |||
| Tensor loss_op = null; | |||
| Operation train_op = null; | |||
| public Graph BuildGraph() | |||
| { | |||
| var g = tf.get_default_graph(); | |||
| Tensor z = null; | |||
| tf_with(tf.variable_scope("placeholder"), delegate | |||
| { | |||
| input = tf.placeholder(tf.float32, shape: (-1, 1024)); | |||
| y_true = tf.placeholder(tf.int32, shape: (-1, 1)); | |||
| }); | |||
| tf_with(tf.variable_scope("FullyConnected"), delegate | |||
| { | |||
| var w = tf.get_variable("w", shape: (1024, 1024), initializer: tf.random_normal_initializer(stddev: 0.1f)); | |||
| var b = tf.get_variable("b", shape: 1024, initializer: tf.constant_initializer(0.1)); | |||
| z = tf.matmul(input, w) + b; | |||
| var y = tf.nn.relu(z); | |||
| var w2 = tf.get_variable("w2", shape: (1024, 1), initializer: tf.random_normal_initializer(stddev: 0.1f)); | |||
| var b2 = tf.get_variable("b2", shape: 1, initializer: tf.constant_initializer(0.1)); | |||
| z = tf.matmul(y, w2) + b2; | |||
| }); | |||
| tf_with(tf.variable_scope("Loss"), delegate | |||
| { | |||
| var losses = tf.nn.sigmoid_cross_entropy_with_logits(tf.cast(y_true, tf.float32), z); | |||
| loss_op = tf.reduce_mean(losses); | |||
| }); | |||
| tf_with(tf.variable_scope("Accuracy"), delegate | |||
| { | |||
| var y_pred = tf.cast(z > 0, tf.int32); | |||
| accuracy = tf.reduce_mean(tf.cast(tf.equal(y_pred, y_true), tf.float32)); | |||
| // accuracy = tf.Print(accuracy, data =[accuracy], message = "accuracy:") | |||
| }); | |||
| // We add the training operation, ... | |||
| var adam = tf.train.AdamOptimizer(0.01f); | |||
| train_op = adam.minimize(loss_op, name: "train_op"); | |||
| return g; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // batches of 128 samples, each containing 1024 data points | |||
| x_inputs_data = tf.random_normal(new[] { 128, 1024 }, mean: 0, stddev: 1); | |||
| // We will try to predict this law: | |||
| // predict 1 if the sum of the elements is positive and 0 otherwise | |||
| y_inputs_data = tf.cast(tf.reduce_sum(x_inputs_data, axis: 1, keepdims: true) > 0, tf.int32); | |||
| } | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var g = BuildGraph(); | |||
| using (var sess = tf.Session()) | |||
| Train(sess); | |||
| return true; | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| var sw = new Stopwatch(); | |||
| sw.Start(); | |||
| // init variables | |||
| sess.run(tf.global_variables_initializer()); | |||
| // check the accuracy before training | |||
| var (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| sess.run(accuracy, (input, x_input), (y_true, y_input)); | |||
| // training | |||
| foreach (var i in range(5000)) | |||
| { | |||
| // by sampling some input data (fetching) | |||
| (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| var (_, loss) = sess.run((train_op, loss_op), (input, x_input), (y_true, y_input)); | |||
| // We regularly check the loss | |||
| if (i % 500 == 0) | |||
| print($"iter:{i} - loss:{loss}"); | |||
| } | |||
| // Finally, we check our final accuracy | |||
| (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| sess.run(accuracy, (input, x_input), (y_true, y_input)); | |||
| print($"Time taken: {sw.Elapsed.TotalSeconds}s"); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,129 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.Text; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// How to optimise your input pipeline with queues and multi-threading | |||
| /// https://blog.metaflow.fr/tensorflow-how-to-optimise-your-input-pipeline-with-queues-and-multi-threading-e7c3874157e0 | |||
| /// </summary> | |||
| public class FullyConnectedInQueue : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public bool IsImportingGraph { get; set; } | |||
| public string Name => "Fully Connected Neural Network In Queue"; | |||
| Tensor input = null; | |||
| Tensor x_inputs_data = null; | |||
| Tensor y_inputs_data = null; | |||
| Tensor accuracy = null; | |||
| Tensor y_true = null; | |||
| Tensor loss_op = null; | |||
| Operation train_op = null; | |||
| public Graph BuildGraph() | |||
| { | |||
| var g = tf.get_default_graph(); | |||
| Tensor z = null; | |||
| // We build our small model: a basic two layers neural net with ReLU | |||
| tf_with(tf.variable_scope("queue"), delegate | |||
| { | |||
| // enqueue 5 batches | |||
| var q = tf.FIFOQueue(capacity: 5, dtype: tf.float32); | |||
| // We use the "enqueue" operation so 1 element of the queue is the full batch | |||
| var enqueue_op = q.enqueue(x_inputs_data); | |||
| var numberOfThreads = 1; | |||
| // var qr = tf.train.QueueRunner(q, [enqueue_op] * numberOfThreads); | |||
| }); | |||
| return g; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // batches of 128 samples, each containing 1024 data points | |||
| x_inputs_data = tf.random_normal(new[] { 128, 1024 }, mean: 0, stddev: 1); | |||
| // We will try to predict this law: | |||
| // predict 1 if the sum of the elements is positive and 0 otherwise | |||
| y_inputs_data = tf.cast(tf.reduce_sum(x_inputs_data, axis: 1, keepdims: true) > 0, tf.int32); | |||
| } | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var g = BuildGraph(); | |||
| using (var sess = tf.Session()) | |||
| Train(sess); | |||
| return true; | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| var sw = new Stopwatch(); | |||
| sw.Start(); | |||
| // init variables | |||
| sess.run(tf.global_variables_initializer()); | |||
| // check the accuracy before training | |||
| var (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| sess.run(accuracy, (input, x_input), (y_true, y_input)); | |||
| // training | |||
| foreach (var i in range(5000)) | |||
| { | |||
| // by sampling some input data (fetching) | |||
| (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| var (_, loss) = sess.run((train_op, loss_op), (input, x_input), (y_true, y_input)); | |||
| // We regularly check the loss | |||
| if (i % 500 == 0) | |||
| print($"iter:{i} - loss:{loss}"); | |||
| } | |||
| // Finally, we check our final accuracy | |||
| (x_input, y_input) = sess.run((x_inputs_data, y_inputs_data)); | |||
| sess.run(accuracy, (input, x_input), (y_true, y_input)); | |||
| print($"Time taken: {sw.Elapsed.TotalSeconds}s"); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,190 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Simple vanilla neural net solving the famous XOR problem | |||
| /// https://github.com/amygdala/tensorflow-workshop/blob/master/workshop_sections/getting_started/xor/README.md | |||
| /// </summary> | |||
| public class NeuralNetXor : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "NN XOR"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public int num_steps = 10000; | |||
| private NDArray data; | |||
| private (Operation, Tensor, Tensor) make_graph(Tensor features,Tensor labels, int num_hidden = 8) | |||
| { | |||
| var stddev = 1 / Math.Sqrt(2); | |||
| var hidden_weights = tf.Variable(tf.truncated_normal(new int []{2, num_hidden}, seed:1, stddev: (float) stddev )); | |||
| // Shape [4, num_hidden] | |||
| var hidden_activations = tf.nn.relu(tf.matmul(features, hidden_weights)); | |||
| var output_weights = tf.Variable(tf.truncated_normal( | |||
| new[] {num_hidden, 1}, | |||
| seed: 17, | |||
| stddev: (float) (1 / Math.Sqrt(num_hidden)) | |||
| )); | |||
| // Shape [4, 1] | |||
| var logits = tf.matmul(hidden_activations, output_weights); | |||
| // Shape [4] | |||
| var predictions = tf.tanh(tf.squeeze(logits)); | |||
| var loss = tf.reduce_mean(tf.square(predictions - tf.cast(labels, tf.float32)), name:"loss"); | |||
| var gs = tf.Variable(0, trainable: false, name: "global_step"); | |||
| var train_op = tf.train.GradientDescentOptimizer(0.2f).minimize(loss, global_step: gs); | |||
| return (train_op, loss, gs); | |||
| } | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| float loss_value = 0; | |||
| if (IsImportingGraph) | |||
| loss_value = RunWithImportedGraph(); | |||
| else | |||
| loss_value = RunWithBuiltGraph(); | |||
| return loss_value < 0.0628; | |||
| } | |||
| private float RunWithImportedGraph() | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| tf.train.import_meta_graph("graph/xor.meta"); | |||
| Tensor features = graph.get_operation_by_name("Placeholder"); | |||
| Tensor labels = graph.get_operation_by_name("Placeholder_1"); | |||
| Tensor loss = graph.get_operation_by_name("loss"); | |||
| Tensor train_op = graph.get_operation_by_name("train_op"); | |||
| Tensor global_step = graph.get_operation_by_name("global_step"); | |||
| var init = tf.global_variables_initializer(); | |||
| float loss_value = 0; | |||
| // Start tf session | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| sess.run(init); | |||
| var step = 0; | |||
| var y_ = np.array(new int[] { 1, 0, 0, 1 }, dtype: np.int32); | |||
| while (step < num_steps) | |||
| { | |||
| // original python: | |||
| //_, step, loss_value = sess.run( | |||
| // [train_op, gs, loss], | |||
| // feed_dict={features: xy, labels: y_} | |||
| // ) | |||
| (_, step, loss_value) = sess.run((train_op, global_step, loss), (features, data), (labels, y_)); | |||
| if (step == 1 || step % 1000 == 0) | |||
| Console.WriteLine($"Step {step} loss: {loss_value}"); | |||
| } | |||
| Console.WriteLine($"Final loss: {loss_value}"); | |||
| } | |||
| return loss_value; | |||
| } | |||
| private float RunWithBuiltGraph() | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| var features = tf.placeholder(tf.float32, new TensorShape(4, 2)); | |||
| var labels = tf.placeholder(tf.int32, new TensorShape(4)); | |||
| var (train_op, loss, gs) = make_graph(features, labels); | |||
| var init = tf.global_variables_initializer(); | |||
| float loss_value = 0; | |||
| // Start tf session | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| sess.run(init); | |||
| var step = 0; | |||
| var y_ = np.array(new int[] { 1, 0, 0, 1 }, dtype: np.int32); | |||
| while (step < num_steps) | |||
| { | |||
| (_, step, loss_value) = sess.run((train_op, gs, loss), (features, data), (labels, y_)); | |||
| if (step == 1 || step % 1000 == 0) | |||
| Console.WriteLine($"Step {step} loss: {loss_value}"); | |||
| } | |||
| Console.WriteLine($"Final loss: {loss_value}"); | |||
| } | |||
| return loss_value; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| data = new float[,] | |||
| { | |||
| {1, 0 }, | |||
| {1, 1 }, | |||
| {0, 0 }, | |||
| {0, 1 } | |||
| }; | |||
| if (IsImportingGraph) | |||
| { | |||
| // download graph meta data | |||
| string url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/graph/xor.meta"; | |||
| Web.Download(url, "graph", "xor.meta"); | |||
| } | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,120 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.Drawing; | |||
| using System.Linq; | |||
| using System.Reflection; | |||
| using Tensorflow; | |||
| using Console = Colorful.Console; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| class Program | |||
| { | |||
| static void Main(string[] args) | |||
| { | |||
| int finished = 0; | |||
| var errors = new List<string>(); | |||
| var success = new List<string>(); | |||
| var parsedArgs = ParseArgs(args); | |||
| var examples = Assembly.GetEntryAssembly().GetTypes() | |||
| .Where(x => x.GetInterfaces().Contains(typeof(IExample))) | |||
| .Select(x => (IExample)Activator.CreateInstance(x)) | |||
| .Where(x => x.Enabled) | |||
| .OrderBy(x => x.Name) | |||
| .ToArray(); | |||
| if (parsedArgs.ContainsKey("ex")) | |||
| examples = examples.Where(x => x.Name == parsedArgs["ex"]).ToArray(); | |||
| Console.WriteLine(Environment.OSVersion.ToString(), Color.Yellow); | |||
| Console.WriteLine($"TensorFlow Binary v{tf.VERSION}", Color.Yellow); | |||
| Console.WriteLine($"TensorFlow.NET v{Assembly.GetAssembly(typeof(TF_DataType)).GetName().Version}", Color.Yellow); | |||
| for (var i = 0; i < examples.Length; i++) | |||
| Console.WriteLine($"[{i}]: {examples[i].Name}"); | |||
| var key = "0"; | |||
| if (examples.Length > 1) | |||
| { | |||
| Console.Write($"Choose one example to run, hit [Enter] to run all: ", Color.Yellow); | |||
| key = Console.ReadLine(); | |||
| } | |||
| var sw = new Stopwatch(); | |||
| for (var i = 0; i < examples.Length; i++) | |||
| { | |||
| if (i.ToString() != key && key != "") continue; | |||
| var example = examples[i]; | |||
| Console.WriteLine($"{DateTime.UtcNow} Starting {example.Name}", Color.White); | |||
| try | |||
| { | |||
| sw.Restart(); | |||
| bool isSuccess = example.Run(); | |||
| sw.Stop(); | |||
| if (isSuccess) | |||
| success.Add($"Example: {example.Name} in {sw.Elapsed.TotalSeconds}s"); | |||
| else | |||
| errors.Add($"Example: {example.Name} in {sw.Elapsed.TotalSeconds}s"); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| errors.Add($"Example: {example.Name}"); | |||
| Console.WriteLine(ex); | |||
| } | |||
| finished++; | |||
| Console.WriteLine($"{DateTime.UtcNow} Completed {example.Name}", Color.White); | |||
| } | |||
| success.ForEach(x => Console.WriteLine($"{x} is OK!", Color.Green)); | |||
| errors.ForEach(x => Console.WriteLine($"{x} is Failed!", Color.Red)); | |||
| Console.WriteLine($"{finished} of {examples.Length} example(s) are completed."); | |||
| Console.ReadLine(); | |||
| } | |||
| private static Dictionary<string, string> ParseArgs(string[] args) | |||
| { | |||
| var parsed = new Dictionary<string, string>(); | |||
| for (int i = 0; i < args.Length; i++) | |||
| { | |||
| string key = args[i].Substring(1); | |||
| switch (key) | |||
| { | |||
| case "ex": | |||
| parsed.Add(key, args[++i]); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| return parsed; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,32 +0,0 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <OutputType>Exe</OutputType> | |||
| <TargetFramework>netcoreapp3.0</TargetFramework> | |||
| <GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||
| <DefineConstants>DEBUG;TRACE</DefineConstants> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Compile Remove="Keras.cs" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Colorful.Console" Version="1.2.9" /> | |||
| <PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> | |||
| <PackageReference Include="SciSharp.TensorFlow.Redist" Version="1.14.0" /> | |||
| <PackageReference Include="SharpZipLib" Version="1.1.0" /> | |||
| <PackageReference Include="System.Drawing.Common" Version="4.5.1" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\..\src\TensorFlowDatasets\TensorFlowDatasets.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowNET.Models\TensorFlowNET.Models.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowText\TensorFlowText.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowHub\TensorFlowHub.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,164 +0,0 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using Tensorflow; | |||
| using Newtonsoft.Json; | |||
| using System.Linq; | |||
| using NumSharp; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// This example classifies movie reviews as positive or negative using the text of the review. | |||
| /// This is a binary—or two-class—classification, an important and widely applicable kind of machine learning problem. | |||
| /// https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_text_classification.ipynb | |||
| /// </summary> | |||
| public class BinaryTextClassification : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public string Name => "Binary Text Classification"; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| string dir = "binary_text_classification"; | |||
| string dataFile = "imdb.zip"; | |||
| NDArray train_data, train_labels, test_data, test_labels; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| Console.WriteLine($"Training entries: {train_data.shape[0]}, labels: {train_labels.shape[0]}"); | |||
| // A dictionary mapping words to an integer index | |||
| var word_index = GetWordIndex(); | |||
| /*train_data = keras.preprocessing.sequence.pad_sequences(train_data, | |||
| value: word_index["<PAD>"], | |||
| padding: "post", | |||
| maxlen: 256); | |||
| test_data = keras.preprocessing.sequence.pad_sequences(test_data, | |||
| value: word_index["<PAD>"], | |||
| padding: "post", | |||
| maxlen: 256);*/ | |||
| // input shape is the vocabulary count used for the movie reviews (10,000 words) | |||
| int vocab_size = 10000; | |||
| var model = keras.Sequential(); | |||
| var layer = keras.layers.Embedding(vocab_size, 16); | |||
| model.add(layer); | |||
| return false; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| Directory.CreateDirectory(dir); | |||
| // get model file | |||
| string url = $"https://github.com/SciSharp/TensorFlow.NET/raw/master/data/{dataFile}"; | |||
| Utility.Web.Download(url, dir, "imdb.zip"); | |||
| Utility.Compress.UnZip(Path.Join(dir, $"imdb.zip"), dir); | |||
| // prepare training dataset | |||
| var x_train = ReadData(Path.Join(dir, "x_train.txt")); | |||
| var labels_train = ReadData(Path.Join(dir, "y_train.txt")); | |||
| var indices_train = ReadData(Path.Join(dir, "indices_train.txt")); | |||
| x_train = x_train[indices_train]; | |||
| labels_train = labels_train[indices_train]; | |||
| var x_test = ReadData(Path.Join(dir, "x_test.txt")); | |||
| var labels_test = ReadData(Path.Join(dir, "y_test.txt")); | |||
| var indices_test = ReadData(Path.Join(dir, "indices_test.txt")); | |||
| x_test = x_test[indices_test]; | |||
| labels_test = labels_test[indices_test]; | |||
| // not completed | |||
| var xs = x_train.hstack(x_test); | |||
| var labels = labels_train.hstack(labels_test); | |||
| var idx = x_train.size; | |||
| var y_train = labels_train; | |||
| var y_test = labels_test; | |||
| // convert x_train | |||
| train_data = new NDArray(np.int32, (x_train.size, 256)); | |||
| /*for (int i = 0; i < x_train.size; i++) | |||
| train_data[i] = x_train[i].Data<string>()[1].Split(',').Select(x => int.Parse(x)).ToArray();*/ | |||
| test_data = new NDArray(np.int32, (x_test.size, 256)); | |||
| /*for (int i = 0; i < x_test.size; i++) | |||
| test_data[i] = x_test[i].Data<string>()[1].Split(',').Select(x => int.Parse(x)).ToArray();*/ | |||
| train_labels = y_train; | |||
| test_labels = y_test; | |||
| } | |||
| private NDArray ReadData(string file) | |||
| { | |||
| var lines = File.ReadAllLines(file); | |||
| var nd = new NDArray(lines[0].StartsWith("[") ? typeof(string) : np.int32, new Shape(lines.Length)); | |||
| if (lines[0].StartsWith("[")) | |||
| { | |||
| for (int i = 0; i < lines.Length; i++) | |||
| { | |||
| /*var matches = Regex.Matches(lines[i], @"\d+\s*"); | |||
| var data = new int[matches.Count]; | |||
| for (int j = 0; j < data.Length; j++) | |||
| data[j] = Convert.ToInt32(matches[j].Value); | |||
| nd[i] = data.ToArray();*/ | |||
| nd[i] = lines[i].Substring(1, lines[i].Length - 2).Replace(" ", string.Empty); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = 0; i < lines.Length; i++) | |||
| nd[i] = Convert.ToInt32(lines[i]); | |||
| } | |||
| return nd; | |||
| } | |||
| private Dictionary<string, int> GetWordIndex() | |||
| { | |||
| var result = new Dictionary<string, int>(); | |||
| var json = File.ReadAllText(Path.Join(dir, "imdb_word_index.json")); | |||
| var dict = JsonConvert.DeserializeObject<Dictionary<string, int>>(json); | |||
| dict.Keys.Select(k => result[k] = dict[k] + 3).ToList(); | |||
| result["<PAD>"] = 0; | |||
| result["<START>"] = 1; | |||
| result["<UNK>"] = 2; // unknown | |||
| result["<UNUSED>"] = 3; | |||
| return result; | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,272 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using NumSharp; | |||
| using Tensorflow; | |||
| using Tensorflow.Sessions; | |||
| using TensorFlowNET.Examples.Text; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// https://github.com/dongjun-Lee/text-classification-models-tf | |||
| /// </summary> | |||
| public class CnnTextClassification : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "CNN Text Classification"; | |||
| public int? DataLimit = null; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| const string dataDir = "cnn_text"; | |||
| string dataFileName = "dbpedia_csv.tar.gz"; | |||
| string TRAIN_PATH = $"{dataDir}/dbpedia_csv/train.csv"; | |||
| string TEST_PATH = $"{dataDir}/dbpedia_csv/test.csv"; | |||
| int NUM_CLASS = 14; | |||
| int BATCH_SIZE = 64; | |||
| int NUM_EPOCHS = 10; | |||
| int WORD_MAX_LEN = 100; | |||
| int CHAR_MAX_LEN = 1014; | |||
| float loss_value = 0; | |||
| double max_accuracy = 0; | |||
| int alphabet_size = -1; | |||
| int vocabulary_size = -1; | |||
| NDArray train_x, valid_x, train_y, valid_y; | |||
| ITextModel textModel; | |||
| public string ModelName = "word_cnn"; // word_cnn | char_cnn | vd_cnn | word_rnn | att_rnn | rcnn | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = IsImportingGraph ? ImportGraph() : BuildGraph(); | |||
| using (var sess = tf.Session(graph)) | |||
| Train(sess); | |||
| return max_accuracy > 0.9; | |||
| } | |||
| // TODO: this originally is an SKLearn utility function. it randomizes train and test which we don't do here | |||
| private (NDArray, NDArray, NDArray, NDArray) train_test_split(NDArray x, NDArray y, float test_size = 0.3f) | |||
| { | |||
| Console.WriteLine("Splitting in Training and Testing data..."); | |||
| int len = x.shape[0]; | |||
| //int classes = y.Data<int>().Distinct().Count(); | |||
| //int samples = len / classes; | |||
| int train_size = (int)Math.Round(len * (1 - test_size)); | |||
| train_x = x[new Slice(stop: train_size), new Slice()]; | |||
| valid_x = x[new Slice(start: train_size), new Slice()]; | |||
| train_y = y[new Slice(stop: train_size)]; | |||
| valid_y = y[new Slice(start: train_size)]; | |||
| Console.WriteLine("\tDONE"); | |||
| return (train_x, valid_x, train_y, valid_y); | |||
| } | |||
| private void FillWithShuffledLabels(int[][] x, int[] y, int[][] shuffled_x, int[] shuffled_y, Random random, Dictionary<int, HashSet<int>> labels) | |||
| { | |||
| int i = 0; | |||
| var label_keys = labels.Keys.ToArray(); | |||
| while (i < shuffled_x.Length) | |||
| { | |||
| var key = label_keys[random.Next(label_keys.Length)]; | |||
| var set = labels[key]; | |||
| var index = set.First(); | |||
| if (set.Count == 0) | |||
| { | |||
| labels.Remove(key); // remove the set as it is empty | |||
| label_keys = labels.Keys.ToArray(); | |||
| } | |||
| shuffled_x[i] = x[index]; | |||
| shuffled_y[i] = y[index]; | |||
| i++; | |||
| } | |||
| } | |||
| private IEnumerable<(NDArray, NDArray, int)> batch_iter(NDArray inputs, NDArray outputs, int batch_size, int num_epochs) | |||
| { | |||
| var num_batches_per_epoch = (len(inputs) - 1) / batch_size + 1; | |||
| var total_batches = num_batches_per_epoch * num_epochs; | |||
| foreach (var epoch in range(num_epochs)) | |||
| { | |||
| foreach (var batch_num in range(num_batches_per_epoch)) | |||
| { | |||
| var start_index = batch_num * batch_size; | |||
| var end_index = Math.Min((batch_num + 1) * batch_size, len(inputs)); | |||
| if (end_index <= start_index) | |||
| break; | |||
| yield return (inputs[new Slice(start_index, end_index)], outputs[new Slice(start_index, end_index)], total_batches); | |||
| } | |||
| } | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // full dataset https://github.com/le-scientifique/torchDatasets/raw/master/dbpedia_csv.tar.gz | |||
| var url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/data/dbpedia_subset.zip"; | |||
| Web.Download(url, dataDir, "dbpedia_subset.zip"); | |||
| Compress.UnZip(Path.Combine(dataDir, "dbpedia_subset.zip"), Path.Combine(dataDir, "dbpedia_csv")); | |||
| Console.WriteLine("Building dataset..."); | |||
| var (x, y) = (new int[0][], new int[0]); | |||
| if(ModelName == "char_cnn") | |||
| { | |||
| (x, y, alphabet_size) = DataHelpers.build_char_dataset(TRAIN_PATH, "char_cnn", CHAR_MAX_LEN); | |||
| } | |||
| else | |||
| { | |||
| var word_dict = DataHelpers.build_word_dict(TRAIN_PATH); | |||
| vocabulary_size = len(word_dict); | |||
| (x, y) = DataHelpers.build_word_dataset(TRAIN_PATH, word_dict, WORD_MAX_LEN); | |||
| } | |||
| Console.WriteLine("\tDONE "); | |||
| var (train_x, valid_x, train_y, valid_y) = train_test_split(x, y, test_size: 0.15f); | |||
| Console.WriteLine("Training set size: " + train_x.shape[0]); | |||
| Console.WriteLine("Test set size: " + valid_x.shape[0]); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| // download graph meta data | |||
| var meta_file = "word_cnn.meta"; | |||
| var meta_path = Path.Combine("graph", meta_file); | |||
| if (File.GetLastWriteTime(meta_path) < new DateTime(2019, 05, 11)) | |||
| { | |||
| // delete old cached file which contains errors | |||
| Console.WriteLine("Discarding cached file: " + meta_path); | |||
| if(File.Exists(meta_path)) | |||
| File.Delete(meta_path); | |||
| } | |||
| var url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/graph/" + meta_file; | |||
| Web.Download(url, "graph", meta_file); | |||
| Console.WriteLine("Import graph..."); | |||
| tf.train.import_meta_graph(Path.Join("graph", meta_file)); | |||
| Console.WriteLine("\tDONE "); | |||
| return graph; | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| var graph = tf.Graph().as_default(); | |||
| switch (ModelName) | |||
| { | |||
| case "word_cnn": | |||
| textModel = new WordCnn(vocabulary_size, WORD_MAX_LEN, NUM_CLASS); | |||
| break; | |||
| case "char_cnn": | |||
| textModel = new CharCnn(alphabet_size, CHAR_MAX_LEN, NUM_CLASS); | |||
| break; | |||
| } | |||
| return graph; | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| var graph = tf.get_default_graph(); | |||
| sess.run(tf.global_variables_initializer()); | |||
| var saver = tf.train.Saver(tf.global_variables()); | |||
| var train_batches = batch_iter(train_x, train_y, BATCH_SIZE, NUM_EPOCHS); | |||
| var num_batches_per_epoch = (len(train_x) - 1) / BATCH_SIZE + 1; | |||
| Tensor is_training = graph.OperationByName("is_training"); | |||
| Tensor model_x = graph.OperationByName("x"); | |||
| Tensor model_y = graph.OperationByName("y"); | |||
| Tensor loss = graph.OperationByName("loss/Mean"); | |||
| Operation optimizer = graph.OperationByName("loss/Adam"); | |||
| Tensor global_step = graph.OperationByName("Variable"); | |||
| Tensor accuracy = graph.OperationByName("accuracy/accuracy"); | |||
| var sw = new Stopwatch(); | |||
| sw.Start(); | |||
| int step = 0; | |||
| foreach (var (x_batch, y_batch, total) in train_batches) | |||
| { | |||
| (_, step, loss_value) = sess.run((optimizer, global_step, loss), | |||
| (model_x, x_batch), (model_y, y_batch), (is_training, true)); | |||
| if (step % 10 == 0) | |||
| { | |||
| Console.WriteLine($"Training on batch {step}/{total} loss: {loss_value.ToString("0.0000")} {sw.ElapsedMilliseconds}ms."); | |||
| sw.Restart(); | |||
| } | |||
| if (step % 100 == 0) | |||
| { | |||
| // Test accuracy with validation data for each epoch. | |||
| var valid_batches = batch_iter(valid_x, valid_y, BATCH_SIZE, 1); | |||
| var (sum_accuracy, cnt) = (0.0f, 0); | |||
| foreach (var (valid_x_batch, valid_y_batch, total_validation_batches) in valid_batches) | |||
| { | |||
| var valid_feed_dict = new FeedDict | |||
| { | |||
| [model_x] = valid_x_batch, | |||
| [model_y] = valid_y_batch, | |||
| [is_training] = false | |||
| }; | |||
| float accuracy_value = sess.run(accuracy, (model_x, valid_x_batch), (model_y, valid_y_batch), (is_training, false)); | |||
| sum_accuracy += accuracy_value; | |||
| cnt += 1; | |||
| } | |||
| var valid_accuracy = sum_accuracy / cnt; | |||
| print($"\nValidation Accuracy = {valid_accuracy.ToString("P")}\n"); | |||
| // Save model | |||
| if (valid_accuracy > max_accuracy) | |||
| { | |||
| max_accuracy = valid_accuracy; | |||
| saver.save(sess, $"{dataDir}/word_cnn.ckpt", global_step: step); | |||
| print("Model is saved.\n"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,218 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Security.Cryptography; | |||
| using System.Text; | |||
| using System.Text.RegularExpressions; | |||
| using TensorFlowNET.Examples.Utility; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| public class DataHelpers | |||
| { | |||
| public static Dictionary<string, int> build_word_dict(string path) | |||
| { | |||
| var contents = File.ReadAllLines(path); | |||
| var words = new List<string>(); | |||
| foreach (var content in contents) | |||
| words.AddRange(clean_str(content).Split(' ').Where(x => x.Length > 1)); | |||
| var word_counter = words.GroupBy(x => x) | |||
| .Select(x => new { Word = x.Key, Count = x.Count() }) | |||
| .OrderByDescending(x => x.Count) | |||
| .ToArray(); | |||
| var word_dict = new Dictionary<string, int>(); | |||
| word_dict["<pad>"] = 0; | |||
| word_dict["<unk>"] = 1; | |||
| word_dict["<eos>"] = 2; | |||
| foreach (var word in word_counter) | |||
| word_dict[word.Word] = word_dict.Count; | |||
| return word_dict; | |||
| } | |||
| public static (int[][], int[]) build_word_dataset(string path, Dictionary<string, int> word_dict, int document_max_len) | |||
| { | |||
| var contents = File.ReadAllLines(path); | |||
| var x = contents.Select(c => (clean_str(c) + " <eos>") | |||
| .Split(' ').Take(document_max_len) | |||
| .Select(w => word_dict.ContainsKey(w) ? word_dict[w] : word_dict["<unk>"]).ToArray()) | |||
| .ToArray(); | |||
| for (int i = 0; i < x.Length; i++) | |||
| if (x[i].Length == document_max_len) | |||
| x[i][document_max_len - 1] = word_dict["<eos>"]; | |||
| else | |||
| Array.Resize(ref x[i], document_max_len); | |||
| var y = contents.Select(c => int.Parse(c.Substring(0, c.IndexOf(','))) - 1).ToArray(); | |||
| return (x, y); | |||
| } | |||
| public static (int[][], int[], int) build_char_dataset(string path, string model, int document_max_len, int? limit = null, bool shuffle=true) | |||
| { | |||
| string alphabet = "abcdefghijklmnopqrstuvwxyz0123456789-,;.!?:’'\"/|_#$%ˆ&*˜‘+=<>()[]{} "; | |||
| /*if (step == "train") | |||
| df = pd.read_csv(TRAIN_PATH, names =["class", "title", "content"]);*/ | |||
| var char_dict = new Dictionary<string, int>(); | |||
| char_dict["<pad>"] = 0; | |||
| char_dict["<unk>"] = 1; | |||
| foreach (char c in alphabet) | |||
| char_dict[c.ToString()] = char_dict.Count; | |||
| var contents = File.ReadAllLines(path); | |||
| if (shuffle) | |||
| new Random(17).Shuffle(contents); | |||
| //File.WriteAllLines("text_classification/dbpedia_csv/train_6400.csv", contents.Take(6400)); | |||
| var size = limit == null ? contents.Length : limit.Value; | |||
| var x = new int[size][]; | |||
| var y = new int[size]; | |||
| var tenth = size / 10; | |||
| var percent = 0; | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| if ((i + 1) % tenth == 0) | |||
| { | |||
| percent += 10; | |||
| Console.WriteLine($"\t{percent}%"); | |||
| } | |||
| string[] parts = contents[i].ToLower().Split(",\"").ToArray(); | |||
| string content = parts[2]; | |||
| content = content.Substring(0, content.Length - 1); | |||
| var a = new int[document_max_len]; | |||
| for (int j = 0; j < document_max_len; j++) | |||
| { | |||
| if (j >= content.Length) | |||
| a[j] = char_dict["<pad>"]; | |||
| else | |||
| a[j] = char_dict.ContainsKey(content[j].ToString()) ? char_dict[content[j].ToString()] : char_dict["<unk>"]; | |||
| } | |||
| x[i] = a; | |||
| y[i] = int.Parse(parts[0]); | |||
| } | |||
| return (x, y, alphabet.Length + 2); | |||
| } | |||
| /// <summary> | |||
| /// Loads MR polarity data from files, splits the data into words and generates labels. | |||
| /// Returns split sentences and labels. | |||
| /// </summary> | |||
| /// <param name="positive_data_file"></param> | |||
| /// <param name="negative_data_file"></param> | |||
| /// <returns></returns> | |||
| public static (string[], NDArray) load_data_and_labels(string positive_data_file, string negative_data_file) | |||
| { | |||
| Directory.CreateDirectory("CnnTextClassification"); | |||
| Utility.Web.Download(positive_data_file, "CnnTextClassification", "rt -polarity.pos"); | |||
| Utility.Web.Download(negative_data_file, "CnnTextClassification", "rt-polarity.neg"); | |||
| // Load data from files | |||
| var positive_examples = File.ReadAllLines("CnnTextClassification/rt-polarity.pos") | |||
| .Select(x => x.Trim()) | |||
| .ToArray(); | |||
| var negative_examples = File.ReadAllLines("CnnTextClassification/rt-polarity.neg") | |||
| .Select(x => x.Trim()) | |||
| .ToArray(); | |||
| var x_text = new List<string>(); | |||
| x_text.AddRange(positive_examples); | |||
| x_text.AddRange(negative_examples); | |||
| x_text = x_text.Select(x => clean_str(x)).ToList(); | |||
| var positive_labels = positive_examples.Select(x => new int[2] { 0, 1 }).ToArray(); | |||
| var negative_labels = negative_examples.Select(x => new int[2] { 1, 0 }).ToArray(); | |||
| var y = np.concatenate(new NDArray[] { new int[][][] { positive_labels, negative_labels } }); | |||
| return (x_text.ToArray(), y); | |||
| } | |||
| private static string clean_str(string str) | |||
| { | |||
| str = Regex.Replace(str, "[^A-Za-z0-9(),!?]", " "); | |||
| str = Regex.Replace(str, ",", " "); | |||
| return str; | |||
| } | |||
| /// <summary> | |||
| /// Padding | |||
| /// </summary> | |||
| /// <param name="sequences"></param> | |||
| /// <param name="pad_tok">the char to pad with</param> | |||
| /// <returns>a list of list where each sublist has same length</returns> | |||
| public static (int[][], int[]) pad_sequences(int[][] sequences, int pad_tok = 0) | |||
| { | |||
| int max_length = sequences.Select(x => x.Length).Max(); | |||
| return _pad_sequences(sequences, pad_tok, max_length); | |||
| } | |||
| public static (int[][][], int[][]) pad_sequences(int[][][] sequences, int pad_tok = 0) | |||
| { | |||
| int max_length_word = sequences.Select(x => x.Select(w => w.Length).Max()).Max(); | |||
| int[][][] sequence_padded; | |||
| var sequence_length = new int[sequences.Length][]; | |||
| for (int i = 0; i < sequences.Length; i++) | |||
| { | |||
| // all words are same length now | |||
| var (sp, sl) = _pad_sequences(sequences[i], pad_tok, max_length_word); | |||
| sequence_length[i] = sl; | |||
| } | |||
| int max_length_sentence = sequences.Select(x => x.Length).Max(); | |||
| (sequence_padded, _) = _pad_sequences(sequences, np.repeat(pad_tok, max_length_word).GetData<int>().ToArray(), max_length_sentence); | |||
| (sequence_length, _) = _pad_sequences(sequence_length, 0, max_length_sentence); | |||
| return (sequence_padded, sequence_length); | |||
| } | |||
| private static (int[][], int[]) _pad_sequences(int[][] sequences, int pad_tok, int max_length) | |||
| { | |||
| var sequence_length = new int[sequences.Length]; | |||
| for (int i = 0; i < sequences.Length; i++) | |||
| { | |||
| sequence_length[i] = sequences[i].Length; | |||
| Array.Resize(ref sequences[i], max_length); | |||
| } | |||
| return (sequences, sequence_length); | |||
| } | |||
| private static (int[][][], int[]) _pad_sequences(int[][][] sequences, int[] pad_tok, int max_length) | |||
| { | |||
| var sequence_length = new int[sequences.Length]; | |||
| for (int i = 0; i < sequences.Length; i++) | |||
| { | |||
| sequence_length[i] = sequences[i].Length; | |||
| Array.Resize(ref sequences[i], max_length); | |||
| for (int j = 0; j < max_length - sequence_length[i]; j++) | |||
| { | |||
| sequences[i][max_length - j - 1] = new int[pad_tok.Length]; | |||
| Array.Copy(pad_tok, sequences[i][max_length - j - 1], pad_tok.Length); | |||
| } | |||
| } | |||
| return (sequences, sequence_length); | |||
| } | |||
| public static string CalculateMD5Hash(string input) | |||
| { | |||
| // step 1, calculate MD5 hash from input | |||
| MD5 md5 = System.Security.Cryptography.MD5.Create(); | |||
| byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); | |||
| byte[] hash = md5.ComputeHash(inputBytes); | |||
| // step 2, convert byte array to hex string | |||
| StringBuilder sb = new StringBuilder(); | |||
| for (int i = 0; i < hash.Length; i++) | |||
| { | |||
| sb.Append(hash[i].ToString("X2")); | |||
| } | |||
| return sb.ToString(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,59 +0,0 @@ | |||
| using System; | |||
| using System.IO; | |||
| using Tensorflow; | |||
| using Tensorflow.Estimators; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Bidirectional LSTM-CRF Models for Sequence Tagging | |||
| /// https://github.com/guillaumegenthial/tf_ner/tree/master/models/lstm_crf | |||
| /// </summary> | |||
| public class BiLstmCrfNer : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "bi-LSTM + CRF NER"; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| return false; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| var hp = new HyperParams("BiLstmCrfNer"); | |||
| hp.filepath_words = Path.Combine(hp.data_root_dir, "vocab.words.txt"); | |||
| hp.filepath_chars = Path.Combine(hp.data_root_dir, "vocab.chars.txt"); | |||
| hp.filepath_tags = Path.Combine(hp.data_root_dir, "vocab.tags.txt"); | |||
| hp.filepath_glove = Path.Combine(hp.data_root_dir, "glove.npz"); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,55 +0,0 @@ | |||
| using System; | |||
| using Tensorflow; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// The CRF module implements a linear-chain CRF layer for learning to predict tag sequences. | |||
| /// This variant of the CRF is factored into unary potentials for every element | |||
| /// in the sequence and binary potentials for every transition between output tags. | |||
| /// | |||
| /// tensorflow\contrib\crf\python\ops\crf.py | |||
| /// </summary> | |||
| public class CRF : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public string Name => "CRF"; | |||
| public bool Run() | |||
| { | |||
| return true; | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,233 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using Tensorflow; | |||
| using Tensorflow.Estimators; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| using static TensorFlowNET.Examples.DataHelpers; | |||
| namespace TensorFlowNET.Examples.Text.NER | |||
| { | |||
| /// <summary> | |||
| /// A NER model using Tensorflow (LSTM + CRF + chars embeddings). | |||
| /// State-of-the-art performance (F1 score between 90 and 91). | |||
| /// | |||
| /// https://github.com/guillaumegenthial/sequence_tagging | |||
| /// </summary> | |||
| public class LstmCrfNer : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| public string Name => "LSTM + CRF NER"; | |||
| HyperParams hp; | |||
| int nwords, nchars, ntags; | |||
| CoNLLDataset dev, train; | |||
| Tensor word_ids_tensor; | |||
| Tensor sequence_lengths_tensor; | |||
| Tensor char_ids_tensor; | |||
| Tensor word_lengths_tensor; | |||
| Tensor labels_tensor; | |||
| Tensor dropout_tensor; | |||
| Tensor lr_tensor; | |||
| Operation train_op; | |||
| Tensor loss; | |||
| Tensor merged; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = tf.Graph().as_default(); | |||
| tf.train.import_meta_graph("graph/lstm_crf_ner.meta"); | |||
| float loss_value = 0f; | |||
| //add_summary(); | |||
| word_ids_tensor = graph.OperationByName("word_ids"); | |||
| sequence_lengths_tensor = graph.OperationByName("sequence_lengths"); | |||
| char_ids_tensor = graph.OperationByName("char_ids"); | |||
| word_lengths_tensor = graph.OperationByName("word_lengths"); | |||
| labels_tensor = graph.OperationByName("labels"); | |||
| dropout_tensor = graph.OperationByName("dropout"); | |||
| lr_tensor = graph.OperationByName("lr"); | |||
| train_op = graph.OperationByName("train_step/Adam"); | |||
| loss = graph.OperationByName("Mean"); | |||
| //merged = graph.OperationByName("Merge/MergeSummary"); | |||
| var init = tf.global_variables_initializer(); | |||
| using (var sess = tf.Session()) | |||
| { | |||
| sess.run(init); | |||
| foreach (var epoch in range(hp.epochs)) | |||
| { | |||
| Console.Write($"Epoch {epoch + 1} out of {hp.epochs}, "); | |||
| loss_value = run_epoch(sess, train, dev, epoch); | |||
| print($"train loss: {loss_value}"); | |||
| } | |||
| } | |||
| return loss_value < 0.1; | |||
| } | |||
| private float run_epoch(Session sess, CoNLLDataset train, CoNLLDataset dev, int epoch) | |||
| { | |||
| float accuracy = 0; | |||
| // iterate over dataset | |||
| var batches = minibatches(train, hp.batch_size); | |||
| foreach (var(words, labels) in batches) | |||
| { | |||
| var (fd, _) = get_feed_dict(words, labels, hp.lr, hp.dropout); | |||
| (_, accuracy) = sess.run((train_op, loss), feed_dict: fd); | |||
| } | |||
| return accuracy; | |||
| } | |||
| private IEnumerable<((int[][], int[])[], int[][])> minibatches(CoNLLDataset data, int minibatch_size) | |||
| { | |||
| var x_batch = new List<(int[][], int[])>(); | |||
| var y_batch = new List<int[]>(); | |||
| foreach(var (x, y) in data.GetItems()) | |||
| { | |||
| if (len(y_batch) == minibatch_size) | |||
| { | |||
| yield return (x_batch.ToArray(), y_batch.ToArray()); | |||
| x_batch.Clear(); | |||
| y_batch.Clear(); | |||
| } | |||
| var x3 = (x.Select(x1 => x1.Item1).ToArray(), x.Select(x2 => x2.Item2).ToArray()); | |||
| x_batch.Add(x3); | |||
| y_batch.Add(y); | |||
| } | |||
| if (len(y_batch) > 0) | |||
| yield return (x_batch.ToArray(), y_batch.ToArray()); | |||
| } | |||
| /// <summary> | |||
| /// Given some data, pad it and build a feed dictionary | |||
| /// </summary> | |||
| /// <param name="words"> | |||
| /// list of sentences. A sentence is a list of ids of a list of | |||
| /// words. A word is a list of ids | |||
| /// </param> | |||
| /// <param name="labels">list of ids</param> | |||
| /// <param name="lr">learning rate</param> | |||
| /// <param name="dropout">keep prob</param> | |||
| private (FeedItem[], int[]) get_feed_dict((int[][], int[])[] words, int[][] labels, float lr = 0f, float dropout = 0f) | |||
| { | |||
| int[] sequence_lengths; | |||
| int[][] word_lengths; | |||
| int[][] word_ids; | |||
| int[][][] char_ids; | |||
| if (true) // use_chars | |||
| { | |||
| (char_ids, word_ids) = (words.Select(x => x.Item1).ToArray(), words.Select(x => x.Item2).ToArray()); | |||
| (word_ids, sequence_lengths) = pad_sequences(word_ids, pad_tok: 0); | |||
| (char_ids, word_lengths) = pad_sequences(char_ids, pad_tok: 0); | |||
| } | |||
| // build feed dictionary | |||
| var feeds = new List<FeedItem>(); | |||
| feeds.Add(new FeedItem(word_ids_tensor, np.array(word_ids))); | |||
| feeds.Add(new FeedItem(sequence_lengths_tensor, np.array(sequence_lengths))); | |||
| if(true) // use_chars | |||
| { | |||
| feeds.Add(new FeedItem(char_ids_tensor, np.array(char_ids))); | |||
| feeds.Add(new FeedItem(word_lengths_tensor, np.array(word_lengths))); | |||
| } | |||
| (labels, _) = pad_sequences(labels, 0); | |||
| feeds.Add(new FeedItem(labels_tensor, np.array(labels))); | |||
| feeds.Add(new FeedItem(lr_tensor, lr)); | |||
| feeds.Add(new FeedItem(dropout_tensor, dropout)); | |||
| return (feeds.ToArray(), sequence_lengths); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| hp = new HyperParams("LstmCrfNer") | |||
| { | |||
| epochs = 50, | |||
| dropout = 0.5f, | |||
| batch_size = 20, | |||
| lr_method = "adam", | |||
| lr = 0.001f, | |||
| lr_decay = 0.9f, | |||
| clip = false, | |||
| epoch_no_imprv = 3, | |||
| hidden_size_char = 100, | |||
| hidden_size_lstm = 300 | |||
| }; | |||
| hp.filepath_dev = hp.filepath_test = hp.filepath_train = Path.Combine(hp.data_root_dir, "test.txt"); | |||
| // Loads vocabulary, processing functions and embeddings | |||
| hp.filepath_words = Path.Combine(hp.data_root_dir, "words.txt"); | |||
| hp.filepath_tags = Path.Combine(hp.data_root_dir, "tags.txt"); | |||
| hp.filepath_chars = Path.Combine(hp.data_root_dir, "chars.txt"); | |||
| string url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/data/lstm_crf_ner.zip"; | |||
| Web.Download(url, hp.data_root_dir, "lstm_crf_ner.zip"); | |||
| Compress.UnZip(Path.Combine(hp.data_root_dir, "lstm_crf_ner.zip"), hp.data_root_dir); | |||
| // 1. vocabulary | |||
| /*vocab_tags = load_vocab(hp.filepath_tags); | |||
| nwords = vocab_words.Count; | |||
| nchars = vocab_chars.Count; | |||
| ntags = vocab_tags.Count;*/ | |||
| // 2. get processing functions that map str -> id | |||
| dev = new CoNLLDataset(hp.filepath_dev, hp); | |||
| train = new CoNLLDataset(hp.filepath_train, hp); | |||
| // download graph meta data | |||
| var meta_file = "lstm_crf_ner.meta"; | |||
| var meta_path = Path.Combine("graph", meta_file); | |||
| url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/graph/" + meta_file; | |||
| Web.Download(url, "graph", meta_file); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,51 +0,0 @@ | |||
| using System; | |||
| using Tensorflow; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// https://github.com/guillaumegenthial/tf_ner | |||
| /// </summary> | |||
| public class NamedEntityRecognition : IExample | |||
| { | |||
| public bool Enabled { get; set; } = false; | |||
| public string Name => "NER"; | |||
| public bool IsImportingGraph { get; set; } = false; | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public bool Run() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,243 +0,0 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples.Utility; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples | |||
| { | |||
| /// <summary> | |||
| /// Implement Word2Vec algorithm to compute vector representations of words. | |||
| /// https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/word2vec.py | |||
| /// </summary> | |||
| public class Word2Vec : IExample | |||
| { | |||
| public bool Enabled { get; set; } = true; | |||
| public string Name => "Word2Vec"; | |||
| public bool IsImportingGraph { get; set; } = true; | |||
| // Training Parameters | |||
| float learning_rate = 0.1f; | |||
| int batch_size = 128; | |||
| int num_steps = 30000; //3000000; | |||
| int display_step = 1000; //10000; | |||
| int eval_step = 5000;//200000; | |||
| // Evaluation Parameters | |||
| string[] eval_words = new string[] { "five", "of", "going", "hardware", "american", "britain" }; | |||
| string[] text_words; | |||
| List<WordId> word2id; | |||
| int[] data; | |||
| // Word2Vec Parameters | |||
| int embedding_size = 200; // Dimension of the embedding vector | |||
| int max_vocabulary_size = 50000; // Total number of different words in the vocabulary | |||
| int min_occurrence = 10; // Remove all words that does not appears at least n times | |||
| int skip_window = 3; // How many words to consider left and right | |||
| int num_skips = 2; // How many times to reuse an input to generate a label | |||
| int num_sampled = 64; // Number of negative examples to sample | |||
| int data_index = 0; | |||
| int top_k = 8; // number of nearest neighbors | |||
| float average_loss = 0; | |||
| public bool Run() | |||
| { | |||
| PrepareData(); | |||
| var graph = tf.Graph().as_default(); | |||
| tf.train.import_meta_graph($"graph{Path.DirectorySeparatorChar}word2vec.meta"); | |||
| // Input data | |||
| Tensor X = graph.OperationByName("Placeholder"); | |||
| // Input label | |||
| Tensor Y = graph.OperationByName("Placeholder_1"); | |||
| // Compute the average NCE loss for the batch | |||
| Tensor loss_op = graph.OperationByName("Mean"); | |||
| // Define the optimizer | |||
| var train_op = graph.OperationByName("GradientDescent"); | |||
| Tensor cosine_sim_op = graph.OperationByName("MatMul_1"); | |||
| // Initialize the variables (i.e. assign their default value) | |||
| var init = tf.global_variables_initializer(); | |||
| using (var sess = tf.Session(graph)) | |||
| { | |||
| // Run the initializer | |||
| sess.run(init); | |||
| var x_test = (from word in eval_words | |||
| join id in word2id on word equals id.Word into wi | |||
| from wi2 in wi.DefaultIfEmpty() | |||
| select wi2 == null ? 0 : wi2.Id).ToArray(); | |||
| foreach (var step in range(1, num_steps + 1)) | |||
| { | |||
| // Get a new batch of data | |||
| var (batch_x, batch_y) = next_batch(batch_size, num_skips, skip_window); | |||
| (_, float loss) = sess.run((train_op, loss_op), (X, batch_x), (Y, batch_y)); | |||
| average_loss += loss; | |||
| if (step % display_step == 0 || step == 1) | |||
| { | |||
| if (step > 1) | |||
| average_loss /= display_step; | |||
| print($"Step {step}, Average Loss= {average_loss.ToString("F4")}"); | |||
| average_loss = 0; | |||
| } | |||
| // Evaluation | |||
| if (step % eval_step == 0 || step == 1) | |||
| { | |||
| print("Evaluation..."); | |||
| var sim = sess.run(cosine_sim_op, (X, x_test)); | |||
| foreach(var i in range(len(eval_words))) | |||
| { | |||
| var nearest = (0f - sim[i]).argsort<float>() | |||
| .Data<int>() | |||
| .Skip(1) | |||
| .Take(top_k) | |||
| .ToArray(); | |||
| string log_str = $"\"{eval_words[i]}\" nearest neighbors:"; | |||
| foreach (var k in range(top_k)) | |||
| log_str = $"{log_str} {word2id.First(x => x.Id == nearest[k]).Word},"; | |||
| print(log_str); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return average_loss < 100; | |||
| } | |||
| // Generate training batch for the skip-gram model | |||
| private (NDArray, NDArray) next_batch(int batch_size, int num_skips, int skip_window) | |||
| { | |||
| var batch = np.ndarray(new Shape(batch_size), dtype: np.int32); | |||
| var labels = np.ndarray((batch_size, 1), dtype: np.int32); | |||
| // get window size (words left and right + current one) | |||
| int span = 2 * skip_window + 1; | |||
| var buffer = new Queue<int>(span); | |||
| if (data_index + span > data.Length) | |||
| data_index = 0; | |||
| data.Skip(data_index).Take(span).ToList().ForEach(x => buffer.Enqueue(x)); | |||
| data_index += span; | |||
| foreach (var i in range(batch_size / num_skips)) | |||
| { | |||
| var context_words = range(span).Where(x => x != skip_window).ToArray(); | |||
| var words_to_use = new int[] { 1, 6 }; | |||
| foreach(var (j, context_word) in enumerate(words_to_use)) | |||
| { | |||
| batch[i * num_skips + j] = buffer.ElementAt(skip_window); | |||
| labels[i * num_skips + j, 0] = buffer.ElementAt(context_word); | |||
| } | |||
| if (data_index == len(data)) | |||
| { | |||
| //buffer.extend(data[0:span]); | |||
| data_index = span; | |||
| } | |||
| else | |||
| { | |||
| buffer.Enqueue(data[data_index]); | |||
| data_index += 1; | |||
| } | |||
| } | |||
| // Backtrack a little bit to avoid skipping words in the end of a batch | |||
| data_index = (data_index + len(data) - span) % len(data); | |||
| return (batch, labels); | |||
| } | |||
| public void PrepareData() | |||
| { | |||
| // Download graph meta | |||
| var url = "https://github.com/SciSharp/TensorFlow.NET/raw/master/graph/word2vec.meta"; | |||
| Web.Download(url, "graph", "word2vec.meta"); | |||
| // Download a small chunk of Wikipedia articles collection | |||
| url = "https://raw.githubusercontent.com/SciSharp/TensorFlow.NET/master/data/text8.zip"; | |||
| Web.Download(url, "word2vec", "text8.zip"); | |||
| // Unzip the dataset file. Text has already been processed | |||
| Compress.UnZip($"word2vec{Path.DirectorySeparatorChar}text8.zip", "word2vec"); | |||
| int wordId = 0; | |||
| text_words = File.ReadAllText($"word2vec{Path.DirectorySeparatorChar}text8").Trim().ToLower().Split(); | |||
| // Build the dictionary and replace rare words with UNK token | |||
| word2id = text_words.GroupBy(x => x) | |||
| .Select(x => new WordId | |||
| { | |||
| Word = x.Key, | |||
| Occurrence = x.Count() | |||
| }) | |||
| .Where(x => x.Occurrence >= min_occurrence) // Remove samples with less than 'min_occurrence' occurrences | |||
| .OrderByDescending(x => x.Occurrence) // Retrieve the most common words | |||
| .Select(x => new WordId | |||
| { | |||
| Word = x.Word, | |||
| Id = ++wordId, // Assign an id to each word | |||
| Occurrence = x.Occurrence | |||
| }) | |||
| .ToList(); | |||
| // Retrieve a word id, or assign it index 0 ('UNK') if not in dictionary | |||
| data = (from word in text_words | |||
| join id in word2id on word equals id.Word into wi | |||
| from wi2 in wi.DefaultIfEmpty() | |||
| select wi2 == null ? 0 : wi2.Id).ToArray(); | |||
| word2id.Insert(0, new WordId { Word = "UNK", Id = 0, Occurrence = data.Count(x => x == 0) }); | |||
| print($"Words count: {text_words.Length}"); | |||
| print($"Unique words: {text_words.Distinct().Count()}"); | |||
| print($"Vocabulary size: {word2id.Count}"); | |||
| print($"Most common words: {string.Join(", ", word2id.Take(10))}"); | |||
| } | |||
| public Graph ImportGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public Graph BuildGraph() | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Train(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Predict(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| public void Test(Session sess) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| private class WordId | |||
| { | |||
| public string Word { get; set; } | |||
| public int Id { get; set; } | |||
| public int Occurrence { get; set; } | |||
| public override string ToString() | |||
| { | |||
| return Word + " " + Id + " " + Occurrence; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,147 +0,0 @@ | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.Text | |||
| { | |||
| public class CharCnn : ITextModel | |||
| { | |||
| public CharCnn(int alphabet_size, int document_max_len, int num_class) | |||
| { | |||
| var learning_rate = 0.001f; | |||
| var filter_sizes = new int[] { 7, 7, 3, 3, 3, 3 }; | |||
| var num_filters = 256; | |||
| var kernel_initializer = tf.truncated_normal_initializer(stddev: 0.05f); | |||
| var x = tf.placeholder(tf.int32, new TensorShape(-1, document_max_len), name: "x"); | |||
| var y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y"); | |||
| var is_training = tf.placeholder(tf.@bool, new TensorShape(), name: "is_training"); | |||
| var global_step = tf.Variable(0, trainable: false); | |||
| var keep_prob = tf.where(is_training, 0.5f, 1.0f); | |||
| var x_one_hot = tf.one_hot(x, alphabet_size); | |||
| var x_expanded = tf.expand_dims(x_one_hot, -1); | |||
| // ============= Convolutional Layers ============= | |||
| Tensor pool1 = null, pool2 = null; | |||
| Tensor conv3 = null, conv4 = null, conv5 = null, conv6 = null; | |||
| Tensor h_pool = null; | |||
| tf_with(tf.name_scope("conv-maxpool-1"), delegate | |||
| { | |||
| var conv1 = tf.layers.conv2d(x_expanded, | |||
| filters: num_filters, | |||
| kernel_size: new[] { filter_sizes[0], alphabet_size }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| pool1 = tf.layers.max_pooling2d(conv1, | |||
| pool_size: new[] { 3, 1 }, | |||
| strides: new[] { 3, 1 }); | |||
| pool1 = tf.transpose(pool1, new[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-maxpool-2"), delegate | |||
| { | |||
| var conv2 = tf.layers.conv2d(pool1, | |||
| filters: num_filters, | |||
| kernel_size: new[] {filter_sizes[1], num_filters }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| pool2 = tf.layers.max_pooling2d(conv2, | |||
| pool_size: new[] { 3, 1 }, | |||
| strides: new[] { 3, 1 }); | |||
| pool2 = tf.transpose(pool2, new[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-3"), delegate | |||
| { | |||
| conv3 = tf.layers.conv2d(pool2, | |||
| filters: num_filters, | |||
| kernel_size: new[] { filter_sizes[2], num_filters }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| conv3 = tf.transpose(conv3, new[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-4"), delegate | |||
| { | |||
| conv4 = tf.layers.conv2d(conv3, | |||
| filters: num_filters, | |||
| kernel_size: new[] { filter_sizes[3], num_filters }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| conv4 = tf.transpose(conv4, new[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-5"), delegate | |||
| { | |||
| conv5 = tf.layers.conv2d(conv4, | |||
| filters: num_filters, | |||
| kernel_size: new[] { filter_sizes[4], num_filters }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| conv5 = tf.transpose(conv5, new[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-maxpool-6"), delegate | |||
| { | |||
| conv6 = tf.layers.conv2d(conv5, | |||
| filters: num_filters, | |||
| kernel_size: new[] { filter_sizes[5], num_filters }, | |||
| kernel_initializer: kernel_initializer, | |||
| activation: tf.nn.relu()); | |||
| var pool6 = tf.layers.max_pooling2d(conv6, | |||
| pool_size: new[] { 3, 1 }, | |||
| strides: new[] { 3, 1 }); | |||
| pool6 = tf.transpose(pool6, new[] { 0, 2, 1, 3 }); | |||
| h_pool = tf.reshape(pool6, new[] { -1, 34 * num_filters }); | |||
| }); | |||
| // ============= Fully Connected Layers ============= | |||
| Tensor fc1_out = null, fc2_out = null; | |||
| Tensor logits = null; | |||
| Tensor predictions = null; | |||
| tf_with(tf.name_scope("fc-1"), delegate | |||
| { | |||
| fc1_out = tf.layers.dense(h_pool, | |||
| 1024, | |||
| activation: tf.nn.relu(), | |||
| kernel_initializer: kernel_initializer); | |||
| }); | |||
| tf_with(tf.name_scope("fc-2"), delegate | |||
| { | |||
| fc2_out = tf.layers.dense(fc1_out, | |||
| 1024, | |||
| activation: tf.nn.relu(), | |||
| kernel_initializer: kernel_initializer); | |||
| }); | |||
| tf_with(tf.name_scope("fc-3"), delegate | |||
| { | |||
| logits = tf.layers.dense(fc2_out, | |||
| num_class, | |||
| kernel_initializer: kernel_initializer); | |||
| predictions = tf.argmax(logits, -1, output_type: tf.int32); | |||
| }); | |||
| tf_with(tf.name_scope("loss"), delegate | |||
| { | |||
| var y_one_hot = tf.one_hot(y, num_class); | |||
| var loss = tf.reduce_mean( | |||
| tf.nn.softmax_cross_entropy_with_logits_v2(logits: logits, labels: y_one_hot)); | |||
| var optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step: global_step); | |||
| }); | |||
| tf_with(tf.name_scope("accuracy"), delegate | |||
| { | |||
| var correct_predictions = tf.equal(predictions, y); | |||
| var accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32), name: "accuracy"); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,6 +0,0 @@ | |||
| namespace TensorFlowNET.Examples.Text | |||
| { | |||
| interface ITextModel | |||
| { | |||
| } | |||
| } | |||
| @@ -1,171 +0,0 @@ | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using Tensorflow; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.Text | |||
| { | |||
| public class VdCnn : ITextModel | |||
| { | |||
| private int embedding_size; | |||
| private int[] filter_sizes; | |||
| private int[] num_filters; | |||
| private int[] num_blocks; | |||
| private float learning_rate; | |||
| private IInitializer cnn_initializer; | |||
| private IInitializer fc_initializer; | |||
| public Tensor x { get; private set; } | |||
| public Tensor y { get; private set; } | |||
| public Tensor is_training { get; private set; } | |||
| private RefVariable global_step; | |||
| private RefVariable embeddings; | |||
| private Tensor x_emb; | |||
| private Tensor x_expanded; | |||
| private Tensor logits; | |||
| private Tensor predictions; | |||
| private Tensor loss; | |||
| public VdCnn(int alphabet_size, int document_max_len, int num_class) | |||
| { | |||
| embedding_size = 16; | |||
| filter_sizes = new int[] { 3, 3, 3, 3, 3 }; | |||
| num_filters = new int[] { 64, 64, 128, 256, 512 }; | |||
| num_blocks = new int[] { 2, 2, 2, 2 }; | |||
| learning_rate = 0.001f; | |||
| cnn_initializer = tensorflow.keras.initializers.he_normal(); | |||
| fc_initializer = tf.truncated_normal_initializer(stddev: 0.05f); | |||
| x = tf.placeholder(tf.int32, new TensorShape(-1, document_max_len), name: "x"); | |||
| y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y"); | |||
| is_training = tf.placeholder(tf.@bool, new TensorShape(), name: "is_training"); | |||
| global_step = tf.Variable(0, trainable: false); | |||
| // Embedding Layer | |||
| tf_with(tf.name_scope("embedding"), delegate | |||
| { | |||
| var init_embeddings = tf.random_uniform(new int[] { alphabet_size, embedding_size }, -1.0f, 1.0f); | |||
| embeddings = tf.get_variable("embeddings", initializer: init_embeddings); | |||
| x_emb = tf.nn.embedding_lookup(embeddings, x); | |||
| x_expanded = tf.expand_dims(x_emb, -1); | |||
| }); | |||
| Tensor conv0 = null; | |||
| Tensor conv1 = null; | |||
| Tensor conv2 = null; | |||
| Tensor conv3 = null; | |||
| Tensor conv4 = null; | |||
| Tensor h_flat = null; | |||
| Tensor fc1_out = null; | |||
| Tensor fc2_out = null; | |||
| // First Convolution Layer | |||
| tf_with(tf.variable_scope("conv-0"), delegate | |||
| { | |||
| conv0 = tf.layers.conv2d(x_expanded, | |||
| filters: num_filters[0], | |||
| kernel_size: new int[] { filter_sizes[0], embedding_size }, | |||
| kernel_initializer: cnn_initializer, | |||
| activation: tf.nn.relu()); | |||
| conv0 = tf.transpose(conv0, new int[] { 0, 1, 3, 2 }); | |||
| }); | |||
| tf_with(tf.name_scope("conv-block-1"), delegate { | |||
| conv1 = conv_block(conv0, 1); | |||
| }); | |||
| tf_with(tf.name_scope("conv-block-2"), delegate { | |||
| conv2 = conv_block(conv1, 2); | |||
| }); | |||
| tf_with(tf.name_scope("conv-block-3"), delegate { | |||
| conv3 = conv_block(conv2, 3); | |||
| }); | |||
| tf_with(tf.name_scope("conv-block-4"), delegate | |||
| { | |||
| conv4 = conv_block(conv3, 4, max_pool: false); | |||
| }); | |||
| // ============= k-max Pooling ============= | |||
| tf_with(tf.name_scope("k-max-pooling"), delegate | |||
| { | |||
| var h = tf.transpose(tf.squeeze(conv4, new int[] { -1 }), new int[] { 0, 2, 1 }); | |||
| var top_k = tf.nn.top_k(h, k: 8, sorted: false)[0]; | |||
| h_flat = tf.reshape(top_k, new int[] { -1, 512 * 8 }); | |||
| }); | |||
| // ============= Fully Connected Layers ============= | |||
| tf_with(tf.name_scope("fc-1"), scope => | |||
| { | |||
| fc1_out = tf.layers.dense(h_flat, 2048, activation: tf.nn.relu(), kernel_initializer: fc_initializer); | |||
| }); | |||
| tf_with(tf.name_scope("fc-2"), scope => | |||
| { | |||
| fc2_out = tf.layers.dense(fc1_out, 2048, activation: tf.nn.relu(), kernel_initializer: fc_initializer); | |||
| }); | |||
| tf_with(tf.name_scope("fc-3"), scope => | |||
| { | |||
| logits = tf.layers.dense(fc2_out, num_class, activation: null, kernel_initializer: fc_initializer); | |||
| predictions = tf.argmax(logits, -1, output_type: tf.int32); | |||
| }); | |||
| // ============= Loss and Accuracy ============= | |||
| tf_with(tf.name_scope("loss"), delegate | |||
| { | |||
| var y_one_hot = tf.one_hot(y, num_class); | |||
| loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits: logits, labels: y_one_hot)); | |||
| var update_ops = tf.get_collection<object>(tf.GraphKeys.UPDATE_OPS); | |||
| tf_with(tf.control_dependencies(update_ops.Select(x => (Operation)x).ToArray()), delegate | |||
| { | |||
| var adam = tf.train.AdamOptimizer(learning_rate); | |||
| adam.minimize(loss, global_step: global_step); | |||
| }); | |||
| }); | |||
| } | |||
| private Tensor conv_block(Tensor input, int i, bool max_pool = true) | |||
| { | |||
| return tf_with(tf.variable_scope($"conv-block-{i}"), delegate | |||
| { | |||
| Tensor conv = null; | |||
| // Two "conv-batch_norm-relu" layers. | |||
| foreach (var j in Enumerable.Range(0, 2)) | |||
| { | |||
| tf_with(tf.variable_scope($"conv-{j}"), delegate | |||
| { | |||
| // convolution | |||
| conv = tf.layers.conv2d( | |||
| input, | |||
| filters: num_filters[i], | |||
| kernel_size: new int[] { filter_sizes[i], num_filters[i - 1] }, | |||
| kernel_initializer: cnn_initializer, | |||
| activation: null); | |||
| // batch normalization | |||
| conv = tf.layers.batch_normalization(conv, training: is_training); | |||
| // relu | |||
| conv = tf.nn.relu(conv); | |||
| conv = tf.transpose(conv, new int[] { 0, 1, 3, 2 }); | |||
| }); | |||
| } | |||
| if (max_pool) | |||
| { | |||
| // Max pooling | |||
| return tf.layers.max_pooling2d( | |||
| conv, | |||
| pool_size: new int[] { 3, 1 }, | |||
| strides: new int[] { 2, 1 }, | |||
| padding: "SAME"); | |||
| } | |||
| else | |||
| { | |||
| return conv; | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,99 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.Examples.Text | |||
| { | |||
| public class WordCnn : ITextModel | |||
| { | |||
| public WordCnn(int vocabulary_size, int document_max_len, int num_class) | |||
| { | |||
| var embedding_size = 128; | |||
| var learning_rate = 0.001f; | |||
| var filter_sizes = new int[3, 4, 5]; | |||
| var num_filters = 100; | |||
| var x = tf.placeholder(tf.int32, new TensorShape(-1, document_max_len), name: "x"); | |||
| var y = tf.placeholder(tf.int32, new TensorShape(-1), name: "y"); | |||
| var is_training = tf.placeholder(tf.@bool, new TensorShape(), name: "is_training"); | |||
| var global_step = tf.Variable(0, trainable: false); | |||
| var keep_prob = tf.where(is_training, 0.5f, 1.0f); | |||
| Tensor x_emb = null; | |||
| tf_with(tf.name_scope("embedding"), scope => | |||
| { | |||
| var init_embeddings = tf.random_uniform(new int[] { vocabulary_size, embedding_size }); | |||
| var embeddings = tf.get_variable("embeddings", initializer: init_embeddings); | |||
| x_emb = tf.nn.embedding_lookup(embeddings, x); | |||
| x_emb = tf.expand_dims(x_emb, -1); | |||
| }); | |||
| var pooled_outputs = new List<Tensor>(); | |||
| for (int len = 0; len < filter_sizes.Rank; len++) | |||
| { | |||
| int filter_size = filter_sizes.GetLength(len); | |||
| var conv = tf.layers.conv2d( | |||
| x_emb, | |||
| filters: num_filters, | |||
| kernel_size: new int[] { filter_size, embedding_size }, | |||
| strides: new int[] { 1, 1 }, | |||
| padding: "VALID", | |||
| activation: tf.nn.relu()); | |||
| var pool = tf.layers.max_pooling2d( | |||
| conv, | |||
| pool_size: new[] { document_max_len - filter_size + 1, 1 }, | |||
| strides: new[] { 1, 1 }, | |||
| padding: "VALID"); | |||
| pooled_outputs.Add(pool); | |||
| } | |||
| var h_pool = tf.concat(pooled_outputs, 3); | |||
| var h_pool_flat = tf.reshape(h_pool, new TensorShape(-1, num_filters * filter_sizes.Rank)); | |||
| Tensor h_drop = null; | |||
| tf_with(tf.name_scope("dropout"), delegate | |||
| { | |||
| h_drop = tf.nn.dropout(h_pool_flat, keep_prob); | |||
| }); | |||
| Tensor logits = null; | |||
| Tensor predictions = null; | |||
| tf_with(tf.name_scope("output"), delegate | |||
| { | |||
| logits = tf.layers.dense(h_drop, num_class); | |||
| predictions = tf.argmax(logits, -1, output_type: tf.int32); | |||
| }); | |||
| tf_with(tf.name_scope("loss"), delegate | |||
| { | |||
| var sscel = tf.nn.sparse_softmax_cross_entropy_with_logits(logits: logits, labels: y); | |||
| var loss = tf.reduce_mean(sscel); | |||
| var adam = tf.train.AdamOptimizer(learning_rate); | |||
| var optimizer = adam.minimize(loss, global_step: global_step); | |||
| }); | |||
| tf_with(tf.name_scope("accuracy"), delegate | |||
| { | |||
| var correct_predictions = tf.equal(predictions, y); | |||
| var accuracy = tf.reduce_mean(tf.cast(correct_predictions, TF_DataType.TF_FLOAT), name: "accuracy"); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,20 +0,0 @@ | |||
| using System; | |||
| namespace TensorFlowNET.Examples.Utility | |||
| { | |||
| public static class ArrayShuffling | |||
| { | |||
| public static T[] Shuffle<T>(this Random rng, T[] array) | |||
| { | |||
| int n = array.Length; | |||
| while (n > 1) | |||
| { | |||
| int k = rng.Next(n--); | |||
| T temp = array[n]; | |||
| array[n] = array[k]; | |||
| array[k] = temp; | |||
| } | |||
| return array; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,105 +0,0 @@ | |||
| using System.Collections.Generic; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using Tensorflow.Estimators; | |||
| namespace TensorFlowNET.Examples.Utility | |||
| { | |||
| public class CoNLLDataset | |||
| { | |||
| static Dictionary<string, int> vocab_chars; | |||
| static Dictionary<string, int> vocab_words; | |||
| static Dictionary<string, int> vocab_tags; | |||
| HyperParams _hp; | |||
| string _path; | |||
| public CoNLLDataset(string path, HyperParams hp) | |||
| { | |||
| if (vocab_chars == null) | |||
| vocab_chars = load_vocab(hp.filepath_chars); | |||
| if (vocab_words == null) | |||
| vocab_words = load_vocab(hp.filepath_words); | |||
| if (vocab_tags == null) | |||
| vocab_tags = load_vocab(hp.filepath_tags); | |||
| _path = path; | |||
| } | |||
| private (int[], int) processing_word(string word) | |||
| { | |||
| var char_ids = word.ToCharArray().Select(x => vocab_chars[x.ToString()]).ToArray(); | |||
| // 1. preprocess word | |||
| if (true) // lowercase | |||
| word = word.ToLower(); | |||
| if (false) // isdigit | |||
| word = "$NUM$"; | |||
| // 2. get id of word | |||
| int id = vocab_words.GetValueOrDefault(word, vocab_words["$UNK$"]); | |||
| return (char_ids, id); | |||
| } | |||
| private int processing_tag(string word) | |||
| { | |||
| // 1. preprocess word | |||
| if (false) // lowercase | |||
| word = word.ToLower(); | |||
| if (false) // isdigit | |||
| word = "$NUM$"; | |||
| // 2. get id of word | |||
| int id = vocab_tags.GetValueOrDefault(word, -1); | |||
| return id; | |||
| } | |||
| private Dictionary<string, int> load_vocab(string filename) | |||
| { | |||
| var dict = new Dictionary<string, int>(); | |||
| int i = 0; | |||
| File.ReadAllLines(filename) | |||
| .Select(x => dict[x] = i++) | |||
| .Count(); | |||
| return dict; | |||
| } | |||
| public IEnumerable<((int[], int)[], int[])> GetItems() | |||
| { | |||
| var lines = File.ReadAllLines(_path); | |||
| int niter = 0; | |||
| var words = new List<(int[], int)>(); | |||
| var tags = new List<int>(); | |||
| foreach (var l in lines) | |||
| { | |||
| string line = l.Trim(); | |||
| if (string.IsNullOrEmpty(line) || line.StartsWith("-DOCSTART-")) | |||
| { | |||
| if (words.Count > 0) | |||
| { | |||
| niter++; | |||
| yield return (words.ToArray(), tags.ToArray()); | |||
| words.Clear(); | |||
| tags.Clear(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| var ls = line.Split(' '); | |||
| // process word | |||
| var word = processing_word(ls[0]); | |||
| var tag = processing_tag(ls[1]); | |||
| words.Add(word); | |||
| tags.Add(tag); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,102 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 ICSharpCode.SharpZipLib.Core; | |||
| using ICSharpCode.SharpZipLib.GZip; | |||
| using ICSharpCode.SharpZipLib.Tar; | |||
| using System; | |||
| using System.IO; | |||
| using System.IO.Compression; | |||
| using System.Linq; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| namespace TensorFlowNET.Examples.Utility | |||
| { | |||
| public class Compress | |||
| { | |||
| public static void ExtractGZip(string gzipFileName, string targetDir) | |||
| { | |||
| // Use a 4K buffer. Any larger is a waste. | |||
| byte[] dataBuffer = new byte[4096]; | |||
| using (System.IO.Stream fs = new FileStream(gzipFileName, FileMode.Open, FileAccess.Read)) | |||
| { | |||
| using (GZipInputStream gzipStream = new GZipInputStream(fs)) | |||
| { | |||
| // Change this to your needs | |||
| string fnOut = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFileName)); | |||
| using (FileStream fsOut = File.Create(fnOut)) | |||
| { | |||
| StreamUtils.Copy(gzipStream, fsOut, dataBuffer); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| public static void UnZip(String gzArchiveName, String destFolder) | |||
| { | |||
| var flag = gzArchiveName.Split(Path.DirectorySeparatorChar).Last().Split('.').First() + ".bin"; | |||
| if (File.Exists(Path.Combine(destFolder, flag))) return; | |||
| Console.WriteLine($"Extracting."); | |||
| var task = Task.Run(() => | |||
| { | |||
| ZipFile.ExtractToDirectory(gzArchiveName, destFolder); | |||
| }); | |||
| while (!task.IsCompleted) | |||
| { | |||
| Thread.Sleep(200); | |||
| Console.Write("."); | |||
| } | |||
| File.Create(Path.Combine(destFolder, flag)); | |||
| Console.WriteLine(""); | |||
| Console.WriteLine("Extracting is completed."); | |||
| } | |||
| public static void ExtractTGZ(String gzArchiveName, String destFolder) | |||
| { | |||
| var flag = gzArchiveName.Split(Path.DirectorySeparatorChar).Last().Split('.').First() + ".bin"; | |||
| if (File.Exists(Path.Combine(destFolder, flag))) return; | |||
| Console.WriteLine($"Extracting."); | |||
| var task = Task.Run(() => | |||
| { | |||
| using (var inStream = File.OpenRead(gzArchiveName)) | |||
| { | |||
| using (var gzipStream = new GZipInputStream(inStream)) | |||
| { | |||
| using (TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream)) | |||
| tarArchive.ExtractContents(destFolder); | |||
| } | |||
| } | |||
| }); | |||
| while (!task.IsCompleted) | |||
| { | |||
| Thread.Sleep(200); | |||
| Console.Write("."); | |||
| } | |||
| File.Create(Path.Combine(destFolder, flag)); | |||
| Console.WriteLine(""); | |||
| Console.WriteLine("Extracting is completed."); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,81 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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 Newtonsoft.Json; | |||
| using System.Collections.Generic; | |||
| namespace TensorFlowNET.Examples.Utility | |||
| { | |||
| public class PbtxtItem | |||
| { | |||
| public string name { get; set; } | |||
| public int id { get; set; } | |||
| public string display_name { get; set; } | |||
| } | |||
| public class PbtxtItems | |||
| { | |||
| public List<PbtxtItem> items { get; set; } | |||
| } | |||
| public class PbtxtParser | |||
| { | |||
| public static PbtxtItems ParsePbtxtFile(string filePath) | |||
| { | |||
| string line; | |||
| string newText = "{\"items\":["; | |||
| using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath)) | |||
| { | |||
| while ((line = reader.ReadLine()) != null) | |||
| { | |||
| string newline = string.Empty; | |||
| if (line.Contains("{")) | |||
| { | |||
| newline = line.Replace("item", "").Trim(); | |||
| //newText += line.Insert(line.IndexOf("=") + 1, "\"") + "\","; | |||
| newText += newline; | |||
| } | |||
| else if (line.Contains("}")) | |||
| { | |||
| newText = newText.Remove(newText.Length - 1); | |||
| newText += line; | |||
| newText += ","; | |||
| } | |||
| else | |||
| { | |||
| newline = line.Replace(":", "\":").Trim(); | |||
| newline = "\"" + newline;// newline.Insert(0, "\""); | |||
| newline += ","; | |||
| newText += newline; | |||
| } | |||
| } | |||
| newText = newText.Remove(newText.Length - 1); | |||
| newText += "]}"; | |||
| reader.Close(); | |||
| } | |||
| PbtxtItems items = JsonConvert.DeserializeObject<PbtxtItems>(newText); | |||
| return items; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,57 +0,0 @@ | |||
| /***************************************************************************** | |||
| Copyright 2018 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. | |||
| 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; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Net; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| namespace TensorFlowNET.Examples.Utility | |||
| { | |||
| public class Web | |||
| { | |||
| public static bool Download(string url, string destDir, string destFileName) | |||
| { | |||
| if (destFileName == null) | |||
| destFileName = url.Split(Path.DirectorySeparatorChar).Last(); | |||
| Directory.CreateDirectory(destDir); | |||
| string relativeFilePath = Path.Combine(destDir, destFileName); | |||
| if (File.Exists(relativeFilePath)) | |||
| { | |||
| Console.WriteLine($"{relativeFilePath} already exists."); | |||
| return false; | |||
| } | |||
| var wc = new WebClient(); | |||
| Console.WriteLine($"Downloading {relativeFilePath}"); | |||
| var download = Task.Run(() => wc.DownloadFile(url, relativeFilePath)); | |||
| while (!download.IsCompleted) | |||
| { | |||
| Thread.Sleep(1000); | |||
| Console.Write("."); | |||
| } | |||
| Console.WriteLine(""); | |||
| Console.WriteLine($"Downloaded {relativeFilePath}"); | |||
| return true; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,115 +0,0 @@ | |||
| | |||
| from __future__ import absolute_import, division, print_function | |||
| import tensorflow as tf | |||
| from tensorflow import keras | |||
| import numpy as np | |||
| print(tf.__version__) | |||
| imdb = keras.datasets.imdb | |||
| (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000) | |||
| print("Training entries: {}, labels: {}".format(len(train_data), len(train_labels))) | |||
| print(train_data[0]) | |||
| len(train_data[0]), len(train_data[1]) | |||
| # A dictionary mapping words to an integer index | |||
| word_index = imdb.get_word_index() | |||
| # The first indices are reserved | |||
| word_index = {k:(v+3) for k,v in word_index.items()} | |||
| word_index["<PAD>"] = 0 | |||
| word_index["<START>"] = 1 | |||
| word_index["<UNK>"] = 2 # unknown | |||
| word_index["<UNUSED>"] = 3 | |||
| reverse_word_index = dict([(value, key) for (key, value) in word_index.items()]) | |||
| def decode_review(text): | |||
| return ' '.join([reverse_word_index.get(i, '?') for i in text]) | |||
| decode_review(train_data[0]) | |||
| train_data = keras.preprocessing.sequence.pad_sequences(train_data, | |||
| value=word_index["<PAD>"], | |||
| padding='post', | |||
| maxlen=256) | |||
| test_data = keras.preprocessing.sequence.pad_sequences(test_data, | |||
| value=word_index["<PAD>"], | |||
| padding='post', | |||
| maxlen=256) | |||
| print(train_data[0]) | |||
| # input shape is the vocabulary count used for the movie reviews (10,000 words) | |||
| vocab_size = 10000 | |||
| model = keras.Sequential() | |||
| model.add(keras.layers.Embedding(vocab_size, 16)) | |||
| model.add(keras.layers.GlobalAveragePooling1D()) | |||
| model.add(keras.layers.Dense(16, activation=tf.nn.relu)) | |||
| model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid)) | |||
| model.summary() | |||
| model.compile(optimizer='adam', | |||
| loss='binary_crossentropy', | |||
| metrics=['accuracy']) | |||
| x_val = train_data[:10000] | |||
| partial_x_train = train_data[10000:] | |||
| y_val = train_labels[:10000] | |||
| partial_y_train = train_labels[10000:] | |||
| history = model.fit(partial_x_train, | |||
| partial_y_train, | |||
| epochs=20, | |||
| batch_size=512, | |||
| validation_data=(x_val, y_val), | |||
| verbose=1) | |||
| results = model.evaluate(test_data, test_labels) | |||
| print(results) | |||
| history_dict = history.history | |||
| history_dict.keys() | |||
| import matplotlib.pyplot as plt | |||
| acc = history_dict['acc'] | |||
| val_acc = history_dict['val_acc'] | |||
| loss = history_dict['loss'] | |||
| val_loss = history_dict['val_loss'] | |||
| epochs = range(1, len(acc) + 1) | |||
| # "bo" is for "blue dot" | |||
| plt.plot(epochs, loss, 'bo', label='Training loss') | |||
| # b is for "solid blue line" | |||
| plt.plot(epochs, val_loss, 'b', label='Validation loss') | |||
| plt.title('Training and validation loss') | |||
| plt.xlabel('Epochs') | |||
| plt.ylabel('Loss') | |||
| plt.legend() | |||
| plt.show() | |||
| plt.clf() # clear figure | |||
| plt.plot(epochs, acc, 'bo', label='Training acc') | |||
| plt.plot(epochs, val_acc, 'b', label='Validation acc') | |||
| plt.title('Training and validation accuracy') | |||
| plt.xlabel('Epochs') | |||
| plt.ylabel('Accuracy') | |||
| plt.legend() | |||
| plt.show() | |||
| @@ -1,107 +0,0 @@ | |||
| ''' | |||
| A linear regression learning algorithm example using TensorFlow library. | |||
| Author: Aymeric Damien | |||
| Project: https://github.com/aymericdamien/TensorFlow-Examples/ | |||
| ''' | |||
| from __future__ import print_function | |||
| import tensorflow as tf | |||
| import numpy | |||
| import matplotlib.pyplot as plt | |||
| rng = numpy.random | |||
| # Parameters | |||
| learning_rate = 0.01 | |||
| training_epochs = 1000 | |||
| display_step = 10 | |||
| # Training Data | |||
| train_X = numpy.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167, | |||
| 7.042,10.791,5.313,7.997,5.654,9.27,3.1]) | |||
| train_Y = numpy.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221, | |||
| 2.827,3.465,1.65,2.904,2.42,2.94,1.3]) | |||
| n_samples = train_X.shape[0] | |||
| if False: | |||
| # tf Graph Input | |||
| X = tf.placeholder("float") | |||
| Y = tf.placeholder("float") | |||
| # Set model weights | |||
| W = tf.Variable(-0.06, name="weight") | |||
| b = tf.Variable(-0.73, name="bias") | |||
| # Construct a linear model | |||
| mul = tf.multiply(X, W) | |||
| pred = tf.add(mul, b) | |||
| # Mean squared error | |||
| sub = pred-Y | |||
| pow = tf.pow(sub, 2) | |||
| reduce = tf.reduce_sum(pow) | |||
| cost = reduce/(2*n_samples) | |||
| # Gradient descent | |||
| # Note, minimize() knows to modify W and b because Variable objects are trainable=True by default | |||
| grad = tf.train.GradientDescentOptimizer(learning_rate) | |||
| optimizer = grad.minimize(cost) | |||
| # tf.train.export_meta_graph(filename='save_model.meta'); | |||
| else: | |||
| # tf Graph Input | |||
| new_saver = tf.train.import_meta_graph("linear_regression.meta") | |||
| nodes = tf.get_default_graph()._nodes_by_name; | |||
| optimizer = nodes["GradientDescent"] | |||
| cost = nodes["truediv"].outputs[0] | |||
| X = nodes["Placeholder"].outputs[0] | |||
| Y = nodes["Placeholder_1"].outputs[0] | |||
| W = nodes["weight"].outputs[0] | |||
| b = nodes["bias"].outputs[0] | |||
| pred = nodes["Add"].outputs[0] | |||
| # Initialize the variables (i.e. assign their default value) | |||
| init = tf.global_variables_initializer() | |||
| # Start training | |||
| with tf.Session() as sess: | |||
| # Run the initializer | |||
| sess.run(init) | |||
| # Fit all training data | |||
| for epoch in range(training_epochs): | |||
| for (x, y) in zip(train_X, train_Y): | |||
| sess.run(optimizer, feed_dict={X: x, Y: y}) | |||
| # Display logs per epoch step | |||
| if (epoch+1) % display_step == 0: | |||
| c = sess.run(cost, feed_dict={X: train_X, Y:train_Y}) | |||
| print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c), \ | |||
| "W=", sess.run(W), "b=", sess.run(b)) | |||
| print("Optimization Finished!") | |||
| training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y}) | |||
| print("Training cost=", training_cost, "W=", sess.run(W), "b=", sess.run(b), '\n') | |||
| # Graphic display | |||
| plt.plot(train_X, train_Y, 'ro', label='Original data') | |||
| plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line') | |||
| plt.legend() | |||
| plt.show() | |||
| # Testing example, as requested (Issue #2) | |||
| test_X = numpy.asarray([6.83, 4.668, 8.9, 7.91, 5.7, 8.7, 3.1, 2.1]) | |||
| test_Y = numpy.asarray([1.84, 2.273, 3.2, 2.831, 2.92, 3.24, 1.35, 1.03]) | |||
| print("Testing... (Mean square loss Comparison)") | |||
| testing_cost = sess.run( | |||
| tf.reduce_sum(tf.pow(pred - Y, 2)) / (2 * test_X.shape[0]), | |||
| feed_dict={X: test_X, Y: test_Y}) # same function as cost above | |||
| print("Testing cost=", testing_cost) | |||
| print("Absolute mean square loss difference:", abs( | |||
| training_cost - testing_cost)) | |||
| plt.plot(test_X, test_Y, 'bo', label='Testing data') | |||
| plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line') | |||
| plt.legend() | |||
| plt.show() | |||
| @@ -1,100 +0,0 @@ | |||
| ''' | |||
| A logistic regression learning algorithm example using TensorFlow library. | |||
| This example is using the MNIST database of handwritten digits | |||
| (http://yann.lecun.com/exdb/mnist/) | |||
| Author: Aymeric Damien | |||
| Project: https://github.com/aymericdamien/TensorFlow-Examples/ | |||
| ''' | |||
| from __future__ import print_function | |||
| import tensorflow as tf | |||
| # Import MNIST data | |||
| from tensorflow.examples.tutorials.mnist import input_data | |||
| mnist = input_data.read_data_sets("/tmp/data/", one_hot=True) | |||
| # Parameters | |||
| learning_rate = 0.01 | |||
| training_epochs = 10 | |||
| batch_size = 100 | |||
| display_step = 1 | |||
| # tf Graph Input | |||
| x = tf.placeholder(tf.float32, [None, 784]) # mnist data image of shape 28*28=784 | |||
| y = tf.placeholder(tf.float32, [None, 10]) # 0-9 digits recognition => 10 classes | |||
| # Set model weights | |||
| W = tf.Variable(tf.zeros([784, 10])) | |||
| b = tf.Variable(tf.zeros([10])) | |||
| # Construct model | |||
| pred = tf.nn.softmax(tf.matmul(x, W) + b) # Softmax | |||
| # Minimize error using cross entropy | |||
| cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1)) | |||
| # Gradient Descent | |||
| optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) | |||
| # Initialize the variables (i.e. assign their default value) | |||
| init = tf.global_variables_initializer() | |||
| # Start training | |||
| with tf.Session() as sess: | |||
| # Run the initializer | |||
| sess.run(init) | |||
| # Training cycle | |||
| for epoch in range(training_epochs): | |||
| avg_cost = 0. | |||
| total_batch = int(mnist.train.num_examples/batch_size) | |||
| # Loop over all batches | |||
| for i in range(total_batch): | |||
| batch_xs, batch_ys = mnist.train.next_batch(batch_size) | |||
| # Run optimization op (backprop) and cost op (to get loss value) | |||
| _, c = sess.run([optimizer, cost], feed_dict={x: batch_xs, | |||
| y: batch_ys}) | |||
| # Compute average loss | |||
| avg_cost += c / total_batch | |||
| # Display logs per epoch step | |||
| if (epoch+1) % display_step == 0: | |||
| print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost)) | |||
| print("Optimization Finished!") | |||
| # Test model | |||
| correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)) | |||
| # Calculate accuracy | |||
| accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) | |||
| print("Accuracy:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels})) | |||
| # predict | |||
| # results = sess.run(pred, feed_dict={x: batch_xs[:1]}) | |||
| # save model | |||
| saver = tf.train.Saver() | |||
| save_path = saver.save(sess, "logistic_regression/model.ckpt") | |||
| tf.train.write_graph(sess.graph.as_graph_def(),'logistic_regression','model.pbtxt', as_text=True) | |||
| freeze_graph.freeze_graph(input_graph = 'logistic_regression/model.pbtxt', | |||
| input_saver = "", | |||
| input_binary = False, | |||
| input_checkpoint = 'logistic_regression/model.ckpt', | |||
| output_node_names = "Softmax", | |||
| restore_op_name = "save/restore_all", | |||
| filename_tensor_name = "save/Const:0", | |||
| output_graph = 'logistic_regression/model.pb', | |||
| clear_devices = True, | |||
| initializer_nodes = "") | |||
| # restoring the model | |||
| saver = tf.train.import_meta_graph('logistic_regression/tensorflowModel.ckpt.meta') | |||
| saver.restore(sess,tf.train.latest_checkpoint('logistic_regression')) | |||
| # predict | |||
| # pred = graph._nodes_by_name["Softmax"] | |||
| # output = pred.outputs[0] | |||
| # x = graph._nodes_by_name["Placeholder"] | |||
| # input = x.outputs[0] | |||
| # results = sess.run(output, feed_dict={input: batch_xs[:1]}) | |||
| @@ -1,67 +0,0 @@ | |||
| | |||
| import tensorflow as tf | |||
| import math | |||
| # Creates an inference graph. | |||
| # Hidden 1 | |||
| images = tf.constant(1.2, tf.float32, shape=[100, 28]) | |||
| with tf.name_scope("hidden1"): | |||
| weights = tf.Variable( | |||
| tf.truncated_normal([28, 128], | |||
| stddev=1.0 / math.sqrt(float(28))), | |||
| name="weights") | |||
| biases = tf.Variable(tf.zeros([128]), | |||
| name="biases") | |||
| hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases) | |||
| # Hidden 2 | |||
| with tf.name_scope("hidden2"): | |||
| weights = tf.Variable( | |||
| tf.truncated_normal([128, 32], | |||
| stddev=1.0 / math.sqrt(float(128))), | |||
| name="weights") | |||
| biases = tf.Variable(tf.zeros([32]), | |||
| name="biases") | |||
| hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases) | |||
| # Linear | |||
| with tf.name_scope("softmax_linear"): | |||
| weights = tf.Variable( | |||
| tf.truncated_normal([32, 10], | |||
| stddev=1.0 / math.sqrt(float(32))), | |||
| name="weights") | |||
| biases = tf.Variable(tf.zeros([10]), | |||
| name="biases") | |||
| logits = tf.matmul(hidden2, weights) + biases | |||
| tf.add_to_collection("logits", logits) | |||
| init_all_op = tf.global_variables_initializer() | |||
| with tf.Session() as sess: | |||
| # Initializes all the variables. | |||
| sess.run(init_all_op) | |||
| # Runs to logit. | |||
| sess.run(logits) | |||
| # Creates a saver. | |||
| saver0 = tf.train.Saver() | |||
| saver0.save(sess, 'my-save-dir/my-model-10000') | |||
| # Generates MetaGraphDef. | |||
| saver0.export_meta_graph('my-save-dir/my-model-10000.meta') | |||
| # Then later import it and extend it to a training graph. | |||
| with tf.Session() as sess: | |||
| new_saver = tf.train.import_meta_graph('my-save-dir/my-model-10000.meta') | |||
| new_saver.restore(sess, 'my-save-dir/my-model-10000') | |||
| # Addes loss and train. | |||
| labels = tf.constant(0, tf.int32, shape=[100], name="labels") | |||
| batch_size = tf.size(labels) | |||
| logits = tf.get_collection("logits")[0] | |||
| loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, | |||
| logits=logits) | |||
| tf.summary.scalar('loss', loss) | |||
| # Creates the gradient descent optimizer with the given learning rate. | |||
| optimizer = tf.train.GradientDescentOptimizer(0.01) | |||
| # Runs train_op. | |||
| train_op = optimizer.minimize(loss) | |||
| sess.run(train_op) | |||
| @@ -1,78 +0,0 @@ | |||
| import tensorflow as tf | |||
| from tensorflow.contrib import rnn | |||
| #import mnist dataset | |||
| from tensorflow.examples.tutorials.mnist import input_data | |||
| mnist=input_data.read_data_sets("/tmp/data/",one_hot=True) | |||
| #define constants | |||
| #unrolled through 28 time steps | |||
| time_steps=28 | |||
| #hidden LSTM units | |||
| num_units=128 | |||
| #rows of 28 pixels | |||
| n_input=28 | |||
| #learning rate for adam | |||
| learning_rate=0.001 | |||
| #mnist is meant to be classified in 10 classes(0-9). | |||
| n_classes=10 | |||
| #size of batch | |||
| batch_size=128 | |||
| #weights and biases of appropriate shape to accomplish above task | |||
| out_weights=tf.Variable(tf.random_normal([num_units,n_classes])) | |||
| out_bias=tf.Variable(tf.random_normal([n_classes])) | |||
| #defining placeholders | |||
| #input image placeholder | |||
| x=tf.placeholder("float",[None,time_steps,n_input]) | |||
| #input label placeholder | |||
| y=tf.placeholder("float",[None,n_classes]) | |||
| #processing the input tensor from [batch_size,n_steps,n_input] to "time_steps" number of [batch_size,n_input] tensors | |||
| input=tf.unstack(x ,time_steps,1) | |||
| #defining the network | |||
| lstm_layer=rnn.BasicLSTMCell(num_units,forget_bias=1) | |||
| outputs,_=rnn.static_rnn(lstm_layer,input,dtype="float32") | |||
| #converting last output of dimension [batch_size,num_units] to [batch_size,n_classes] by out_weight multiplication | |||
| prediction=tf.matmul(outputs[-1],out_weights)+out_bias | |||
| #loss_function | |||
| loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y)) | |||
| #optimization | |||
| opt=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss) | |||
| #model evaluation | |||
| correct_prediction=tf.equal(tf.argmax(prediction,1),tf.argmax(y,1)) | |||
| accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) | |||
| #initialize variables | |||
| init=tf.global_variables_initializer() | |||
| with tf.Session() as sess: | |||
| sess.run(init) | |||
| iter=1 | |||
| while iter<800: | |||
| batch_x,batch_y=mnist.train.next_batch(batch_size=batch_size) | |||
| batch_x=batch_x.reshape((batch_size,time_steps,n_input)) | |||
| sess.run(opt, feed_dict={x: batch_x, y: batch_y}) | |||
| if iter %10==0: | |||
| acc=sess.run(accuracy,feed_dict={x:batch_x,y:batch_y}) | |||
| los=sess.run(loss,feed_dict={x:batch_x,y:batch_y}) | |||
| print("For iter ",iter) | |||
| print("Accuracy ",acc) | |||
| print("Loss ",los) | |||
| print("__________________") | |||
| iter=iter+1 | |||
| #calculating test accuracy | |||
| test_data = mnist.test.images[:128].reshape((-1, time_steps, n_input)) | |||
| test_label = mnist.test.labels[:128] | |||
| print("Testing Accuracy:", sess.run(accuracy, feed_dict={x: test_data, y: test_label})) | |||
| @@ -1,48 +0,0 @@ | |||
| import tensorflow as tf | |||
| # hyperparameters | |||
| n_neurons = 128 | |||
| learning_rate = 0.001 | |||
| batch_size = 128 | |||
| n_epochs = 10 | |||
| # parameters | |||
| n_steps = 28 # 28 rows | |||
| n_inputs = 28 # 28 cols | |||
| n_outputs = 10 # 10 classes | |||
| # build a rnn model | |||
| X = tf.placeholder(tf.float32, [None, n_steps, n_inputs]) | |||
| y = tf.placeholder(tf.int32, [None]) | |||
| cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons) | |||
| output, state = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32) | |||
| logits = tf.layers.dense(state, n_outputs) | |||
| cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits) | |||
| loss = tf.reduce_mean(cross_entropy) | |||
| optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss) | |||
| prediction = tf.nn.in_top_k(logits, y, 1) | |||
| accuracy = tf.reduce_mean(tf.cast(prediction, tf.float32)) | |||
| # input data | |||
| from tensorflow.examples.tutorials.mnist import input_data | |||
| mnist = input_data.read_data_sets("MNIST_data/") | |||
| X_test = mnist.test.images # X_test shape: [num_test, 28*28] | |||
| X_test = X_test.reshape([-1, n_steps, n_inputs]) | |||
| y_test = mnist.test.labels | |||
| # initialize the variables | |||
| init = tf.global_variables_initializer() | |||
| # train the model | |||
| with tf.Session() as sess: | |||
| sess.run(init) | |||
| n_batches = mnist.train.num_examples // batch_size | |||
| for epoch in range(n_epochs): | |||
| for batch in range(n_batches): | |||
| X_train, y_train = mnist.train.next_batch(batch_size) | |||
| X_train = X_train.reshape([-1, n_steps, n_inputs]) | |||
| sess.run(optimizer, feed_dict={X: X_train, y: y_train}) | |||
| loss_train, acc_train = sess.run( | |||
| [loss, accuracy], feed_dict={X: X_train, y: y_train}) | |||
| print('Epoch: {}, Train Loss: {:.3f}, Train Acc: {:.3f}'.format( | |||
| epoch + 1, loss_train, acc_train)) | |||
| loss_test, acc_test = sess.run( | |||
| [loss, accuracy], feed_dict={X: X_test, y: y_test}) | |||
| print('Test Loss: {:.3f}, Test Acc: {:.3f}'.format(loss_test, acc_test)) | |||
| @@ -1,164 +0,0 @@ | |||
| # imports | |||
| import tensorflow as tf | |||
| import numpy as np | |||
| import matplotlib.pyplot as plt | |||
| img_h = img_w = 28 # MNIST images are 28x28 | |||
| img_size_flat = img_h * img_w # 28x28=784, the total number of pixels | |||
| n_classes = 10 # Number of classes, one class per digit | |||
| def load_data(mode='train'): | |||
| """ | |||
| Function to (download and) load the MNIST data | |||
| :param mode: train or test | |||
| :return: images and the corresponding labels | |||
| """ | |||
| from tensorflow.examples.tutorials.mnist import input_data | |||
| mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) | |||
| if mode == 'train': | |||
| x_train, y_train, x_valid, y_valid = mnist.train.images, mnist.train.labels, \ | |||
| mnist.validation.images, mnist.validation.labels | |||
| return x_train, y_train, x_valid, y_valid | |||
| elif mode == 'test': | |||
| x_test, y_test = mnist.test.images, mnist.test.labels | |||
| return x_test, y_test | |||
| def randomize(x, y): | |||
| """ Randomizes the order of data samples and their corresponding labels""" | |||
| permutation = np.random.permutation(y.shape[0]) | |||
| shuffled_x = x[permutation, :] | |||
| shuffled_y = y[permutation] | |||
| return shuffled_x, shuffled_y | |||
| def get_next_batch(x, y, start, end): | |||
| x_batch = x[start:end] | |||
| y_batch = y[start:end] | |||
| return x_batch, y_batch | |||
| # Load MNIST data | |||
| x_train, y_train, x_valid, y_valid = load_data(mode='train') | |||
| print("Size of:") | |||
| print("- Training-set:\t\t{}".format(len(y_train))) | |||
| print("- Validation-set:\t{}".format(len(y_valid))) | |||
| print('x_train:\t{}'.format(x_train.shape)) | |||
| print('y_train:\t{}'.format(y_train.shape)) | |||
| print('x_train:\t{}'.format(x_valid.shape)) | |||
| print('y_valid:\t{}'.format(y_valid.shape)) | |||
| print(y_valid[:5, :]) | |||
| # Hyper-parameters | |||
| epochs = 10 # Total number of training epochs | |||
| batch_size = 100 # Training batch size | |||
| display_freq = 100 # Frequency of displaying the training results | |||
| learning_rate = 0.001 # The optimization initial learning rate | |||
| h1 = 200 # number of nodes in the 1st hidden layer | |||
| # weight and bais wrappers | |||
| def weight_variable(name, shape): | |||
| """ | |||
| Create a weight variable with appropriate initialization | |||
| :param name: weight name | |||
| :param shape: weight shape | |||
| :return: initialized weight variable | |||
| """ | |||
| initer = tf.truncated_normal_initializer(stddev=0.01) | |||
| return tf.get_variable('W_' + name, | |||
| dtype=tf.float32, | |||
| shape=shape, | |||
| initializer=initer) | |||
| def bias_variable(name, shape): | |||
| """ | |||
| Create a bias variable with appropriate initialization | |||
| :param name: bias variable name | |||
| :param shape: bias variable shape | |||
| :return: initialized bias variable | |||
| """ | |||
| initial = tf.constant(0., shape=shape, dtype=tf.float32) | |||
| return tf.get_variable('b_' + name, | |||
| dtype=tf.float32, | |||
| initializer=initial) | |||
| def fc_layer(x, num_units, name, use_relu=True): | |||
| """ | |||
| Create a fully-connected layer | |||
| :param x: input from previous layer | |||
| :param num_units: number of hidden units in the fully-connected layer | |||
| :param name: layer name | |||
| :param use_relu: boolean to add ReLU non-linearity (or not) | |||
| :return: The output array | |||
| """ | |||
| in_dim = x.get_shape()[1] | |||
| W = weight_variable(name, shape=[in_dim, num_units]) | |||
| b = bias_variable(name, [num_units]) | |||
| layer = tf.matmul(x, W) | |||
| layer += b | |||
| if use_relu: | |||
| layer = tf.nn.relu(layer) | |||
| return layer | |||
| # Create the graph for the linear model | |||
| # Placeholders for inputs (x) and outputs(y) | |||
| x = tf.placeholder(tf.float32, shape=[None, img_size_flat], name='X') | |||
| y = tf.placeholder(tf.float32, shape=[None, n_classes], name='Y') | |||
| # Create a fully-connected layer with h1 nodes as hidden layer | |||
| fc1 = fc_layer(x, h1, 'FC1', use_relu=True) | |||
| # Create a fully-connected layer with n_classes nodes as output layer | |||
| output_logits = fc_layer(fc1, n_classes, 'OUT', use_relu=False) | |||
| # Define the loss function, optimizer, and accuracy | |||
| logits = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=output_logits) | |||
| loss = tf.reduce_mean(logits, name='loss') | |||
| optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, name='Adam-op').minimize(loss) | |||
| correct_prediction = tf.equal(tf.argmax(output_logits, 1), tf.argmax(y, 1), name='correct_pred') | |||
| accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy') | |||
| # Network predictions | |||
| cls_prediction = tf.argmax(output_logits, axis=1, name='predictions') | |||
| # export graph | |||
| #tf.train.export_meta_graph(filename='neural_network.meta', graph=tf.get_default_graph(), clear_extraneous_savers= True, as_text = True) | |||
| # Create the op for initializing all variables | |||
| init = tf.global_variables_initializer() | |||
| # Create an interactive session (to keep the session in the other cells) | |||
| sess = tf.InteractiveSession() | |||
| # Initialize all variables | |||
| sess.run(init) | |||
| # Number of training iterations in each epoch | |||
| num_tr_iter = int(len(y_train) / batch_size) | |||
| for epoch in range(epochs): | |||
| print('Training epoch: {}'.format(epoch + 1)) | |||
| # Randomly shuffle the training data at the beginning of each epoch | |||
| x_train, y_train = randomize(x_train, y_train) | |||
| for iteration in range(num_tr_iter): | |||
| start = iteration * batch_size | |||
| end = (iteration + 1) * batch_size | |||
| x_batch, y_batch = get_next_batch(x_train, y_train, start, end) | |||
| # Run optimization op (backprop) | |||
| feed_dict_batch = {x: x_batch, y: y_batch} | |||
| sess.run(optimizer, feed_dict=feed_dict_batch) | |||
| if iteration % display_freq == 0: | |||
| # Calculate and display the batch loss and accuracy | |||
| loss_batch, acc_batch = sess.run([loss, accuracy], | |||
| feed_dict=feed_dict_batch) | |||
| print("iter {0:3d}:\t Loss={1:.2f},\tTraining Accuracy={2:.01%}". | |||
| format(iteration, loss_batch, acc_batch)) | |||
| # Run validation after every epoch | |||
| feed_dict_valid = {x: x_valid[:1000], y: y_valid[:1000]} | |||
| loss_valid, acc_valid = sess.run([loss, accuracy], feed_dict=feed_dict_valid) | |||
| print('---------------------------------------------------------') | |||
| print("Epoch: {0}, validation loss: {1:.2f}, validation accuracy: {2:.01%}". | |||
| format(epoch + 1, loss_valid, acc_valid)) | |||
| print('---------------------------------------------------------') | |||
| @@ -1,126 +0,0 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using Tensorflow; | |||
| using TensorFlowNET.Examples; | |||
| using static Tensorflow.Binding; | |||
| namespace TensorFlowNET.ExamplesTests | |||
| { | |||
| [TestClass] | |||
| public class ExamplesTest | |||
| { | |||
| [TestMethod] | |||
| public void BasicOperations() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new BasicOperations() { Enabled = true }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void HelloWorld() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new HelloWorld() { Enabled = true }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void ImageRecognition() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new HelloWorld() { Enabled = true }.Run(); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void InceptionArchGoogLeNet() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new InceptionArchGoogLeNet() { Enabled = true }.Run(); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void KMeansClustering() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new KMeansClustering() { Enabled = true, IsImportingGraph = true, train_size = 500, validation_size = 100, test_size = 100, batch_size =100 }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void LinearRegression() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new LinearRegression() { Enabled = true }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void LogisticRegression() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new LogisticRegression() { Enabled = true, training_epochs=10, train_size = 500, validation_size = 100, test_size = 100 }.Run(); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void NaiveBayesClassifier() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new NaiveBayesClassifier() { Enabled = false }.Run(); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void NamedEntityRecognition() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new NamedEntityRecognition() { Enabled = true }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void NearestNeighbor() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new NearestNeighbor() { Enabled = true, TrainSize = 500, ValidationSize = 100, TestSize = 100 }.Run(); | |||
| } | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void WordCnnTextClassification() | |||
| => new CnnTextClassification { Enabled = true, ModelName = "word_cnn", DataLimit =100 }.Run(); | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void CharCnnTextClassification() | |||
| => new CnnTextClassification { Enabled = true, ModelName = "char_cnn", DataLimit = 100 }.Run(); | |||
| [Ignore] | |||
| [TestMethod] | |||
| public void TextClassificationWithMovieReviews() | |||
| { | |||
| tf.Graph().as_default(); | |||
| new BinaryTextClassification() { Enabled = true }.Run(); | |||
| } | |||
| [TestMethod] | |||
| public void NeuralNetXor() | |||
| { | |||
| tf.Graph().as_default(); | |||
| Assert.IsTrue(new NeuralNetXor() { Enabled = true, IsImportingGraph = false }.Run()); | |||
| } | |||
| [Ignore("Not working")] | |||
| [TestMethod] | |||
| public void NeuralNetXor_ImportedGraph() | |||
| { | |||
| tf.Graph().as_default(); | |||
| Assert.IsTrue(new NeuralNetXor() { Enabled = true, IsImportingGraph = true }.Run()); | |||
| } | |||
| [Ignore("Not working")] | |||
| [TestMethod] | |||
| public void ObjectDetection() | |||
| { | |||
| tf.Graph().as_default(); | |||
| Assert.IsTrue(new ObjectDetection() { Enabled = true, IsImportingGraph = true }.Run()); | |||
| } | |||
| } | |||
| } | |||
| @@ -39,7 +39,6 @@ | |||
| <ProjectReference Include="..\..\src\TensorFlowHub\TensorFlowHub.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
| <ProjectReference Include="..\..\src\TensorFlowText\TensorFlowText.csproj" /> | |||
| <ProjectReference Include="..\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||