Browse Source

tf.data.Dataset.range #446

tags/v0.20
Oceania2018 5 years ago
parent
commit
64c5157de5
17 changed files with 254 additions and 38 deletions
  1. +7
    -5
      src/TensorFlowNET.Core/Binding.Util.cs
  2. +5
    -2
      src/TensorFlowNET.Core/Data/DatasetManager.cs
  3. +3
    -4
      src/TensorFlowNET.Core/Data/DatasetV2.cs
  4. +28
    -0
      src/TensorFlowNET.Core/Data/RangeDataset.cs
  5. +1
    -1
      src/TensorFlowNET.Core/Data/TensorSliceDataset.cs
  6. +23
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/DataHandlerArgs.cs
  7. +12
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/SequentialArgs.cs
  8. +33
    -0
      src/TensorFlowNET.Core/Keras/Engine/DataAdapters/DataHandler.cs
  9. +22
    -0
      src/TensorFlowNET.Core/Keras/Engine/DataAdapters/IDataAdapter.cs
  10. +23
    -0
      src/TensorFlowNET.Core/Keras/Engine/DataAdapters/TensorLikeDataAdapter.cs
  11. +28
    -1
      src/TensorFlowNET.Core/Keras/Engine/Model.cs
  12. +11
    -4
      src/TensorFlowNET.Core/Keras/Engine/Sequential.cs
  13. +8
    -4
      src/TensorFlowNET.Core/Keras/KerasApi.cs
  14. +0
    -13
      src/TensorFlowNET.Core/Keras/Models.cs
  15. +16
    -0
      src/TensorFlowNET.Core/Operations/dataset_ops.cs
  16. +30
    -0
      test/TensorFlowNET.UnitTest/Dataset/DatasetTest.cs
  17. +4
    -4
      test/TensorFlowNET.UnitTest/Keras/LayersTest.cs

+ 7
- 5
src/TensorFlowNET.Core/Binding.Util.cs View File

@@ -265,15 +265,17 @@ namespace Tensorflow
yield return (i, values[i]); yield return (i, values[i]);
} }


public static IEnumerable<(int, T)> enumerate<T>(IEnumerable<T> values, int start = 0)
public static IEnumerable<(int, T)> enumerate<T>(IEnumerable<T> values, int start = 0, int step = 1)
{ {
int i = 0; int i = 0;
foreach(var val in values)
foreach (var val in values)
{ {
if (i++ < start)
i += step;

if (i < start)
continue; continue;
yield return (i - start, val);
yield return (i - step - start, val);
} }
} }




+ 5
- 2
src/TensorFlowNET.Core/Data/DatasetManager.cs View File

@@ -1,7 +1,7 @@
using NumSharp;
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Tensorflow.Data;


namespace Tensorflow namespace Tensorflow
{ {
@@ -9,5 +9,8 @@ namespace Tensorflow
{ {
public IDatasetV2 from_tensor_slices(Tensor features, Tensor labels) public IDatasetV2 from_tensor_slices(Tensor features, Tensor labels)
=> new TensorSliceDataset(features, labels); => new TensorSliceDataset(features, labels);

public IDatasetV2 range(int count, TF_DataType output_type = TF_DataType.TF_INT64)
=> new RangeDataset(count, output_type: output_type);
} }
} }

+ 3
- 4
src/TensorFlowNET.Core/Data/DatasetV2.cs View File

@@ -78,9 +78,8 @@ namespace Tensorflow
{ {
var ownedIterator = new OwnedIterator(this); var ownedIterator = new OwnedIterator(this);


bool stop = false;
Tensor[] results = null; Tensor[] results = null;
while (!stop)
while (true)
{ {
try try
{ {
@@ -88,10 +87,10 @@ namespace Tensorflow
} }
catch (StopIteration) catch (StopIteration)
{ {
stop = true;
break;
} }


yield return (results[0], results[1]);
yield return (results[0], results.Length == 1 ? null : results[1]);
} }
} }




+ 28
- 0
src/TensorFlowNET.Core/Data/RangeDataset.cs View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Framework.Models;
using static Tensorflow.Binding;

namespace Tensorflow.Data
{
public class RangeDataset : DatasetSource
{
Tensor start;
Tensor step;
Tensor stop;

public RangeDataset(int stop,
int start = 0,
int step = 1,
TF_DataType output_type = TF_DataType.TF_INT64)
{
this.start = tf.convert_to_tensor((long)start);
this.step = tf.convert_to_tensor((long)step);
this.stop = tf.convert_to_tensor((long)stop);

structure = new TensorSpec[] { new TensorSpec(new int[0], dtype: output_type) };
variant_tensor = ops.range_dataset(this.start, this.stop, this.step, output_types, output_shapes);
}
}
}

+ 1
- 1
src/TensorFlowNET.Core/Data/TensorSliceDataset.cs View File

@@ -7,7 +7,7 @@ using System.Text;
using Tensorflow.Framework.Models; using Tensorflow.Framework.Models;
using static Tensorflow.Binding; using static Tensorflow.Binding;


namespace Tensorflow
namespace Tensorflow.Data
{ {
public class TensorSliceDataset : DatasetSource public class TensorSliceDataset : DatasetSource
{ {


+ 23
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/DataHandlerArgs.cs View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.ArgsDefinition
{
public class DataHandlerArgs
{
public Tensor X { get; set; }
public Tensor Y { get; set; }
public int BatchSize { get; set; } = 32;
public int StepsPerEpoch { get; set; } = -1;
public int InitialEpoch { get; set; } = 0;
public int Epochs { get; set; } = 1;
public bool Shuffle { get; set; } = false;
public int MaxQueueSize { get; set; } = 10;
public int Workers { get; set; } = 1;
public bool UseMultiprocessing { get; set; } = false;
public Model Model { get; set; }
public IVariableV1 StepsPerExecution { get; set; }
}
}

+ 12
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/SequentialArgs.cs View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.ArgsDefinition
{
public class SequentialArgs : ModelArgs
{
public List<Layer> Layers { get; set; }
}
}

+ 33
- 0
src/TensorFlowNET.Core/Keras/Engine/DataAdapters/DataHandler.cs View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.ArgsDefinition;

namespace Tensorflow.Keras.Engine.DataAdapters
{
/// <summary>
/// Handles iterating over epoch-level `tf.data.Iterator` objects.
/// </summary>
public class DataHandler
{
DataHandlerArgs args;

Tensor x => args.X;
Tensor y => args.Y;
int batch_size => args.BatchSize;
int steps_per_epoch => args.StepsPerEpoch;
int initial_epoch => args.InitialEpoch;
int epochs => args.Epochs;
bool shuffle => args.Shuffle;
int max_queue_size => args.MaxQueueSize;
int workers => args.Workers;
bool use_multiprocessing => args.UseMultiprocessing;
Model model => args.Model;
IVariableV1 steps_per_execution => args.StepsPerExecution;

public DataHandler(DataHandlerArgs args)
{

}
}
}

+ 22
- 0
src/TensorFlowNET.Core/Keras/Engine/DataAdapters/IDataAdapter.cs View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Keras.Engine.DataAdapters
{
/// <summary>
/// In TF 2.0, tf.data is the preferred API for user to feed in data. In order
/// to simplify the training code path, all the input data object will be
/// converted to `tf.data.Dataset` if possible.
/// </summary>
public interface IDataAdapter
{
/// <summary>
/// Whether the current DataAdapter could handle the input x and y.
/// </summary>
/// <param name="x">input features</param>
/// <param name="y">target labels</param>
/// <returns></returns>
bool CanHandle(Tensor x, Tensor y = null);
}
}

+ 23
- 0
src/TensorFlowNET.Core/Keras/Engine/DataAdapters/TensorLikeDataAdapter.cs View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using static Tensorflow.Binding;

namespace Tensorflow.Keras.Engine.DataAdapters
{
/// <summary>
/// Adapter that handles Tensor-like objects, e.g. EagerTensor and NumPy.
/// </summary>
public class TensorLikeDataAdapter : IDataAdapter
{
public TensorLikeDataAdapter()
{
tf.data.Dataset.range(5);
}

public bool CanHandle(Tensor x, Tensor y = null)
{
throw new NotImplementedException();
}
}
}

+ 28
- 1
src/TensorFlowNET.Core/Keras/Engine/Model.cs View File

@@ -1,4 +1,6 @@
using Tensorflow.Keras.ArgsDefinition;
using NumSharp;
using System;
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Optimizers; using Tensorflow.Keras.Optimizers;


namespace Tensorflow.Keras.Engine namespace Tensorflow.Keras.Engine
@@ -39,5 +41,30 @@ namespace Tensorflow.Keras.Engine


// Prepare list of loss functions, same size of model outputs. // Prepare list of loss functions, same size of model outputs.
} }

/// <summary>
/// Generates output predictions for the input samples.
/// </summary>
/// <param name="x">Input samples</param>
/// <param name="batch_size">Number of samples per batch</param>
/// <param name="verbose">Verbosity mode</param>
/// <param name="steps">
/// Total number of steps (batches of samples)
/// before declaring the prediction round finished.
/// </param>
/// <param name="max_queue_size"></param>
/// <param name="workers"></param>
/// <param name="use_multiprocessing"></param>
/// <returns></returns>
public Tensor predict(Tensor x,
int batch_size = 32,
int verbose = 0,
int steps = -1,
int max_queue_size = 10,
int workers = 1,
bool use_multiprocessing = false)
{
throw new NotImplementedException("");
}
} }
} }

+ 11
- 4
src/TensorFlowNET.Core/Keras/Engine/Sequential.cs View File

@@ -26,8 +26,9 @@ namespace Tensorflow.Keras.Engine
/// `Sequential` groups a linear stack of layers into a `tf.keras.Model`. /// `Sequential` groups a linear stack of layers into a `tf.keras.Model`.
/// `Sequential` provides training and inference features on this model. /// `Sequential` provides training and inference features on this model.
/// </summary> /// </summary>
public class Sequential
public class Sequential : Model
{ {
SequentialArgs args;
bool _is_graph_network; bool _is_graph_network;
Tensor inputs; Tensor inputs;
Tensor outputs; Tensor outputs;
@@ -37,13 +38,19 @@ namespace Tensorflow.Keras.Engine
TensorShape inferredInputShape; TensorShape inferredInputShape;
bool hasExplicitInputShape; bool hasExplicitInputShape;
TF_DataType inputDType; TF_DataType inputDType;
List<Layer> layers;
List<Layer> layers => args.Layers;
public TensorShape output_shape => outputs.TensorShape; public TensorShape output_shape => outputs.TensorShape;
bool built = false; bool built = false;


public Sequential(Layer[] layers = null, string name = null)
public Sequential(SequentialArgs args)
: base(new ModelArgs
{
Name = args.Name
})
{ {
this.layers = layers == null ? new List<Layer>() : layers.ToList();
this.args = args;
if (args.Layers == null)
args.Layers = new List<Layer>();
// SupportsMasking = true; // SupportsMasking = true;
computeOutputAndMaskJointly = true; computeOutputAndMaskJointly = true;
autoTrackSubLayers = false; autoTrackSubLayers = false;


+ 8
- 4
src/TensorFlowNET.Core/Keras/KerasApi.cs View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using Tensorflow.Keras; using Tensorflow.Keras;
@@ -19,10 +20,13 @@ namespace Tensorflow


public BackendImpl backend { get; } = new BackendImpl(); public BackendImpl backend { get; } = new BackendImpl();


public Models models { get; } = new Models();

public Sequential Sequential()
=> new Sequential();
public Sequential Sequential(List<Layer> layers = null,
string name = null)
=> new Sequential(new SequentialArgs
{
Layers = layers,
Name = name
});


/// <summary> /// <summary>
/// Instantiate a Keras tensor. /// Instantiate a Keras tensor.


+ 0
- 13
src/TensorFlowNET.Core/Keras/Models.cs View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras
{
public class Models
{
public Sequential Sequential()
=> new Sequential();
}
}

+ 16
- 0
src/TensorFlowNET.Core/Operations/dataset_ops.cs View File

@@ -33,6 +33,22 @@ namespace Tensorflow
throw new NotImplementedException(""); throw new NotImplementedException("");
} }


public Tensor range_dataset(Tensor start, Tensor stop, Tensor step, TF_DataType[] output_types, TensorShape[] output_shapes, string name = null)
{
if (tf.Context.executing_eagerly())
{
var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
"RangeDataset", name,
null,
start, stop, step,
"output_types", output_types,
"output_shapes", output_shapes);
return results[0];
}

throw new NotImplementedException("");
}

public Tensor repeat_dataset(Tensor input_dataset, Tensor count, TF_DataType[] output_types, TensorShape[] output_shapes, string name = null) public Tensor repeat_dataset(Tensor input_dataset, Tensor count, TF_DataType[] output_types, TensorShape[] output_shapes, string name = null)
{ {
if (tf.Context.executing_eagerly()) if (tf.Context.executing_eagerly())


+ 30
- 0
test/TensorFlowNET.UnitTest/Dataset/DatasetTest.cs View File

@@ -0,0 +1,30 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.UnitTest;
using static Tensorflow.Binding;

namespace TensorFlowNET.UnitTest.Dataset
{
[TestClass]
public class DatasetTest : EagerModeTestBase
{
[TestMethod]
public void Range()
{
int iStep = 0;
long value = 0;

var dataset = tf.data.Dataset.range(3);
foreach(var (step, item) in enumerate(dataset))
{
Assert.AreEqual(iStep, step);
iStep++;

Assert.AreEqual(value, (long)item.Item1);
value++;
}
}
}
}

+ 4
- 4
test/TensorFlowNET.UnitTest/Keras/LayersTest.cs View File

@@ -19,7 +19,7 @@ namespace TensorFlowNET.UnitTest.Keras
[TestMethod] [TestMethod]
public void Sequential() public void Sequential()
{ {
var model = tf.keras.models.Sequential();
var model = tf.keras.Sequential();
model.add(tf.keras.Input(shape: 16)); model.add(tf.keras.Input(shape: 16));
} }


@@ -29,7 +29,7 @@ namespace TensorFlowNET.UnitTest.Keras
[TestMethod] [TestMethod]
public void Embedding() public void Embedding()
{ {
var model = new Sequential();
var model = tf.keras.Sequential();
var layer = tf.keras.layers.Embedding(1000, 64, input_length: 10); var layer = tf.keras.layers.Embedding(1000, 64, input_length: 10);
model.add(layer); model.add(layer);
// the model will take as input an integer matrix of size (batch, // the model will take as input an integer matrix of size (batch,
@@ -39,8 +39,8 @@ namespace TensorFlowNET.UnitTest.Keras
// now model.output_shape == (None, 10, 64), where None is the batch // now model.output_shape == (None, 10, 64), where None is the batch
// dimension. // dimension.
var input_array = np.random.randint(1000, size: (32, 10)); var input_array = np.random.randint(1000, size: (32, 10));
// model.compile("rmsprop", "mse");
// output_array = model.predict(input_array)
model.compile("rmsprop", "mse");
var output_array = model.predict(input_array);
} }


/// <summary> /// <summary>


Loading…
Cancel
Save