diff --git a/src/TensorFlowNET.Core/APIs/tf.layers.cs b/src/TensorFlowNET.Core/APIs/tf.layers.cs
new file mode 100644
index 00000000..b93afd68
--- /dev/null
+++ b/src/TensorFlowNET.Core/APIs/tf.layers.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tensorflow.Layers;
+using Tensorflow.Operations.Activation;
+
+namespace Tensorflow
+{
+ public static partial class tf
+ {
+ public static class layers
+ {
+ public static Tensor conv2d(Tensor inputs,
+ int filters,
+ int[] kernel_size,
+ int[] strides = null,
+ string padding = "valid",
+ string data_format= "channels_last",
+ int[] dilation_rate = null,
+ bool use_bias = true,
+ IActivation activation = null,
+ IInitializer kernel_initializer = null)
+ {
+ if (strides == null)
+ strides = new int[] { 1, 1 };
+ if (dilation_rate == null)
+ dilation_rate = new int[] { 1, 1 };
+
+ var layer = new Conv2D(filters, kernel_size);
+
+ return layer.apply(inputs);
+ }
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Core/APIs/tf.nn.cs b/src/TensorFlowNET.Core/APIs/tf.nn.cs
index 661717eb..65ad45b9 100644
--- a/src/TensorFlowNET.Core/APIs/tf.nn.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.nn.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Tensorflow.Operations.Activation;
namespace Tensorflow
{
@@ -9,9 +10,22 @@ namespace Tensorflow
public static class nn
{
public static (Tensor, Tensor) moments(Tensor x,
- int[] axes,
- string name = null,
- bool keep_dims = false) => nn_impl.moments(x, axes, name: name, keep_dims: keep_dims);
+ int[] axes,
+ string name = null,
+ bool keep_dims = false) => nn_impl.moments(x,
+ axes,
+ name: name,
+ keep_dims: keep_dims);
+
+ public static Tensor embedding_lookup(RefVariable @params,
+ Tensor ids,
+ string partition_strategy = "mod",
+ string name = null) => embedding_ops._embedding_lookup_and_transform(@params,
+ ids,
+ partition_strategy: partition_strategy,
+ name: name);
+
+ public static IActivation relu => new relu();
}
}
}
diff --git a/src/TensorFlowNET.Core/Layers/convolutional.py.cs b/src/TensorFlowNET.Core/Layers/convolutional.py.cs
new file mode 100644
index 00000000..babc761d
--- /dev/null
+++ b/src/TensorFlowNET.Core/Layers/convolutional.py.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tensorflow.Operations.Activation;
+
+namespace Tensorflow.Layers
+{
+ public class Conv2D
+ {
+ private int filters;
+ private int[] kernel_size;
+ private int[] strides;
+
+ public Conv2D(int filters,
+ int[] kernel_size,
+ int[] strides = null,
+ string padding = "valid",
+ string data_format = "channels_last",
+ int[] dilation_rate = null,
+ IActivation activation = null,
+ bool use_bias = true,
+ IInitializer kernel_initializer = null,
+ IInitializer bias_initializer = null,
+ bool trainable = true,
+ string name = null)
+ {
+
+ }
+
+ public Tensor apply(Tensor inputs)
+ {
+ throw new NotImplementedException("apply");
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Core/Operations/Activation/IActivation.cs b/src/TensorFlowNET.Core/Operations/Activation/IActivation.cs
new file mode 100644
index 00000000..ed7c237c
--- /dev/null
+++ b/src/TensorFlowNET.Core/Operations/Activation/IActivation.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tensorflow.Operations.Activation
+{
+ public interface IActivation
+ {
+
+ }
+}
diff --git a/src/TensorFlowNET.Core/Operations/Activation/gen_nn_ops.py.cs b/src/TensorFlowNET.Core/Operations/Activation/gen_nn_ops.py.cs
new file mode 100644
index 00000000..4ee8bd00
--- /dev/null
+++ b/src/TensorFlowNET.Core/Operations/Activation/gen_nn_ops.py.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tensorflow.Operations.Activation
+{
+ public class relu : IActivation
+ {
+
+ }
+}
diff --git a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs
index 8e6bfba0..aff09b98 100644
--- a/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs
+++ b/src/TensorFlowNET.Core/Operations/OpDefLibrary.cs
@@ -364,8 +364,13 @@ namespace Tensorflow
object obj = propertyDescriptor.GetValue(dyn);
string name = propertyDescriptor.Name;
// avoid .net keyword
- if (name == "_ref_")
- name = "ref";
+ switch (name)
+ {
+ case "_ref_":
+ name = "ref";
+ break;
+ }
+
dictionary.Add(name, obj);
}
return dictionary;
diff --git a/src/TensorFlowNET.Core/Operations/array_ops.py.cs b/src/TensorFlowNET.Core/Operations/array_ops.py.cs
index 18de83dd..634278e3 100644
--- a/src/TensorFlowNET.Core/Operations/array_ops.py.cs
+++ b/src/TensorFlowNET.Core/Operations/array_ops.py.cs
@@ -268,5 +268,9 @@ namespace Tensorflow
return Framework.common_shapes.broadcast_shape(shape_x, shape_y);
}
+ public static Tensor gather(Tensor @params, Tensor indices, string name = null, int axis = 0)
+ {
+ return gen_array_ops.gather_v2(@params, indices, axis, name: name);
+ }
}
}
diff --git a/src/TensorFlowNET.Core/Operations/embedding_ops.cs b/src/TensorFlowNET.Core/Operations/embedding_ops.cs
index 27fba04b..bf83e81c 100644
--- a/src/TensorFlowNET.Core/Operations/embedding_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/embedding_ops.cs
@@ -4,11 +4,45 @@ using System.Text;
namespace Tensorflow
{
- public class embedding_ops
+ public class embedding_ops : Python
{
- public Tensor _embedding_lookup_and_transform()
+ ///
+ /// Helper function for embedding_lookup and _compute_sampled_logits.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Tensor _embedding_lookup_and_transform(RefVariable @params,
+ Tensor ids,
+ string partition_strategy = "mod",
+ string name = null,
+ string max_norm = null)
{
- throw new NotImplementedException("");
+ return with(new ops.name_scope(name, "embedding_lookup", new { @params, ids }), scope =>
+ {
+ name = scope;
+ int np = 1;
+ ids = ops.convert_to_tensor(ids, name: "ids");
+ if(np == 1)
+ {
+ var gather = array_ops.gather(@params, ids, name: name);
+ var result = _clip(@params, ids, max_norm);
+
+ return array_ops.identity(result);
+ }
+
+ throw new NotImplementedException("_embedding_lookup_and_transform");
+ });
+ }
+
+ public static Tensor _clip(RefVariable @params, Tensor ids, string max_norm = null)
+ {
+ if (max_norm == null)
+ return @params;
+
+ throw new NotImplementedException("_clip");
}
}
}
diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
index 80884393..d86e0235 100644
--- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
@@ -19,6 +19,13 @@ namespace Tensorflow
return _op.outputs[0];
}
+ public static Tensor gather_v2(Tensor @params, Tensor indices, int axis, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("GatherV2", name: name, new { @params, indices, axis });
+
+ return _op.outputs[0];
+ }
+
public static Tensor greater(Tx x, Ty y, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Greater", name: name, args: new { x, y });
diff --git a/src/TensorFlowNET.Core/Variables/_VariableStore.cs b/src/TensorFlowNET.Core/Variables/_VariableStore.cs
index 9f067bf8..fc3768a1 100644
--- a/src/TensorFlowNET.Core/Variables/_VariableStore.cs
+++ b/src/TensorFlowNET.Core/Variables/_VariableStore.cs
@@ -51,7 +51,7 @@ namespace Tensorflow
VariableSynchronization synchronization = VariableSynchronization.AUTO,
VariableAggregation aggregation = VariableAggregation.NONE)
{
- bool is_scalar = shape.NDim == 0;
+ bool is_scalar = !(shape is null) && shape.NDim == 0;
if (initializer is IInitializer init)
{
diff --git a/test/TensorFlowNET.Examples/TextClassification/cnn_models/VdCnn.cs b/test/TensorFlowNET.Examples/TextClassification/cnn_models/VdCnn.cs
index cbdcecee..1900b8da 100644
--- a/test/TensorFlowNET.Examples/TextClassification/cnn_models/VdCnn.cs
+++ b/test/TensorFlowNET.Examples/TextClassification/cnn_models/VdCnn.cs
@@ -19,6 +19,7 @@ namespace TensorFlowNET.Examples.TextClassification
private RefVariable global_step;
private RefVariable embeddings;
private Tensor x_emb;
+ private Tensor x_expanded;
public VdCnn(int alphabet_size, int document_max_len, int num_class)
{
@@ -33,11 +34,23 @@ namespace TensorFlowNET.Examples.TextClassification
is_training = tf.placeholder(tf.boolean, new TensorShape(), name: "is_training");
global_step = tf.Variable(0, trainable: false);
+ // Embedding Layer
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_emb = tf.nn.embedding_lookup(embeddings, x);
+ x_expanded = tf.expand_dims(x_emb, -1);
+ });
+
+ // First Convolution Layer
+ with(tf.variable_scope("conv-0"), delegate
+ {
+ var 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);
});
}
}