基于手工打造的卷积CNN的性别识别

时间:2023-02-07 09:41:14

运行环境: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];
		}
	}
}

实验结果:

基于手工打造的卷积CNN的性别识别

程序下载链接:http://download.csdn.net/detail/qq_14845119/9634648