Theano学习笔记(六)——载入与保存、条件

载入与保存

Python标准的保存类别实体并重新载入它们的途径是pickle机制。许多Theano对象可以由此被序列化(或者反序列化),然而pickle的局限性在于,被序列化的类别实例的代码或者数据并没有被同时保存。因此重新载入先前版本的类可能会出问题。

因此,需要寻求基于预期保存和重新载入的耗时的不同机制。

对于短期(比如临时文件和网络转录),Theano的pickle是可行的。

对于长期(比如从实验中保存模型)不应当依赖于Theano的pickle对象。

推荐在任何其他Python项目的过程中的保存和载入底层共享对象。

Pickle基础

pickle和cPickle模块功能相似,但是cPickle用C编码,要更快一些。

可以用cPickle.dump把对象序列化(或者保存或者pickle)为一个文件。

importcPickle
f= file('obj.save', 'wb')
cPickle.dump(my_obj,f, protocol=cPickle.HIGHEST_PROTOCOL)
f.close()

使用了cPickle.HIGHEST_PROTOCOL,使得保存对象的过程大大加快。

使用了’b’二进制模式,是为了在Unix和Windows系统之间保持可移植性。

使用cPickle.load把文件反序列化(或载入,或unpickle)

f= file('obj.save', 'rb')
loaded_obj= cPickle.load(f)
f.close()

可以同时pickle多个对象到同一个文件:

f= file('objects.save', 'wb')
forobj in [obj1, obj2, obj3]:
    cPickle.dump(obj, f,protocol=cPickle.HIGHEST_PROTOCOL)
f.close()

也可以按照同样的顺序载入:

f= file('objects.save', 'rb')
loaded_objects= []
fori in range(3):
    loaded_objects.append(cPickle.load(f))
f.close()

短期序列化

如果有信心,pickle整个模型是个好办法。

这种情况是指,你在项目中执行同样的保存和重载操作,或者这个类已经稳定运行很久了。

通过定义__getstate__ method和__setstate__可以控制从项目中保存何种pickle。

如果模型类包含了正在使用数据集的链接,而又不想pickle每个模型实例,上述控制方法会很实用。

def__getstate__(self):
    state = dict(self.__dict__)
    del state['training_set']
    return state

def__setstate__(self, d):
    self.__dict__.update(d)
self.training_set =cPickle.load(file(self.training_set_file, 'rb'))

长期序列化

如果想要保存的类运行不稳定,例如有函数创建或者删除、类成员重命名,应该只保存或载入类的不可变部分。

依然是使用定义__getstate__ method和__setstate__

例如只想要保存权重矩阵W和偏倚项b:

def__getstate__(self):
    return (self.W, self.b)

def__setstate__(self, state):
    W, b = state
    self.W = W
self.b = b

如果更新了下列函数来表现变量名称的改变,那么即使W和b被重命名为weights和bias,之前的pickle文件依然是可用的:

def__getstate__(self):
    return (self.weights, self.bias)

def__setstate__(self, state):
    W, b = state
    self.weights = W
self.bias = b

条件

-IfElse与Switch

-switch比ifelse更通用,因为switch是逐位操作。

-switch把2个输出变量都计算了,所以比ifelse要慢(只算1个)。

from theano import tensor as T
from theano.ifelse import ifelse
importtheano, time, numpy

a,b= T.scalars('a', 'b')
x,y= T.matrices('x', 'y')

z_switch= T.switch(T.lt(a, b), T.mean(x), T.mean(y))
z_lazy= ifelse(T.lt(a, b), T.mean(x), T.mean(y))

f_switch= theano.function([a, b, x, y], z_switch,
                   mode=theano.Mode(linker='vm'))
f_lazyifelse= theano.function([a, b, x, y], z_lazy,
                   mode=theano.Mode(linker='vm'))

val1= 0.
val2= 1.
big_mat1= numpy.ones((10000, 1000))
big_mat2= numpy.ones((10000, 1000))

n_times= 10

tic= time.clock()
fori in xrange(n_times):
    f_switch(val1, val2, big_mat1, big_mat2)
print'time spent evaluating both values %f sec' % (time.clock() - tic)

tic= time.clock()
fori in xrange(n_times):
    f_lazyifelse(val1, val2, big_mat1,big_mat2)
print'time spent evaluating one value %f sec' % (time.clock() - tic)

测试结果

time spent evaluating both values 0.200000 sec
time spent evaluating one value 0.110000 sec

可见ifelse确实快了1倍,但是必须使用vm或者cvm作为Linker,而未来cvm会作为默认Linker出现。

欢迎参与讨论并关注本博客微博以及知乎个人主页后续内容继续更新哦~

转载请您尊重作者的劳动,完整保留上述文字以及文章链接,谢谢您的支持!

时间: 2024-10-25 00:10:44

Theano学习笔记(六)——载入与保存、条件的相关文章

java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessController的checkPerssiom方法,访问控制器AccessController的栈检查机制又遍历整个 PerssiomCollection来判断具体拥有什么权限一旦发现栈中一个权限不允许的时候抛出异常否则简单的返回,这个过程实际上比我的描述要复杂 得多,这里我只是简单的一句带过,因为这

laravel3学习笔记(六)

原作者博客:ieqi.net ==================================================================================================== ORM Laravel3中MVC体系中Model里最重要的组成部分无疑是ORM了,ORM — object-relational mapper — 将数据操作面向对象化,使得整个web框架的核心风格统一,降低整体复杂度,为开发者提供便利. Laravel3中的ORM叫

Lua学习笔记(六):函数-续

Lua中的函数是带有词法定界(lexical scoping)的第一类值(first-class values).第一类值指:在Lua中函数和其他值(数值.字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值.词法定界指:嵌套的函数可以访问他外部函数中的变量.这一特性给Lua提供了强大的编程能力. Lua中关于函数稍微难以理解的是函数也可以没有名字,匿名的.当我们提到函数名(比如print),实际上是说一个指向函数的变量,像持有其他类型的变量一样:

python之raw_input()(学习笔记六)

python之raw_input()(学习笔记六) 我们经常使用raw_input()读取用户的输入,如下例子所示: >>> name = raw_input('please input your name:'),截图如下: 下面简单说下,raw_input()与if搭配使用,脚本如下: #!/usr/bin/env python # -*- coding:utf-8 -*- birth = raw_input('birth:') if birth < 2000: print '0

swift学习笔记(六)析构过程和使用闭包对属性进行默认值赋值

一.通过闭包和函数实现属性的默认值 当某个存储属性的默认值需要定制时,可以通过闭包或全局函数来为其提供定制的默认值. 注:全局函数结构体和枚举使用关键字static标注    函数则使用class关键字标注 当对一个属性使用闭包函数进行赋值时,每当此属性所述的类型被创建实例时,对应的闭包或函数会被调用,而他们的返回值会被作为属性的默认值. ESC: Class SomeCLass{ let someProperty:SomeType={ //给someProperty赋一个默认值 //返回一个与

初探swift语言的学习笔记六(ARC-自动引用计数,内存管理)

Swift使用自动引用计数(ARC)来管理应用程序的内存使用.这表示内存管理已经是Swift的一部分,在大多数情况下,你并不需要考虑内存的管理.当实例并不再被需要时,ARC会自动释放这些实例所使用的内存. 另外需要注意的: 引用计数仅仅作用于类实例上.结构和枚举是值类型,而非引用类型,所以不能被引用存储和传递. swift的ARC工作过程 每当创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息. 另外当实例不再被使用时,ARC会释放实例所占用的内存,这些

Linux System Programming 学习笔记(六) 进程调度

1. 进程调度 the process scheduler is the component of a kernel that selects which process to run next. 进程调度器需要使 处理器使用率最大化,并且提供 使多个进程并发执行的虚拟 Deciding which processes run, when, and for how long is the process scheduler's fundamental responsibility. 时间片:th

GDI+学习笔记(七)保存简单图像

请尊重本人的工作成果,转载请留言,并说明转载地址,谢谢.地址如下: http://blog.csdn.net/fukainankai/article/details/27710883 前几节中,我们利用GDI+在窗口中绘制了各种各样的图形.图像,这一节,我们将会将这些图像保存成简单图像.所谓简单图像,指的是bmp/jpg/png等图像或者单帧的gif图像.保存成多帧的gif图像稍微复杂一点,本节中暂时不做说明.保存成动态的tiff文件也比较简单,但这里也不做说明,下次有机会和gif一起介绍. 另

Swift学习笔记五:循环和条件语句

一.循环语句 1. for循环 1) for -in 循环,对于数据范围,序列,集合等中的每一个元素,都执行一次 for a in 0...5{}    //循环迭代,从a=0到a=5,执行{}里的代码 注意:a只循环中存在,也就是出了{}a就不存在了 或者遍历数组 let a = [1,2,3] for b in a{} //循环迭代,从b=1到b=3 如果你不需要序列中的每一个值,可以使用_来忽略它,仅仅只是使用循环体本身: for _ in 0...5{}    //循环执行{}里的代码,