簡單感知器模型解決簡單真值表問題

實驗四 簡單感知器模型

一、實驗目的

1. 掌握簡單感知器模型的基本原理。

2. 複習VBVC的基本概念、基本語法和編程方法,並熟練使用VBVC編寫簡單感知器模型程序。

二、實驗設備

微機

三、實驗原理

簡單感知器模型的基本原理:將樣本矢量X輸入到感知器中,得到實際輸出y,再用y與期望輸出d的差來修正下一步的權值。

感知器中神經元定義如下: 

感知器的連接權定義爲可變化的,感知器的訓練(學習)是通過監督學習過程來實現的。簡單感知器引入的學習算法稱爲誤差學習算法,該算法步驟如下:

①選擇一組初始權值wi(0)

②計算輸入樣本Xj所對應的實際輸出y(t)期望輸出dj的誤差dj=|dj-y(t)|;

③如果dj小於閾值T1,轉第⑤步;否則繼續;

④更新權值:。式中,wi(t)是第t步時神經元間的連接權,閾值可視爲輸入恆爲-1的一個權值;η稱爲學習步長,是區間(0, 1)上的一個數,它的取值與訓練速度和w收斂的穩定性有關,η可以是常數,但爲了改進收斂速度,也可以採用變步長。

                    

式中,a是一個正的常數。

⑤若所有樣本都學習完成,計算所有樣本誤差之和,如果E小於閾值T2,學習結束;否則,轉到第②步。

四、預習要求

1. 認真閱讀教材中簡單感知器模型的基本原理。

2. 複習VBVC的基本概念、基本語法和編程方法。

五、實驗內容及步驟

1. 上機編寫程序,在簡單感知器上,,用誤差學習算法實現真值表。

x1

x2

y=x1Ùx2

y=x1Úx2

y=Øx1

0

0

0

0

1

0

1

0

1

1

1

0

0

1

0

1

1

1

1

0

2. 調試程序。

3. 根據實驗結果,寫實驗報告。


實驗代碼::::::::::::::

#include <stdio.h>

int x[5][3]; //輸入數組
int y[5]; //期望輸出
double w[5][3]; //權值
double n_la = 0.1  ;//步長
const int  a_la = 1;//固定正常數
const double DELTA_T1 = 0.0;//總誤差閥值
const double DELTA_T2 = 0.0;//小計算閥值

void intit()
{//初始化真值表輸入
	int i;
	for(i=0; i<4; i++)
		x[i][0] = -1;//第一項都爲-1
	x[0][1] = 0; x[0][2] = 0;
	x[1][1] = 0; x[1][2] = 1;
	x[2][1] = 1; x[2][2] = 0;
	x[3][1] = 1; x[3][2] = 1;
	//輸入期望值	
	printf("請輸入4個期望輸入\n");
	for(i=0; i<4; i++)
		scanf("%d", &y[i]);
	//初始化權值
	w[0][0]=0.5;  w[0][1]=0; w[0][2]=0;
}
double my_fabs(double temp)
{//取絕對值函數
	if(temp < 0)
		return -temp;
	return temp;
}
int sgn(double temp)
{//f函數
	if(temp >= 0)
		return 1;
	return 0;
}
void sa()
{//主要實現函數
	double  sum, delta_sum, yk, yk_temp;
	int i,  k;
	while(1)
	{
		delta_sum=0; //記錄總誤差
		for(k=0; k<4; k++)
		{
			for(i=0, sum=0; i<3; i++)
				sum += w[k][i]*x[k][i];
			n_la = 0.5*(my_fabs(sum) + a_la);//計算變步長
			yk = sgn(sum);
			if(my_fabs(y[k]- yk)<DELTA_T2) 
			{//期望和實際相等
				yk_temp = 0;
			}
			else
			{//期望和實際不相等
			delta_sum+=my_fabs(y[k]-yk);
			yk_temp = n_la * (y[k]-yk);
			}
			if(k < 3)
			{//向後更新
				for(i=0; i<3; i++)	
				{
					w[k+1][i] = yk_temp*x[k][i] + w[k][i];
				}
			}
			else
			{//輪到最後向第一個更新
				for(i=0; i<3; i++)	
				{
					w[0][i] = yk_temp*x[k][i] + w[k][i];
				}
			}
		}
		if(delta_sum <= DELTA_T1)
			break;
	}
	
}
void output()
{//輸出權值
	int i;
	printf("輸出一下權值先\n");
	for(i=0; i<3; i++) 
		printf("w[%d]=%.2lf  ",i,w[0][i]);
	printf("\n");
}
void test()
{//測試一下權值
	int i;
	int a[3];
	printf("測試輸入x1,x2   ");
	a[0] = -1;
	double ys=0;
	scanf("%d%d", &a[1], &a[2]);
	for(i=0; i<3; i++)
		ys += w[0][i]*a[i]; 
	ys = sgn(ys);
	printf("測試出y=%0.lf\n", ys);
	
}
int main()
{
	int i, j;
	for(i=0; i<3; i++)
	{//三種總情況
		intit();
		sa();
		output();
		for(j=0; j<4; j++)//四種輸入情況
			test();
	}
	return 0;
}




發佈了21 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章