入门指南
在本教程中,我们展示了Torchhd的一些基本功能。我们通过下表中的虚构示例展示了该库如何使在超空间中表示和操作信息变得容易:
记录 |
水果 |
重量 |
季节 |
|---|---|---|---|
\(r_1\) |
苹果 |
149.0 |
秋天 |
\(r_2\) |
柠檬 |
70.5 |
冬天 |
\(r_3\) |
芒果 |
173.2 |
夏天 |
基础超向量
编码这些记录的第一步是为每个信息集定义基础超向量。由于这些信息集的性质不同,用于编码它们的基础超向量集也不同。我们首先定义超空间的维度,然后使用torchhd模块中的方法来创建具有适当相关性的基础超向量:
import torchhd
d = 10000 # dimensions
fruits = torchhd.random(3, d)
weights = torchhd.level(10, d)
seasons = torchhd.circular(4, d)
var = torchhd.random(3, d)
为3种水果类型、10个重量级别、4个季节和3个变量创建超向量。下图展示了每组中超向量对之间的距离:
可以使用torchhd.embeddings模块中的类实现类似的行为。这些类提供了将值映射到超向量的便捷方法。例如,要将区间\([0, 200]\)映射到十个权重超向量,上述functional版本需要显式映射到索引:
import torch
weight = torch.tensor([149.0])
# explicit mapping of the fruit weight to an index
w_i = torchhd.value_to_index(weight, 0, 200, 10)
weights[w_i] # select representation of 149
而嵌入具有这种内置的常见行为:
from torchhd import embeddings
W_emb = embeddings.Level(10, d, low=0, high=200)
# select representation of 149
W_emb(weight) # same result as weights[w_i]
操作
一旦定义了基础超向量,我们可以使用torchhd中的MAP操作来通过组合基础超向量编码更复杂的对象。记录\(r_1\)的超向量可以如下创建:
f = torchhd.bind(var[0], fruits[0]) # fruit = apple
w = torchhd.bind(var[1], weights[w_i]) # weight = 149
s = torchhd.bind(var[2], seasons[3]) # season = fall
r1 = torchhd.bundle(torchhd.bundle(f, w), s)
这相当于使用以下简化的语法:
r1 = var[0] * fruits[0] + var[1] * weights[w_i] + var[2] * seasons[3]
数据结构
或者,我们可以使用torchhd模块中提供的常用编码之一。使用这些编码,记录\(r_1\)可以如下编码:
# combine values in one tensor of shape (3, d)
values = torch.stack([fruits[0], weights[w_i], seasons[3]])
r1 = torchhd.hash_table(var, values)
torchhd.structures 模块除了包含二叉树和有限状态自动机外,还包含相同的编码模式,但以数据结构的形式提供。该模块提供了基于类的HDC数据结构实现。使用哈希表类,记录 \(r_1\) 可以表示如下:
from torchhd import structures
r1 = structures.HashTable(d) # r1 = 0
r1.add(var[0], fruits[0]) # r1 + var[0] * fruits[0]
r1.add(var[1], weights[w_i]) # r1 + var[1] * weights[w_i]
r1.add(var[2], seasons[3]) # r1 + var[2] * seasons[3]
# query the hash table by key:
fruit = r1.get(var[0]) # r1 * var[0]
weight = r1.get(var[1]) # r1 * var[1]
season = r1.get(var[2]) # r1 * var[2]