Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
16 changes: 10 additions & 6 deletions src/Microsoft.ML.Dnn/DnnRetrainTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -379,14 +379,18 @@ private void TrainCore(DnnRetrainEstimator.Options options, IDataView input, IDa
ITensorValueGetter[] srcTensorGetters,
Runner runner)
{
float loss = 0;
float metric = 0;
float loss = 0.0f;
float metric = 0.0f;
for (int i = 0; i < inputs.Length; i++)
runner.AddInput(inputs[i], srcTensorGetters[i].GetBufferedBatchTensor());

Tensor[] tensor = runner.Run();
loss = tensor.Length > 0 && tensor[0] != IntPtr.Zero ? (float)tensor[0].ToArray<float>()[0] : 0.0f;
metric = tensor.Length > 1 && tensor[1] != IntPtr.Zero ? (float)tensor[1].ToArray<float>()[0] : 0.0f;
if (tensor.Length > 0 && tensor[0] != IntPtr.Zero)
tensor[0].ToScalar<float>(ref loss);

if (tensor.Length > 1 && tensor[1] != IntPtr.Zero)
tensor[1].ToScalar<float>(ref metric);

return (loss, metric);
}

Expand Down Expand Up @@ -871,7 +875,7 @@ private Delegate MakeGetter<T>(DataViewRow input, int iinfo, ITensorValueGetter[
UpdateCacheIfNeeded(input.Position, srcTensorGetters, activeOutputColNames, outputCache);

var tensor = outputCache.Outputs[_parent._outputs[iinfo]];
dst = tensor.ToArray<T>()[0];
tensor.ToScalar<T>(ref dst);
};
return valuegetter;
}
Expand Down Expand Up @@ -903,7 +907,7 @@ private Delegate MakeGetter<T>(DataViewRow input, int iinfo, ITensorValueGetter[

var editor = VBufferEditor.Create(ref dst, (int)tensorSize);

DnnUtils.FetchData<T>(tensor.ToArray<T>(), editor.Values);
Comment thread
KsenijaS marked this conversation as resolved.
tensor.ToSpan<T>(editor.Values);
Comment thread
eerhardt marked this conversation as resolved.
Outdated
dst = editor.Commit();
};
return valuegetter;
Expand Down
27 changes: 18 additions & 9 deletions src/Microsoft.ML.Dnn/ImageClassificationTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,17 @@ private void CacheFeaturizedImagesToDisk(IDataView input, string labelColumnName
ImageClassificationMetrics metrics = new ImageClassificationMetrics();
metrics.Bottleneck = new BottleneckMetrics();
metrics.Bottleneck.DatasetUsed = dataset;
float[] imageArray = null;
while (cursor.MoveNext())
{
labelGetter(ref label);
imagePathGetter(ref imagePath);
var imagePathStr = imagePath.ToString();
var imageTensor = imageProcessor.ProcessImage(imagePathStr);
runner.AddInput(imageTensor, 0);
var featurizedImage = runner.Run()[0]; // Reuse memory?
writer.WriteLine(label - 1 + "," + string.Join(",", featurizedImage.ToArray<float>()));
var featurizedImage = runner.Run()[0]; // Reuse memory
featurizedImage.ToArray<float>(ref imageArray);
writer.WriteLine(label - 1 + "," + string.Join(",", imageArray));
Comment thread
KsenijaS marked this conversation as resolved.
featurizedImage.Dispose();
imageTensor.Dispose();
metrics.Bottleneck.Index++;
Expand Down Expand Up @@ -338,6 +340,8 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath,

ImageClassificationMetrics metrics = new ImageClassificationMetrics();
metrics.Train = new TrainMetrics();
float accuracy = 0;
float crossentropy = 0;
for (int epoch = 0; epoch < epochs; epoch += 1)
{
metrics.Train.Accuracy = 0;
Expand Down Expand Up @@ -378,8 +382,10 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath,
.AddInput(new Tensor(labelBatchPtr, labelTensorShape, TF_DataType.TF_INT64, labelBatchSizeInBytes), 1)
.Run();

metrics.Train.Accuracy += outputTensors[0].ToArray<float>()[0];
metrics.Train.CrossEntropy += outputTensors[1].ToArray<float>()[0];
outputTensors[0].ToScalar<float>(ref accuracy);
outputTensors[1].ToScalar<float>(ref crossentropy);
metrics.Train.Accuracy += accuracy;
metrics.Train.CrossEntropy += crossentropy;

outputTensors[0].Dispose();
outputTensors[1].Dispose();
Expand Down Expand Up @@ -429,7 +435,8 @@ private void TrainAndEvaluateClassificationLayer(string trainBottleneckFilePath,
.AddInput(new Tensor(labelBatchPtr, labelTensorShape, TF_DataType.TF_INT64, labelBatchSizeInBytes), 1)
.Run();

metrics.Train.Accuracy += outputTensors[0].ToArray<float>()[0];
outputTensors[0].ToScalar<float>(ref accuracy);
metrics.Train.Accuracy += accuracy;
metrics.Train.BatchProcessedCount += 1;
batchIndex = 0;

Expand Down Expand Up @@ -799,8 +806,10 @@ private class OutputCache
private ReadOnlyMemory<char> _imagePath;
private Runner _runner;
private ImageProcessor _imageProcessor;
public UInt32 PredictedLabel { get; set; }
public float[] ClassProbabilities { get; set; }
private long _predictedLabel;
public UInt32 PredictedLabel => (uint)_predictedLabel;
private float[] _classProbability;
public float[] ClassProbabilities => _classProbability;
private DataViewRow _inputRow;

public OutputCache(DataViewRow input, ImageClassificationTransformer transformer)
Expand All @@ -826,8 +835,8 @@ public void UpdateCacheIfNeeded()
_imagePathGetter(ref _imagePath);
var processedTensor = _imageProcessor.ProcessImage(_imagePath.ToString());
var outputTensor = _runner.AddInput(processedTensor, 0).Run();
ClassProbabilities = outputTensor[0].ToArray<float>();
PredictedLabel = (UInt32)outputTensor[1].ToArray<long>()[0];
outputTensor[0].ToArray<float>(ref _classProbability);
outputTensor[1].ToScalar<long>(ref _predictedLabel);
outputTensor[0].Dispose();
outputTensor[1].Dispose();
processedTensor.Dispose();
Expand Down
67 changes: 67 additions & 0 deletions src/Microsoft.ML.Dnn/TensorTypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using NumSharp.Backends;
using NumSharp.Backends.Unmanaged;
using NumSharp.Utilities;
using Tensorflow;

namespace Microsoft.ML.Transforms
{
[BestFriend]
internal static class TensorTypeExtensions
{
public static void ToScalar<T>(this Tensor tensor, ref T dst) where T : unmanaged
{
if (typeof(T).as_dtype() == tensor.dtype)
Comment thread
eerhardt marked this conversation as resolved.
Outdated
{
unsafe
{
dst = *(T*)tensor.buffer;
}
}
}

public static void ToSpan<T>(this Tensor tensor, Span<T> values) where T: unmanaged
{
if (typeof(T).as_dtype() == tensor.dtype)
{
unsafe
{
var len = (long)tensor.size;
fixed (T* dst = values)
{
var src = (T*)tensor.buffer;
len *= ((long)tensor.itemsize);
System.Buffer.MemoryCopy(src, dst, len, len);
Comment thread
eerhardt marked this conversation as resolved.
Outdated
}
}
}
}

public static void ToArray<T>(this Tensor tensor, ref T[] array) where T : unmanaged
{
ulong arrayLen = 0;
if (array != null)
arrayLen = (ulong)array.Length;

if (array == null || arrayLen == 0 || arrayLen < tensor.size)
{
array = new T[tensor.size];
Comment thread
eerhardt marked this conversation as resolved.
Outdated
arrayLen = tensor.size;
Comment thread
eerhardt marked this conversation as resolved.
Outdated
}

if (typeof(T).as_dtype() == tensor.dtype)
Comment thread
eerhardt marked this conversation as resolved.
Outdated
{
unsafe
{
var len = (long)tensor.size;
fixed (T* dst = array)
Comment thread
eerhardt marked this conversation as resolved.
Outdated
{
var src = (T*)tensor.buffer;
len *= ((long)tensor.itemsize);
System.Buffer.MemoryCopy(src, dst, len, len);
}
}
}
}
}
}
6 changes: 2 additions & 4 deletions src/Microsoft.ML.TensorFlow/TensorflowTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -588,15 +588,13 @@ protected override Delegate MakeGetter(DataViewRow input, int iinfo, Func<int, b
private Delegate MakeGetter<T>(DataViewRow input, int iinfo, ITensorValueGetter[] srcTensorGetters, string[] activeOutputColNames, OutputCache outputCache) where T : unmanaged
{
Host.AssertValue(input);

if (_parent.OutputTypes[iinfo].IsStandardScalar())
{
ValueGetter<T> valuegetter = (ref T dst) =>
{
UpdateCacheIfNeeded(input.Position, srcTensorGetters, activeOutputColNames, outputCache);

var tensor = outputCache.Outputs[_parent.Outputs[iinfo]];
dst = tensor.ToArray<T>()[0];
tensor.ToScalar<T>(ref dst);
};
return valuegetter;
}
Expand Down Expand Up @@ -628,7 +626,7 @@ private Delegate MakeGetter<T>(DataViewRow input, int iinfo, ITensorValueGetter[

var editor = VBufferEditor.Create(ref dst, (int)tensorSize);

DnnUtils.FetchData<T>(tensor.ToArray<T>(), editor.Values);
tensor.ToSpan<T>(editor.Values);
dst = editor.Commit();
};
return valuegetter;
Expand Down