import torch import numpy as np class RFFeatureMap(torch.nn.Module): def __init__(self, input_dim, output_dim, sigma=1.0): super().__init__() self.input_dim = input_dim self.output_dim = output_dim self.sigma = sigma # 随机生成特征映射所需的正弦和余弦函数的系数 self.omega = torch.randn(output_dim, input_dim) * self.sigma self.b = torch.rand(output_dim) * 2 * np.pi def forward(self, x): # 计算特征映射 x = x.view(-1, self.input_dim) z = torch.cos(torch.mm(x, self.omega.t()) + self.b) return z
这里我们定义了一个名为RFFeatureMap
的类,它继承自PyTorch的nn.Module
类。该类接受输入维度input_dim
、输出维度output_dim
和高斯核参数sigma
作为参数。在初始化函数中,我们生成了随机正弦和余弦函数的系数omega
和随机偏移量b
,并将它们保存在该类的实例变量中。
在前向函数中,我们首先将输入x
转换为形状为(batch_size, input_dim)
的张量。然后我们通过点乘x
和omega
的转置,加上偏移量b
,并应用余弦函数,计算出特征映射z
。最后我们返回特征映射z
。
下面是一个示例代码,演示如何使用PyTorch生成随机数作为输入数据,并使用上面提供的RFFeatureMap
类对其进行降维:
import torch # 定义随机数生成器 rng = torch.Generator() rng.manual_seed(0) # 定义输入数据的维度和数量 input_dim = 100 num_samples = 1000 # 生成随机输入数据 x = torch.randn(num_samples, input_dim, generator=rng) # 定义特征映射的维度 output_dim = 50 # 创建随机傅里叶特征映射 rf_map = RFFeatureMap(input_dim, output_dim) # 对输入数据进行特征映射 z = rf_map(x) # 打印输出数据的形状 print(z.shape) # 输出: torch.Size([1000, 50])
在此示例中,我们首先定义了一个随机数生成器rng
,并使用其生成了一个大小为(num_samples, input_dim)
的随机输入张量x
。然后我们定义了输出维度output_dim
,并创建了一个RFFeatureMap
实例rf_map
,该实例将输入维度从input_dim
降至output_dim
。
最后,我们使用特征映射rf_map
对输入张量x
进行处理,并将输出结果保存在变量z
中。最终,我们打印出z
的形状,结果为(num_samples, output_dim)
,表明成功地将输入数据从input_dim
降至output_dim
维。
-----------------介绍一下上面的x = torch.randn(num_samples, input_dim, generator=rng)中的generator=rng
在PyTorch中,torch.randn()
函数可以用于生成服从标准正态分布的随机数张量。该函数接受张量的形状作为输入,并返回一个张量,其中的元素都是从标准正态分布中抽取的随机数。
在上述代码中,我们通过传递generator=rng
参数来指定了一个随机数生成器rng
,用于生成随机数张量x
。这个随机数生成器是一个PyTorch中的torch.Generator
类的实例,用于控制随机数生成的过程,使得每次运行程序时生成的随机数序列都是确定的。
在某些情况下,例如在训练深度神经网络时,我们需要确保每次运行程序时都生成不同的随机数序列。这时候,我们可以在每次生成随机数张量时都使用不同的随机数生成器实例,这样可以避免不同运行时的随机数相同的问题。
因此,我们可以在每次生成随机数张量时,通过generator
参数指定一个新的torch.Generator
实例,从而生成不同的随机数序列。例如:
# 使用不同的随机数生成器生成两个随机数张量 x1 = torch.randn(10, generator=torch.Generator()) x2 = torch.randn(10, generator=torch.Generator())
在这个例子中,我们分别使用了两个不同的torch.Generator
实例来生成两个大小为(10,)
的随机数张量。这样可以确保每次生成的随机数序列都是不同的。
-----------如果要确定相同怎么办?
如果需要在多次运行程序时生成相同的随机数序列,可以通过设置随机数生成器的种子(seed)来实现。
在PyTorch中,可以使用torch.manual_seed()
函数来设置全局随机数生成器的种子,该种子将影响所有使用该生成器生成的随机数。例如,我们可以在程序的开头调用torch.manual_seed(0)
函数来设置全局随机数生成器的种子为0
,这样每次运行程序时都将生成相同的随机数序列。
在上述代码中,我们使用了一个torch.Generator
实例rng
作为随机数生成器,并通过rng.manual_seed(0)
函数设置了该生成器的种子为0
。因此,在生成随机数张量x
时,我们传递了generator=rng
参数,以确保每次运行程序时都生成相同的随机数序列。
下面是一个示例代码,演示如何在PyTorch中生成相同的随机数序列:
import torch # 设置全局随机数生成器的种子 torch.manual_seed(0) # 创建随机数生成器 rng = torch.Generator() rng.manual_seed(0) # 生成随机数张量 x = torch.randn(10, generator=rng) # 打印生成的随机数张量 print(x)
在这个例子中,我们首先使用torch.manual_seed(0)
函数设置全局随机数生成器的种子为0
。然后我们创建了一个torch.Generator
实例rng
,并使用rng.manual_seed(0)
函数设置了该生成器的种子为0
。最后,我们使用rng
生成器生成了一个大小为(10,)
的随机数张量,并打印了该张量的值。由于种子相同,因此每次运行程序时都将生成相同的随机数张量。