@@ -5,14 +5,8 @@ VisualStudioVersion = 16.0.29102.190 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | MinimumVisualStudioVersion = 10.0.40219.1 | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "test\TensorFlowNET.UnitTest\TensorFlowNET.UnitTest.csproj", "{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.UnitTest", "test\TensorFlowNET.UnitTest\TensorFlowNET.UnitTest.csproj", "{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}" | ||||
EndProject | 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}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" | ||||
EndProject | 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}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowHub", "src\TensorFlowHub\TensorFlowHub.csproj", "{8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}" | ||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowText", "src\TensorFlowText\TensorFlowText.csproj", "{B598E5D5-BD2D-4191-8532-F2FBAC31AB81}" | 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}.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.ActiveCfg = Release|Any CPU | ||||
{029A8CF1-CF95-4DCB-98AA-9D3D96A83B3E}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU | ||||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU | ||||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU | ||||
{8FD59A5A-97EB-457E-B9F1-D88B0C822C6E}.Debug|Any CPU.Build.0 = 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 | {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\TensorFlowHub\TensorFlowHub.csproj" /> | ||||
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | ||||
<ProjectReference Include="..\..\src\TensorFlowText\TensorFlowText.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowText\TensorFlowText.csproj" /> | ||||
<ProjectReference Include="..\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||