运行环境:VS2008
人脸检测库:于仕琪老师的人脸检测库
程序解析:
程序主要实现了3个卷积层的操作,通过训练获得这3个卷积层的权值。预测的时候就根据这些权值进行相应的分类操作。
前向传播:
int CLayer::FeedForward(double* pInput, bool bDisp) { if (!pInput) { return -1; } m_pInput = pInput; //#pragma omp parallel for for (int i=0;i<m_nOutput;i++) { double f_sum = 0.0; //#pragma omp parallel for for (int j=0;j<m_nInput;j++) { f_sum += m_pInput[j] * m_pWeight[i][j]; } m_pOutput[i] = 1.0 / (1.0 + exp(-1.0*f_sum)); } if (!bDisp) { return -1; } int idx_max = -1; double f_outMax = 0.0f; for (int k=0;k<m_nOutput;k++) { if (m_pOutput[k] > f_outMax) { f_outMax = m_pOutput[k]; idx_max = k; } } return idx_max; }
反向传播:
void CLayer::BackPropagation(bool bIsOutputLayer, int* tranLabel, CLayer* pLayerFront) { // 计算残差 if (bIsOutputLayer) { if (!tranLabel) { printf("Train Label not exist!\n"); return; } for (int i=0;i<m_nOutput;i++) { double factor = m_pOutput[i] * (1.0 - m_pOutput[i]); if ((fabs(m_pOutput[i] - 0.0) < 0.01 && fabs(m_pOutput[i] - tranLabel[i]) > 0.5) || fabs(m_pOutput[i] - 1.0) < 0.01 && fabs(m_pOutput[i] - tranLabel[i]) > 0.5) { factor = 0.25f; //printf("%d,%.04f,%.04f\n",i,m_pOutput[i],tranLabel[i]); } m_pDelta_out[i] = factor * (m_pOutput[i] - tranLabel[i]); } } else { if (!pLayerFront) { printf("Front Layer not exist!\n"); return; } double* f_delta_w_front = NULL; f_delta_w_front = new double[m_nOutput]; if (f_delta_w_front) { //#pragma omp parallel for for (int i=0;i<m_nOutput;i++) { double sum = 0.0f; //#pragma omp parallel for for (int k=0;k<pLayerFront->m_nOutput;k++) { sum += pLayerFront->m_pDelta_out[k] * pLayerFront->m_pWeight[k][i]; } f_delta_w_front[i] = sum; double factor = m_pOutput[i] * (1.0 - m_pOutput[i]); m_pDelta_out[i] = factor * f_delta_w_front[i]; } delete f_delta_w_front; f_delta_w_front = NULL; } } // 更新权值 //#pragma omp parallel for for (int i=0;i<m_nOutput;i++) { //#pragma omp parallel for for (int j=0;j<m_nInput;j++) { m_pWeight[i][j] -= m_Lr * m_pDelta_out[i] * m_pInput[j]; } } }
实验结果:
程序下载链接:http://download.csdn.net/detail/qq_14845119/9634648