python fuel库

原文链接:http://fuel.readthedocs.io/en/latest/overview.html

英文比较烂,所以还是喜欢看直观的中文

综述

假设我们有8个2×2的灰度图,分为4类

import numpy
seed = 1234
rng = numpy.random.RandomState(seed)
features = rng.randint(256, size=(8, 2, 2))
targets = rng.randint(4, size=(8, 1))

没有明白randomstate是生成什么的,好像主要就是用种子生成伪随机序列。features是一个8*2*2的矩阵,最大值不超过256

人工分支

FUEL的任务:

1.与数据交互,存到硬盘或内存

2.决定访问什么数据,以什么顺序

3.迭代选择的数据点

4.每次迭代,对被筛选出的数据进行变换

图解
这里写图片描述

Datasets:数据交互
是一个抽象类,其子类是用来与数据进行交互的

构造参数:
sources:可选,用来限制对数据要求的返回源
axis_labels: 可选,用来设置轴语义.

实例参数:
sources: 一个字符串元祖,反应dataset提供的源和用get_data返回数据顺序
provides_sources: 源名称元祖,反应什么源是可以提供使用的
axis_labels: 字典, source(源)名称到字符元组或者None。用来设置数据集源的轴语义。
num_examples: 当执行时,代表datasets中样本的数量。

请求数据的方法:
open(): 返回一个state格式实体,此实体是Dataset将要用来交互的,或者返回None如果它不需要交互。
get_data(): 给定state实体和一个可选设置请求参数,返回数据。
close(): 给定state实体,正确关闭。
reset(): 对给定实体关闭并重新打开。

IterableDataset
是Dataset子类
允许与迭代实体交互
IterableDataset.open()返回迭代实体.
get_data() 不接收请求
只能迭代实例并且按序操作。

构造参数:
iterables: 字典,源名:对应迭代实体 。用 collections.OrderedDict instances 如果源顺序很重要的话。

IndexableDataset

允许与可加索引的实体交互
IndexableDataset.open() 返回None.
get_data() 方法接受请求
允许随机路径
构造参数:
indexables: 字典,源名:对应的可加索引实体。用collections.OrderedDict 实例如果顺序对你很重要。

Datasets包含一个或多个数据源,比如图片矩阵、标签序列、字典。每个源用不同的名称定义。

IterableDataset
是Dataset最简单的子类,处理迭代实体。

from collections import OrderedDict
from fuel.datasets import IterableDataset
dataset = IterableDataset(
… iterables=OrderedDict([(‘features’, features), (‘targets’, targets)]),
… axis_labels=OrderedDict([(‘features’, (‘batch’, ‘height’, ‘width’)),
… (‘targets’, (‘batch’, ‘index’))]))

这里OrderedDict把列表转换为字典。迭代器类似自动循环或者说遍历所有输入。这个结果是一个数据结构体,恩…自己瞎起的名。数据调用dataset.iterables[0]就表示我们说的features特征。

print(‘Provided sources are {}.’.format(dataset.provides_sources))
Provided sources are (‘features’, ‘targets’).
print(‘Sources are {}.’.format(dataset.sources))
Sources are (‘features’, ‘targets’).
print(‘Axis labels are {}.’.format(dataset.axis_labels))
Axis labels are OrderedDict([(‘features’, (‘batch’, ‘height’, ‘width’)), (‘targets’, (‘batch’, ‘index’))]).
print(‘Dataset contains {} examples.’.format(dataset.num_examples))
Dataset contains 8 examples.

IterableDataset的源顺序取决于iterables的键,而在一般的字典中是没有顺序的。因此我们说如果顺序必要的话,我们建议使用collection.OrderedDict。

Datasets自己是无状态实体。为了从dataset中请求数据,我们需要请求它来实例化一些状态实体。我们用Dataset.open()方法,如果不使用此方法,那么我们只能得到dataset的4个构造属性。(自己理解,欢迎纠正)

state = dataset.open()
print(state.class.name)
imap

当数据是IterableDataset的情况,我们可以看出state是一个迭代实体imap。我们现在可以用get_data()方法访问dataset的实例。

while True:
… try:
… print(dataset.get_data(state=state))
… except StopIteration:
… print(‘Iteration over’)
… break
(array([[ 47, 211],
[ 38, 53]]), array([0]))
(array([[204, 116],
[152, 249]]), array([3]))
(array([[143, 177],
[ 23, 233]]), array([0]))
(array([[154, 30],
[171, 158]]), array([1]))
(array([[236, 124],
[ 26, 118]]), array([2]))
(array([[186, 120],
[112, 220]]), array([2]))
(array([[ 69, 80],
[201, 127]]), array([2]))
(array([[246, 254],
[175, 50]]), array([3]))
Iteration over

最终,迭代器被耗尽并且引发一个StopIteration错误。如果我们需要重新再迭代一次需要用reset()去请求一个新的迭代器。

state = dataset.reset(state=state)
print(dataset.get_data(state=state))
(array([[ 47, 211],
[ 38, 53]]), array([0]))

当你完成任务,别忘了调用dataset的close()方法于这个state上。

dataset.close(state=state)

IndexableDataset可索引dataset
IterableDataset处理是很小的。举个例子,他只是让你按顺序迭代并且例化你的数据。

如果你的数据恰好是可索引的(例如,list或者一个numpy.ndarry),那么IndexableDataset可以非常有用。

from fuel.datasets import IndexableDataset
dataset = IndexableDataset(
… indexables=OrderedDict([(‘features’, features), (‘targets’, targets)]),
… axis_labels=OrderedDict([(‘features’, (‘batch’, ‘height’, ‘width’)),
… (‘targets’, (‘batch’, ‘index’))]))

IndexableDataset比IterableDataset的主要优点就是,可以从一个任意的入口读取数据,而不像迭代型必须从头开始。所以我们必须提供一个request参数。

state = dataset.open()
print(‘State is {}.’.format(state))
State is None.
print(dataset.get_data(state=state, request=[0, 1]))
(array([[[ 47, 211],
[ 38, 53]],
[[204, 116],
[152, 249]]]), array([[0],
[3]]))
dataset.close(state=state)

这里就读出了前两个特征与分类。如果没有对应结果返回NONE。

限制源

在某些情况(例如.无监督学习),或许你想用提供源的子集。通过传递sources的参数可以实现。

restricted_dataset = IndexableDataset(
… indexables=OrderedDict([(‘features’, features), (‘targets’, targets)]),
… axis_labels=OrderedDict([(‘features’, (‘batch’, ‘height’, ‘width’)),
… (‘targets’, (‘batch’, ‘index’))]),
… sources=(‘features’,))
print(restricted_dataset.provides_sources)
(‘features’, ‘targets’)
print(restricted_dataset.sources)
(‘features’,)
state = restricted_dataset.open()
print(restricted_dataset.get_data(state=state, request=[0, 1]))
(array([[[ 47, 211],
[ 38, 53]],
[[204, 116],
[152, 249]]]),)
restricted_dataset.close(state=state)

可见,这种情况下只有features被返回了。

Iteration schemes: which examples to visit(访问的例子)

In summary

IterationScheme
    抽象类.其子类是用来决定实例被访问的顺序
    Methods:
        get_request_iterator(): 返回一个迭代实体,实体返回请求。这些请求可以被提供给dataset的get_data()方法。
BatchScheme
    抽象类,其子类返回包请求。
    常用子类:
        SequentialScheme: 按顺序请求批(batch)
        ShuffledScheme: 随机请求batch。
IndexScheme
    抽象类,其子类返回实例请求。
    常用子类:
        SequentialExampleScheme: 按顺序请求实例
        ShuffledExampleScheme: 随机请求实例

封装和访问我们的数据是可以的,但是如果我们要把其整合到一个训练循环中,我们需要能够迭代数据。为此,我们需要决定请求的目录和其顺序。这能被IterationScheme子类实现。

在他的最基础层次,一个用来建立返回请求的迭代器的迭代计划是可行的,通过它的get_request_iterator() 方法

from fuel.schemes import (SequentialScheme, ShuffledScheme,SequentialExampleScheme, ShuffledExampleScheme)
schemes = [SequentialScheme(examples=8, batch size=4),
ShuffledScheme(examples=8, batch_size=4),
… SequentialExampleScheme(examples=8),
… ShuffledExampleScheme(examples=8)]
for scheme in schemes:
[[0, 1, 2, 3], [4, 5, 6, 7]][[7, 2, 1, 6], [0, 4, 3, 5]][0, 1, 2, 3, 4, 5, 6, 7][7, 2, 1, 6, 0, 4, 3, 5

总的来说,要得到数据就必须用get_request_iterator()方法,这里大概得到的只是索引吧。examples表示例子数,并自动生成0-7。

因此我们可以用一个迭代计划去访问一个dataset以我们需要的顺序。

state = dataset.open()
scheme = ShuffledScheme(examples=dataset.num_examples, batch_size=4)
for request in scheme.get_request_iterator():
… data = dataset.get_data(state=state, request=request)
… print(data[0].shape, data[1].shape)
(4, 2, 2) (4, 1)
(4, 2, 2) (4, 1)
dataset.close(state)

Data streams: automating the iteration process
自动化迭代进程

In summary

AbstractDataStream
    抽象类。其子类是用来协调一个dataset和迭代计划来迭代数据。
    迭代方法:
        get_epoch_iterator(): 返回一个,用来返回例子或batch的迭代器.
    构造参数:
        iteration_scheme: IterationScheme实例, 可选,用来定义迭代顺序.
        axis_labels: 可选,用来定义轴语义.
DataStream
    最常用的data stream.
    Constructor arguments:
        dataset: Dataset实例, 用来迭代的dataset.

迭代计划提供了一个更加便捷的方法来访问dataset对比手动访问来说,但是我们还可以做得更好:从dataset中得到一个新的state,从迭代计划中得到请求,用二者来访问数据并且之前的方法关闭state是重复的。为了自动化这个过程,我们使用data streams,是AbstractDataStream的子类。

最常见的AbstractDataStream子类就是DataStream.用一个dataset和iteration scheme来实例化,并且返回一个纪元迭代器通过get epoch iterator()方法,即按照迭代计划在dataset迭代的结果。

from fuel.streams import DataStream
data_stream = DataStream(dataset=dataset, iteration_scheme=scheme)
for data in data_stream.get_epoch_iterator():
… print(data[0].shape, data[1].shape)
(4, 2, 2) (4, 1)
(4, 2, 2) (4, 1)

Transformers: apply some transformation on the fly
处理时应用变换

In summary

Transformer
    AbstractDataStream的子类.抽象类. 其子类是用来输入一个data stream输出一个data stream, 即对输入data stream进行变换.
    Transformers可以串联生成复杂变换.
    Constructor arguments:
        data_stream: AbstractDataStream实例,输入流

一些AbstractDataStream子类将数据流当做输入。我们称之为transformer,它们促使我们能够建立复杂的数据预处理通道。

Transformer有一下几种常用的类:
Flatten:将输入平坦化为矩阵(对批输入)或者向量(实例输入)
ScaleAndShift:将输入变为标量,缩放与平移。
Cast:将输入投影到一些数据类型。

举个例子,让我们标准化图片即减均值除以标准差

from fuel.transformers import ScaleAndShift
#Note: ScaleAndShift applies (batch * scale) + shift, as
#opposed to (batch + shift) * scale.
scale = 1.0 / features.std()
shift = - scale * features.mean()
standardized_stream = ScaleAndShift(data_stream=data_stream,
… scale=scale, shift=shift,
… which_sources=(‘features’,))

end
同理由于是AbstractDataStream,我们要使用get_epoch_iterator()
这里标准化是在通信过程(on-the-fly)中

for batch in standardized_stream.get_epoch_iterator():
… print(batch)
(array([[[ 0.18530572, -1.54479571],
[ 0.42249705, 0.24111545]],

   [[-1.30760439,  0.98059429],
    [-1.43317627, -1.2238898 ]],

   [[ 1.46892937,  1.58054882],
    [ 0.47830677, -1.2657471 ]],

   [[ 0.63178351, -0.28907693],
    [-0.40069638,  1.10616617]]]), array([[1],
   [0],
   [3],
   [2]]))

(array([[[ 1.32940506, -0.2332672 ],
[-1.60060544, -0.31698179]],

   [[ 0.03182898,  0.50621164],
    [-1.64246273,  1.28754777]],

   [[ 0.88292727, -0.34488665],
    [ 0.15740086,  1.51078666]],

   [[-1.00065091, -0.84717417],
    [ 0.84106998, -0.19140991]]]), array([[2],
   [0],
   [3],
   [2]]))

现在,我们假设需要float32类型的特征(如:在GPU上使用Theano代码)。我们可以把它们投影到on-the-fly,用Cast

from fuel.transformers import Cast
cast_standardized_stream = Cast(
… data_stream=standardized_stream,
… dtype=’float32’, which_sources=(‘features’,))

串联方法

data stream = Cast(
… ScaleAndShift(
… DataStream(
  … dataset=dataset, iteration scheme=scheme),
 … scale=scale, shift=shift, which sources=(‘features’,)),

更进一步
如何使用内建dataset:http://fuel.readthedocs.io/en/latest/built_in_datasets.html
如何导入自己的数据:http://fuel.readthedocs.io/en/latest/h5py_dataset.html
如何根据需要扩展Fuel:http://fuel.readthedocs.io/en/latest/extending_fuel.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当谈到多属性决策时,AHP(层次分析法)是一种常用的方法。在Python中,可以使用多种来实现AHP算法。这里我将使用pyAHP来演示一个简单的AHP多属性决策的Python案例。 首先,确保你已经安装了pyAHP。你可以使用以下命令进行安装: ``` pip install pyahp ``` 接下来,让我们来看一个具体的例子,假设我们需要选择最适合我们需求的汽车。我们将考虑以下三个属性:价格、燃油效率和安全性。我们将根据这些属性来比较不同的汽车选项。 首先,我们需要导入必要的和模块: ```python from pyahp import * ``` 然后,我们定义我们的决策结构,包括层次结构和各个元素: ```python ahp = AHP() ahp.add_alternatives(['Car A', 'Car B', 'Car C']) ahp.add_criteria(['Price', 'Fuel Efficiency', 'Safety']) ``` 接下来,我们设置两个两两比较矩阵,一个是比较汽车选项之间的价格,一个是比较汽车选项之间的燃油效率: ```python ahp.add_matrix('Price', [ [1, 1/3, 3], [3, 1, 5], [1/3, 1/5, 1] ]) ahp.add_matrix('Fuel Efficiency', [ [1, 3, 5], [1/3, 1, 3], [1/5, 1/3, 1] ]) ``` 然后,我们设置一个比较矩阵来比较不同属性之间的重要性: ```python ahp.add_matrix('Importance', [ [1, 5, 3], [1/5, 1, 1/3], [1/3, 3, 1] ]) ``` 现在,我们执行AHP计算并得出结果: ```python result = ahp.compute() ``` 最后,我们可以输出最终的排序结果: ```python print(result['ranking']) ``` 这就是一个简单的AHP多属性决策的Python案例。你可以根据自己的需求修改和扩展这个例子,以适应不同的决策问题。希望对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值