Browse Source

run_bottleneck_on_image.resized_input_values

tags/v0.9
Oceania2018 6 years ago
parent
commit
bd04f5bad2
6 changed files with 99 additions and 27 deletions
  1. +3
    -3
      TensorFlow.NET.sln
  2. +5
    -2
      src/TensorFlowNET.Core/Sessions/BaseSession.cs
  3. +9
    -20
      src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs
  4. +2
    -0
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  5. +1
    -0
      src/TensorFlowNET.Core/tf.cs
  6. +79
    -2
      test/TensorFlowNET.Examples/ImageProcess/RetrainImageClassifier.cs

+ 3
- 3
TensorFlow.NET.sln View File

@@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.168
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
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
@@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\T
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.Core", "src\KerasNET.Core\Keras.Core.csproj", "{902E188F-A953-43B4-9991-72BAB1697BC3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.Core", "src\KerasNET.Core\Keras.Core.csproj", "{902E188F-A953-43B4-9991-72BAB1697BC3}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Keras.Example", "test\KerasNET.Example\Keras.Example.csproj", "{17E1AC16-9E0E-4545-905A-E92C6300C7AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.Example", "test\KerasNET.Example\Keras.Example.csproj", "{17E1AC16-9E0E-4545-905A-E92C6300C7AF}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.UnitTest", "test\KerasNET.Test\Keras.UnitTest.csproj", "{A5839A45-A117-4BEA-898B-DE1ED6E0D58F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Keras.UnitTest", "test\KerasNET.Test\Keras.UnitTest.csproj", "{A5839A45-A117-4BEA-898B-DE1ED6E0D58F}"
EndProject EndProject


+ 5
- 2
src/TensorFlowNET.Core/Sessions/BaseSession.cs View File

@@ -99,6 +99,9 @@ namespace Tensorflow
feed_dict_tensor[subfeed_t] = (NDArray)val; feed_dict_tensor[subfeed_t] = (NDArray)val;
break; break;
case byte[] val: case byte[] val:
feed_dict_tensor[subfeed_t] = np.array(val);
break;
case char[] val:
feed_dict_tensor[subfeed_t] = (NDArray)val; feed_dict_tensor[subfeed_t] = (NDArray)val;
break; break;
case bool val: case bool val:
@@ -130,7 +133,7 @@ namespace Tensorflow


// We only want to really perform the run if fetches or targets are provided, // We only want to really perform the run if fetches or targets are provided,
// or if the call is a partial run that specifies feeds. // or if the call is a partial run that specifies feeds.
var results = _do_run(final_targets.Select(x => (Operation)(object)x).ToList(), final_fetches, feed_dict_tensor);
var results = _do_run(final_targets.Select(x => (Operation)x).ToList(), final_fetches, feed_dict_tensor);


return fetch_handler.build_results(this, results); return fetch_handler.build_results(this, results);
} }
@@ -161,7 +164,7 @@ namespace Tensorflow
case Tensor t1: case Tensor t1:
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), t1); return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), t1);
case NDArray nd: case NDArray nd:
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), new Tensor(nd));
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), new Tensor(nd, tensor.dtype));
case int intVal: case int intVal:
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), new Tensor(intVal)); return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), new Tensor(intVal));
case float floatVal: case float floatVal:


+ 9
- 20
src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs View File

@@ -20,9 +20,9 @@ namespace Tensorflow
_handle = handle; _handle = handle;
} }


public Tensor(NDArray nd)
public Tensor(NDArray nd, TF_DataType? tensorDType = null)
{ {
_handle = Allocate(nd);
_handle = Allocate(nd, tensorDType: tensorDType);
} }


public unsafe Tensor(byte[] buffer) public unsafe Tensor(byte[] buffer)
@@ -38,8 +38,14 @@ namespace Tensorflow
status.Check(true); status.Check(true);
} }


private IntPtr Allocate(NDArray nd)
private IntPtr Allocate(NDArray nd, TF_DataType? tensorDType = null)
{ {
if (tensorDType == TF_DataType.TF_STRING &&
nd.dtype.Name == "Byte")
{
return new Tensor(nd.Data<byte>());
}

IntPtr dotHandle = IntPtr.Zero; IntPtr dotHandle = IntPtr.Zero;
ulong size = 0; ulong size = 0;


@@ -73,23 +79,6 @@ namespace Tensorflow
break; break;
case "Byte": case "Byte":
Marshal.Copy(nd1.Data<byte>(), 0, dotHandle, nd.size); Marshal.Copy(nd1.Data<byte>(), 0, dotHandle, nd.size);
/*var bb = nd.Data<byte>();
var bytes = Marshal.AllocHGlobal(bb.Length);
Marshal.Copy(bb, 0, bytes, bb.Length);
ulong bytes_len = c_api.TF_StringEncodedSize((ulong)bb.Length);
var dataTypeByte = ToTFDataType(nd.dtype);
// shape
var dims2 = nd.shape.Select(x => (long)x).ToArray();

var tfHandle2 = c_api.TF_AllocateTensor(dataTypeByte,
dims2,
nd.ndim,
bytes_len + sizeof(Int64));

dotHandle = c_api.TF_TensorData(tfHandle2);
Marshal.WriteInt64(dotHandle, 0);
c_api.TF_StringEncode(bytes, (ulong)bb.Length, dotHandle + sizeof(Int64), bytes_len, status);
return tfHandle2;*/
break; break;
//case "String": //case "String":
/*string ss = nd.Data<string>()[0]; /*string ss = nd.Data<string>()[0];


+ 2
- 0
src/TensorFlowNET.Core/Tensors/Tensor.cs View File

@@ -187,6 +187,8 @@ namespace Tensorflow
{ {
switch (type.Name) switch (type.Name)
{ {
case "Char":
return TF_DataType.TF_UINT8;
case "Int16": case "Int16":
return TF_DataType.TF_INT16; return TF_DataType.TF_INT16;
case "Int32": case "Int32":


+ 1
- 0
src/TensorFlowNET.Core/tf.cs View File

@@ -8,6 +8,7 @@ namespace Tensorflow
{ {
public static partial class tf public static partial class tf
{ {
public static TF_DataType bytes = TF_DataType.TF_STRING;
public static TF_DataType int16 = TF_DataType.TF_INT16; public static TF_DataType int16 = TF_DataType.TF_INT16;
public static TF_DataType int32 = TF_DataType.TF_INT32; public static TF_DataType int32 = TF_DataType.TF_INT32;
public static TF_DataType float16 = TF_DataType.TF_HALF; public static TF_DataType float16 = TF_DataType.TF_HALF;


+ 79
- 2
test/TensorFlowNET.Examples/ImageProcess/RetrainImageClassifier.cs View File

@@ -1,4 +1,5 @@
using System;
using NumSharp;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@@ -105,7 +106,83 @@ namespace TensorFlowNET.Examples.ImageProcess
Tensor bottleneck_tensor, string module_name) Tensor bottleneck_tensor, string module_name)
{ {
var label_lists = image_lists[label_name]; var label_lists = image_lists[label_name];
var sub_dir_path = Path.Join(image_dir, 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);
}

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);
}

/// <summary>
/// Runs inference on an image to extract the 'bottleneck' summary layer.
/// </summary>
/// <param name="sess">Current active TensorFlow Session.</param>
/// <param name="image_path">Path 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, image_data));
// Then run it through the recognition network.
var bottleneck_values = sess.run(bottleneck_tensor, new FeedItem(resized_input_tensor, resized_input_values));
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;
} }


public void PrepareData() public void PrepareData()


Loading…
Cancel
Save