private SampleCollection CreateNextSamples(SampleCollection allNegSamples, double falsePositiveRate, int maxSampleNum) { int selectSampleCount = (int)(maxSampleNum / falsePositiveRate); if (selectSampleCount <= 0) { selectSampleCount = allNegSamples.Count; } SampleCollection negSamples = allNegSamples.GetNegSamples(selectSampleCount); int oldNum = negSamples.Count; negSamples = this.GetPositivePredictedSamples(negSamples); if (DebugMsg.Debug) { string msg = string.Format("选取了{0}个负样本,通过了{1}个,误检率为{2:P5}\r\n", oldNum, negSamples.Count, (MyFloat)negSamples.Count / oldNum); DebugMsg.AddMessage(msg, 0); } if (negSamples.Count > maxSampleNum) { negSamples.TrimExcess(maxSampleNum); } GC.Collect(); return(negSamples); }
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { try { File.WriteAllText(@"D:\ccc.txt", textBox_debug.Text, Encoding.Default); } catch (System.Exception ex) { DebugMsg.AddMessage(ex.ToString(), 0); } }
private void button_train_Click(object sender, EventArgs e) { textBox_debug.BringToFront(); if (_cascadeClassifier != null) { if (MessageBox.Show("已存在分类器,在现有分类器上继续训练吗?", "", MessageBoxButtons.YesNo) == DialogResult.No) { _cascadeClassifier = new CascadeClassifier(); } } else { _cascadeClassifier = new CascadeClassifier(); } if (!inited) { button_loadSamples_Click(sender, e); // WeakClassifierManager.Instance.CreateHaarFeatures(_size.Width, _size.Height , _colorType); WeakClassifierManager.Instance.CreateHaarFeatures(_size.Width, _size.Height / 2, _colorType); WeakClassifierManager.Instance.AddSymmetricHaarFeatures(_size.Width, _size.Height, _colorType); } //StageClassifier.ViewId = int.Parse(textBox1.Text); GC.Collect(); GC.WaitForFullGCComplete(); BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler( (a, b) => { //cascadeClassifier.Train(posSamples, negSamples, (MyFloat)0.001, (MyFloat)0.5, (MyFloat)0.99); _cascadeClassifier.Train(_posSamples, _negSamples, _validateSamples, _size, _targetFalsePositiveRate, _maxFalsePositiveRate, _minHitRate); }); worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); worker.WorkerReportsProgress = true; DebugMsg.Init(worker); worker.RunWorkerAsync(); inited = true; }
public void Train(SampleCollection posSamples, SampleCollection allNegSamples, SampleCollection validateSamples, Size size, double targetFalsePositiveRate, double maxFalsePositiveRate, double minHitRate) { const int startCapacity = 20; _size = size; List <StageClassifier> stageClassifier = new List <StageClassifier>(startCapacity); double hitRate = 1; double falsePositiveRate = 1; int stageCount = 0; int maxSampleNum; SampleCollection negSamples; { //计算使用的负样本数量 double MaxMemoryUse = MemoryInfo.GetFreePhysicalMemory() - 400e6; if (MaxMemoryUse < 0) { MaxMemoryUse = 1.8e9; } //MaxMemoryUse = 2.48e9; //按照内存大小来选取负样本,在充分利用内存的同时防止使用虚拟内存 int weakNum = WeakClassifierManager.Instance.WeakClassifiers.Length; maxSampleNum = (int)(( MaxMemoryUse - 1.5e6f //预留150M给程序其它部分 ) / weakNum / sizeof(MyFloat)) - posSamples.Count; if (DebugMsg.Debug) { string msg = string.Format("\r\n单次使用负样本:{0},特征数量:{1},预计消耗内存:{2}M\r\n", maxSampleNum, weakNum, MaxMemoryUse / 1024 / 1024); DebugMsg.AddMessage(msg, 0); } } //如果已有分类器,计算当前的性能 if (_classifiers != null && _classifiers.Length > 0) { PredictResult result = EvaluateErrorRate(validateSamples); hitRate = result.HitRate; falsePositiveRate = result.FalsePositiveRate; stageCount = _classifiers.Length; stageClassifier.AddRange(_classifiers); negSamples = CreateNextSamples(allNegSamples, falsePositiveRate, maxSampleNum); if (DebugMsg.Debug) { string msg = string.Format("载入分类器完成,层数:{0},当前性能为:\r\n检测率:\t{1:P5},\t误检率:\t{2:P5}\r\n------\r\n", stageCount, hitRate, falsePositiveRate); DebugMsg.AddMessage(msg, 0); } } else { negSamples = allNegSamples.GetNegSamples(maxSampleNum); } while (falsePositiveRate > targetFalsePositiveRate && negSamples.Count != 0 && posSamples.Count != 0) { stageCount++; if (DebugMsg.Debug) { string msg = string.Format("--------------------\r\n开始训练第{0}级分类器,使用的数量为:\r\n正样本:\t{1}\t负样本:\t{2}\r\n目标检测率:\t{3:P5}\t目标误检率:\t{4:P5}\r\n", stageCount, posSamples.Count, negSamples.Count, minHitRate, maxFalsePositiveRate); DebugMsg.AddMessage(msg, 0); } StageClassifier currentStage = new StageClassifier(stageCount); PredictResult result = currentStage.Train(posSamples, negSamples, validateSamples, maxFalsePositiveRate, minHitRate); falsePositiveRate *= result.FalsePositiveRate; hitRate *= result.HitRate; stageClassifier.Add(currentStage); _classifiers = stageClassifier.ToArray(); if (DebugMsg.Debug) { string msg = string.Format("------\r\n第{0}级分类器训练结束,当前性能为:\r\n检测率:\t{1:P5},\t误检率:\t{2:P5}\r\n弱分类器数量:{3}\r\n目前训练时间总计:{4}\r\n", stageCount, hitRate, falsePositiveRate, currentStage.WeakClassifierCount, DebugMsg.stopwatch.Elapsed.ToString()); DebugMsg.AddMessage(msg, 0); } if (falsePositiveRate > targetFalsePositiveRate) { //posSamples = this.CreateNextSamples(posSamples); validateSamples = this.GetPositivePredictedSamples(validateSamples); negSamples = CreateNextSamples(allNegSamples, falsePositiveRate, maxSampleNum); } this.Save(string.Format(@"D:\ccc{0}.xml", stageCount.ToString())); } if (DebugMsg.Debug) { DebugMsg.stopwatch.Stop(); string msg = string.Format("\r\n--------------------\r\n全部训练完成,训练时间总计:{0}\r\n", DebugMsg.stopwatch.Elapsed.ToString()); DebugMsg.AddMessage(msg, 0); } this.Save(@"D:\ccc.xml"); }
/// <summary> /// 训练级联分类器中一层的强分类器 /// </summary> /// <param name="posSamples"></param> /// <param name="negSamples"></param> /// <param name="maxFalsePositiveRate"></param> /// <param name="minHitRate"></param> /// <returns>训练的统计结果</returns> public PredictResult Train(SampleCollection posSamples, SampleCollection negSamples, SampleCollection validateSamples, double maxFalsePositiveRate, double minHitRate) { List <WeakClassifier> weakClassifiers = new List <WeakClassifier>(10); PredictResult result = new PredictResult(); MyFloat[] sampleWeight = InitWeight(posSamples.Count, negSamples.Count); WeakClassifierManager allWeak = WeakClassifierManager.Instance; Stopwatch watch = new Stopwatch(); watch.Start(); allWeak.PreCalcFeatureValue(posSamples, negSamples); watch.Stop(); if (DebugMsg.Debug) { string msg = string.Format("所有弱分类器特征值预计算完成,用时:{0}\r\n", watch.Elapsed.ToString()); DebugMsg.AddMessage(msg, 0); } int trainTime = 0; do { if (++trainTime != 1) { NormalizeWeight(sampleWeight); } if (DebugMsg.Debug) { string msg = string.Format("开始训练第{0}个弱分类器\r\n", trainTime); DebugMsg.AddMessage(msg, 0); } watch.Reset(); watch.Start(); allWeak.Train(posSamples, negSamples, sampleWeight); WeakClassifier newBestClassifier = AdaBoost(posSamples.Count, negSamples.Count, sampleWeight); //UpdateWeights(newBestClassifier, posSamples.Count, negSamples.Count, sampleWeight); weakClassifiers.Add(newBestClassifier); _classifiers = weakClassifiers.ToArray(); result = EvaluateErrorRate(validateSamples, minHitRate, maxFalsePositiveRate); watch.Stop(); if (DebugMsg.Debug) { string msg = string.Format("训练完成,花费时间{0}\r\n检测率:\t{1:P5}\t误检率:\t{2:P5}\r\n", watch.Elapsed.ToString(), result.HitRate, result.FalsePositiveRate); DebugMsg.AddMessage(msg, 1); } } while (result.FalsePositiveRate > maxFalsePositiveRate); allWeak.ReleaseTrainData(); foreach (WeakClassifier weak in _classifiers) { weak.ReleaseTrainData(); } return(result); }