从hello world 说程序运行机制

Hello World!的编译过程(C语言) 几乎所有学C语言编程的同学第一个接触的程序都是Hello World!。但是它是怎么由c文件转换为可执行文件的呢? 源文件(helloworld.c)如下:#include <stdio.h>int main() { printf("Hello World!\n"); return 0; }以mac为例,使用命令: gcc -o helloworld helloworld.c 阅读详情

开篇

学习任何一门编程语言,都会从hello world 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的hello world。

然而,对于hello world 这个简单程序的内部运行机制,我相信还有很多人都不是很清楚。
hello world 这些信息是如何通显示器过显示的?
cpu执行的代码和程序中我们写的的代码肯定不一样,她是什么样子的?又是如何从我们写的代码变成cpu能执行的代码的?
程序运行时代码是在什么地方?她们是如何组织的?
程序中的变量存储在什么地方?
函数调用是怎样是现的?
这篇文章将简单的讨论程序的运行机制

开发平台隐藏的过程

每一种语言都有自己的开发平台,我们的程序大多是也都是在这里诞生的。从程序源代码到可执行文件的转化过程其实是分很多步而且是很复杂的,只是而现在的开发平台把所有的这些事情都自己承担了,给我们带来方便的同时她也影藏了大量的实现细节。所以大多程序员只负责编写代码,其它的复杂的转换工作则由开发平台默默完成。
按照我的理解,简单 的说从源代码到可执行文件的过程可分为以下几个阶段:
1、从源代码到机器语言并将产生的机器语言按照一定的规律组织起来。我们暂且称为文件A。
2、把文件A和运行A需要的文件B(如库函数)链接起来,形成文件A+
3、把文件A+装载进入内存,运行文件
(其实如果是看参考书或者其他资料的话可能不止这几步,只是这里为了简化我把它归纳为3步) 
这些事形成可执行文件的关键步骤,缺一不可。现在看到被开发平台“蒙蔽”了吧。下面的部分将拨开迷雾,还你开发平台的真面目。

目标文件

在计算机领域有过一句经典的话:
“any problem in computer science can be sloved by another layer of indirecition”
“计算机科学领域的任何问题都可以通过增加一个中间层来解决”
比如说要实现从A到B的转换,可以先把A转换为文件A+,再把文件A+转换为我们需要的文件B。(其实在波利亚的《how to slove it》里面对这种方法也有叙述。在解题的时候可以通过增加中间层来简化问题)
 
那么从源代码到可执行文件的过程可以这样理解。从源代码到可执行文件也是一样的, 通过(不断的)在他们之间增加中间层,来解决问题。
和上文说的, 先把源程序转化为中间文件A,再把中间文件转化为我们需要的目标文件。
在处理文件的时候就是按照这种思路来的。
 
其实上面说的文件A更专业的说法是:目标文件。她不是可执行程序,需要和其它的目标文件进行链接、装载后才能执行。对于一个源程序, 开发平台首先要做的就是把源程序翻译成机器语言。其中很重要的一部就是编译。相信很多人都知道,就是把源代码翻译成机器语言(其实就是一堆二进制代码)。编译知识很重要,却不是本文的重点,有兴趣的可自行google。
目标文件格式:
现在来看一下上面说的目标文件是如何组织的(也就是存放结构)。
起源:
想象一下如果是你来设计会如何组织这些二进制代码?就像书桌上的物品要分类放置才整洁一样,为了便于管理翻译出来的二进制代码也分类存放,把表示代码的放在一起,表示数据的放在一起。这样,二进制代码就分为了不同的块来存放。这样的一个区域就是被称为段(segment)的东西。
标准:
和计算机科学中的很多东西一样,为了方便人们的交流、程序的兼容等问题。也为这种二进制的存放方式制订了标准,于是COFF(common object file format)就诞生了。现在的windows、Linux、等主流操作系统下的目标文件格式和COFF大同小异,都可以认为是它的变种。
a.out:
a.out是目标文件的默认名字。也就是说,当编译一个文件的时候,如果不对编译后的目标文件重命名,编译后就会产生一个名字为a.out的文件。
 具体的为什么会用这个名字这里就不在深究了。有兴趣的可以自己google。
下面的图可以让你更直观的了解目标文件:

上图是目标文件的典型结构,实际的情况可能会有所差别,但都是在这个基础上衍生出来的。

ELF文件头:即上图中的第一个段。其中的header是目标文件的头部,里面包含了这个目标文件的一些基本信息。如该文件的版本、目标机器型号、程序入口地址等等。

文本段:里面的数据主要是程序中的代码部分。
数据段:程序中的数据部分,比如说变量。
重定位段:
重定位段包括了文本重定位和数据重定位,里面包含了重定位信息。一般来说,代码中都会存在引用了外部的函数,或者变量的情况。既然是引用,那么这些函数、变量并没存在该目标文件内。在使用他们的时候, 就要给出他们的实际地址(这个过程发生在链接的时候)。正是这些重定位表,提供了寻找这些实际地址的信息。理解了上面之后,文本重定位和数据重定位也就不难理解了。 
符号表:符号表包含了源代码中所有的符号信息 。 包括每个变量名、函数名等等。里面记录了每个符号的信息,比如说代码中有“student”这个符号,对应的在符号表中就包括这个符号的信息。包括这个符号所在的段、它的属性(读写权限)等相关信息。
其实符号表最初的来源可以说是在编译的词法分析阶段。在做词法分析的时候,就把代码中的每个符号及其属性都记录在符号表中。
字符串表:和符号表差不多的功能,存放了一些字符串信息。
其中还有一点要说吗的是:目标文件都是以二进制来存储的,它本身就是二进制文件。
现实中的目标文件会比这个模型要复杂些,但是它的思路都是一样的,就是按照类型来存储,再加上一些描述目标文件信息的段和链接中需要的信息。
 

a.out剖分

Hello World
空口无凭,我们现在就来研究一下hello world编译后形成的目标文件,这里用 C 来描述。
简单的hellow world 源码:
/*hello.c*/
#include<stdio.h>
int main()
{
  int a=5;
  printf("hellow world \n");
} 
为了在数据段中也有数据可放,这里增加了“int a=5”。
如果在VC上的话,点击运行便能看到结果。
为了能看清楚内部到底是如何处理的,我们使用GCC来编译。
运行
 gcc hello.c
再看我们的目录下,就多了目标文件a.out。

现在我们想做的是看看a.out里到底有什么,可能有童鞋回想到用vim文本查看,当时我也是这么天真的认为。但a.out是何等东西,怎能这么简单就暴露出来呢 。是的,vim不行。“我们遇到的问题大多是前人就已经遇到并且已经解决的",对,其中有一个很强悍的工具叫做objdump。有了它,我们就能彻底的去了解目标文件的各种细节,当然还有一个叫做readelf也很有用,这个在后面介绍。
这两个工具一般Linux里面都会自带有有,可以自行google
注:这里的代码主要是在Linux下用GCC编译,查看目标文件用的是Objdump、readelf。但是我会把所有的运行结果都上图,所以之前没有接触过Linux的童鞋来看下面的内容也完全没问题哦。我用的是ubuntu,感觉挺好~
下面是a.out的组织结构:(每段的起始地址、、大小等等)
查看目标文件的命令是    objdump -h a.out

就和上文中描述的目标文件的格式一样,可以看出是分类存储的。目标文件被分为了6段。

从左到右,第一列(Idx Name)是段的名字,第二列(Size)是大小 ,VMA为虚拟地址,LMA为物理地址,File off是文件内的偏移。也就是这段相对于段中某一参考(一般是段起始)的距离。最后的Algn是对段属性的说明,暂时不用理会

“text”段:代码段。

“data”段:也就是上面说的数据段,保存了源代码中的数据,一般是以初始化的数据。

“bss”段:也是数据段,存放那些未初始化的数据,因为这些数据还未分配空间,所以单独存放。

“rodata”段:只读数据段,里面存放的数据是只读的。

“cmment”存放的是编译器版本信息。

剩下的两段对我们的讨论没有实际意义,就不再介绍。认为他们包含了一些链接、编译、装在的信息就可。

注:

这里的目标文件格式只是列出实际情况中主要部分。实际情况还有一些表未列出。如果你也在用Linux,可以用objdump -X 列出更详细的段内容。

深入a.out

上面部分通过实例说了目标文件中的典型的段,主要是段的信息,如大小 等相关的属性。

那么这些段里面究竟有些什么东西呢,“text”段里到底存了什么东西,还是用我们的objdump。 

objdump -s a.out   通过-s选项就可以查看目标文件的十六进制格式。

查看结果如下:

如上图所示,列出了各段的十六进制表示形式。可以看出图中共分为两栏,左边的一栏是十六进制的表示, 右边则显示相应的信息。
比较明显的如“rodata”只读数据段中就有 “hello world”。。汗,好像程序里的“hello”打错了,后面多加了一个“w”,截图麻烦,。原谅下哈。 
你也可以查看“hellow world”的ASCII值,对应的十六进制就是里面的内容了。
“comment”上文中说的这个段包含了一些编译器的版本信息,这个段后面的内容就是了:GCC编译器,后面的是版本号。
 
a.out反汇编
 编译的过程总是先把源文先变为汇编形式,再翻译为机器语言。(添加中间层嘛)看了这么多的a.out,再研究一下他的汇编形式是恨必要的
objdump -d a.out可以列出文件的汇编形式。不过这里只列出了主要部分,即main函数部分,其实在main函数执行的开始和main函数执行以后都还有多工作要做。
即初始化函数执行环境以及释放函数占用的空间等。

上面的图中,左边是代码的十六进制形式,左边是汇编形式。对汇编熟悉的童鞋应该能看懂大部分,这里就不在多述。

 
a.out头文件
在介绍目标文件格式的时候,提到过头文件这个概念,里面包含了这个目标文件的一些基本信息。如该文件的版本、目标机器型号、程序入口地址等等。
下图是文件头的形式:
可以用readelf -h 来查看。(下图中查看的是 hello.o,它是源文件hello.c编译但未链接的文件。 这个和查看a.out 大部分是一样的)

d

 图中分为两栏,左边一栏表示的是属性,右边是属性值。第一行常被称为魔数。后面是一连串的数字,其中的具体含义就不多说了,可以自己去google。
接下来的是一些和目标文件相关的信息。由于和我们要讨论的问题关系不大,这里就不展开讨论了。
 
上面是内容用具体的实例说了目标文件内部的组织形式,目标文件只是产生可执行文件过程中的一个中间过程,对于程序是如何运行的还没做讨论,
目标文件是如何转变为可执行文件以及可执行文件是如何执行的将在下面的部分中讨论
 

对链接的简单认识

链接通俗的说就是把几个可执行文件。
如果程序A中引用了文件B中定义的函数,为了A中的函数能正常执行,就需要把B中的函数部分也放在A的源代码中,那么将A和B合并成一个文件的过程就是链接了。
有专门的过程用来链接程序,称为链接器。他将一些输入的目标文件加工后合成一个输出文件。这些目标文件中往往有相互的数据、函数引用。
上文中我们看过了hello world的反汇编形式,是一个还没有经过链接的文件,也就是说当引用外部函数的时候是不知道其地址的:
如下图:

上图中,cal指令就是调用了printf()函数,因为这时候printf()函数并不在这个文件中,所以无法确定它的地址,在十六进制中就用“ff ff ff ”来表示它的地址。等经过链接以后,这个地址就会变为函数的实际地址,应为连接后这个函数已经被加载进入这个文件中了。
链接的分类:
按把A相关的数据或函数合并为一个文件的先后可以把链接分为静态链接和动态链接。
静态链接:
在程序执行之前就完成链接工作。也就是等链接完成后文件才能执行。但是这有一个明显的缺点,比如说库函数。如果文件A 和文件B 都需要用到某个库函数,链接完成后他们连接后的文件中都有这个库函数。当A和B同时执行时,内存中就存在该库函数的两份拷贝,这无疑浪费了存储空间。当规模扩大的时候,这种浪费尤为明显。静态链接还有不容易升级等缺点。为了解决这些问题,现在的很多程序都用动态链接。
动态链接:和静态链接不一样,动态链接是在程序执行的时候才进行链接。也就是当程序加载执行的时候。还是上面的例子 ,如果A和B都用到了库函数Fun(),A和B执行的时候内存中就只需要有Fun()的一个拷贝。
关于链接还有很多知识,以后会用专门的文章来谈。这里就不展开讲了。

对装载的简单解释 

 我们知道,程序要运行是必然要把程序加载到内存中的。在过去的机器里都是把整个程序都加载进入物理内存中,现在一般都采用了虚拟存储机制,即每个进程都有完整的地址空间,给人的感觉好像每个进程都能使用完成的内存。然后由一个内存管理器把虚拟地址映射到实际的物理内存地址。
按照上文的叙述, 程序的地址可以分为虚拟地址和实际地址。虚拟地址即她在她的虚拟内存空间中的地址,物理地址就是她被加载的实际地址。

 在上文中查看段 的时候或许你已经注意到了,由于文件是未链接、未加载的,所以每个段的虚拟地址和物理地址都是0.
加载的过程可以这样理解:先为程序中的各部分分配好虚拟地址,然后再建立虚拟地址到物理地址的映射。其实关键的部分就是虚拟地址到物理地址的映射过程。程序装在完成之后,cpu的程序计数器pc就指向文件中的代码起始位置,然后程序就按顺序执行。
 

小结一下

写这篇文章的目的在于梳理程序运行的机制,在一个可执行文件执行的背后都隐藏了什么。
从源代码到可执行文件通常要经历许多中间步骤,每一个中间步骤都生成一个中间文件。只是现在的集成开发环境都吧这些步骤影藏了,习惯于集成开发环境的我们也就逐渐的忽略了这些重要的技术内幕。这篇文章也只是介绍了一下这个过程的主线而已。其中的每一个细节展开来讲都可足已用一篇文章来论述。
上面写的多是我个人的理解和看法。有不足的地方、还望能不吝赐教。
 
 
 

参看资料:computer systems 《windows内核分析》《程序员的自我修养》

如有转载请注明出处:http://www.cnblogs.com/yanlingyin/

一条鱼~@ 博客园    尹雁铃2012-2-12 

 E-mail:yanlingyin@yeah.net

LangGraph 系列之1 —— hello world 摘要: LangGraph是LangChain团队2023年推出的开源框架,用于简化复杂智能体(Agent)的流程控制。它基于有向图模型,将工作流抽象为节点(处理逻辑)和边(流程流向),支持状态管理、条件分支和人机协作,解决了多轮对话、动态流程等复杂场景的开发难题。通过HelloWorld示例可见,开发者只需定义状态结构、节点函数及流程边,即可实现如消息拼接等任务,无需手动处理底层状态同步。LangGraph凭借其模块化设计,已成为构建工业级智能体的核心工具。 阅读详情

相关推荐

linux进程调度原理

调度程序运行时,要在所有可运行状态的进程中选择最值得运行的进程投入运行。选择进程的依据是什么呢?

从hello world程序认识系统如何运行程序

#include <stdio.h> int main() { printf("hello, world\n"); return 0; } hello 程序的生命周期是从一个源程序(或者说源文件)开始的,即程序员通过编辑器创 建并保存的文本文件,文件名是hello.c。源程序实际上就是一个由值0和1组成的位(又称 为比特)序列,8 个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符,现代计算机系统都使用 ASCII 标准来表示文本字符,只由 AS...

qq_60466569的博客 310

实战指南:从零开始用YOLOv8训练VisDrone无人机检测模型

本文提供了一份详细的实战指南,手把手教你从零开始使用YOLOv8训练一个无人机检测模型。内容涵盖VisDrone数据集下载与格式转换、YAML配置文件编写、模型训练与评估,以及最终的推理部署,旨在帮助开发者快速掌握无人机视角下的目标检测技术。

salt的博客 682

C语言源程序到可执行程序过程

C语言从源码到可执行程序的过程 假设我们有源程序helloworld.c: 1.预处理 命令:gcc -E helloworld.c -ohelloworld.i 作用:将helloworld.c预处理输出到helloworld.i文件 2.编译 命令:gcc -Shelloworld.i -ohelloworld.s 作用:将预处理输出文件helloworld.i编译成helloworld.s文件 3.汇编 命令:gcc -chelloworld.s -ohellowor...

m0_38062470的博客 1453

服务器能效测试工具BenchSEE使用方法简介

BenchSEE是由中国标准化研究院开发的一款针对服务器产品能效测试的基准软件。BenchSEE基准的设计参考了全球众多服务器厂家、芯片厂家、能效认证机构和IT节能领域科研机构的意见,旨在满足服务器市场应用对能效测评的需求。BenchSEE基准负载工具支持的服务器类型包括:机架服务器、刀片服务器多节点服务器和机柜服务器等,服务器可以配的最大外理器个数包括:1P,2P和4P等。测试基准涵盖服务器关键部件:CPU,内存和存储介质三大基础部件。

MQWYY3的博客 4216

保姆级教程:用MediaPipe和BlazePose在Python里实时追踪你的健身动作(附完整代码)

本文提供了一份详细的Python教程,教你如何使用MediaPipe和BlazePose实现实时健身动作追踪。从环境配置、模型选型到实时视频流处理架构设计,再到健身动作量化分析和可视化反馈系统优化,教程涵盖了完整的实现步骤和代码示例,帮助开发者快速构建高效的姿态特征点检测系统。

weixin_42531779的博客 153

源程序到可执行程序的过程

(3)汇编阶段:汇编程序(as)对汇编语言源程序进行汇编,生成一个可重定位目标文件(relocatable object file),以o为扩展名,例如,hello.o是一个可重定位目标文件。它是一种二进制文件(binary file),因为其中的代码已经是机器指令,数据以及其他信息也都是用二进制表示的,所以它是不可读的,即打开显示出来的是乱码。(2)编译阶段:编译程序(ccl)对预处理后的源程序进行编译,生成一个汇编语言源程序文件,以s为扩展名,例如,hello.s是一个汇编语言程序文件。

qq_55126913的博客 1727

IsaacGym四足机器人sim to real全过程详细解析(walk these ways方法)

本文使用强化学习的方法运行到Aliengo机器人上完成从训练到部署的全过程。该方法使用的是GO1机器人提供了完整的sim to real代码和遥控器控制代码,所以我们只需要重新训练和部署健康就可以使用在Aliengo上。该方法使用lcm进行通讯首先程序通过UDP和机器人控制板进行通讯获取机器人状态并下达指令。然后又通过lcm进行机器人状态信息的发布和模型命令的获取。

weixin_44061195的博客 2万+

从Hello World说程序运行机制

开篇 学习任何一门编程语言,都会从hello world 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的hello world。然而,对于hello world 这个简单程序的内部运行机制,我相信还有很多人都不是很清楚。 hello world 这些信息是如何通显示...

124

从FER2013到AffectNet:表情识别数据集十年演进史与你的项目选型攻略

本文回顾了从FER2013到AffectNet等主流人脸表情识别数据集的十年演进历程,详细分析了各数据集的特点、适用场景及技术突破。针对不同项目需求,提供了从移动端应用到高精度研究的选型策略,特别强调AffectNet在现代FER项目中的核心价值,并给出混合数据集构建的实战方案。

weixin_26808439的博客 521

手把手教您同花顺如何设置大盘分时均价线

本文将手把手教你如何在同花顺PC端开启大盘指数分时图📈

XiaoqiangClub的博客 4380

从 Hello World 说程序运行机制

开篇学习任何一门编程语言,都会从hello world 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的hello world。然而,对于hello ...

308

手把手教你学simulink(28.2)--四旋翼无人机景示例:基于自抗扰控制(ADRC)的无人机姿态稳定系统

通过上述代码实现,您可以逐步创建和搭建一个基于自抗扰控制的无人机姿态稳定系统。该系统能够实时估计和补偿外部扰动及模型不确定性,确保无人机姿态稳定。自抗扰控制具有较强的鲁棒性和适应性,能够在存在不确定性和扰动的情况下提供快速且精确的控制性能。Simulink提供了强大的建模和仿真工具,使得控制系统工程师能够快速构建复杂的控制算法,并将其应用于实际工程中。无人机动力学建模:建立无人机的六自由度(6-DOF)动力学模型,包括位置、速度、姿态角和角速度。自抗扰控制器设计。

MHD0815的博客 499

转载:从hello world 说程序运行机制

转自 http://www.cnblogs.com/yanlingyin/archive/2012/03/05/2379199.html  开篇 学习任何一门编程语言,都会从hello world 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的hello world。 然而,对于hello world 这个简单程序的内部运行机制,我相信还有很多人都不是很清楚。 h

liyongbao1988的专栏 651

【DeepSeek R1构建本地RAG知识库】数据结构化清洗-知识图谱制作、使用、dify集成

本文探讨了在构建本地RAG(Retrieval-Augmented Generation)系统时,如何通过引入知识图谱来增强系统的知识理解能力。传统的向量数据库和嵌入模型虽然能处理语义匹配,但无法有效捕捉知识间的关联性。知识图谱通过“实体-关系-属性”的结构化表示,能够更好地支持推理、推荐和多跳问答等高级功能。文章详细介绍了知识图谱的基本概念、制作思路,以及如何使用Neo4j图数据库进行知识图谱的构建和查询。通过实例展示了从PDF文件解析到知识图谱入库的全过程,强调了知识图谱在提升RAG系统性能中的重要作用

少说,多做 561

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Rust 的Hello World

之前介绍了Rust的安装,那么,我们编写第一个Rust程序。遵循编程语言学习的传统,我们将编写一个在屏幕上打印"Hello, world!"的小程序!

Humbunklung的专栏 1762

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java程序运行机制Hello,World

Java程序运行机制 1.编译型:操作系统 C C++ 2.解释型:网页 Java 程序运行机制 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lnd01ZpE-1622941878487)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20210516201150273.png)] Hello,World public class Hello { public static void m

qq_45343541的博客 169

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

上一篇: CPU流水线的探秘之旅
下一篇: 视觉直观感受 7 种常用的排序算法
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值