public override void Run() { _converter = new MovListToCodeConverter(Properties.Settings.Default.movementsList.Count,Properties.Settings.Default.allowedMovements); movCode=(int)_converter.Convert(new ushort[] { 1, 3 }, null, null, null); movCode = (int)_converter.Convert(new ushort[] { 1, 2 }, null, null, null); movCode = (int)_converter.Convert(new ushort[] { 5 }, null, null, null); movCode = (int)_converter.Convert(new ushort[] { 1, 3, 6 }, null, null, null); }
/// <summary> /// Worker method performing the actual validation process /// </summary> private void ValidationWorker() { /* * WE HAVE MOVED THE VALIDATION CODE FROM THE PatternRecognizer OBJECT TO HERE. * This was done because certain required value objects like movement lists have * nothing to do with pattern recognising. */ int okCount = 0; int failCount = 0; int expected; int predicted; ClassifToMovCodeConverter c2mConverter = new ClassifToMovCodeConverter(); MovListToCodeConverter ml2cConverter = new MovListToCodeConverter(totalSingleMovements, allowedComplexMovements); c2mConverter.multipleActivation = _patternRecognizer.multipleActivationEnabled; c2mConverter.activationLevel = _patternRecognizer.activationLevel; c2mConverter.activationTolerance = _patternRecognizer.activationTolerance; c2mConverter.movementCodes = _patternRecognizer.trainingPackage.movementCodes; Dictionary<int, Dictionary<int, int>> confusionMatrix = new Dictionary<int, Dictionary<int, int>>(); Dictionary<int, int> predictedDictionary; progressLog.Log(ProgressLogItem.Info, "*********** VALIDATION ************"); foreach (DataSet dataSet in _patternRecognizer.trainingPackage.validationSets) { expected = dataSet.movementCode; okCount = 0; failCount = 0; foreach (DataWindow dataWindow in dataSet.set) { double[] inputVector = new double[_patternRecognizer.inputDim]; for (int j = 0; j < dataWindow.features.Values.Count; j++) { double[] channelVector = (double[])dataWindow.features.Values.ElementAt(j); for (int k = 0; k < channelVector.Length; k++) inputVector[(j * channelVector.Length) + k] = channelVector[k]; } double[] outputVector = (double[])_patternRecognizer.Classify(inputVector); //Here we must determine which movement code corresponds better //with the input vector. The method for doing this changes depending on //whether we are using explicit movement codes or not, so we implement it using a converter class if (_patternRecognizer.multipleActivationEnabled) { List<ushort> movementList = (List<ushort>)c2mConverter.Convert(outputVector, null, null, null); predicted = (int)ml2cConverter.Convert(movementList.ToArray(), null, null, null); //The following happens when several outputs went active producing an impossible composite movement //such as "rest + open" or "open + close", for instance. if (predicted == -1) predicted = movementList.First(); //TODO: in this case, we opt for getting the //first movement of the list, bur we could do other things, like try and remove an element at //a tome and see when we come to a valid combination } else predicted = (int)c2mConverter.Convert(outputVector, null, null, null); //Now we check if the predicted movement matches the expected movement if (predicted == expected) okCount++; else failCount++; //Additionally, we compose the confusion matrix. if (confusionMatrix.TryGetValue(expected, out predictedDictionary)) { int predictedCount; if (predictedDictionary.TryGetValue(predicted, out predictedCount)) { predictedDictionary[predicted]++; } else predictedDictionary.Add(predicted, 1); } else { predictedDictionary = new Dictionary<int, int>(); predictedDictionary.Add(predicted, 1); confusionMatrix.Add(expected, predictedDictionary); } } string report = "Testing movement <mov " + expected + "/> -> correct: " + Math.Round(100 * okCount / (double)(okCount + failCount), 2) + "%"; confusionMatrix.TryGetValue(expected, out predictedDictionary); if (predictedDictionary.Keys.Count > 1) { report = report + "; misclassified as: "; foreach (int prediction in predictedDictionary.Keys) { if (prediction != expected) { report = report + "<mov " + prediction + "/> " + Math.Round(100 * predictedDictionary[prediction] / (double)(okCount + failCount), 2) + "%; "; } } } progressLog.Log(ProgressLogItem.Info, report); } progressLog.Log(ProgressLogItem.Info, "********* VALIDATION FINISHED *********"); }
public override void Init() { base.Init(); _producerGuid = _objectServer.RegisterProducer(); _matchBuffer.Clear(); _lastOutput = int.MinValue; _converter = new ClassifToMovCodeConverter(); _converter.multipleActivation = multipleActivation; _converter.activationLevel = activationLevel; _converter.activationTolerance = activationTolerance; _converter.movementCodes = movementCodes; _codeConverter = new MovListToCodeConverter(numSingleMovements,allowedComplexMovements); if (levelControlled) movementCodeMaker = ThresholdCodeMaker; else movementCodeMaker = PatternRecognitionCodeMaker; }
private void Init() { _version = -1; _minmaxDefined = false; knownMovements = null; requestedMovements = null; _converter = null; _movCodeToStringConverter = null; }
/// <summary> /// Scans the list of movements obtained form the HDF5 for each of the known individual movements /// The output is an list such as the one used by RecordingConfig as schedule. /// </summary> /// <param name="movsFromFile"></param> /// <param name="knownMovs"></param> /// <returns></returns> private List<ScheduleItem> GuessMovs(string[] movsFromFile, StringCollection knownMovs, StringCollection allowedMovs) { List<ScheduleItem> movSchedule = new List<ScheduleItem>(); List<ushort> movComposition = new List<ushort>(); int movCode; _converter = null; if (knownMovs != null && allowedMovs != null) _converter = new MovListToCodeConverter(knownMovs.Count, allowedMovs); for (int i = 0; i < movsFromFile.Length; i++) { string movName = movsFromFile[i]; movComposition.Clear(); for (int j = 0; j < knownMovs.Count; j++) { string knownMov = knownMovs[j]; if (System.Text.RegularExpressions.Regex.IsMatch(movName, knownMov, System.Text.RegularExpressions.RegexOptions.IgnoreCase)) { //We have found a basic movement inside this movement name movComposition.Add((ushort)j); } } //Here we need to guess the movement code from the movement composition. We need a converter! //For now, we just write a 0 ushort[] compositionArray = movComposition.ToArray(); movCode = 0; if (_converter != null) { movCode = (int)_converter.Convert(compositionArray, null, null, null); } ScheduleItem scheduleItem = new ScheduleItem((ushort)movCode, movComposition.ToArray()); movSchedule.Add(scheduleItem); } return movSchedule; }
/// <summary> /// Composes a recording schedule by using as inputs the list of selected movements, the number of /// simultaneous movements and checking the restrictions for combining movements /// </summary> public void ComposeSchedule() { ObservableCollection<ScheduleItem> schedule = recordingConfig.schedule; List<ushort[]> provList = new List<ushort[]>(); ushort[] movement; if ((_selectedMovements.Count <= 0) || (simultMovements <= 0)) return; if (_simultMovements > 1) recursiveCompose(provList, new ushort[_simultMovements], 0, 0); else { for (int i = 0; i < _selectedMovements.Count; i++) { movement = new ushort[_simultMovements]; movement[0] = (ushort)_selectedMovements.ElementAt(i).idTag; provList.Add(movement); } } if (provList.Count > 0) { //At this point we should have a list of allowed compound movements created from the list //of selected simple movements and the number simultaneous movements selected. Now we compose //a schedule including rests and repetitions //Adding as much initial rests as WarmupItems are configured in the recording configuration. These //WILL NOT BE RECORDED MovListToCodeConverter converter = new MovListToCodeConverter(numSingleMovements , allowedComplexMovements); for (int i = 0; i < recordingConfig.scheduleWarmupItems; i++) { movement = new ushort[1]; movement[0] = 0; schedule.Add(new ScheduleItem((int)converter.Convert(movement,null,null,null), movement)); } for (int i = 0; i < provList.Count; i++) { for (int j = 0; j < recordingConfig.repetitions; j++) { schedule.Add(new ScheduleItem((int)converter.Convert(provList.ElementAt(i),null,null,null), provList.ElementAt(i))); movement = new ushort[1]; movement[0] = 0; schedule.Add(new ScheduleItem((int)converter.Convert(movement,null,null,null), movement)); //An rest after each movement } } //The schedule is now complete. } }