Skip to content

Commit 6507a5f

Browse files
committed
Finished InceptionV3 image recognition.
1 parent 53882c7 commit 6507a5f

24 files changed

Lines changed: 244 additions & 99 deletions

TensorFlow.NET.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "t
99
EndProject
1010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}"
1111
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensorFlowNET.Utility", "src\TensorFlowNET.Utility\TensorFlowNET.Utility.csproj", "{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}"
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Utility", "src\TensorFlowNET.Utility\TensorFlowNET.Utility.csproj", "{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}"
1313
EndProject
1414
Global
1515
GlobalSection(SolutionConfigurationPlatforms) = preSolution

src/TensorFlowNET.Core/APIs/tf.io.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@ public partial class tf
99
public static Tensor read_file(string filename, string name = "") => gen_io_ops.read_file(filename, name);
1010

1111
public static gen_image_ops image => new gen_image_ops();
12+
13+
public static void import_graph_def(GraphDef graph_def,
14+
Dictionary<string, Tensor> input_map = null,
15+
string[] return_elements = null,
16+
string name = "",
17+
OpList producer_op_list = null) => importer.import_graph_def(graph_def, input_map, return_elements, name, producer_op_list);
1218
}
1319
}

src/TensorFlowNET.Core/Graphs/Graph.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Tensorflow
1212
/// then create a TensorFlow session to run parts of the graph across a set of local and remote devices.
1313
/// https://www.tensorflow.org/guide/graphs
1414
/// </summary>
15-
public partial class Graph : IDisposable
15+
public partial class Graph : IPython, IDisposable
1616
{
1717
private IntPtr _handle;
1818
private Dictionary<int, ITensorOrOperation> _nodes_by_id;
@@ -62,6 +62,8 @@ public ITensorOrOperation as_graph_element(object obj, bool allow_tensor = true,
6262
return _as_graph_element_locked(obj, allow_tensor, allow_operation);
6363
}
6464

65+
public Graph as_default() => ops.set_default_graph(this);
66+
6567
private Tensor _as_graph_element(object obj)
6668
{
6769
if (obj is RefVariable var)
@@ -359,6 +361,15 @@ public void Dispose()
359361
c_api.TF_DeleteGraph(_handle);
360362
}
361363

364+
public void __enter__()
365+
{
366+
}
367+
368+
public void __exit__()
369+
{
370+
371+
}
372+
362373
public static implicit operator IntPtr(Graph graph)
363374
{
364375
return graph._handle;

src/TensorFlowNET.Core/Operations/OperationDescription.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Tensorflow
77
public class OperationDescription
88
{
99
private IntPtr _handle;
10+
public IntPtr op => _handle;
1011

1112
public OperationDescription(Graph graph, string opType, string opName)
1213
{

src/TensorFlowNET.Core/Operations/c_api.ops.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public partial class c_api
2929
/// <summary>
3030
/// For inputs that take a single tensor.
3131
/// </summary>
32-
/// <param name="desc"></param>
33-
/// <param name="input"></param>
32+
/// <param name="desc">TF_OperationDescription*</param>
33+
/// <param name="input">TF_Output</param>
3434
[DllImport(TensorFlowLibName)]
3535
public static extern void TF_AddInput(IntPtr desc, TF_Output input);
3636

src/TensorFlowNET.Core/Operations/gen_image_ops.py.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public Tensor decode_jpeg(Tensor contents,
3939
}
4040
}
4141

42-
public Tensor resize_bilinear(Tensor images, int[] size, bool align_corners = false, string name = "")
42+
public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, string name = "")
4343
{
4444
if (tf.context.executing_eagerly())
4545
{

src/TensorFlowNET.Core/Sessions/BaseSession.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ private NDArray _run(object fetches, FeedItem[] feed_dict = null)
6161
var subfeed_dtype = subfeed_t.dtype.as_numpy_datatype();
6262
switch (subfeed_val)
6363
{
64+
case IntPtr pointer:
65+
feed_dict_tensor[subfeed_t] = pointer;
66+
break;
6467
case NDArray nd:
6568
feed_dict_tensor[subfeed_t] = nd;
6669
break;
@@ -73,6 +76,9 @@ private NDArray _run(object fetches, FeedItem[] feed_dict = null)
7376
case string str:
7477
feed_dict_tensor[subfeed_t] = (NDArray)str;
7578
break;
79+
case byte[] bytes:
80+
feed_dict_tensor[subfeed_t] = (NDArray)bytes;
81+
break;
7682
default:
7783
throw new NotImplementedException("_run subfeed");
7884
}
@@ -120,6 +126,8 @@ private NDArray[] _do_run(List<Operation> target_list, List<Tensor> fetch_list,
120126
{
121127
switch (x.Value)
122128
{
129+
case IntPtr pointer:
130+
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), pointer);
123131
case Tensor t1:
124132
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), t1);
125133
case NDArray nd:
@@ -131,7 +139,7 @@ private NDArray[] _do_run(List<Operation> target_list, List<Tensor> fetch_list,
131139
case double doubleVal:
132140
return new KeyValuePair<TF_Output, Tensor>(tensor._as_tf_output(), new Tensor(doubleVal));
133141
default:
134-
break;
142+
throw new NotImplementedException("feed_dict data type");
135143
}
136144
}
137145
throw new NotImplementedException("_do_run.feed_dict");
@@ -182,6 +190,7 @@ private unsafe NDArray fetchValue(IntPtr output)
182190
NDArray nd = null;
183191
Type type = tensor.dtype.as_numpy_datatype();
184192
var ndims = tensor.shape.Select(x => (int)x).ToArray();
193+
var offset = c_api.TF_TensorData(output);
185194

186195
switch (tensor.dtype)
187196
{
@@ -195,25 +204,25 @@ private unsafe NDArray fetchValue(IntPtr output)
195204
case TF_DataType.TF_INT16:
196205
var shorts = new short[tensor.size];
197206
for (ulong i = 0; i < tensor.size; i++)
198-
shorts[i] = *(short*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i));
207+
shorts[i] = *(short*)(offset + (int)(tensor.itemsize * i));
199208
nd = np.array(shorts).reshape(ndims);
200209
break;
201210
case TF_DataType.TF_INT32:
202211
var ints = new int[tensor.size];
203212
for (ulong i = 0; i < tensor.size; i++)
204-
ints[i] = *(int*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i));
213+
ints[i] = *(int*)(offset + (int)(tensor.itemsize * i));
205214
nd = np.array(ints).reshape(ndims);
206215
break;
207216
case TF_DataType.TF_FLOAT:
208217
var floats = new float[tensor.size];
209218
for (ulong i = 0; i < tensor.size; i++)
210-
floats[i] = *(float*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i));
219+
floats[i] = *(float*)(offset + (int)(tensor.itemsize * i));
211220
nd = np.array(floats).reshape(ndims);
212221
break;
213222
case TF_DataType.TF_DOUBLE:
214223
var doubles = new double[tensor.size];
215224
for (ulong i = 0; i < tensor.size; i++)
216-
doubles[i] = *(double*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i));
225+
doubles[i] = *(double*)(offset + (int)(tensor.itemsize * i));
217226
nd = np.array(doubles).reshape(ndims);
218227
break;
219228
default:

src/TensorFlowNET.Core/Sessions/Session.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ public Session(IntPtr handle)
2828
_handle = handle;
2929
}
3030

31-
public Session(Graph graph, SessionOptions opts, Status s = null)
31+
public Session(Graph g, SessionOptions opts = null, Status s = null)
3232
{
3333
if (s == null)
3434
s = Status;
35-
_handle = c_api.TF_NewSession(graph, opts, s);
35+
graph = g;
36+
Options = opts == null ? new SessionOptions() : opts;
37+
_handle = c_api.TF_NewSession(graph, Options, s);
3638
Status.Check(true);
3739
}
3840

@@ -50,7 +52,7 @@ public static Session LoadFromSavedModel(string path)
5052

5153
status.Check();
5254

53-
tf.g = new Graph(graph);
55+
new Graph(graph).as_default();
5456

5557
return sess;
5658
}

src/TensorFlowNET.Core/TensorFlowNET.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Upgraded to TensorFlow 1.13 RC-1.
4646

4747
<ItemGroup>
4848
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
49-
<PackageReference Include="NumSharp" Version="0.7.1" />
49+
<PackageReference Include="NumSharp" Version="0.7.2" />
5050
</ItemGroup>
5151

5252
<ItemGroup>

src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ public Tensor(NDArray nd)
2525
_handle = Allocate(nd);
2626
}
2727

28+
public unsafe Tensor(byte[] buffer)
29+
{
30+
var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length);
31+
_handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8));
32+
33+
IntPtr tensor = c_api.TF_TensorData(_handle);
34+
Marshal.WriteInt64(tensor, 0);
35+
fixed (byte* src = &buffer[0])
36+
c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(Int64)), size, status);
37+
38+
status.Check(true);
39+
}
40+
2841
private IntPtr Allocate(NDArray nd)
2942
{
3043
IntPtr dotHandle = IntPtr.Zero;
@@ -43,20 +56,21 @@ private IntPtr Allocate(NDArray nd)
4356
switch (nd.dtype.Name)
4457
{
4558
case "Int16":
46-
Marshal.Copy(nd.Data<short>(), 0, dotHandle, nd.size);
59+
Marshal.Copy(nd.ravel().Data<short>(), 0, dotHandle, nd.size);
4760
break;
4861
case "Int32":
49-
Marshal.Copy(nd.Data<int>(), 0, dotHandle, nd.size);
62+
Marshal.Copy(nd.ravel().Data<int>(), 0, dotHandle, nd.size);
5063
break;
5164
case "Single":
52-
Marshal.Copy(nd.Data<float>(), 0, dotHandle, nd.size);
65+
Marshal.Copy(nd.ravel().Data<float>(), 0, dotHandle, nd.size);
5366
break;
5467
case "Double":
55-
Marshal.Copy(nd.Data<double>(), 0, dotHandle, nd.size);
68+
Marshal.Copy(nd.ravel().Data<double>(), 0, dotHandle, nd.size);
5669
break;
57-
case "Byte":
58-
var bb = nd.Data<byte>();
59-
var bytes = Marshal.AllocHGlobal(bb.Length) ;
70+
//case "Byte":
71+
/*var bb = nd.Data<byte>();
72+
var bytes = Marshal.AllocHGlobal(bb.Length);
73+
Marshal.Copy(bb, 0, bytes, bb.Length);
6074
ulong bytes_len = c_api.TF_StringEncodedSize((ulong)bb.Length);
6175
var dataTypeByte = ToTFDataType(nd.dtype);
6276
// shape
@@ -70,9 +84,10 @@ private IntPtr Allocate(NDArray nd)
7084
dotHandle = c_api.TF_TensorData(tfHandle2);
7185
Marshal.WriteInt64(dotHandle, 0);
7286
c_api.TF_StringEncode(bytes, (ulong)bb.Length, dotHandle + sizeof(Int64), bytes_len, status);
73-
return tfHandle2;
74-
case "String":
75-
string ss = nd.Data<string>()[0];
87+
return tfHandle2;*/
88+
break;
89+
//case "String":
90+
/*string ss = nd.Data<string>()[0];
7691
var str = Marshal.StringToHGlobalAnsi(ss);
7792
ulong dst_len = c_api.TF_StringEncodedSize((ulong)ss.Length);
7893
var dataType1 = ToTFDataType(nd.dtype);
@@ -87,7 +102,8 @@ private IntPtr Allocate(NDArray nd)
87102
dotHandle = c_api.TF_TensorData(tfHandle1);
88103
Marshal.WriteInt64(dotHandle, 0);
89104
c_api.TF_StringEncode(str, (ulong)ss.Length, dotHandle + sizeof(Int64), dst_len, status);
90-
return tfHandle1;
105+
return tfHandle1;*/
106+
break;
91107
default:
92108
throw new NotImplementedException("Marshal.Copy failed.");
93109
}
@@ -101,7 +117,7 @@ private IntPtr Allocate(NDArray nd)
101117

102118
var tfHandle = c_api.TF_NewTensor(dataType,
103119
dims,
104-
nd.ndim,
120+
dims.Length,
105121
dotHandle,
106122
size,
107123
deallocator,

0 commit comments

Comments
 (0)