BP神经网络及其在教学质量评价中 的应用

本文学习笔记是自己的理解,如有错误的地方,请大家指正批评,共同进步,谢谢!

之前的教学质量评价,只是通过对教学指标的简单处理,如求平均值或人为的给出各指标的权值来加权求和,其评价结果带有很大主观性。利用BP神经网络建立教学质量评价系统的模型,通过调查分析得到教学评价指标,将其标量化成确定的数据作为其输入,用BP神经网络训练后作为实际输出,将之前得到的教学效果作为期望输出。比较期望输出与实际输出的误差。当误差达到期望的最小值时,认为训练成功。训练成功后可以得到比较准确的权值和阈值,用训练成功后的网络处理另一组新得到的教学评价指标,得到教学质量评价结果。该方法用于教学质量评价中,既克服了专家在评价过程中的主观因素,又得到了满意的评价结果,具有广泛的适用性。

1、BP神经网络介绍

BP神经网络是加州大学的Rumelhart和Mcclelland提出的一种人工神经网络学习算法,是一种按照误差逆向传播算法训练的神经网络。其学习规则为:使用梯度下降法,通过误差反向传播不断调整网络的权值和阈值,使网络的误差平方和最小。从本质上说,这是一类由大量信息处理单元通过广泛联结而构成的动态信息处理系统。

BP神经网络包括信息的正向传播和误差的反向传播两个过程。信息的正向传播:将教学评价指标各数据通过网络的输入层输入网络,

入层反传,周而复始,直至误差达到期望最小,认为网络训练成功。之后就可以利用训练好的网络处理新的教学质量指标,得到准确的教学质量评价结果。

BP神经网络逻辑结构图如下:

2、BP神经网络的教学质量评价模型应用

教学评价指标(每个指标打分范围0-10):x1:为人师表, 以自身行为影响学生;x2:作业适量、批改认真、耐心答疑;x3:激发学生兴趣、启发创新思维;x4:教师衣着、言谈举止及精神状态;x5:教学态度与教学技巧;x6:讲授重点突出、条理清晰;x7:能够把复杂问题清楚地表达;x8:引导学生探讨、解决问题;x9:注重教学互动、师生交流;x10:充分利用现代化教学手段。

(1) 输入层神经元个数的确定

根据我们调查中的的教学评价指标, 一共有10个指标, 可将这10个指标作为模型的输入神经元, 所以输入层神经元个数n= 10.

(2) 输出层神经元个数的确定

我们将评价结果作为网络的输出, 输出层个数m=1

(3) 网络隐含层数的确定

隐含层可以是一层也可以是多层,根据之前的理论证明,在对教学质量评价模型中, 我们选择隐含层为1层

(4) 隐含层神经元个数的确定

一般情况下, 隐含层神经元个数是根据网络收敛性能的好坏来确定的。隐含层神经元个数过少可能训练不出网络或者网络不够强壮, 但隐含层神经元个数过多, 又会使学习时间过长, 误差也不一定最佳, 因此存在一个如何确定合适的隐含层神经元个数的问题。一般可以采用试凑法, 通过比较网络输出值与期望输出值之间的误差,来确定隐层神经元个数。在本文中我们根据相关经验初定隐含层神经元个数s=8.

之后将所有评价指标数据及之前得到的比较完善的教学质量评价结果输入网络,对网络进行训练。我们取学习率=0.5,定误差最小值为=0.00001。训练结束后,得到合适的权值阈值,用此权值阈值对之后再调查得到的评价指标进行处理,得到合适的教学质量评价结果。

3、评价结果分析

调查问卷得到的教学指标打分,如下:

将如上8个样本的10个教学指标保存在txt文档中,把数据读入网络的输入层,经过5116次网络训练达到设定好的误差最小值,得到修改好的权值和阈值。并用训练好的网络处理新数据(5.5 7.5 4 5 8 4.5 7 8 8.5 6),得到实际输出教学质量(6.901607)。

4、结论

BP神经网络模型由于其具有高度非线性函数映射功能及自适应、自学习能力,可以有效克服传统教学质量评价方法的缺陷,降低传统评价方法中指标权重确定的人为影响因素,而且精度较高。经过上述训练,我们发现BP神经网络模型的输出值与真实值之间的误差比较小,性能完全可以满足实际应用的要求。另外,网络的输出精度取决于输入的训练样本的数量,训练样本的数量越多,其输出的教学效果评估值就越接近于实际的评估值。

总之, 运用BP神经网络建立教学质量评价模型, 可以为各学校教学管理部门寻求科学的教学质量评估解决方案提供有益的参考。

5、神经网络的C语言代码实现及详细解释

// bp.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#include "conio.h"
#include "time.h"
#define X 8 //样本个数
#define X1 10 //输入层神经元个数
#define X2 8 //隐层神经元个数
#define X3 1 //输出层神经元个数
#define Y 20 //权值调整次数
double w1[X2][X1];//输入层到隐层的权值
double w2[X3][X2];//隐层到输出层的权值
double y[X2];//输入层到隐层的阈值
double y2[X3];//隐层到输出层的阈值
double p[X1];//样本的再次赋值,以便后面方便引用
double t[X3];//样本的再次赋值,以便后面方便引用
double t1[X3];
double yci[X2];//隐层的输入值
double yco[X2];//隐层的输出值
double sci[X3];//输出层的输入值
double sco[X3];//输出层的输出值
double em[X];//第k个样本的总误差
double dao1[X3];//利用梯度下降法对输出层计算输出值的求导
double dao2[X2];//利用梯度下降法对隐层计算输出值的求导:dao2=求导(yco)*求和(dao1*误差e*权值w2)
double zsco[X3];
double l1;//隐层到输出层的学习因子
double l2;//输入层到隐层的学习因子
char c=' ';
FILE *fp;
//存放样本数据的结构体
struct xuexishuju
{
	double shuru[X1];//输入神经元的数据
	double qiwangshuchu[X3];//期望输出的数据
}xuexishuju[X];
//存放每次调整的权值的结构体
struct quanzhi
{
	double qz1[X2][X1];//输入层到隐层的权值
	double qz2[X3][X2];//隐层到输出层的权值
}quanzhi[Y];
struct yuzhi
{
	double yz1[X2];//输入层到隐层的阈值
	double yz2[X3];//隐层到输出层的阈值
}yuzhi[Y];
//从样本中获取数据
int huoqushuju()
{
	int i=0;
	int j=0;
	int k=0;
	double data;
	int m=0;//X值变化时,m,n对应的程序也要变化
	int n=0;
	//if(fp=fopen("D:\\BP Neural Network\\输入数据.txt","+")==NULL)//打开文件//不能放在if里面???
	//{
	//	printf("对不起!文件打不开!");
	//	getch();//屏幕暂停,等待键盘时间
	//	exit(1);
	//}
	fp=fopen("输入数据.txt","r");
	if(fp==NULL)//打开文件
	{
		printf("对不起!文件打不开!");
		getch();//屏幕暂停,等待键盘时间
		exit(1);
	}
	while(fscanf(fp,"%lf",&data)!=EOF)//把数据一次传给data
	{
		j++;
		if(j<=(X*X1))
		{
			if(i<X1)
			{
				xuexishuju[k].shuru[i]=data;
			}
			if(k==(X-1)&&i==(X1-1))
			{
				k=0;
				i=-1;
			}
			if(i==(X1-1))
			{
				k++;
				i=-1;
			}
		}
		else if((j>X*X1)&&(j<=(X*X1+X*X3)))
		{
			if(i<X3)
			{
				xuexishuju[k].qiwangshuchu[i]=data;
			}
			if(k==(X-1)&&i==(X3-1))
			{
				k=0;
				i=-1;
			}
			if(i==(X3-1))
			{
				k++;
				i=-1;
			}
		}
		i++;
	}
	fclose(fp);
	printf("\n样本数据输入成功!");
	printf("\n样本数据如下:");
	for(k=0;k<X;k++)
	{
		for(i=0;i<X1;i++)
		{
			printf("\n学习数据[%d]的输入数据[%d]=%f",k,i,xuexishuju[k].shuru[i]);
		}
		for(j=0;j<X3;j++)
		{
			printf("\n学习数据[%d]的期望数据[%d]=%f",k,j,xuexishuju[k].qiwangshuchu[j]);
		}
	}
	printf("\n开始计算...\n");
	getch();
	return 1;
}

//初始化首次的权值、阈值
int chushihuaquanyu()
{
	int a1,a2,a3,a4,a5,a6;
	//开始时输入层到隐层的权值的初始化
	for(a1=0;a1<X2;a1++)
	{
		for(a2=0;a2<X1;a2++)
		{
			w1[a1][a2]=(double)((rand()/32767.0)*2-1);//用随机函数产生-1~1之间的随机数据,作为初始权值
			printf("输入层到隐层初始权值w1[%d][%d]=%f\n",a1,a2,w1[a1][a2]);
		}
	}
	//开始时隐层到输出层的权值的初始化
	for(a3=0;a3<X3;a3++)
	{
		for(a4=0;a4<X2;a4++)
		{
			w2[a3][a4]=(double)((rand()/32767.0)*2-1);//用随机函数产生-1~1之间的随机数据,作为初始权值
			printf("隐层到输出层初始权值w2[%d][%d]=%f\n",a3,a4,w2[a3][a4]);
		}
	}
	//开始时输入层到隐层的阈值的初始化
	for(a5=0;a5<X2;a5++)
	{
		y[a5]=(double)((rand()/32767.0)*2-1);//用随机函数产生-1~1之间的随机数据,作为初始阈值
		printf("输入层到隐层初始阈值y[%d]=%f\n",a5,y[a5]);
	}
	//开始时隐层到输出层的阈值的初始化
	for(a6=0;a6<X3;a6++)
	{
		y2[a6]=(double)((rand()/32767.0)*2-1);//用随机函数产生-1~1之间的随机数据,作为初始阈值
		printf("隐层到输出层初始阈值y2[%d]=%f\n",a6,y2[a6]);
	}
	return 1;
}

//样本的再次赋值,以便后面方便引用
int zaishurup(int k)
{
	for(int i=0;i<X1;i++)
	{
		p[i]=xuexishuju[k].shuru[i];
		//printf("p[%d]=%f\n",i,p[i]);
	}
	return 1;
}
int zaishurut(int k)
{
	for(int j=0;j<X3;j++)
	{
		t1[j]=xuexishuju[k].qiwangshuchu[j];
		t[j]=1.0/(1.0+exp(-t1[j]));
		//printf("t[%d]=%f\n",j,t[j]);
	}
	return 1;
}

//输入层到隐层的加权求和
int ru_yin_quan()
{
	double sum;
	for(int j=0;j<X2;j++)
	{
		sum=0.0;
		for(int i=0;i<X1;i++)
		{
			sum+=w1[j][i]*p[i];//输入层到隐层的加权求和
		}
		yci[j]=sum-y[j];//隐层的输入值
		yco[j]=1.0/(1.0+exp(-yci[j]));//隐层的输出值,用sigmod函数进行处理的
	}
	return 1;
}
//隐层到输出层的加权求和
int yin_chu_quan()
{
	double sum;
	for(int j=0;j<X3;j++)
	{
		sum=0.0;
		for(int i=0;i<X2;i++)
		{
			sum+=w2[j][i]*yci[i];//隐层到输出层的加权求和
		}
		sci[j]=sum-y2[j];//输出层的输入值
		sco[j]=1.0/(1.0+exp(-sci[j]));//输出层的输出值,用sigmod函数进行处理的
	}
	return 1;
}

//求总误差
int wc_chu_yin(int k)
{
	double e[X3];
	double fange=0.0;
	for(int j=0;j<X3;j++)
	{
		e[j]=t[j]-sco[j];
		fange+=(e[j])*(e[j]);
		dao1[j]=sco[j]*(1-sco[j])*e[j];//求导
		em[k]=fange/2;
	}
	return 1;
}
int wc_yin_ru()
{
	double summ;
	for(int i=0;i<X2;i++)
	{
		summ=0.0;
		for(int j=0;j<X3;j++)
		{
			summ+=dao1[j]*w2[j][i];
		}
		dao2[i]=summ*yco[i]*(1-yco[i]);
	}
	return 1;
}

//将每次变化后的权值赋值到结构体中,以便下次学习算法的调用
int baocunw(int k)
{
	for(int i=0;i<X2;i++)
	{
		for(int j=0;j<X1;j++)
		{
			quanzhi[k].qz1[i][j]=w1[i][j];
		}
	}
	for(int ii=0;ii<X3;ii++)
	{
		for(int jj=0;jj<X2;jj++)
		{
			quanzhi[k].qz2[ii][jj]=w2[ii][jj];
		}
	}
	return 1;
}
//将每次变化后的阈值赋值到结构体中,以便下次学习算法的调用
int baocuny(int k)
{
	for(int i=0;i<X2;i++)
	{
		yuzhi[k].yz1[i]=y[i];
	}
	for(int j=0;j<X3;j++)
	{
		yuzhi[k].yz2[j]=y2[j];
	}
	return 1;
}

//求变化后的输出层到隐层的新权值、阈值
int xin_chu_yin()
{
	for(int k=0;k<X3;k++)
	{
		for(int j=0;j<X2;j++)
		{
			w2[k][j]=w2[k][j]-l1*dao1[k]*yco[j];//变化后的新权值
		}
		y2[k]=y2[k]-l1*dao1[k];//变化后的新阈值
	}
	return 1;
}
//求变化后的隐层到输入层的新权值、阈值
int xin_yin_ru()
{
	for(int j=0;j<X2;j++)
	{
		for(int i=0;i<X1;i++)
		{
			w1[j][i]=w2[j][i]-l2*dao2[j]*p[i];
		}
		y[j]=y[j]-l2*dao2[j];
	}
	return 1;
}

//保存最后一次正确的权值阈值到txt文件
void baocunquan()
{
	FILE *fp;
	fp=fopen("保存权值.txt","w");
	if(fp==NULL)
	{
		printf("对不起!文件打不开!\n");
		getch();
		exit(1);
	}
	fprintf(fp,"保存的最后一次正确的权值数据如下:\n");
	fprintf(fp,"输入层到隐层的权值数据:\n");
	for(int i=0;i<X2;i++)
	{
		for(int j=0;j<X1;j++)
		{
			fprintf(fp,"w1[%d][%d]=%f\n",i,j,w1[i][j]);
		}
	}
	fprintf(fp,"\n");
	fprintf(fp,"隐层到输出层的权值数据:\n");
	for(int ii=0;ii<X3;ii++)
	{
		for(int jj=0;jj<X2;jj++)
		{
			fprintf(fp,"w2[%d][%d]=%f\n",ii,jj,w2[ii][jj]);
		}
	}
	fprintf(fp,"\n");
	fclose(fp);
	printf("最后一次权值保存成功!\n");
	getch();
}
void baocunyu()
{
	FILE *fp;
	fp=fopen("保存阈值.txt","w");
	if(fp==NULL)
	{
		printf("对不起!文件打不开!\n");
		getch();
		exit(1);
	}
	fprintf(fp,"保存的最后一次正确的阈值数据如下:\n");
	fprintf(fp,"输入层到隐层的阈值值数据:\n");
	for(int i=0;i<X2;i++)
	{
		fprintf(fp,"y[%d]=%f\n",i,y[i]);
	}
	fprintf(fp,"\n");
	fprintf(fp,"隐层到输出层的阈值数据:\n");
	for(int j=0;j<X3;j++)
	{
		fprintf(fp,"y2[%d]=%f\n",j,y2[j]);
	}
	fprintf(fp,"\n");
	fclose(fp);
	printf("最后一次阈值保存成功!\n");
	getch();
}
void main()
{
	double wc1=0.00001;//设定好的误差最大值
	double wc2;//计算实际误差
	int s1=20000;//设定好的误差学习次数最大值
	int s2=0;//实际误差学习次数
	l1=0.5;//给学习因子赋个值
	l2=0.5;
	huoqushuju();//从样本中获取数据
	chushihuaquanyu();//初始化首次的权值、阈值(利用随机函数产生)
	do
	{
		int k;
		++s2;
		wc2=0;
		for(k=0;k<X;k++)
		{
			zaishurup(k);//样本的再次赋值
			zaishurut(k);
			ru_yin_quan();//输入层到隐层的加权求和
			yin_chu_quan();//隐层到输出层的加权求和
			wc_chu_yin(k);//求总误差
			wc_yin_ru();
			baocunw(k);//将每次变化后的权值赋值到结构体中,以便下次学习算法的调用
			baocuny(k);//将每次变化后的阈值赋值到结构体中,以便下次学习算法的调用
			xin_chu_yin();//求变化后的输出层到隐层的新权值、阈值
			xin_yin_ru();//求变化后的隐层到输入层的新权值、阈值
			wc2+=em[k];//把m个样本的总误差加起来

		}
		printf("第%d次计算误差=%f\t",s2,wc2);
		printf("设定误差=%f\n",wc1);
		if(s2>s1)
		{
			printf("计算次数已经超过20000次,敲任意键退出循环!\n");
			getch();
			break;
		}
	}while(wc2>wc1);
	printf("一共训练了%d次!\n",s2);
	baocunquan();//保存最后一次正确的权值到txt文件
	baocunyu();//保存最后一次正确的阈值到txt文件
	printf("神经网络已经训练好\n");
	printf("请利用训练好的网络的权值和阈值对新一组教学指标数据进行求解!\n");
	printf("请输入新一组教学指标数据:\n");
	double sc[X1];
	for(int a=0;a<X1;a++)
	{
		scanf("%lf",&sc[a]);
	}
	double sum1,sum2;
	for(int j=0;j<X2;j++)
	{
		sum1=0.0;
		for(int i=0;i<X1;i++)
		{
			sum1+=w1[j][i]*sc[i];//输入层到隐层的加权求和
		}
		yci[j]=sum1-y[j];//隐层的输入值
		yco[j]=1.0/(1.0+exp(-yci[j]));//隐层的输出值,用sigmod函数进行处理的
	}
	for(int jj=0;jj<X3;jj++)
	{
		sum2=0.0;
		for(int ii=0;ii<X2;ii++)
		{
			sum2+=w2[jj][ii]*yci[ii];//隐层到输出层的加权求和
		}
		sci[jj]=sum2-y2[jj];//输出层的输入值
		sco[jj]=1.0/(1.0+exp(-sci[jj]));//输出层的输出值,用sigmod函数进行处理的
	}
	for(int b=0;b<X3;b++)
	{
		zsco[b]=log(sco[b])-log(1-sco[b])-2;
		printf("新指标数据评价得到的教学质量结果:%f\n",zsco[b]);
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-10 00:59:16

BP神经网络及其在教学质量评价中 的应用的相关文章

关于‘基于UML的教学质量评价系统建模研究’随笔

?? 我认为关于教学质量评价最重要的就是调查过程中应该要有私密性,这才使调查具有真实性.在本校的这几年中,本人也曾使用过教学质量评价系统,所以在看文献之前我也有了对这个系统最基本的看法,那就是要设立两个角色:学生和后台管理员.看了这篇文献以后,我觉得我对这个系统的看法基本上也没有太大的变化.只不过是文献中实现的功能好像是比我想象中的多了那么一点. 其实文献中主要将系统分为了三个模块:用户注册模块,评价模块以及管理模块.在我个人看来,用户注册模块是一个多余的东西.因为评价教师的教学质量只能是本校的

Matlab的BP神经网络工具箱及其在函数逼近中的应用

1.神经网络工具箱概述 Matlab神经网络工具箱几乎包含了现有神经网络的最新成果,神经网络工具箱模型包括感知器.线性网络.BP网络.径向基函数网络.竞争型神经网络.自组织网络和学习向量量化网络.反馈网络.本文只介绍BP神经网络工具箱. 2.BP神经网络工具箱介绍 BP神经网络学习规则是不断地调整神经网络的权值和偏值,使得网络输出的均方误差和最小.下面是关于一些BP神经网络的创建和训练的名称: (1)newff:创建一前馈BP网络(隐含层只有一层) (2)newcf:创建一多层前馈BP网络(隐含

继续Jsoup 正方教务系统的教学质量评价一键好评

又到了每次给众多学科的老师评价了,但是每位老师评价的内容项有20多个,还得一个一个手动选择,所以懒人方法就此想做一个一键好评的功能了. 续上次用jsoup HttpClient等可以正常登陆教务系统,那么就可以继续下面的了 首先还是得抓包分析 看到有几门科目需要评价的,可以提前分析出来,保存起来, 一.直接web网页分析... <a href="xsjxpj.aspx?xkkh=(2013-2014-2)-05b31067-0311-1&xh=2011125127&gnmk

详细MATLAB 中BP神经网络算法的实现

MATLAB 中BP神经网络算法的实现 BP神经网络算法提供了一种普遍并且实用的方法从样例中学习值为实数.离散值或者向量的函数,这里就简单介绍一下如何用MATLAB编程实现该算法. 具体步骤 这里以一个普遍实用的简单案例为例子进行编程的说明. 假设一组x1,x2,x3的值对应一个y值,有2000组这样的数字,我们选择其中1900组x1,x2,x3和y作为样本,其余100组x1,x2,x3作为测试数据来验证.   首先需要读取这些数据,并把数据赋值给input 和 output . 我是把数据存储

BP神经网络基本原理

2.1 BP神经网络基本原理 BP网络模型处理信息的基本原理是:输入信号Xi通过中间节点(隐层点)作用于输出节点,经过非线形变换,产生输出信号Yk,网络训练的每一个样本包含输入向量X和期望输出量t,网络输出值Y与期望输出值t之间的偏差,通过调整输入节点与隐层节点的联接强度取值Wij和隐层节点与输出节点之间的联接强度Tjk以及阈值,使误差沿梯度方向下降,经过重复学习训练,确定与最小误差相相应的网络參数(权值和阈值),训练即告停止.此时经过训练的神经网络即能对相似样本的输入信息,自行处理输出误差最小

学习日记(2.19 BP神经网络完整代码解读)

BP网络实现手写数字识别代码解读 1.添加偏置 #添加偏置 temp=np.ones([X.shape[0],X.shape[1]+1]) temp[:,0:-1]=X X=temp np.ones()函数 numpy.ones()函数的功能是返回一个全都是1的N维数组,其中shape(用来指定返回数组的大小).dtype(数组元素的类型).order(是否以内存中的C或Fortran连续(行或列)顺序存储多维数据).后两个参数都是可选的,一般只需设定第一个参数. shape[]的功能是: 0查

BP神经网络

BP 神经网络中的 BP 为 Back  Propagation 的简写,最早它是由Rumelhart.McCelland等科学家于 1986 年提出来的,Rumelhart 并在Nature 上发表了一篇非常著名的文章 <Learning representations by back-propagating errors> .随着时代的迁移,BP神经网络理论不断的得到改进.更新,现在无疑已成为了应用最为广泛的神经网络模型之一.让我们一起来探索下 BP神经网络最初的 基本模型和概念! 从神经

【转载】BP神经网络

原文地址:http://blog.csdn.net/acdreamers/article/details/44657439 今天来讲BP神经网络,神经网络在机器学习中应用比较广泛,比如函数逼近,模式识别,分类,数据压缩,数据 挖掘等领域.接下来介绍BP神经网络的原理及实现. Contents   1. BP神经网络的认识   2. 隐含层的选取   3. 正向传递子过程   4. 反向传递子过程   5. BP神经网络的注意点   6. BP神经网络的C++实现 1. BP神经网络的认识    

C#实现的bp神经网络并应用于综合评价

由于课程设计选的题目是基于神经网络的综合评价,利用暑假时间用C#实现的bp神经网络.其中用到的_Matrix类是C#实现的矩阵类http://blog.csdn.net/lanqiuchaoren/article/details/37738665.此bp神经网络包含1个隐藏层,其中输入层,隐藏层,输出层个数都可以根据需要更改. 具体bp神经网络代码如下 BP类: using Matrix_Mul; using Excel = Microsoft.Office.Interop.Excel; usi