Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/TensorFlowNET.Core/Keras/BackendBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using NumSharp;
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow;

namespace Tensorflow.Keras
{
public abstract class BackendBase
{
TF_DataType _FLOATX = dtypes.float32;
float _EPSILON = 1e-7f;
ImageDataFormat _IMAGE_DATA_FORMAT = ImageDataFormat.channels_last;


public float epsilon() => _EPSILON;

public void set_epsilon(float e) => _EPSILON = e;

public TF_DataType floatx() => _FLOATX;

public void set_floatx(TF_DataType floatx) => _FLOATX = floatx;

public NDArray cast_to_floatx(NDArray x) => np.array(x, dtype: _FLOATX.as_numpy_datatype());

public ImageDataFormat image_data_format() => _IMAGE_DATA_FORMAT;

public void set_image_data_format(ImageDataFormat data_format) => _IMAGE_DATA_FORMAT = data_format;

public ImageDataFormat normalize_data_format(object value = null)
{
if (value == null)
value = _IMAGE_DATA_FORMAT;
if (value.GetType() == typeof(ImageDataFormat))
return (ImageDataFormat)value;
else if (value.GetType() == typeof(string))
{
ImageDataFormat dataFormat;
if(Enum.TryParse((string)value, true, out dataFormat))
{
if (Enum.IsDefined(typeof(ImageDataFormat), dataFormat) | dataFormat.ToString().Contains(","))
return dataFormat;
}
}
throw new Exception("The `data_format` argument must be one of \"channels_first\", \"channels_last\". Received: " + value.ToString());
}

//Legacy Methods

public void set_image_dim_ordering(ImageDimOrder dim_ordering)
{
if (dim_ordering == ImageDimOrder.th)
_IMAGE_DATA_FORMAT = ImageDataFormat.channels_first;
else if (dim_ordering == ImageDimOrder.tf)
_IMAGE_DATA_FORMAT = ImageDataFormat.channels_last;
else
throw new Exception("Unknown dim_ordering:"+ dim_ordering);
}

public ImageDimOrder image_dim_ordering()
{
if (_IMAGE_DATA_FORMAT == ImageDataFormat.channels_first)
return ImageDimOrder.th;
else
return ImageDimOrder.tf;
}
}
public enum ImageDimOrder
{
tf,
th
}
}
8 changes: 8 additions & 0 deletions src/TensorFlowNET.Core/Keras/GraphLearningPhase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Tensorflow.Keras
{
public enum GraphLearningPhase
{
train_mode = 1,
test_mode = 0
}
}
8 changes: 8 additions & 0 deletions src/TensorFlowNET.Core/Keras/ImageDataFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Tensorflow.Keras
{
public enum ImageDataFormat
{
channels_last,
channels_first
}
}
6 changes: 3 additions & 3 deletions src/TensorFlowNET.Core/Keras/Utils/base_layer_utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ public static string unique_layer_name(string name, Dictionary<(string, string),
{
var graph = ops.get_default_graph();
Dictionary<(string, string), int> name_uid_map = null;
if (backend.PER_GRAPH_LAYER_NAME_UIDS.ContainsKey(graph.graph_key))
if (backend.PER_GRAPH_LAYER_NAME_UIDS.ContainsKey(graph))
{
name_uid_map = backend.PER_GRAPH_LAYER_NAME_UIDS[graph.graph_key];
name_uid_map = backend.PER_GRAPH_LAYER_NAME_UIDS[graph];
}
else
{
name_uid_map = new Dictionary<(string, string), int>();
backend.PER_GRAPH_LAYER_NAME_UIDS[graph.graph_key] = name_uid_map;
backend.PER_GRAPH_LAYER_NAME_UIDS[graph] = name_uid_map;
}

return name_uid_map;
Expand Down
85 changes: 78 additions & 7 deletions src/TensorFlowNET.Core/Keras/backend.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.CompilerServices;
using static Tensorflow.Python;

namespace Tensorflow.Keras
{
public class backend
public class backend : BackendBase
{
/* ---------------------------------------- KERAS BACKEND NATIVE OBJECTS ---------------------------------------- */
public static Func<Array, double> py_sum = sum;
public static Func<Array, bool> py_all = all;
//Func<Array, bool> py_any = any;
//Func<double, double, double, IEnumerable<double>> py_slice = slice;

public static Session _SESSION = Tensorflow.tf.defaultSession;
public static Graph _GRAPH = null;
public static Dictionary<Graph, GraphLearningPhase> _GRAPH_LEARNING_PHASES;
//Dictionary<Graph, Dictionary<string, int>> PER_GRAPH_LAYER_NAME_UIDS;
public static bool _MANUAL_VAR_INIT = false;
public static List<string> _LOCAL_DEVICES = null;
/* -------------------------------------- KERAS BACKEND NATIVE OBJECTS END -------------------------------------- */

/// <summary>
/// A global dictionary mapping graph objects to an index of counters used
/// for various layer names in each graph.
/// Allows to give unique autogenerated names to layers, in a graph-specific way.
/// </summary>
public static Dictionary<string, Dictionary<(string, string), int>> PER_GRAPH_LAYER_NAME_UIDS = new Dictionary<string, Dictionary<(string, string), int>>();
public static Dictionary<Graph, Dictionary<(string, string), int>> PER_GRAPH_LAYER_NAME_UIDS = new Dictionary<Graph, Dictionary<(string, string), int>>();
public static Dictionary<string, RefVariable> _GRAPH_VARIABLES = new Dictionary<string, RefVariable>();
public static Dictionary<string, Optimizer> _GRAPH_TF_OPTIMIZERS = new Dictionary<string, Optimizer>();

public static _DummyEagerGraph _DUMMY_EAGER_GRAPH = new _DummyEagerGraph();

public static void track_variable(RefVariable v)
{
var graph = v.graph;
_GRAPH_VARIABLES[graph.graph_key] = v;
}

public static Tensor placeholder(int[] shape = null,
int ndim = -1,
TF_DataType dtype = TF_DataType.DtInvalid,
bool sparse = false,
public static Tensor placeholder(int[] shape = null,
int ndim = -1,
TF_DataType dtype = TF_DataType.DtInvalid,
bool sparse = false,
string name = null)
{
if(sparse)
if (sparse)
{
throw new NotImplementedException("placeholder sparse is true");
}
Expand All @@ -39,5 +59,56 @@ public static Graph get_graph()
{
return ops.get_default_graph();
}

public static int get_uid(string prefix, string @namespace = "")
{
var graph = tf.get_default_graph();
if (!PER_GRAPH_LAYER_NAME_UIDS.ContainsKey(graph))
PER_GRAPH_LAYER_NAME_UIDS.Add(graph, new defaultdict<(string, string), int>());
PER_GRAPH_LAYER_NAME_UIDS[graph][(@namespace, prefix)] += 1;

return PER_GRAPH_LAYER_NAME_UIDS[graph][(@namespace, prefix)];
}
public static int get_uid((string, string) name)
{
var graph = tf.get_default_graph();
if (!PER_GRAPH_LAYER_NAME_UIDS.ContainsKey(graph))
PER_GRAPH_LAYER_NAME_UIDS.Add(graph, new defaultdict<(string, string), int>());
PER_GRAPH_LAYER_NAME_UIDS[graph][(name)] += 1;

return PER_GRAPH_LAYER_NAME_UIDS[graph][name];
}
public static void reset_uids() => PER_GRAPH_LAYER_NAME_UIDS = new Dictionary<Graph, Dictionary<(string, string), int>>();
public static void clear_session()
{
ops.reset_default_graph();
reset_uids();
_SESSION = null;
var phase = tf.placeholder_with_default(false, new int[] { }, name: "keras_learning_phase");
_GRAPH_LEARNING_PHASES = new Dictionary<Graph, GraphLearningPhase>();
_GRAPH_LEARNING_PHASES[tf.get_default_graph()] = 0;
}
public static void manual_variable_initialization(bool value)
{
_MANUAL_VAR_INIT = value;
}
public static GraphLearningPhase learning_phase()
{
var graph = tf.get_default_graph();
if (_GRAPH_LEARNING_PHASES.ContainsKey(graph))
{
var phase = tf.placeholder_with_default(false, shape: new int[] { }, name: "keras_learning_phase");
_GRAPH_LEARNING_PHASES[graph] = 0;
}
return _GRAPH_LEARNING_PHASES[graph];
}
public static void set_learning_phase(bool value)
{
_GRAPH_LEARNING_PHASES[tf.get_default_graph()] = (GraphLearningPhase)((value) ? 1 : 0);
}


public class _DummyEagerGraph
{ }
}
}
22 changes: 22 additions & 0 deletions src/TensorFlowNET.Core/Keras/defaultdict.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Generic;

namespace System.Collections.Generic
{
public class defaultdict<TKey, TValue> : Dictionary<TKey, TValue> where TValue : new()
{
public new TValue this[TKey key]
{
get
{
TValue val;
if(!TryGetValue(key, out val))
{
val = default(TValue);
Add(key, val);
}
return val;
}
set { base[key] = value; }
}
}
}
63 changes: 63 additions & 0 deletions src/TensorFlowNET.Core/Python.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,69 @@ public static Dictionary<string, object> ConvertToDict(object dyn)
return dictionary;
}


public static bool all(IEnumerable enumerable)
{
foreach (var e1 in enumerable)
{
if (!Convert.ToBoolean(e1))
return false;
}
return true;
}

public static bool any(IEnumerable enumerable)
{
foreach (var e1 in enumerable)
{
if (Convert.ToBoolean(e1))
return true;
}
return false;
}

public static double sum(IEnumerable enumerable)
{
var typedef = new Type[] { typeof(double), typeof(int), typeof(float) };
var sum = 0.0d;
foreach (var e1 in enumerable)
{
if (!typedef.Contains(e1.GetType()))
throw new Exception("Numeric array expected");
sum += (double)e1;
}
return sum;
}

public static double sum<TKey, TValue>(Dictionary<TKey, TValue> values)
{
return sum(values.Keys);
}

public static IEnumerable<double> slice(double start, double end, double step = 1)
{
for (double i = start; i < end; i += step)
yield return i;
}

public static IEnumerable<float> slice(float start, float end, float step = 1)
{
for (float i = start; i < end; i += step)
yield return i;
}

public static IEnumerable<int> slice(int start, int end, int step = 1)
{
for (int i = start; i < end; i += step)
yield return i;
}

public static IEnumerable<int> slice(int range)
{
for (int i = 0; i < range; i++)
yield return i;
}

public static bool hasattr(object obj, string key)
{
var __type__ = (obj).GetType();
Expand Down
Loading