c语言怎么写界面(必备6篇)

个人学习 13 0

c语言怎么写界面 第1篇

在开发阶段,项目遇到了很多问题,包括但不限于算法实现问题、超参数设置问题、激活函数编写问题、损失函数求导问题等。在测试阶段,代码运行速率慢和准确率低成为难点。

由于本项目是在CPU上运行的,暂时没有加入基于CUDA编程的功能,以及激活函数中含有指数部分,故训练时间较长,且随着隐含层层数和神经元个数的增加,训练所需时间会爆炸式增长。

到目前为止,运行时间最长的一次是6层神经网络(即,1层输入层、4层隐含层、1层输出层,本课设并未给出其图像),共训练120轮,隐含层神经元个数依次为485、485、256、256,初始学习率为,每训练10轮,学习率自乘,激活函数使用Sigmoid函数,权重和偏置的初始值均为取值范围为[-1,1]的随机数。该模型从2022年4月29日晚23时开始运行,到次日同时间段,共运行24小时左右。同时,模型准确率较低,仅从第1轮的提升到第120轮的,提升了20个百分点,最后收敛在33%。

当然,在实验过程中,我也多次遇到未知的问题,也学到了很多东西。

一个最明显的提升就是,各种报错见识得多了,知道了处理办法,同时也初步掌握了单步调试等工程师的基础能力。新学到的知识有很多,譬如说,“写入访问权限冲突”问题可能是由数组越界造成的;“Stack Overflow”问题就是栈溢出问题,只要限制内存的调用就可以了;“初始值设定项值太多”则是因为控制神经层层数的宏定义没有及时与隐含层变量匹配上;模型训练完之后的激活值返回出“-nan(ind)”,即“-not a number(indeterminate)”,表示该返回值无法识别且不是数字,可能出现的原因是0做分母、负数开放等等,诸如此类。

在程序与算法方面,我复习了梯度下降法推导等数学模型,首次尝试使用偏底层的C语言而非有包装好的函数的Python语言编写神经网络,同时也学习了用Python语言绘制简单函数图像的方法,对代码的掌控能力大大加强。尤其是C语言中链表、指针和文件的使用,代码逻辑的体现,可谓渐入佳境。在完善项目的过程中,反向传播算法这一机器学习的基础理论也已基本掌握。

在完成报告的过程中,我也巩固了用Excel表格绘制图像、用PPT演示文档绘制示算法意图以及用Word文档撰写实验报告的基本能力,为未来的科研生涯打下基础。

不得不承认的是,模型性能并不是很好,还有改进和提升的空间。但是通过这个项目,我真真实实地学到了很多,还是非常感谢老师的帮助以及自己的努力和进步的。

本人能力有限,还望各路大佬批评、指正。

c语言怎么写界面 第2篇

本文为我本学期的高级语言程序设计课程的课设报告,发出来只是为了记录自己的学习过程,不是发出来给大家抄作业的!!!不是发出来给大家抄作业的!!!不是发出来给大家抄作业的!!!(重要的事情说三遍)

再者说,我改了那么久的参数,写了那么久的课设报告,发出来虽说有想满足自己虚荣心的想法,但是就这样被白嫖党抄袭去,确实不太妥当。

我的代码参考B站某视频(链接:【教 人 工 智 障 认 数 字】纯C语言 手撸 多层感知机+反向传播算法 mnist 数字识别_哔哩哔哩_bilibili),核心部分没怎么改动,但是在其基础上增加了很多注释(好像没啥用,只能说更方便理解),修改了隐含层层数和神经元个数,更改了激活函数等,做了一大堆实验,但是效果都很不好。

原视频中的准确率都是90%左右的,我最高才50%上下。

在知乎写公式和含角标的字母有点麻烦,主要是排版不好看,因此在全文后半段,公式大多数都是从我的课设报告中截的图。

c语言怎么写界面 第3篇

利用多层感知机和反向传播网络,识别MNIST手写数字数据集。每训练10000个数据,就打印一次阶段性实验数据,包括训练轮数、当前数据索引、当前数据标签、各输出层神经元的激活值。每完成一轮训练,打印该轮训练中,测试集在神经网络模型上的准确率。

数据来源是MNIST手写数字数据集,其_有60000份训练集数据和10000份测试集数据。数据集的官网链接是http://st/(已设为超链接)。每份MNIST数据都以二进制文件形式储存,并包括图片(Image)和标签(Label)两部分,图片部分是一张28×28像素的手写数字图片,标签部分是该图片所对应的数字。

由于图片和标签是各自作为一个二进制文件单独存放的,所以共有4份数据文件,即训练集图片、训练集标签、测试集图片和测试集标签。

对于图片文件而言,组成结构为4字节的幻数(此处可理解为一个标识)、4字节的图片张数、4字节的图片高度、4字节的图片宽度以及多个1字节的像素点灰度值。像素值取值为0到255,0和255分别表示纯白和纯黑,且数值越靠近0就越白,越靠近255就越黑。

对于标签文件而言,组成结构为4字节的幻数、4字节的图片张数和多个1字节的图片标签值。标签值取值为0到9,对应0到9的数字。

暂无界面需求。

开发环境:Visual Studio 2022

建议运行环境:Visual Studio 2022

VS项目的资源文件栏中需要附上四份数据文件,数据文件下载地址为http://st/,下载后需按程序中所写内容更改文件名称。

c语言怎么写界面 第4篇

本模块将阐述整个项目的参考资料及测试、调试过程。

初期,本项目参考了很多博客园、CSDN、Github等论坛的文章、代码,以及知乎论坛、BiliBili视频网站等平台的讲解视频,其中帮助最大的是BiliBili视频网站的某个视频(视频链接:https://www.T4y1G7Rw?share_source=copy_web)。

在明确了思路之后,代码初稿很快完工,最初的超参数设置与参考视频中设置一致,即学习率恒为,采用2层隐含层结构,每层50个神经元,随机数设置为[-1, 1]之间的随机数,激活函数使用Sigmoid函数,训练50轮。但是初代模型的性能较差,准确率低于10%。

于是,本项目尝试更改隐含层的神经元个数。多次尝试后发现,虽然准确率有所提升,但一直维持在10%至20%之间,效果不佳。以其中一次实验为例,保持其他参数不变,仅更改隐含层神经元个数为100和50个,记录每轮的准确率结果并绘制折线统计图如下。

可以看出,本轮实验的准确率收敛在上下。

根据参考视频和相关资料,原始的随机数模块公式为

其中,rand( )是C语言标准库中所含的伪随机数生成函数,RAND_MAX则C语言标准库中定义的一个宏,表示rand( )所能返回的最大数值,对于int来说,RAND_MAX的值为32767,对于unsigned int来说,则是65535。

为提高模型的准确率,项目更改了权重ω和偏置b的随机数公式。新的公式参考C语言中生成[n,m]范围内随机数的公式来生成[-1,1]间的随机数。

修改后的模型准确率大幅提升,但是产生了明显的震荡现象。以其中一次实验为例,报错隐含层层数为2,每层神经元个数为50,学习率为,激活函数为Sigmoid函数不变,仅修改随机数公式,训练50轮后得到以下图像。

将实验一和实验二结合,即同时更改隐含层神经元个数为实验一神经元个数并修改随机数公式为实验二公式,得到效果更好的实验三。实验三中,以准确率为纵轴、训练轮数为横轴的折线统计图如下。

在前三种实验方式的基础上,项目新增一层神经层,希望通过增加网络的复杂程度以提高整个系统的鲁棒性。同时,模型通过缩减学习率来缩短梯度下降的步长,放弃速率而追求精度。在进行了多轮实验后,模型的性能再次实现质的飞跃。

训练过程中,出现一个非常有意思的现象,即每层的神经元个数较少的时候,其性能也可能比大量神经元训练效果更好。到目前为止,在所有的数十次实验中,效果最佳的是一个五层神经网络,即1层输入层、3层隐含层、1层输出层。隐含层神经元个数依次为50、16和16,权重向量和偏置的初始值是以实验二公式生成的[-1,1]的随机数,学习率为。该次实验的准确率一度达到且保持上升趋势。训练50轮的实验四图像如下。

在后续的实验中,项目修改了损失函数的公式,将原公式乘以\frac{1}{2},再次进行训练时发现,准确率上升速率剧烈增长,但是实验中前期就出现明显的过拟合现象,即模型在达到较良好的效果之后,过分追求细枝末节上的精确程度,而导致模型参数往尽可能满足训练集的角度上更新,最终逐渐削弱对除训练集之外样本的识别能力的现象。

典型案例是当学习率为,隐含层设为3层,神经元个数分别为100、50和16,且随机数取值-1到1之间,满足实验二公式的时候。当均方差损失函数公式被更改后,进行50轮训练。模型在第1轮的准确率就高于实验四个百分点,更是在第9轮训练时就达到了的准确率,仅比实验四第50轮的准确率低不到个百分点。但是当实验轮数往后推进时,本次实验的准确率开始呈缓慢下降趋势,在第50轮实验时跌破40%。

综合比对模型现状与过拟合原因后,项目尝试在损失函数后增加正则化项,但是效果不佳。保持实验五参数不变,修改学习率为后,模型依旧呈过拟合现象,且准确率不及实验五。在学习率改为的基础上,修改实验五模型的激活函数,由Sigmoid函数改为Elu函数,其余参数不变,训练50轮后出现惊人的现象,即准确率保持不变。考虑到当输入值X\rightarrow\infty之后,有Elu(X)\rightarrow\infty成立,所以对Elu函数的函数值进行归一化处理,使激活值保持在0到1之间。

但遗憾的是,归一化处理并没有从根本上改变模型的缺陷,而是小幅度提高模型准确率后稳定在另一个值上。这在理论上是很难达到的结果。Elu函数处理下的折线统计图见图。

将激活函数设为Tanh函数,删去归一化处理并保持其他参数不变,得到的准确率收敛于10%,更改学习率为,结果不变。修改其它参数,使学习率恒为,3层隐含层神经元个数依次为50、16和16,可得到震荡现象非常明显的神经网络模型。

除此之外,项目还尝试了学习率的动态衰减,即每训练一定轮数,学习率自乘一个0到1之间的小数,以减小届时的步长,达到提高准确率的效果。再增加神经网络层数、调整神经元个数、增加训练轮数等常规方法也经常作为实验步骤。同时,项目亦尝试修改随机数生成公式为基于Box-Muller方法的正态分布随机数生成模型,但可惜的是上述方法均表现不佳。

目前,性能最好的超参数还是如实验四模型所设。

c语言怎么写界面 第5篇

本项目是基于多层感知机和反向传播网络的机器学习项目,目标是实现识别MNIST手写数字数据集。此模块将展示本项目的基本原理以及数学推导过程。

词条上对激活函数的解释是“在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端”。常用的激活函数有Sigmoid函数、Tanh函数、ReLU函数等,本项目依次尝试了Sigmoid函数、Elu函数和Tanh函数作为激活函数的效果,并选择Sigmoid函数作为最终的激活函数。

以下是对几种激活函数的简单介绍。

Sigmoid函数的函数值取值范围为(0,1),多用来做二分类,一般情况下在特征相差比较复杂或是相差不是特别大时效果比较好。但是在反向传播时,Sigmoid函数可能会由于其指数级的运算而出现梯度消失现象,即随着隐含层层数增加,模型准确率不增反减的现象。Sigmoid函数的公式为

Sigmoid(x)=\frac{1}{1 +e^{-x}}

其导数可以用自身表示,即为

\frac{dSigmoid(x)}{dx}=\frac{e^{-x}}{(1+e^{-x})^{2}}=Sigmoid(x)(1-Sigmoid(x))

以下为用Python绘制的Sigmoid函数图像。

提到Elu函数,就不得不说ReLU函数。在训练神经网络的时候,由于ReLU函数会使负值全部变成0,极有可能导致某一神经元的参数全部归零而无法进行后续操作,形成神经元“坏死”的情况。因此,Elu函数在ReLU函数的基础上进行改进,解决了神经元坏死的现象。两种函数的函数表达式和图像如下。

一般情况下,Elu函数的α值都是人为规定的常数值,在本项目中,该值取1。

还有一种常用的激活函数是Tanh函数,即双曲正切函数,是双曲正弦函数和双曲余弦函数的比值。双曲函数是三角函数通过欧拉公式等复指数形式变换得到的另一种基本初等函数。

其函数图像为

对于Tanh函数和Sigmoid函数,还要一条性质,即二者表达式之间的相互转化。转换公式如下。

Tanh(x)=2(Sigmoid(2x))-1

除了激活函数以外,对于整个模型来说,还有一个非常重要的函数,即损失函数。损失函数又名代价函数,往往被用来衡量事件的“风险”或“损失”。在本项目中,损失函数被用以评价模型的准确性。

以上为“梯度下降”词条的部分解释,本项目利用梯度下降法求解最小损失函数。

反向传播算法是非常简单,也是很基础的机器学习算法。

在训练一个神经网络的时候,我们的目的就是使模型中的参数都取到最理想的数值。对于一个简单的神经网络模型,我们可以通过人工计算解得对应参数并在程序的开头由宏定义设置好,以达到最优的效果。但是,神经网络往往是庞大的,有上万成亿个参数,甚至数十亿个参数。本项目计算量不算很大,但参数量也是以万计的。也在这种情况下,人力计算非常低效。因此,本项目选择反向传播算法。反向传播网络分为两大部分,第一是正向传播部分,目标是计算求解出损失函数;第二是反向传播部分,目标是修改模型中的参数,以提高模型性能。

一般情况下,神经网络是由一个输入层、多个隐含层和一个输出层组成的。输入层的神经元数值为Xi(i=1,2,3…),即为输入到神经网络模型中的样本。隐含层数目和每层网络的神经元个数都是人为规定的。通常来说,样本数量越大,隐含层层数就要越多才能保证模型的性能。而每层的神经元个数则会根据构造法、删除法、黄金分割法等有数学理论支撑的计算方法选择出较优的神经元个数。输出层用以输出神经网络的运算结果,该层的神经元个数与项目需求有关。

在正向传播过程中,神经网络通过权重ω和偏置b依次构造前一层每个神经元的激活值与后一层每个神经元初值之间的函数关系,从而计算出后一层神经元的初值,由激活函数加工后作为新的激活值与再下一层神经网络进行运算。

以八个神经元的四层神经网络为例(如图所示)。

该网络共有一个输入层、两个隐含层和一个输出层,除第一层之外,每一层与前一层的神经元之间都有一个权重向量ω和一个偏置b。因此,由X1、X2、ω和b1组成的函数可以计算出Z11的数值。将Z11代入激活函数中,可以求解出该神经元的激活值A11。同理可得A12和A13,再由A12、A13和新的ω、b可以求解出Z21和Z22,代入激活函数得到A21和A22。依次类推,即可得到输出层的结果A31。由于激活函数不一定是线性函数,所以这一过程可能产生非线性的结果,加之以神经网络的复杂性,整个模型也可以有效地处理线性问题之外的其他情况。

在神经网络中,每两个神经元之间的链接方式都呈线性函数关系。以图为例,初值Z的具体数值可以由以权重向量ω和偏置b1作为常量且前一层神经元激活值X1和X2作为变量的线性函数求得。假设激活函数为σ(∙),则激活值A可以Z和σ(∙)表示。

需要注意的是,没有角标的ω均指向量(ω1,ω2)。

在反向传播的过程中,将均方差损失函数的算式完全展开后可以得到关于各层权重和偏置的多元函数。为了求解出这些参数以确定其最佳值,我们需要对所有参数求偏导,即求解损失函数的梯度。

以五个神经元的三层神经网络为例(如图所示)。

如以上例子所述,可通过反向传播算法更新神经网络中的所有参数并再次训练模型。当如此反复进行多次正反向传播后,即可确定效果较好的参数,提高模型的性能,完成预定的目标。

Box-Muller方法

Box-Muller方法是获取服从高斯分布(即正态分布)的随机数的常用方法。其思想是先得到服从均匀分布的随机数再将服从均匀分布的随机数转变为服从正态分布的随机数。该方法的原理和推导过程较为复杂,这里不多赘述,仅列举该方法的表述和公式。

归一化处理

在某论坛对归一化有这样一种解释:“在机器学习领域,往往不同评价指标(即特征向量中的不同特征就是所述的不同评价指标)往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。”

但需要注意的是,归一化和标准化是有区别的,但很多初学者会弄混二者之间的概念。归一化处理后的数据是被严格限制在[0,1]的区间内的,而标准化只对数据的均值和标准差有限制,对数据本身的限制并不大。补充一句,常见的标准化方法是零均值标准化。

常见的归一化方法有均值归一化、线性归一化等,本项目使用的是线性归一化方法。

c语言怎么写界面 第6篇

项目是基于多层感知机和反向传播算法的手写数字识别模型。训练、测试过程均无需用户操作。

请在Windows系统上进行操作。

安装

本项目可下载在设备的任意目录下。

启动

双击打开手写数字识别程序的exe文件。

1、本项目exe程序须与数据集文件放在统一文件夹下;

2、用户请勿随意更改代码内容。

抱歉,评论功能暂时关闭!