Linux内核模块使用浮点float double运算的方法

内核中如何进行浮点数运算 第一章 内核进行浮点运算的条件 现代处理器硬件已经支持浮点运算, 而且作为一个组件对待, 可选配, 根据需求和方案选型处理器时评估是否需要硬件支持。在STM系列浮点硬件单元叫做FPU(float process unit),ARM中归属协处理器。 如果要使用硬件浮点的话, 需要满足三个条件: 硬件要有浮点运算单元-------------通过测试代码运行计算结果正常,推测mt6739是支持的 内核要配置使能硬件浮点(主要设置协处理器)-------------看看对应的宏有没有float相关的,本文没有配 阅读详情
AI摘要

本文深入探讨了Linux系统中浮点运算的处理机制,特别是针对内核态与用户态的不同处理方式,分析了如何在内核态支持浮点运算,并解释了用户态浮点运算的工作原理。

        最近我们有一个需求,需要把用户态的浮点数运算全部放到内核态运行,以提高运行速度,移植的过程中发现问题没有这么简单,然后我们抽丝剥茧,揭开 Linux 对浮点处理的原理。前面写了好几个内核模块测试float的比较和加减,Makefile里面啥也不用加,代码也没有啥特殊的地方,但是这次写的模块就各种不行,报错如下:

 经过查找资料,发现这俩函数都是libc库里的,一个__lesf2表示两个float类型的变量的less or equal比较关系,实际上我用的就是if(a<=b),另外一个__gesf2就是>=的意思。这俩函数找不到,因为这俩货是libc中的,不是内核的,如果想用,就得把这俩货弄到内核模块中并导出符号,这个我也懒得弄了(主要是没有经验)。

        后面又查了好多资料,最后找到下文的内容。它没有直接帮我解决问题,最后我还是参考它的内容曲线救国了。贴一下代码吧,贼矬。等后面弄明白了再改一下。

//两个三维空间坐标点是否是一个长方体空间的左下角坐标和右上角坐标;
//(x1,y1,z1)代表左下角,(x2,y2,z2)代表右上角。

int noinline position_compare_float(float x1, float y1, float z1, float x2, float y2, float z2)
{
	int flag1 = 0,flag2 = 0,flag3 = 0;
	float a;
	kernel_fpu_begin();
	a = x1 - x2;
	kernel_fpu_end();
	
	kernel_fpu_begin();
	memcpy(&flag1, &a, 4);
	kernel_fpu_end();

	kernel_fpu_begin();
	a = y1 - y2;
	kernel_fpu_end();
	
	kernel_fpu_begin();
	memcpy(&flag2, &a, 4);
	kernel_fpu_end();

	kernel_fpu_begin();
	a = z1 - z2;
	kernel_fpu_end();

	kernel_fpu_begin();
	memcpy(&flag3, &a, 4);
	kernel_fpu_end();
	
	
	if ((flag1 >> 31) || (flag2 >> 31) || (flag3 >> 31))
		return 0;
	return 1;
	
	/*if((x1 <= x2) && (y1 <= y2) && (z1 <= z2))
	{
		flag = 1;
	}
	else
	{
		flag = 0;
	}

	return flag;*/
}

以下是本人找到的可用的文章,主要是可以在x86_64上用,而不是arm。


此文章的代码基于 x86 64 位 CPU,Linux 4.14 内核。 

一、 Linux 内核添加浮点运算出现的问题

我们以一个简单的浮点运算例子来说明:

test_float.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <asm/fpu/api.h>
#include <linux/delay.h>

static noinline double float_divide(double float1, double float2)
{
    return float1 / float2;
}

static int __init test_float_init(void)
{
  double result, float1 = 4.9, float2 = 0.49;
​
  result = float_divide(float1, float2);
  printk("result = %d\n", (int)result);
​
  return 0;
}
​
static void __exit test_float_exit(void)
{
  ;
}
​
module_init(test_float_init);
module_exit(test_float_exit);
MODULE_LICENSE("GPL");

Makefile

obj-m := test_float.o
KDIR := /lib/modules/$(shell uname -r)/build
​
all:
    make -C $(KDIR) M=$(PWD) modules

        这个内核模块就是计算了两个浮点数除的结果,然后将结果打印出来 。但是我们执行 make 编译的时候发现报错:

        提示 SSE 寄存器返回的报错信息为 “SSE disabled”。我们执行 make V=1 查看关键的编译信息:

        我们发现在 gcc 的参数中有 -mno-sse -mno-mmx -mno-sse2 选项,原来 gcc 默认的编译选项禁用了 sse、mmx、sse2 等浮点运算指令。

二、通过添加 gcc 编译参数和 kernel_fpu_begin/kernel_fpu_end 来解决问题

为了让内核支持浮点运算,我们在 Makefile 中添加支持 sse 等选项,源码中添加 kernel_fpu_begin/kernel_fpu_end 函数,修改后的源码如下所示:

test_float.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <asm/fpu/api.h>
#include <linux/delay.h>

static noinline double float_divide(double float1, double float2)
{
    return float1 / float2;
}

static int __init test_float_init(void)
{
  double result, float1 = 4.9, float2 = 0.49;
​
  kernel_fpu_begin();
  result = float_divide(float1, float2);
  kernel_fpu_end();
  printk("result = %d\n", (int)result);
​
  return 0;
}
​
static void __exit test_float_exit(void)
{
  ;
}
​
module_init(test_float_init);
module_exit(test_float_exit);
MODULE_LICENSE("GPL");

Makefile

obj-m := test_float.o
KDIR := /lib/modules/$(shell uname -r)/build
​
FPU_CFLAGS += -mhard-float
FPU_CFLAGS += -msse -msse2
CFLAGS_test_float.o += $(FPU_CFLAGS)
​
all:
    make -C $(KDIR) M=$(PWD) modules

        此时执行 make,发现编译正确通过了:

        然后 insmod test_float.ko,观察 dmesg 的输出:

        从上面的例子,结合内核源码中 arch/x86/Makefile 中的 KBUILD_CFLAGS,可以看到编译内核及内核模块时,gcc 选项继承 Linux 中的规则,指定了 -mno-sse -mno-mmx -mno-sse2,也就是禁用了 FPU 。所以,要想内核模组支持浮点运算,编译选项需要显式的指定 -msse -msse2。

三、 Linux 内核态对浮点运算处理方式的分析

从上面可以看到,我们为了实现一个内核模块的浮点运算,添加了编译参数 -mhard-float和-msse -msse2,对于编译参数来说,-mhard-float 是告诉编译器直接生成浮点运算的指令,而 -msse -msse2 则是告诉编译器可以使用 sse/sse2 指令集来编译代码。

  kernel_fpu_begin 和 kernel_fpu_end 也是必须的,因为 Linux 内核为了提高系统的运行速率,在任务上下文切换时,只会保存/恢复普通寄存器的值,并不包括 FPU 浮点寄存器的值,而调用 kernel_fpu_begin 主要作用是关掉系统抢占,浮点计算结束后调用 kernel_fpu_end 开启系统抢占,这使得代码不会被中断,从而安全的进行浮点运算,并且要求这之间的代码不能有休眠或调度操作,另外不得有嵌套的情况出现(将会覆盖原始保存的状态,然后执行 kernel_fpu_end() 最终将恢复错误的 FPU 状态)。

void kernel_fpu_begin(void)
{
preempt_disable();
  __kernel_fpu_begin();
}

四、三角函数在 Linux 内核态的实现

由于内核态不支持浮点运算,所以像三角函数之类浮点运算都没有实现,如果需要,可以将用户态 glibc 中相关的三角函数的实现移植到内核态。

五、 Linux 用户态对浮点运算处理方式的分析

为什么用户态浮点运算就不需要指定编译选项以及显式调用 kernel_fpu_begin 和 kernel_fpu_end 函数呢?我们在用户态下写一个简单的带浮点运算的例子:

user_float.c
#include <stdio.h>
​
int main(int argc, char **argv)
{
  int result, float1=4.9, float2=0.49;
​
  result = float1 / float2;
  printf("result = %d\n", result);
​
  return 0;
}

我们分别使用下面四条编译指令查看编译出来的汇编:

  1. gcc -S user_float.c
  2. gcc -S user_float.c -msoft-float
  3. gcc -S user_float.c -mhard-float
  4. gcc -S user_float.c -msoft-float -mno-sse -mno-mmx -mno-sse2

        前三条命令编译成功。依次查看编译生成的汇编代码,发现生成的汇编代码是完全一样的,都是用到了 sse 指令中的 mmx 寄存器,也就是使用到了 FPU。

第四条命令编译失败 ,提示 error: SSE register return with SSE disabled。从上面的现象中我们可以得出结论,系统默认使用 gcc 编译用户态程序时,gcc 默认使用 FPU,也就是使用硬浮点来编译。

        经过查阅各种文档和分析代码,x86 CPU 提供如下特性:CPU 提供的 TS 寄存器的第三个位是任务已切换标志Task Switched bit,CPU 在每次任务切换时会设置这个位。而且 TS 的这个位被设置时,当进程使用 FPU 指令时 CPU 会产生一个 DNA(Device Not Availabel)异常。Linux 使用此特性,当用户态应用程序进行浮点运算时(SSE 等指令),触发 DNA 异常,同时使用 FPU 专用寄存器和指令来执行浮点数功能,此时 TS_USEDFPU 标志为 1,表示用户态进程使用了 FPU。

void fpu__restore(struct fpu *fpu)
{
  fpu__initialize(fpu);

  /* Avoid __kernel_fpu_begin() right after fpregs_activate() */
  kernel_fpu_disable();
  trace_x86_fpu_before_restore(fpu);
  fpregs_activate(fpu);
  copy_kernel_to_fpregs(&fpu->state);
  trace_x86_fpu_after_restore(fpu);
  kernel_fpu_enable();
}
EXPORT_SYMBOL_GPL(fpu__restore);

        假设用户态进程 A 使用到了 FPU 执行浮点运算,此时用户态进程 B 被调度执行,那么当进程 A 被调度出去的时候,内核设置 TS 并调用 fpu__restore 将 FPU 的内容保存。当进程 A 恢复浮点运算执行时,触发 DNA 异常,相应的异常处理程序会恢复 FPU 之前保存的状态。

        假设用户态进程 A 使用到了 FPU 执行浮点运算(TS_USEDFPU 标志为 1),此时内核态进程 C 调度并使用 FPU,由于内核只会保存普通的寄存器的值,并不包括 FP 等寄存器的值,所以内核会主动调用 kernel_fpu_begin 函数保存寄存器内容,使用完之后调用 kernel_fpu_end。当用户态进程 A 恢复浮点运算执行时,触发 DNA 异常,相应的异常处理程序会恢复 FPU 寄存器的内容。

六、 结论

  1. Linux 中当任务切换时,缺省不保存浮点器寄存器。
  2. 如果需要内核态支持浮点运算,需要增加支持浮点的编译选项和使用 kernel_fpu_begin 和 kernel_fpu_end 函数手动处理上下文。
  3. 用户态缺省支持浮点运算,但是需要内核来辅助。

原文:技术|抽丝剥茧 Linux 浮点运算的原理

Linux 内核使用浮点问题​ 一、硬浮点与软浮点 1. 硬浮点 编译器将代码直接编译成硬件浮点协处理器(浮点运算单元FPU)能识别的指令,这些指令在执行的时候ARM核直接把它转给协处理器执行。FPU 通常有一套额外的寄存器来完成浮点参数传递和运算。使用实际的硬件浮点运算单元(FPU)会带来性能的提升 2. 软浮点 编译器把浮点运算转成浮点运算的函数调用和库函数调用(即用整数运算模拟浮点运算),没有FPU的指令调用,也没有浮点寄... 阅读详情

相关推荐

C语言浮点数详解:float、double精度与scanf格式符避坑指南

在C语言编程中,浮点数是一个既基础又容易踩坑的话题。很多开发者会遇到0.1加0.2不等于0.3的困惑,这源于IEEE 754标准的底层存储机制:浮点数通过符号位、指数位和尾数位来表示,有限的内存无法精确存储无限循环的二进制小数。本文从精度原理出发,深入对比float、double和long double的取值范围与有效位数,并解析scanf与printf中%f、%lf、%Lf格式符的对称性陷阱。同时介绍科学计数法的书写规则及字面量默认类型,帮助开发者避免隐式转换带来的精度损失。最后结合实战经验,给出浮点数比

weixin_32247165的博客 190

Linux内核使用浮点运算问题

  上一篇博文中电池温度检测原理和示例代码,由于驱动要使用对数函数而从网上参看一个实现 double ln(double a) { int N = 15; int k,nk; double x,xx,y; x = (a-1)/(a+1); xx = x*x; nk = 2*N+1; y = 1.0/nk; ...

weixin_34250709的博客 3154

C++: error: SSE register return with SSE disabled、 -mno-sse

看gcc的代码,会发现这个函数的参数是double,返回值是double,也就是编译器会判断是否需要xmm寄存器,也就是sse的支持,如果是double类型,肯定就是需要sse的支持。在std_abs.h这个文件里有函数constexpr double std::abs(double);第一步看,这个c++的编译使用的stdlib.h 是 /usr/include/c++/8/在这个目录;第三步,用到头文件:#include 那这个函数,在哪里显示的说需要sse的支持?

mzhan017的博客 1240

个人编译移动内核时遇到的一些问题报错及处理方法【不定时更新2021.1.3】

1. 用qemu 创建虚拟机来运行编译的小型系统时: WARNING: Image format was not specified for '/home/……/rootfs.img' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify

lyxubx的博客 8552

浅谈linux kernel对于浮点运算的支持

目前大多数CPU都支持浮点运算单元FPU,FPU作为一个单独的协处理器放置在处理器核外,但是对于嵌入式处理器,浮点运算本来就少用,有些嵌入式处理器就会去掉浮点协处理器。 X86处理器一般都是有FPU的。而ARM PPC MIPS处理器就会出现没有FPU的现象。 linux kernel如何处理浮点运算,我们就分为带FPU的处理器和不带FPU的处理器来讨论。 (以下为个人知识总结,研究不深,错误之处希望大家指正,共同学习) 一 对于带FPU的处理器 1 对于linux kernel来说,kernel本身编译默认使用了-msoft-float选项,默认编译为软浮点程序,软浮点含义是有gcc编译器模

从KVM虚拟化到Openstack云化架构综述

目录 摘要 OpenStack的虚拟化技术 OpenStack架构介绍 Nova Swift KeyStone Neutron Glance Cinder Ceilometer Heat 摘要 这两年的工作中,接触到公有云和私有云的项目还不少。起初对于Openstack的了解,仅停留在其几大组件的交互上,如Nova、Neutron、Glance等,以及对各大云厂商功能点上...

liyunpeng229的博客 2051

linux 下 float 和 double 精度计算差别

今天在根据需求写代码时候,偶尔发现linux 下 设置变量类型 float 和double 计算时, 得到的结果是不一样的。 要求: 设定值 = 传入值 * 10 * 122.88 /1000; case: 设定值 = 1666*10*122.88/1000                         = 2047.1808   设置成 float时,代码: #include #

NI KI 4417

机器学习 -- 信用卡评分模型 -- 互联网金融风控

互联网金融主要分为资金类和资产类。资金类主要是理财产品,吸储,主要指标是用户转化、留存和复投,重在客户运营。资产类主要是贷款,包括消费金融和现金贷,小额贷款属于此类,主要目的是用户转化,还款和风险控制,信用卡评分模型就属于风险控制。 信用评分作用是对贷款申请人(信用卡申请人)做风险评估分值的方法。 信用卡评分是以大量数据的统计结果为基础,根据客户提供的资料和历史数据对客户的信用进行评估,评分卡模型...

XiaoMaEr66的博客 2416

linux中double大小,linux 下 float 和 double 精度計算差別

今天在根據需求寫代碼時候,偶爾發現linux 下 設置變量類型 float 和double 計算時,得到的結果是不一樣的。要求:設定值 = 傳入值 * 10 * 122.88 /1000;case: 設定值 = 1666*10*122.88/1000= 2047.1808設置成 float時,代碼:#include#include unsigned int fun(unsigned int sf...

weixin_28816215的博客 211

打造会自主学习的 AI 助手:OpenClaw 记忆系统完全指南

这不是科幻,这是我正在使用的系统。我的 AI 助手「小琳」已经运行了一段时间,积累了大量的知识和经验,而且还在不断学习成长。心跳(Heartbeat)是 OpenClaw 的定时轮询机制,可以让 AI 主动做一些事情。你有没有遇到过这样的困扰:每次和 AI 对话,它都像失忆了一样,之前聊过的内容完全不记得?设置定时任务:每天早上 8 点,查询天气和热点新闻,通过钉钉推送给我。让你的 AI 助手拥有持久记忆,能够自主学习、总结经验、不断成长。这不仅仅是一个「能记住事情的 AI」,而是一个。

Honmaple的博客 1633

教程 | VeriStand硬件在环仿真测试第一章

这篇是系列文章的第一章,满满的都是干货,感兴趣的话欢迎一起交流探讨。

HUASUITECH的博客 1万+

linux中double大小,linux 下 float 和 double 精度计算差别

今天在根据需求写代码时候,偶尔发现linux 下 设置变量类型 float 和double 计算时,得到的结果是不一样的。要求:设定值 = 传入值 * 10 * 122.88 /1000;case: 设定值 = 1666*10*122.88/1000= 2047.1808设置成 float时,代码:#include#include unsigned int fun(unsigned int sf...

weixin_33344572的博客 292

低功耗设计:如何计算power switch的数量?

power switch加多了漏电高,加少了ir drop会有问题,具体加多少合适要如何计算呢?这里可以给一个参考方式。 第一步,先选switch cell的类型 通常选用HVT类型的switch cell,优点是漏电更低,缺点也很明显,电阻大,压降也大,switch cell的大小选择,可以选择(开启电阻x面积)最小的switch cell,即单位面积提供最小并联电阻的cell类型。 第二步,计算数量 选好类型,确定了开启电阻,可以按照如下公式计算数量: Ron/Xnum • W/V = V•P

m0_61544122的博客 3570

linux中double大小,linux 下 float 跟 double 精度计算差别

linux 下 float 和 double 精度计算差别今天在根据需求写代码时候,偶尔发现linux 下 设置变量类型 float 和double 计算时,得到的结果是不一样的。要求:设定值 = 传入值 * 10 * 122.88 /1000;case: 设定值 = 1666*10*122.88/1000= 2047.1808设置成 float时,代码:#include#include uns...

weixin_35348899的博客 421

从入门到精通|Yalmip+Cplex在电力系统中的应用(Matlab代码实现)

​ 火电成本包括运行成本、碳捕集成本,其中火电运行成本由运行维护成 本和发电煤耗成本构成,发电煤耗与其出力关系: ,F 为机组煤耗量(kg/h),P 为机组出力/MW;运行维护成本按照 0.5 倍煤耗成本考虑,碳捕集成本取决于碳排放量及碳捕集单价,火电机组相关参数如附表 1 所示,电煤价格为 700 元/t ​

weixin_46039719的博客 1550

海康DS-7604N-K1/RTB固件包

【摘要】海康DS-7604N-K1/RTB萤石云设备发布V4.30.091版本升级程序(2022.09.19),仅适用于指定型号。升级前需先升级至V3.4.106基础版本,刷机会重置设备为未激活状态,需重新设置admin密码。该机型支持密码/手势登录,无密码时可通过U盘升级。注意事项:升级存在风险,需确认程序适用性;升级过程严禁断电;必须阅读压缩包内的刷机说明。此为定制机型,非必要不建议升级。(150字)

海康威视技术支持 1567

分析一次double强转float的翻车原因

背景 人逢喜事精神爽,总算熬到下班撩~~ 正准备和同事打个招呼回家,被同事拖住问了. ????‍♂️: 你们组做的那块代码,把double类型数据成float有问题啊????. ????‍♀️: 嗯?不对是正常啊,float精度是没有double高,但float能保存到小数点后好多位,对我们来说完全够用了! ????‍♂️: 不是啊,这不是小数点多少位的问题,而是现在整型数据,转出来也有问题啊,你看. ????‍♀...

weixin_30735391的博客 958

云原生监控:Prometheus+Grafana监控Nginx实战

在云原生环境中,应用的高可用性和性能优化至关重要。Nginx作为一款广泛使用的高性能Web服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,对其进行有效的监控能够及时发现潜在问题,保障服务的稳定运行。本文章的目的是详细介绍如何使用Prometheus和Grafana构建一套完整的监控系统来监控Nginx,范围涵盖从环境搭建、数据采集、存储到可视化展示的整个流程。

AI云原生与云计算技术学院 1574

float与double的范围和精度

一下内容来源于网络,为了学习特意摘录下的。 1 范围 float和double的范围是由指数的位数来决定的。 float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bit...

JohnnyTim的博客 896

深度学习工具包 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")

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

java浮点类型float精度与Double精度范围实例使用说明

红颜丽人 追求技术就像追求爱情! 跳至内容 博客首页  JAVA程序开发  LINUX系统学习  数据库技术  C++学习  网站建设  新闻资讯  WEB前端开发  电脑知识  生活情趣 java浮点类型float精度与Double精度范围实例使用说明 java浮点类型float精度与Double精度范围实例

evilcry2012的专栏 1817

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

浮点型数据存储空间全解析:从float到long double的内存占用对比(GCC环境实测)

本文深入解析了GCC环境下float、double和long double三种浮点型数据类型的存储空间特性,通过实测数据对比了它们的内存占用和平台差异。文章详细探讨了存储空间与数值精度的关系,并提供了实际应用中的类型选择策略,帮助开发者在内存优化和性能需求之间做出平衡决策。

hp777的博客 632

lwip-2.0.3

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

float和double的区别

1、C中float和double的区别 float:单精度类型,最多可以精确到小数点为7位,占用内存为4字节,占用内存的消耗速度为double的一半 double:双精度类型,最多可以精确到小数点为16位,占用内存为8字节,占用内存的消耗速度为float的两倍 一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快。 参考博客:https://www.cnblogs.com/liuti...

Littlehero_121的博客 8884

Linux下C库学习 - float.h

float.h说到float.h就必须要先说一下float,double,long double这三种数据类型在计算机里面的表示 说到浮点数,在计算机里面不像整数,是分为三个部分的 符号位 指数位 尾数位 指数位的长度决定了浮点数的表示范围,而尾数位的长度决定了浮点数的表示精度(小数点的位数)比如以float类型举例,float类型一般占32位,其中1位符号位,8位指数位,23位尾数位,因为指数位

mill_li的博客 2484
上一篇: linux 下查看进程内的线程有哪些
下一篇: WARNING: modpost: missing MODULE_LICENSE()以及内核模块无法验证
土豆西瓜大芝麻
博客等级 码龄18年 1189粉丝 238原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值