1. 程式人生 > >cpp-BP與特徵臉實現人臉表情識別(一):BP神經網路

cpp-BP與特徵臉實現人臉表情識別(一):BP神經網路

這是一份充滿野指標的只是用來理解的玩具程式碼

最近用耶魯人臉庫簡單實現了人臉表情識別,寫幾篇部落格留個紀念。

分為 BP神經網路 與 實現人臉識別 兩篇部落格,對於遇到的問題與程式碼進行總結分析。

第一篇需要理解 BP神經網路的原理,先給出程式碼再總結。

直接複製貼上 程式碼很醜。。。

//DateSet.h
//created by WK

#ifndef DATASET_H
#define DATASET_H

#include <vector>
#include <cfloat>

using namespace std;

//資料集
class DataSet
{
private:
	int					InputNum;
	int					OutputNum;
	vector<double*>		DataMap;
	double				*Max;
	double				*Mini;

public:
	DataSet(int inputnum, int outputnum)
	{
		this->InputNum	=	inputnum;
		this->OutputNum =	outputnum;
		this->Max		=	NULL;
		this->Mini		=	NULL;
	}
	void AddRow(double *inputArray, double *outputArray)
	{
		double *data = new double[this->InputNum + this->OutputNum];
		for (int i = 0; i<this->InputNum; ++i)
		{
			data[i] = inputArray[i];
		}
		for (int i = 0; i<this->OutputNum; ++i)
		{
			data[InputNum + i] = outputArray[i];
		}
		this->DataMap.push_back(data);
	}
	void Normaliz()
	{
		if (this->Max)
		{
			delete this->Max;
			this->Max = NULL;
		}
		if (this->Mini)
		{
			delete this->Mini;
			this->Mini = NULL;
		}
			 
		this->Max = new double[this->InputNum + this->OutputNum];
		this->Mini = new double[this->InputNum + this->OutputNum];
		for (int i = 0; i < this->InputNum + this->OutputNum; ++i)
		{
			double max = INT_MIN;
			double mini = DBL_MAX;
			for (int j = 0; j < DataMap.size(); ++j)
			{
				max = (max > DataMap[j][i] ? max : DataMap[j][i]);
				mini = (mini < DataMap[j][i] ? mini : DataMap[j][i]);
			}
			
			if (max == mini)
				continue;

			for (int j = 0; j < DataMap.size(); ++j)
			{
				DataMap[j][i] = (DataMap[j][i] - mini) / (max - mini);
			}
			Max[i] = max;
			Mini[i] = mini;
		}
	}
	double *GetMax()
	{
		return this->Max;
	}
	double *GetMini()
	{
		return this->Mini;
	}
	int GetInputNum()
	{
		return this->InputNum;
	}
	int GetOutputNum()
	{
		return this->OutputNum;
	}
	int GetRows()
	{
		return DataMap.size();
	}
	vector<double*> GetDataMap()
	{
		return DataMap;
	}
 
};


#endif // !DATASET_H



這是對資料集的簡單封裝
private:
	int					InputNum;
	int					OutputNum;
	vector<double*>		DataMap;
	double				*Max;
	double				*Mini;


1.保留輸入輸出的變數的個數,每一行資料,前InputNum 個為輸入 後OutputNum 個為輸出

2.採用double* 的vector 便於動態新增資料,使用AddRow新增一行資料

3.Max Mini 分別儲存了每一列資料的最大最小值,注意是每一列即不同組別的同類資料,用於歸一化

4.Normaliz 採用常見的歸一化,分別將每一列進行歸一化,即不同組別的同類資料進行歸一化

/********************************************************************************************************************************************************************/

//TransferFunc.h
//created by WK

#ifndef TRANSFERFUNC_H
#define TRANSFERFUNC_H

#include <cmath>

enum Functypes
{
	FUNCTYPE_TANH,
	FUNCTYPE_STEP,
	FUNCTYPE_LINEAR,
	FUNCTYPE_SIGMOID,
	FUNCTYPE_SGN,
	FUNVTYPE_RAMP
};

class Function
{
private:
	double Step(double input)
	{
		if (input <= 0)
			return 0;
		else
			return 1;
	}
	double Linear(double input)
	{
		return input;
	}
	double Sigmoid(double input)
	{
		return 1.0 / (1.0 + exp(-1.0*input));
	}
	double Sgn(double input)
	{
		if (input < 0)
			return -1;
		else
			return 1;
	}
	double Ramp(double input)
	{
		if (input < 0)
			return 0;
		else if (input >= 0 && input <= 1)
			return input;
		else
			return 1;
	}
public:

	double GetResult(int funcType, double input)
	{
		switch (funcType)
		{
		case FUNCTYPE_TANH:
			return tanh(input);
		case FUNCTYPE_STEP:
			return Step(input);
		case FUNCTYPE_LINEAR:
			return Linear(input);
		case FUNCTYPE_SIGMOID:
			return Sigmoid(input);
		case FUNCTYPE_SGN:
			return Sgn(input);
		case FUNVTYPE_RAMP:
			return Ramp(input);
		default:
			return input;
		}
	}
};

#endif // !TRANSFERFUNC_H




這是對傳遞函式的簡單封裝

1.傳入函式型別以及輸入資料,即可獲取相應函式計算所得結果

/****************************************************************************************************************************************************************/

//net.h
//created by WK

#ifndef NET_H
#define NET_H


#include <vector>
#include <iostream>
#include "TransferFunc.h"
#include "DataSet.h"
#include <cstdlib>

using namespace std;

#define WINITVALUE 0.001
#define TINITVALUE 0

//神經元
class Neuron
{
private:
	double				Input;
	double				Output;
	double				Threshold;
	double				*Last_weight;			//神經元維護後向的權重
	int					LastLayerNeuNum;
	int					TransferFunctionType;
	Function			Transferfunction;

public:
	Neuron(double threshold, int lastlayerneunum, int funcType)
	{
		this->Input = 0;
		this->Output = 0;
		this->Threshold = threshold;
		this->LastLayerNeuNum = lastlayerneunum;
		this->TransferFunctionType = funcType;
		this->Last_weight = new double[lastlayerneunum];
		//關鍵的初始化權值
		for (int i = 0; i < lastlayerneunum; ++i)
			this->Last_weight[i] = (2.0*(double)rand() / RAND_MAX) - 1;

	}
	void SetInput(double input)
	{
		this->Input = input;
	}
	double GetOutput()
	{
		this->Output = Transferfunction.GetResult(this->TransferFunctionType, this->Input - this->Threshold);

		return this->Output;
	}
	double* GetThreshold()
	{
		return &this->Threshold;
	}
	double *GetWeight()
	{
		return this->Last_weight;
	}
	void SetFuncType(int functype)
	{
		this->TransferFunctionType = functype;
	}
};

//多層感知機
class MultiLayerPerceptron
{
private:
	int			OutTransfetFunctionType;
	int			HideTransfetFunctionType;
	int			InTransfetFunctionType;
	int			InLayerNeuNum;
	int			HideLayerNeuNum;
	int			OutLayerNeuNum;
	double		Speed;
	Neuron		**InputNeurons;
	Neuron		**OutputNeurons;
	Neuron		**HidenNeurons;
public:

	MultiLayerPerceptron(int intransferfunctiontype, int inLayerNeuNum, int hidetransferfunctiontype, int hideLayerNeuNum, int outtransferfunctiontype, int outLayerNeuNum, double speed)
	{
		this->InTransfetFunctionType = intransferfunctiontype;
		this->HideTransfetFunctionType = hidetransferfunctiontype;
		this->OutTransfetFunctionType = outtransferfunctiontype;
		this->InLayerNeuNum = inLayerNeuNum;
		this->HideLayerNeuNum = hideLayerNeuNum;
		this->OutLayerNeuNum = outLayerNeuNum;
		this->Speed = speed;

		this->InputNeurons = (Neuron**)new void*[inLayerNeuNum];
		for (int i = 0; i < inLayerNeuNum; ++i)
			this->InputNeurons[i] = new Neuron(TINITVALUE, 0, intransferfunctiontype);
		this->HidenNeurons = (Neuron**)new void*[hideLayerNeuNum];
		for (int i = 0; i < hideLayerNeuNum; ++i)
			this->HidenNeurons[i] = new Neuron(TINITVALUE, inLayerNeuNum, hidetransferfunctiontype);
		this->OutputNeurons = (Neuron**)new void*[outLayerNeuNum];
		for (int i = 0; i < outLayerNeuNum; ++i)
			this->OutputNeurons[i] = new Neuron(TINITVALUE, hideLayerNeuNum, outtransferfunctiontype);
	}
	//獲取正向的輸出
	void GetOutput(double *output)
	{
		double sum;

		for (int i = 0; i < this->HideLayerNeuNum; ++i)
		{
			sum = 0;
			for (int j = 0; j < this->InLayerNeuNum; ++j)
				sum += this->HidenNeurons[i]->GetWeight()[j] * this->InputNeurons[j]->GetOutput();
			this->HidenNeurons[i]->SetInput(sum);
		}
		for (int i = 0; i < this->OutLayerNeuNum; ++i)
		{
			sum = 0;
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
				sum += this->OutputNeurons[i]->GetWeight()[j] * this->HidenNeurons[j]->GetOutput();
			this->OutputNeurons[i]->SetInput(sum);
			output[i] = this->OutputNeurons[i]->GetOutput();
		}
	}

	//學習所有資料一次
	void Learn(DataSet *trainingSet)
	{
		double *expect;
		double *data;
		double *output = new double[this->OutLayerNeuNum];
		for (int i = 0; i < trainingSet->GetRows(); ++i)
		{
			data = trainingSet->GetDataMap()[i];
			expect = data + trainingSet->GetInputNum();
			for (int j = 0; j < trainingSet->GetInputNum(); ++j)
				this->InputNeurons[j]->SetInput(data[j]);
			this->GetOutput(output);
			//更改隱藏層到輸出層權重以及閾值
			//更新公式詳見機器學習
			for (int j = 0; j < this->OutLayerNeuNum; ++j)
			{
				double delta = this->Speed * output[j] * (1 - output[j]) * (expect[j] - output[j]);

				for (int k = 0; k < this->HideLayerNeuNum; ++k)
					this->OutputNeurons[j]->GetWeight()[k] += (delta * this->HidenNeurons[k]->GetOutput());
				*this->OutputNeurons[j]->GetThreshold() -= delta;
			}
			//更改輸入層到隱藏層的權重以及閾值
			//更新公式詳見機器學習
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
			{
				double t = 0;
				for (int k = 0; k < this->OutLayerNeuNum; ++k)
					t += (this->OutputNeurons[k]->GetWeight()[j] * output[k] * (1 - output[k])*(expect[k] - output[k]));
				double delta = this->HidenNeurons[j]->GetOutput() * (1 - this->HidenNeurons[j]->GetOutput()) * t;
				for (int k = 0; k < this->InLayerNeuNum; ++k)
					this->HidenNeurons[j]->GetWeight()[k] += (this->Speed * this->InputNeurons[k]->GetOutput() * delta);
				*this->HidenNeurons[j]->GetThreshold() -= (this->Speed * delta);
			}
		}
	}

	void Test(DataSet *Set)
	{
		double *output = new double[this->OutLayerNeuNum];
		double *expect = new double[this->OutLayerNeuNum];

		for (int i = 0; i < Set->GetRows(); ++i)
		{
			for (int j = 0; j < Set->GetInputNum(); ++j)
				this->InputNeurons[j]->SetInput(Set->GetDataMap()[i][j]);
			this->GetOutput(output);
			for (int j = 0; j < Set->GetOutputNum(); ++j)
			{
				cout << "output: ";
				cout << output[j] << "  ";
				cout << "expect: ";
				cout << Set->GetDataMap()[i][Set->GetInputNum() + j] << "  ";
			}
			cout << endl;
		}
		cout << endl;
		cout << "in to hide Weight:" << endl;
		for (int i = 0; i < this->HideLayerNeuNum; ++i)
		{
			for (int j = 0; j < this->InLayerNeuNum; ++j)
			{
				cout << this->HidenNeurons[i]->GetWeight()[j] << "  ";
			}
			cout << endl;
		}
		cout << endl;
		cout << "hide to out Weight:" << endl;
		for (int i = 0; i < this->OutLayerNeuNum; ++i)
		{
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
			{
				cout << this->OutputNeurons[i]->GetWeight()[j] << "  ";
			}
			cout << endl;
		}
	}

};

#endif // !NET_H


以上為 神經元 以及 BP神經網路的程式碼 以下分開說

/****************************************************************************************************************************************/

//神經元
class Neuron
{
private:
	double				Input;
	double				Output;
	double				Threshold;
	double				*Last_weight;			//神經元維護後向的權重
	int					LastLayerNeuNum;
	int					TransferFunctionType;
	Function			Transferfunction;

public:
	Neuron(double threshold, int lastlayerneunum, int funcType)
	{
		this->Input = 0;
		this->Output = 0;
		this->Threshold = threshold;
		this->LastLayerNeuNum = lastlayerneunum;
		this->TransferFunctionType = funcType;
		this->Last_weight = new double[lastlayerneunum];
		//關鍵的初始化權值
		for (int i = 0; i < lastlayerneunum; ++i)
			this->Last_weight[i] = (2.0*(double)rand() / RAND_MAX) - 1;

	}
	void SetInput(double input)
	{
		this->Input = input;
	}
	double GetOutput()
	{
		this->Output = Transferfunction.GetResult(this->TransferFunctionType, this->Input - this->Threshold);

		return this->Output;
	}
	double* GetThreshold()
	{
		return &this->Threshold;
	}
	double *GetWeight()
	{
		return this->Last_weight;
	}
	void SetFuncType(int functype)
	{
		this->TransferFunctionType = functype;
	}
};



以上為神經元

1.輸入值,輸出值,閾值,以及傳輸函式型別無需多言,構造必須指定 閾值,上一層神經元個數用於分配記憶體給權重陣列,以及傳輸函式型別

2.每一個神經元維護後向的權值Last_weight   舉例

    s前1 代表 前一層的1號神經元輸出                    s後1 代表後一層1號神經元的輸入  w表示權重  有:

    s後1 = w1 * s前1 + w2 * s前2.......                  暫時忽略閾值與傳輸函式

    即由 s後1 這個神經元維護一個數組,這個陣列的元素是 w1 w2 w3
    (權重的維護有多種實現方式 隨意)

/***********************************************************************************************************************************************************************************/

//多層感知機
class MultiLayerPerceptron
{
private:
	int			OutTransfetFunctionType;
	int			HideTransfetFunctionType;
	int			InTransfetFunctionType;
	int			InLayerNeuNum;
	int			HideLayerNeuNum;
	int			OutLayerNeuNum;
	double		Speed;
	Neuron		**InputNeurons;
	Neuron		**OutputNeurons;
	Neuron		**HidenNeurons;
public:

	MultiLayerPerceptron(int intransferfunctiontype, int inLayerNeuNum, int hidetransferfunctiontype, int hideLayerNeuNum, int outtransferfunctiontype, int outLayerNeuNum, double speed)
	{
		this->InTransfetFunctionType = intransferfunctiontype;
		this->HideTransfetFunctionType = hidetransferfunctiontype;
		this->OutTransfetFunctionType = outtransferfunctiontype;
		this->InLayerNeuNum = inLayerNeuNum;
		this->HideLayerNeuNum = hideLayerNeuNum;
		this->OutLayerNeuNum = outLayerNeuNum;
		this->Speed = speed;

		this->InputNeurons = (Neuron**)new void*[inLayerNeuNum];
		for (int i = 0; i < inLayerNeuNum; ++i)
			this->InputNeurons[i] = new Neuron(TINITVALUE, 0, intransferfunctiontype);
		this->HidenNeurons = (Neuron**)new void*[hideLayerNeuNum];
		for (int i = 0; i < hideLayerNeuNum; ++i)
			this->HidenNeurons[i] = new Neuron(TINITVALUE, inLayerNeuNum, hidetransferfunctiontype);
		this->OutputNeurons = (Neuron**)new void*[outLayerNeuNum];
		for (int i = 0; i < outLayerNeuNum; ++i)
			this->OutputNeurons[i] = new Neuron(TINITVALUE, hideLayerNeuNum, outtransferfunctiontype);
	}
	//獲取正向的輸出
	void GetOutput(double *output)
	{
		double sum;

		for (int i = 0; i < this->HideLayerNeuNum; ++i)
		{
			sum = 0;
			for (int j = 0; j < this->InLayerNeuNum; ++j)
				sum += this->HidenNeurons[i]->GetWeight()[j] * this->InputNeurons[j]->GetOutput();
			this->HidenNeurons[i]->SetInput(sum);
		}
		for (int i = 0; i < this->OutLayerNeuNum; ++i)
		{
			sum = 0;
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
				sum += this->OutputNeurons[i]->GetWeight()[j] * this->HidenNeurons[j]->GetOutput();
			this->OutputNeurons[i]->SetInput(sum);
			output[i] = this->OutputNeurons[i]->GetOutput();
		}
	}

	//學習所有資料一次
	void Learn(DataSet *trainingSet)
	{
		double *expect;
		double *data;
		double *output = new double[this->OutLayerNeuNum];
		for (int i = 0; i < trainingSet->GetRows(); ++i)
		{
			data = trainingSet->GetDataMap()[i];
			expect = data + trainingSet->GetInputNum();
			for (int j = 0; j < trainingSet->GetInputNum(); ++j)
				this->InputNeurons[j]->SetInput(data[j]);
			this->GetOutput(output);
			//更改隱藏層到輸出層權重以及閾值
			//更新公式詳見機器學習
			for (int j = 0; j < this->OutLayerNeuNum; ++j)
			{
				double delta = this->Speed * output[j] * (1 - output[j]) * (expect[j] - output[j]);

				for (int k = 0; k < this->HideLayerNeuNum; ++k)
					this->OutputNeurons[j]->GetWeight()[k] += (delta * this->HidenNeurons[k]->GetOutput());
				*this->OutputNeurons[j]->GetThreshold() -= delta;
			}
			//更改輸入層到隱藏層的權重以及閾值
			//更新公式詳見機器學習
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
			{
				double t = 0;
				for (int k = 0; k < this->OutLayerNeuNum; ++k)
					t += (this->OutputNeurons[k]->GetWeight()[j] * output[k] * (1 - output[k])*(expect[k] - output[k]));
				double delta = this->HidenNeurons[j]->GetOutput() * (1 - this->HidenNeurons[j]->GetOutput()) * t;
				for (int k = 0; k < this->InLayerNeuNum; ++k)
					this->HidenNeurons[j]->GetWeight()[k] += (this->Speed * this->InputNeurons[k]->GetOutput() * delta);
				*this->HidenNeurons[j]->GetThreshold() -= (this->Speed * delta);
			}
		}
	}

	void Test(DataSet *Set)
	{
		double *output = new double[this->OutLayerNeuNum];
		double *expect = new double[this->OutLayerNeuNum];

		for (int i = 0; i < Set->GetRows(); ++i)
		{
			for (int j = 0; j < Set->GetInputNum(); ++j)
				this->InputNeurons[j]->SetInput(Set->GetDataMap()[i][j]);
			this->GetOutput(output);
			for (int j = 0; j < Set->GetOutputNum(); ++j)
			{
				cout << "output: ";
				cout << output[j] << "  ";
				cout << "expect: ";
				cout << Set->GetDataMap()[i][Set->GetInputNum() + j] << "  ";
			}
			cout << endl;
		}
		cout << endl;
		cout << "in to hide Weight:" << endl;
		for (int i = 0; i < this->HideLayerNeuNum; ++i)
		{
			for (int j = 0; j < this->InLayerNeuNum; ++j)
			{
				cout << this->HidenNeurons[i]->GetWeight()[j] << "  ";
			}
			cout << endl;
		}
		cout << endl;
		cout << "hide to out Weight:" << endl;
		for (int i = 0; i < this->OutLayerNeuNum; ++i)
		{
			for (int j = 0; j < this->HideLayerNeuNum; ++j)
			{
				cout << this->OutputNeurons[i]->GetWeight()[j] << "  ";
			}
			cout << endl;
		}
	}

};


以上為bp神經網路

1.構造需指定 輸入層神經元個數,輸入層神經元傳輸函式型別,隱藏層(單隱)神經元個數,隱藏層神經元傳輸函式型別,輸出層神經元個數,輸出層神經元傳輸函式型別,學習速率

2.Neuron** 的成員維護一層的神經元,儲存指標陣列

3.Getoutput 設定輸入層各神經元的input 呼叫Getoutput  獲取輸出神經元的輸出值

4.Learn 根據 周志華所著的機器學習中的權重更新公式,更新權重,這裡的程式碼略為臃腫

5.Test 用於測試

/********************************************************************************************************************************************************************************************/

以下為神經網路測試 解決異或問題

#include "net.h"

int main()
{
	DataSet *trainingSet = new DataSet(2, 1);
	trainingSet->AddRow(new double[2]{ 1,1 }, new double[1]{ 0 });
	trainingSet->AddRow(new double[2]{ 1,0 }, new double[1]{ 1 });
	trainingSet->AddRow(new double[2]{ 0,1 }, new double[1]{ 1 });
	trainingSet->AddRow(new double[2]{ 0,0 }, new double[1]{ 0 });

	//層激勵函式型別 神經元個數... 學習速率  
	MultiLayerPerceptron *m = new MultiLayerPerceptron(FUNCTYPE_LINEAR, 2, FUNCTYPE_SIGMOID, 5, FUNCTYPE_SIGMOID, 1, 0.9);

	//學習1000次  
	for (int i = 0; i < 1000; ++i)
		m->Learn(trainingSet);

	m->Test(trainingSet);



	system("pause");

}


相關推薦

cpp-BP特徵實現人臉表情識別():BP神經網路

這是一份充滿野指標的只是用來理解的玩具程式碼 最近用耶魯人臉庫簡單實現了人臉表情識別,寫幾篇部落格留個紀念。 分為 BP神經網路 與 實現人臉識別 兩篇部落格,對於遇到的問題與程式碼進行總結分析。 第一篇需要理解 BP神經網路的原理,先給出程式碼再總結。 直接複製貼上 程

人臉表情識別筆記(二)特徵提取之LBP(區域性二值模式)原理及MATLAB程式碼

一:原理部分 LBP(Local Binary Pattern,區域性二值模式)是一種用來描述影象區域性紋理特徵的運算元;它具有旋轉不變性和灰度不變性等顯著的優點。它是首先由T. Ojala, M.Pietikäinen, 和D. Harwood 在1994年提出,用

opencv dlib 結合實現人臉融合

融合流程檢測面部標記旋轉、縮放和轉換第二張影象,使之與第一張影象相適應調整第二張影象的色彩平衡,使之與第一個相匹配把第二張影象的特性混合在第一張影象中實現流程找到人臉矩陣使用dlib提取面部標記用Dlib實現了論文One Millisecond Face Alignment

python手寫bp神經網路實現人臉性別識別1.0

寫在前面:本實驗用到的圖片均來自google圖片,侵刪! 實驗介紹 用python手寫一個簡單bp神經網路,實現人臉的性別識別。由於本人的機器配置比較差,所以無法使用網上很紅的人臉大資料資料集(如lfw資料集等等),所以我從google圖片下載了一些

基於MATLAB,運用PCA+SVM的特徵方法人臉識別

%% %主程式,程式從此開始 clc,clear npersons=40;%選取40個人的臉 global imgrow; global imgcol; imgrow=112; imgcol=92; %% %讀取訓練資料 disp('讀取訓練資料...') [f_matrix,t

人臉表情識別 深度神經網絡 python實現 簡單模型 fer2013數據集

lib [1] clas nbsp ces ini batch 類別 rep 參考網址:https://sefiks.com/2018/01/01/facial-expression-recognition-with-keras/ 1.數據集介紹及處理: (1)  數據

《基於剪下波變換的人臉表情識別》筆記

【時間】2018.10.16 【題目】《基於剪下波變換的人臉表情識別》筆記 【論文連結】http://www.wanfangdata.com.cn/details/detail.do?_type=degree&id=Y2102266 概述     本文是閱

新手速成---TensorFlow實現jaffe表情識別--準備工作+step1

背景 正如前文講的,博主主要是為了交作業。。。作業三選一,牛津花卉資料集、jaffe表情資料集、股票預測,很顯然我選的表情識別。 JAFFE資料集一共有213張影象.選取了10名日本女學生,每個人做出7種表情.7種表情包括: Angry,Disgust,Fear,Happy,Sad,Su

使用OpenCv實現人臉跟蹤(

簡介 OpenCV是一個基於BSD許可開源發行的跨平臺計算機視覺庫。擁有C++,Python和Java介面,並且支援Windows, Linux, Mac OS, iOS 和 Android系統。實現了影象處理和計算機視覺方面的很多通用演算法。 主要模組以及功能

python資料建模KNN演算法實現手寫體數字識別

      資料建模指的是對現實世界各類資料的抽象組織,建立一一個適合的模型對資料進行處理。在資料分析與挖掘中,我們通常需要根據一-些資料建 立起特定的模型,然後處理。模型的建立需要依賴於演算法, - -般,常見的演算法有分類、聚類、關聯、

Tensorflow入門教程(二十九)人臉表情識別(上)人臉表情資料集-fer2013

------韋訪 20181102 1、概述 好久沒更新tensorflow的教程了,這這段時間一直在學習機器學習的基礎,但是如果想去找工作,沒有一點實際的應用可能就沒那麼容易聊了,所以,做一下人臉表情識別的例子,其實我最終的目的是想做一個疲勞檢測的例子,這裡就先練練手,

人臉表情識別概述(

一、人臉表情識別技術目前主要的應用領域包括人機互動、安全、機器人制造、醫療、通訊和汽車領域等 二、1971年,心理學家Ekman與Friesen的研究最早提出人類有六種主要情感,每種情感以唯一的表情來反映人的一種獨特的心理活動。這六種情感被稱為基本情感,由憤怒(anger

人臉表情識別常用的幾個資料庫

人臉表情識別就是讓計算機識別人臉的各種表情,進而分析表情所代表的情緒,意圖等。人臉表情識別可以用在測謊,醫學輔助診斷,人機互動方面。 與人臉識別相比,人臉表情特徵更加細微,而且受各種因素的干擾也更大

【線性代數】矩陣、向量、行列式、特徵值特徵向量(掌握這些概念篇文章就夠了)

在數學領域中,線性代數是一門十分有魅力的學科,首先,它不難學;其次,它能廣泛應用於現實生活中;另外,在機器學習越來越被重視的現在,線性代數也能算得上是一個優秀程式設計師的基本素養吧? 一、線性代數的入門知識 很多人在大學學習線性代數時,國內

人臉表情識別——定製自己的資料載入方式

背景 將人臉分割成幾部分,送入並行的網路結構。出現的問題是: 使用torchvision.datasets.ImageLoader函式載入資料集後,當使用torch.utils.data.DataLoader進行shuffle後,這幾部分的影象的Label無

深度動態序列人臉表情識別——論文筆記

人臉表情識別分為動態序列識別和靜態圖片識別,本文只與動態序列有關這裡也有一篇推送解析的這篇文章,但是不全,很多提到的文章沒有翻譯,不過只作為概覽的話倒是可以深度學習 + 動態序列人臉表情識別綜述研究背景與意義人臉表情識別已經成為一個人機互動領域的研究熱點,涉及到心理學、統計學

論文分析--《基於深度學習的人臉表情識別演算法研究_宋新慧》

1.摘要:文章中提出的演算法:1)針對靜態的影象:細節感知遷移網路      資料集:CK+;Kaggle2)針對視訊序列:利用多工學習的遞迴神經網路      資料集:I-PFE2.本文工作:1)基於細節感知遷移網路的人臉表情識別:傳統特徵提取方法存在的問題:光照、角度等影

人臉表情識別經典論文

主要是重點研究了四篇人臉表情識別的paper。分別是一篇中文中文文獻:2006年清華大學朱健翔發表在《光電子·鐳射》上面的文章《結合Gabor特徵與Adaboost的人臉表情識別》。三兩篇外文文獻:2014CVPR上面的文章《Facial Expression Recogn

人臉表情識別實驗——fer2013

2018年7月21日22:43:57更新 轉化好的圖片資料集,百度雲分享見文章末尾。 人臉表情識別——fer2013 一、實驗概覽 第一篇文獻中有網路結構圖,但根據我做實驗的情況來看,這篇論文水分較大,達不到論文中所說的分類精度。第二篇

CNN fer2013資料集人臉表情識別及優化(1)

fer2013資料集介紹 fer2013資料集來自於kaggle上的一次人臉表情比賽,資料下載地址為:[https://www.kaggle.com/c/challenges-in-represent