python - 截断 Pytorch 张量的 SVD 分解而不转移到 cpu
问题描述
我正在 Pytorch 中训练一个模型,我想使用截断的 SVD 分解输入。为了计算 SVD,我将输入女巫是 Pytorch Cuda 张量到 CPU 并使用TruncatedSVD
from scikit-learn
perform truncate,之后,我将结果传输回 GPU。以下是我的模型的代码:
class ImgEmb(nn.Module):
def __init__(self, input_size, hidden_size):
super(ImgEmb, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.drop = nn.Dropout(0.2)
self.mlp = nn.Linear(input_size/2, hidden_size)
self.relu = nn.Tanh()
self.svd = TruncatedSVD(n_components=input_size/2)
def forward(self, input):
svd=self.svd.fit_transform(input.cpu())
svd_tensor=torch.from_numpy(svd)
svd_tensor=svd_tensor.cuda()
mlp=self.mlp(svd_tensor)
res = self.relu(mlp)
return res
我想知道是否有一种方法可以实现截断的 SVD 而无需来回传输到 GPU?(因为它非常耗时并且根本没有效率)
解决方案
您可以直接使用 PyTorch 的 SVD 并手动截断它,或者您可以使用来自TensorLy的截断 SVD和 PyTorch 后端:
import tensorly as tl
tl.set_backend('pytorch')
U, S, V = tl.truncated_svd(matrix, n_eigenvecs=10)
但是,GPU SVD 在大型矩阵上的扩展性不是很好。您还可以使用 TensorLy 的部分 svd,它仍会将您的输入复制到 CPU,但如果您只保留几个特征值会更快,因为它将使用稀疏特征分解。在 Scikit-learn 的截断 SVD 中,您还可以使用 'algorithm = arpack' 来使用 Scipy 的稀疏 SVD,如果您只需要几个组件,这可能会更快。
推荐阅读
- aws-glue - AWS Glue 自定义分类器
- visual-studio - 在 Visual Studio 2019 中重新打开关闭的选项卡(撤消关闭)?
- flutter - 滚动未来的 ListView
- flutter - 未处理的异常:RangeError(索引):无效值:有效值范围为空:0
- forms - Symfony 完全忽略了重定向和表单的处理
- facebook - Chatfuel 或 Manychat 等聊天机器人平台如何在后端创建 Facebook 应用程序来服务聊天机器人?
- python - 如何以表格格式编写日志记录我希望它们在 python 中按列显示而不使用 pandas
- scala - Scala 泛型类型扩展了 Comparable 接口
- swiftui - 用于在触摸上执行操作的 SwiftUI 方法
- angular - 角,访问,写管