private static RecognitionResults RecognizeImage(double[] input, long inputToken, int width, int height, int finalResolution, TrainedRecognizer[] recognizers, LifeEventToVector lifeEvents, ConvolutionBase2D convolution, bool isColor)
        {
            if (recognizers == null)
            {
                return new RecognitionResults(inputToken, new double[lifeEvents.Types.Length]);
            }

            double[] normalized = NormalizeInput(input, width, height, finalResolution, convolution, isColor);

            foreach (var recognizer in recognizers)
            {
                double[] output = recognizer.Network.Compute(normalized);

                //TODO: Analyze outputs of all the recognizers to come up with a final result.  Can't just take the average -- if they all
                //agree, that's great.  But disagreement should have a zero output (or at least a very weak output)
                return new RecognitionResults(inputToken, output);
            }

            throw new ApplicationException("finish this");
        }
        private void FinishedTraining(TrainedRecognizer result)
        {
            lock (_lock)
            {
                _trainingTask = null;

                if (result != null)
                {
                    //TODO: Keep a few around.  If max count is met, throw out the oldest/worst
                    _recognizers = new[] { result };
                    _currentTrainingData = Tuple.Create(result.InputRaw, result.InputNormalized);
                }

                if (_areLifeEventsDirty || result == null)      // null means it was unsuccessful.  Try again
                {
                    // There is new data, train against it
                    TrainerInput trainerInput = GetTrainingInput();

                    if (trainerInput != null)
                    {
                        _areLifeEventsDirty = false;
                        _trainingTask = new Task<TrainedRecognizer>(() => Train(trainerInput, _convolution, _isColor, _finalResolution));
                        _trainingTask.ContinueWith(r => FinishedTraining(r.Result));
                        _trainingTask.Start();
                    }
                }
            }
        }