/// <summary> /// Create Value object from dense input as batch of sequences data with sequenceStartFlags. /// </summary> /// <typeparam name="T">data type</typeparam> /// <param name="sampleShape">data shape</param> /// <param name="sequences">data sequence</param> /// <param name="sequenceStartFlag">true indicates that it is a new sequence. /// false means a continuation of a previous sequence.</param> /// <param name="device">device</param> /// <param name="readOnly">whether it a readonly value</param> /// <returns></returns> public static Value Create <T>(NDShape sampleShape, IEnumerable <IEnumerable <T> > sequences, IEnumerable <bool> sequenceStartFlags, DeviceDescriptor device, bool readOnly = false) { var seqFlags = Helper.AsBoolVector(sequenceStartFlags); if (typeof(T).Equals(typeof(float))) { var inputAsSequencesVector = new FloatVectorVector(); foreach (var seq in sequences) { var seqVector = Helper.AsFloatVector(seq); // The seqVector is copied when adding to inputAsSequencesVector. inputAsSequencesVector.Add(seqVector); } return(Value._CreateDenseFloat(sampleShape, inputAsSequencesVector, seqFlags, device, readOnly)); } else if (typeof(T).Equals(typeof(double))) { var inputAsSequencesVector = new DoubleVectorVector(); foreach (var seq in sequences) { var seqVector = Helper.AsDoubleVector(seq); inputAsSequencesVector.Add(seqVector); } return(Value._CreateDenseDouble(sampleShape, inputAsSequencesVector, seqFlags, device, readOnly)); } else { throw new ArgumentException("The data type " + typeof(T).ToString() + " is not supported. Only float or double is supported by CNTK."); } }
/// <summary> /// Return the data of the Value object as a list of sequences with variable length. /// This method returns an IList<IList<T>>. Each element of the outer list represents a sequence. /// Each sequence, represented by IList<T>, contains a variable number of samples. /// Each sample consits of a fixed number of elements with type of 'T'. The number of elements is determined by the variable shape. /// The number of samples = (the count of elements in IList<T>)/(the count of elements of the sample) /// The shape of the variable should match the shape of the Value object. /// </summary> /// <typeparam name="T">data type</typeparam> /// <param name="outputVariable">the source variable</param> /// <returns></returns> public IList <IList <T> > GetDenseData <T>(Variable outputVariable) { var sequences = new List <IList <T> >(); if (typeof(T).Equals(typeof(float))) { if (_GetDataType() != DataType.Float) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new FloatVectorVector(); _CopyVariableValueToFloat(outputVariable, seqVec); foreach (var seq in seqVec) { var seqList = seq as IList <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } // It is required to create a new List from seq, since seq is dependent on the life cycle of seqVec. sequences.Add(new List <T>(seqList)); } } else if (typeof(T).Equals(typeof(double))) { if (_GetDataType() != DataType.Double) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new DoubleVectorVector(); _CopyVariableValueToDouble(outputVariable, seqVec); foreach (var seq in seqVec) { var seqList = seq as IList <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } // It is required to create a new List from seq, since seq is dependent on the life cycle of seqVec. sequences.Add(new List <T>(seqList)); } } else { throw new ArgumentException("The value type does not match the list type."); } return(sequences); }
public void CopyVariableValueTo <T>(Variable outputVariable, List <List <T> > sequences) { sequences.Clear(); if (typeof(T).Equals(typeof(float))) { if (_GetDataType() != DataType.Float) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new FloatVectorVector(); _CopyVariableValueToFloat(outputVariable, seqVec); foreach (var seq in seqVec) { var seqList = seq as IList <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } sequences.Add(new List <T>(seqList)); } } else if (typeof(T).Equals(typeof(double))) { if (_GetDataType() != DataType.Double) { throw new ArgumentException("The value type does not match the list type."); } var seqVec = new DoubleVectorVector(); _CopyVariableValueToDouble(outputVariable, seqVec); foreach (var seq in seqVec) { var seqList = seq as IList <T>; if (seqList == null) { throw new TypeAccessException("Cannot convert to the value type."); } sequences.Add(new List <T>(seqList)); } } else { throw new ArgumentException("The value type does not match the list type."); } }
// Create Value based on dense input // Todo: could this be a extension to Value class?? // Todo: use Variable instead of varName. VarName as extension method // Todo: List can have maximal 2^31-1, enough? Otherwise need to go to array which supports 64bit size public Value CreateValue <T>(string varName, List <List <T> > sequences, DeviceDescriptor computeDevice) { var variable = getVariableByName(varName); var dim = variable.Shape.TotalSize; if (typeof(T).Equals(typeof(float))) { var inputSeqVector = new FloatVectorVector(); foreach (var seq in sequences) { if (seq.Count() % dim != 0) { throw new InvalidDataException("the number of data in sequences does not match the input dimension"); } var samples = new FloatVector(seq); inputSeqVector.Add(samples); } var inputValue = Value.CreateDenseFloat(variable.Shape, inputSeqVector, computeDevice); return(inputValue); } else if (typeof(T).Equals(typeof(double))) { var inputSeqVector = new DoubleVectorVector(); foreach (var seq in sequences) { if (seq.Count() % dim != 0) { throw new InvalidDataException("the number of data in sequences does not match the input dimension"); } var samples = new DoubleVector(seq); inputSeqVector.Add(samples); } var inputValue = Value.CreateDenseDouble(variable.Shape, inputSeqVector, computeDevice); return(inputValue); } else { throw new InvalidDataException("The data type " + typeof(T).ToString() + " is not supported. Only float or double is supported by CNTK."); } }