/// <summary> /// Forward computation. /// </summary> /// <param name="colBottom">input blob vector. /// </param> /// <param name="colTop">output blob vector. /// </param> protected void forwardCpu(BlobCollection <T> colBottom, BlobCollection <T> colTop) { // Retrieve all ground truth. m_hostGt.CopyFrom(colBottom[3]); float[] rgfGtData = m_hostGt.GetHostDataAsFloat(); DictionaryMap <List <NormalizedBBox> > rgAllGtBboxes = m_bboxUtil.GetGroundTruth(rgfGtData, m_nNumGt, m_nBackgroundLabelId, m_bUseDifficultGt); // Retrieve all prior bboxes. It is the same within a batch since we assume all // images in a batch are of the same dimension. List <List <float> > rgrgPriorVariances; m_hostPrio.CopyFrom(colBottom[2]); float[] rgfPriorData = m_hostPrio.GetHostDataAsFloat(); List <NormalizedBBox> rgPriorBboxes = m_bboxUtil.GetPrior(rgfPriorData, m_nNumPriors, out rgrgPriorVariances); // Retrieve all predictions. m_hostLoc.CopyFrom(colBottom[0]); float[] rgfLocData = m_hostLoc.GetHostDataAsFloat(); List <LabelBBox> rgAllLocPreds = m_bboxUtil.GetLocPredictions(rgfLocData, m_nNum, m_nNumPriors, m_nLocClasses, m_bShareLocation); // Find matches between source bboxes and ground truth bboxes. List <DictionaryMap <List <float> > > rgAllMatchOverlaps; m_bboxUtil.FindMatches(rgAllLocPreds, rgAllGtBboxes, rgPriorBboxes, rgrgPriorVariances, m_param.multiboxloss_param, out rgAllMatchOverlaps, out m_rgAllMatchIndices); // Sample hard negative (and positive) examples based on mining type. int nNumNegs; m_nNumMatches = m_bboxUtil.MineHardExamples(colBottom[1], rgAllLocPreds, rgAllGtBboxes, rgPriorBboxes, rgrgPriorVariances, rgAllMatchOverlaps, m_param.multiboxloss_param, m_rgAllMatchIndices, m_rgrgAllNegIndices, out nNumNegs); if (m_nNumMatches >= 1) { // Form data to pass on to loc_loss_layer. List <int> rgLocShape = new List <int>() { 1, m_nNumMatches * 4 }; m_blobLocPred.Reshape(rgLocShape); m_blobLocGt.Reshape(rgLocShape); m_bboxUtil.EncodeLocPrediction(rgAllLocPreds, rgAllGtBboxes, m_rgAllMatchIndices, rgPriorBboxes, rgrgPriorVariances, m_param.multiboxloss_param, m_blobLocPred, m_blobLocGt); m_locLossLayer.Reshape(m_colLocBottom, m_colLocTop); m_locLossLayer.Forward(m_colLocBottom, m_colLocTop); } else { m_blobLocLoss.SetData(0, 0); } // Form data to pass on to conf_loss_layer if (m_bDoNegMining) { m_nNumConf = m_nNumMatches + nNumNegs; } else { m_nNumConf = m_nNum * m_nNumPriors; } if (m_nNumConf >= 1) { // Reshape the confidence data. List <int> rgConfShape = new List <int>(); if (m_confLossType == MultiBoxLossParameter.ConfLossType.SOFTMAX) { rgConfShape.Add(m_nNumConf); m_blobConfGt.Reshape(rgConfShape); rgConfShape.Add(m_nNumClasses); m_blobConfPred.Reshape(rgConfShape); } else if (m_confLossType == MultiBoxLossParameter.ConfLossType.LOGISTIC) { rgConfShape.Add(1); rgConfShape.Add(m_nNumConf); rgConfShape.Add(m_nNumClasses); m_blobConfGt.Reshape(rgConfShape); m_blobConfPred.Reshape(rgConfShape); } else { m_log.FAIL("Unknown confidence loss type."); } if (!m_bDoNegMining) { // Consider all scores. // Share data and diff with bottom[1]. m_log.CHECK_EQ(m_blobConfPred.count(), colBottom[1].count(), "The conf pred and bottom[1] should have the same count."); m_blobConfPred.ShareData(colBottom[1]); } m_blobConfGt.SetData(m_nBackgroundLabelId); m_hostConf.CopyFrom(colBottom[1]); float[] rgfConfData = m_hostConf.GetHostDataAsFloat(); m_bboxUtil.EncodeConfPrediction(rgfConfData, m_nNum, m_nNumPriors, m_param.multiboxloss_param, m_rgAllMatchIndices, m_rgrgAllNegIndices, rgAllGtBboxes, m_blobConfPred, m_blobConfGt); m_confLossLayer.Reshape(m_colConfBottom, m_colConfTop); m_confLossLayer.Forward(m_colConfBottom, m_colConfTop); } else { m_blobConfLoss.SetData(0, 0); } double dfNormalizer = GetNormalizer(m_param.loss_param.normalization.Value, m_nNum, m_nNumPriors, m_nNumMatches); double dfLoss = 0; if (m_param.propagate_down[0]) { double dfLocLoss = Utility.ConvertVal <T>(m_blobLocLoss.GetData(0)); dfLoss += m_fLocWeight * dfLocLoss / dfNormalizer; } if (m_param.propagate_down[1]) { double dfConfLoss = Utility.ConvertVal <T>(m_blobConfLoss.GetData(0)); dfLoss += dfConfLoss / dfNormalizer; } colTop[0].SetData(dfLoss, 0); }