近似核方法Random Binning Feature(RBF)词嵌入降维
Random Binning Feature(RBF)
-
- 介绍
- 代码
- 附录-详细解释
介绍
Random Binning Feature(RBF)
。RBF
将输入数据映射到固定的特征空间,其中每个维度对应于输入数据的一个固定范围。这个范围由我们自己指定,并且在 RBF
中是固定不变的。
假设我们有一个形状为 (N, d)
的输入张量 x
,我们想要将其映射到形状为 (N, D)
的特征空间,其中 D
是我们想要映射到的特征空间的维度。我们可以按如下方式进行 RBF
映射:
将每个输入维度分成 k
个不同的范围,例如 [-1, -0.5], [-0.5, 0], [0, 0.5], [0.5, 1]
。这些范围被称为“箱子”(bins
)。
对于每个箱子,生成一个随机向量 r
,该向量的每个元素都是从标准正态分布中随机抽取的。
将每个输入维度分配到相应的箱子中。对于每个箱子,将输入维度中位于该箱子中的元素加起来,然后乘以该箱子对应的随机向量 r
。重复此过程 k
次,并将所有 k
个结果拼接在一起形成一个新的特征向量。
将所有箱子中的特征向量相加,得到最终的特征向量。
代码
代码如下:
import torchclass RBF(torch.nn.Module):def __init__(self, d, D, k):super(RBF, self).__init__()self.d = dself.D = Dself.k = kself.bins = self.generate_bins()self.r = self.generate_weights()def generate_bins(self):bins = []for i in range(self.d):bins.append(torch.linspace(-1, 1, self.k+1)[1:-1])return binsdef generate_weights(self):r = torch.randn(self.k, self.d, self.D)return rdef forward(self, x):batch_size = x.shape[0]x = x.unsqueeze(2).repeat(1, 1, self.k, self.D)bins = torch.tensor(self.bins).unsqueeze(2).unsqueeze(0).repeat(batch_size, 1, 1, self.D)x = (x > bins).to(torch.float32) * (x < bins + 1/self.k).to(torch.float32)x = x.sum(dim=1)r = self.r.unsqueeze(0).repeat(batch_size, 1, 1, 1)x = x.unsqueeze(3).repeat(1, 1, 1, self.D)r = r.repeat(batch_size, 1, self.k, 1)x = x * rx = x.sum(dim=2)return x
在这个代码中,我们定义了一个 RBF
类,它是一个继承自 PyTorch
的 nn.Module
类的子类。我们在 init
函数中初始化了 RBF
的一些参数,包括输入维度 d
、输出维度 D
和箱子数量 k
。我们还定义了两个帮助函数:generate_bins
和 generate_weights
。
generate_bins
函数生成了箱子列表。对于每个输入维度,我们使用 torch.linspace
在 [-1, 1]
之间生成 k+1
个数,并删除第一个和最后一个数。这些数用作该维度中的箱子边界。
generate_weights
函数生成了随机权重 r
。我们使用 PyTorch
的 torch.randn
函数从标准正态分布中随机生成 kdD
个数,并将其形状重塑为 (k, d, D)
。
在 forward
函数中,我们首先将输入张量 x
的形状重塑为 (batch_size, d, 1, 1)
,并使用 unsqueeze
和 repeat
函数来将其复制为形状为 (batch_size, d, k, D)
的张量。我们还将箱子列表转换为张量形式,并使用 unsqueeze
和 repeat
函数将其复制为形状为 (batch_size, d, k, D)
的张量。
接下来,我们将 x 和 bins 进行比较,生成一个布尔张量。使用 to
函数将布尔张量转换为浮点张量,并乘以 1/self.k
得到每个箱子中的元素数量。我们将所有元素数量相加得到一个形状为 (batch_size, k, D)
的张量。
然后,我们将随机权重 r
和上面的张量进行乘法,得到一个形状为 (batch_size, d, k, D)
的张量。使用 sum
函数沿着 k
维度进行求和,得到一个形状为 (batch_size, d, D)
的张量。
最后,我们将所有输入维度上的特征向量相加,得到最终的特征向量。
下面是一个实例化 RBF 类的例子:
import torch# 实例化RBF模型
rbf_model = RBF(d=10, D=5, k=20)# 生成随机数
x = torch.randn(32, 10)# 输入随机数到RBF模型中
output = rbf_model(x)print(output.shape) # 打印输出的形状
这里实例化了一个 RBF
类的对象 model
,其中 d=10
表示输入特征向量的维度为 10
,D=64
表示输出特征向量的维度为 64
,k=5
表示使用 5
个均匀分布的间隔将特征向量划分为若干个小区间。
附录-详细解释
以上代码实现了 Random Binning Feature (RBF)
方法,用于将高维输入数据映射到低维特征空间中。RBF
通过将输入空间分成多个小区间,并使用随机权重将每个小区间映射到低维特征空间中,从而实现降维的目的。
该代码实现了一个名为 RBF
的 PyTorch
模块,其构造函数接受三个参数:d
,表示输入数据的维度;D
,表示映射到的低维特征空间的维度;k
,表示每个输入维度被划分成的小区间数量。
在构造函数中,首先调用了父类的构造函数,然后将输入参数保存在类的属性中。接着,生成了一组小区间 bins
,其中每个小区间都是一个从 -1 到 1
的等间隔序列,序列长度为 k
。这些小区间用于将输入数据映射到低维特征空间中。
接下来,调用 generate_weights()
方法生成一个随机权重张量 r
,该张量的形状为 (k, d, D)
。该张量用于将每个小区间映射到低维特征空间中。
在 forward()
方法中,首先获取输入数据的 batch_size
,然后将输入数据的形状从 (batch_size, d)
变为 (batch_size, d, 1, 1)
,并将其复制 k
次得到形状为 (batch_size, d, k, 1)
的张量 x
。
将小区间 bins
变形为形状为 (1, d, k, 1)
的张量,并将其复制 batch_size
次得到形状为 (batch_size, d, k, 1)
的张量 bins
。
使用 x
和 bins
进行比较运算,得到一个布尔型张量,表示每个输入数据点位于哪个小区间中。将这个张量转换为浮点型张量,即可得到相应的二进制特征。这里使用了 PyTorch
的广播机制,将 x
和 bins
的形状进行了匹配。
使用 sum
函数对第二个维度进行求和,得到形状为 (batch_size, k, D)
的张量 x
。
使用 unsqueeze
函数将 x
的最后一个维度变为 (batch_size, k, D, 1)
,然后将 r
复制 batch_size
次得到形状为 (batch_size, k, d, D)
的张量 r
。
使用 repeat
函数将 x
和 r
的维度匹配,然后对它们进行点乘操作,得到形状为 (batch_size, d, D)
的张量 x
。
最后返回 x
,即为输入数据 x
在 RBF
映射下得到的低维特征表示。