public Tensor CreateVariable(float[] data, long[] shape, string name = "") { var arr = new CNTK.NDArrayView(BackendUtil.CastShapeInt(shape), data, DeviceManager.Current); var v = new CNTK.Variable(BackendUtil.CastShapeInt(shape), VariableKind.Parameter, CNTK.DataType.Float, arr, false, new AxisVector(), false, name, name); return(Out(v)); }
private Tensor CreateVariable(int[] data, long[] shape, string name = "") { shape = BackendUtil.Row2ColMajor(shape); var arr = new CNTK.NDArrayView(BackendUtil.CastShapeInt(shape), Array.ConvertAll(data, x => (float)x), DeviceManager.Current); var v = new CNTK.Variable(BackendUtil.CastShapeInt(shape), VariableKind.Input, CNTK.DataType.Float, arr, false, new AxisVector(), false, name, name); return(Out(v)); }
/// <summary> /// Detect what's in the given image. /// </summary> /// <param name="imagePath">The path of the image to check.</param> /// <returns>A tuple of probabilities indicating if the image contains a dog or a cat.</returns> private (double cat, double dog) DetectScene(string imagePath) { // load the neural network if (network == null) { var path = @"..\..\..\..\..\models\catdogdetector.model"; network = Function.Load(path, NetUtil.CurrentDevice); } // grab the image var imageData = new float[150 * 150 * 3]; using (var mat = Cv.Cv2.ImRead(imagePath)) { using (var mat2 = new Cv.Mat(150, 150, mat.Type())) { Cv.Cv2.Resize(mat, mat2, new OpenCvSharp.Size(150, 150)); imageData = StyleTransfer.FlattenByChannel(mat2, new float[] { 0, 0, 0 }); } } // set up a tensor to hold the image data var imageValue = new CNTK.NDArrayView( new int[] { 150, 150, 3 }, imageData, NetUtil.CurrentDevice); // set up input and output dictionaries var inputs = new Dictionary <CNTK.Variable, CNTK.Value>() { { network.Arguments[0], new CNTK.Value(imageValue) } }; var outputs = new Dictionary <CNTK.Variable, CNTK.Value>() { { network.Outputs[0], null } }; // run the neural network network.Evaluate(inputs, outputs, NetUtil.CurrentDevice); // return the result var key = network.Outputs[0]; var result = outputs[key].GetDenseData <float>(key); return(result[0][0], result[0][1]); }
// The value represents a n-dimensional tensor with 2 dynamic axes: sequence and batch // It assumes that only the highest 2 axes are dynamic, and all the other axes are static. public static void CopyTo <T>(this Value value, Variable variable, List <List <T> > data) { if ((value.GetDataType() == DataType.Float) && (!typeof(T).Equals(typeof(float))) || (value.GetDataType() == DataType.Double) && (!typeof(T).Equals(typeof(double)))) { throw new ArgumentException("The value type does not match the list type."); } // Todo: how to check whether the dynamic axes are the highest 2 axes in the shape. if (variable.DynamicAxes().Count != 2) { throw new ArgumentException("The variable should have 2 dynamic axes."); } var variableShape = variable.Shape; var valueShape = value.Shape; if (variableShape != value.Shape.SubShape(0, valueShape.Rank - 2)) { throw new ArgumentException("The variable and value does not have same shape."); } // Todo: transform sparse to dense // Currently only for dense if ((value.GetStorageFormat() != StorageFormat.Dense)) { throw new ArgumentException("The value is not in denst format."); } var outputNDArrayView = value.Data(); var outputShape = outputNDArrayView.Shape(); var outputShapeRank = outputShape.Rank; var numOfElementsInSample = variableShape.TotalSize; var numOfSamplesInSequence = outputShape.GetDimensionSize(outputShapeRank - 2); var numOfSequences = outputShape.GetDimensionSize(outputShapeRank - 1); // Copy the data from the output buffer. // Todo: directly access the data in output buffer? // Todo: need to map DataBuffer() to C# NDArrayView cpuOutputNDArrayView; uint numOfOutputData = outputNDArrayView.Shape().TotalSize; // Todo: consider mask. Debug.Assert(numOfElementsInSample * numOfSamplesInSequence * numOfSequences == numOfOutputData); T[] outputData = new T[numOfOutputData]; if (value.GetDataType() == DataType.Float) { cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as float[], numOfOutputData, DeviceDescriptor.CPUDevice); } else if (value.GetDataType() == DataType.Double) { cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as double[], numOfOutputData, DeviceDescriptor.CPUDevice); } else { throw new ArgumentException("The data type " + value.GetDataType().ToString() + " is not supported. Only float or double is supported by CNTK."); } cpuOutputNDArrayView.CopyFrom(outputNDArrayView); for (int seqIndex = 0, dataIndex = 0; seqIndex < numOfSequences; seqIndex++) { var seqData = new List <T>(); // Todo: consider mask // Todo: make it more efficient. for (int i = 0; i < numOfElementsInSample * numOfSamplesInSequence; i++) { seqData.Add(outputData[dataIndex++]); } data.Add(seqData); } }
// Copy Value to List<List<T>> for dense input // Todo: could this be a extension to Value class?? public void CopyValueTo <T>(string varName, Value value, List <List <T> > sequences) { // Todo: deal with GPUDevice. if (value.Device != DeviceDescriptor.CPUDevice) { throw new InvalidOperationException("Currently only CPU device is supported."); } if ((value.GetDataType() == DataType.Float) && (!typeof(T).Equals(typeof(float))) || (value.GetDataType() == DataType.Double) && (!typeof(T).Equals(typeof(double)))) { throw new InvalidDataException("The value type does not match the list type."); } // Todo: transform sparse to dense // Currently only for dense if ((value.GetStorageFormat() != StorageFormat.Dense)) { throw new InvalidDataException("The value is not in denst format."); } var variable = getVariableByName(varName); var outputNDArrayView = value.Data(); var outputShape = outputNDArrayView.Shape(); var varRank = variable.Shape.Rank; var valueRank = outputNDArrayView.Shape().Rank; Debug.Assert(varRank + 2 == valueRank); var numOfElementsInSample = variable.Shape.TotalSize; var numOfSamplesInSequence = outputShape.GetDimensionSize(varRank); var numOfSequences = outputShape.GetDimensionSize(varRank + 1); //var outputShape = outputVar.Shape().AppendShape(new NDShape(dynamicAxisShape)); // Copy the data from the output buffer. // Todo: directly access the data in output buffer? // Todo: need to map DataBuffer() to C# NDArrayView cpuOutputNDArrayView; uint numOfOutputData = outputNDArrayView.Shape().TotalSize; Debug.Assert(numOfElementsInSample * numOfSamplesInSequence * numOfSequences == numOfOutputData); T[] outputData = new T[numOfOutputData]; if (value.GetDataType() == DataType.Float) { cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as float[], numOfOutputData, DeviceDescriptor.CPUDevice); } else if (value.GetDataType() == DataType.Double) { cpuOutputNDArrayView = new NDArrayView(outputNDArrayView.Shape(), outputData as double[], numOfOutputData, DeviceDescriptor.CPUDevice); } else { throw new InvalidDataException("The data type " + value.GetDataType().ToString() + " is not supported. Only float or double is supported by CNTK."); } cpuOutputNDArrayView.CopyFrom(outputNDArrayView); for (int seqIndex = 0, dataIndex = 0; seqIndex < numOfSequences; seqIndex++) { var seqData = new List <T>(); // Todo: make it more efficient. for (int i = 0; i < numOfElementsInSample * numOfSamplesInSequence; i++) { seqData.Add(outputData[dataIndex++]); } sequences.Add(seqData); } }