【教程】Cupy、Numpy、Torch互相转换

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]

如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~

目录

概念介绍

CuPy

NumPy

Tensor

示例代码


概念介绍

CuPy

  • 定义CuPy 是一个 GPU 加速的数组计算库,专门设计来在 NVIDIA GPU 上执行高效的数值计算。它的 API 和 NumPy 类似,因此 CuPyNumPy 的 GPU 版本。
  • 特点
    • CuPy 通过 CUDA(NVIDIA 提供的并行计算架构)在 GPU 上执行大规模并行计算,相较于 NumPy,它可以显著提高数值运算的速度,尤其是在深度学习、科学计算等需要大量数据处理的场景下。
    • CuPyNumPy 的接口几乎是完全兼容的,支持几乎所有 NumPy 数组操作,如广播、索引、数学运算等。
    • 支持直接与 GPU 进行内存操作,避免数据传输时的性能瓶颈。
    • 可以与 PyTorch 等深度学习框架集成,提供高效的 GPU 数组操作。
  • 主要用途
    • 数值计算、矩阵运算、图像处理、深度学习等。
    • 高效利用 GPU 计算资源加速数据处理。

NumPy

  • 定义NumPy 是 Python 中用于进行高效数组操作的核心库,广泛用于科学计算、数据分析等领域。它为 Python 提供了高效的数组操作功能,特别是在多维数组(ndarray)的操作上。

  • 特点

    • CPU 基础NumPy 运行在 CPU 上,虽然它的数组操作是高度优化的,但相比 CuPy,在需要大量并行计算的场景下,性能可能不如 CuPy
    • 广泛的数学库NumPy 提供了大量的数学函数,包括线性代数、傅里叶变换、随机数生成等。
    • 兼容性NumPy 是 Python 数值计算的基础,许多其他库(如 SciPyPandasTensorFlowPyTorch)都依赖于 NumPy 数组进行数据传递和计算。
    • 数据存储NumPy 数组在内存中是连续存储的,这有助于加速访问速度。
  • 主要用途

    • 数学计算、线性代数、统计分析、图像处理等。
    • 数据预处理和科学计算。

Tensor

  • 定义Tensor 是深度学习框架(如 PyTorchTensorFlow)中用于表示多维数组的数据结构。它类似于 NumPy 数组,但通常具有更多的功能,比如自动求导(用于反向传播)、在 GPU 上执行加速计算等。

  • 特点

    • 深度学习专用Tensor 主要用于深度学习框架,它包含了用于神经网络训练的多种功能,如梯度计算和模型参数更新。
    • 支持多设备 :与 NumPyCuPy 不同,Tensor 可以在不同的设备(如 CPU、GPU)上进行计算。PyTorchTensorFlow 都允许将 Tensor 数据直接传输到 GPU 上进行加速运算。
    • 自动求导 :在深度学习中,Tensor 经常与自动求导机制(如 PyTorchautograd)结合使用,用于计算模型训练中的梯度。
    • 高效计算 :与 NumPyCuPy 相比,Tensor 在支持多设备并行计算(尤其是在 GPU 上)时性能非常强大。
  • 主要用途

    • 深度学习、神经网络训练和推理。
    • 图像处理、序列建模、强化学习等 AI 任务。

示例代码

python 复制代码
import cupy as cp
import numpy as np
import torch
import time


def convert_tensor(input_array, target_type, device=None):
    """
    将输入的数据类型转换为目标类型,支持 CuPy、NumPy 和 PyTorch Tensor 之间的转换。
    对于 CuPy 到 PyTorch 的转换,使用 DLPack 进行高效转换。

    参数:
    input_array: 输入的数组,可以是 CuPy 数组、NumPy 数组或 PyTorch Tensor
    target_type: 目标类型,可以是 'cupy', 'numpy', 或 'torch'

    返回:
    转换后的目标类型的数据
    """
    if isinstance(input_array, cp.ndarray):
        # 从 CuPy 转换
        if target_type == 'numpy':
            return input_array.get()  # 或 cp.asnumpy(input_array)
        elif target_type == 'torch':
            # CuPy 到 PyTorch 使用 DLPack
            res = torch.utils.dlpack.from_dlpack(input_array.toDlpack())
            # return torch.from_numpy(input_array.get())
            # 如果目标设备是 None,则返回默认设备上的 tensor;否则转移到指定的设备
            if device: res = res.to(device)
            return res
        else:
            raise ValueError(f"Unsupported target type '{target_type}' for CuPy array.")

    elif isinstance(input_array, np.ndarray):
        # 从 NumPy 转换
        if target_type == 'cupy':
            if device:
                with cp.cuda.Device(device[-1]):
                    res = cp.asarray(input_array)
            else:
                res = cp.asarray(input_array)
            return res
        elif target_type == 'torch':
            res = torch.from_numpy(input_array)
            # 如果目标设备是 None,则返回默认设备上的 tensor;否则转移到指定的设备
            if device: res = res.to(device)
            return res
        else:
            raise ValueError(f"Unsupported target type '{target_type}' for NumPy array.")

    elif isinstance(input_array, torch.Tensor):
        # 从 PyTorch Tensor 转换
        if target_type == 'cupy':
            # 确保 tensor 在 GPU 上
            if input_array.device.type != 'cuda': raise ValueError("PyTorch tensor must be on GPU.")
            if device: input_array = input_array.to(device)
            return cp.from_dlpack(torch.utils.dlpack.to_dlpack(input_array))
            # return cp.asarray(input_array.cpu().numpy())
        elif target_type == 'numpy':
            return input_array.numpy()
        else:
            raise ValueError(f"Unsupported target type '{target_type}' for PyTorch Tensor.")
    else:
        raise TypeError("Input must be a CuPy array, NumPy array, or PyTorch Tensor.")
python 复制代码
# 示例用法:
# 创建一个较大的数组
N = 10**6  # 100万元素
# CuPy -> NumPy
cp_array = cp.random.rand(N)
t = time.time()
np_array = convert_tensor(cp_array, 'numpy')
print(f'[{time.time()-t}] {np_array}')

# NumPy -> PyTorch
np_array = np.random.rand(N)
t = time.time()
tensor = convert_tensor(np_array, 'torch')
print(f'[{time.time()-t}] {tensor}')

# NumPy -> CuPy
np_array = np.random.rand(N)
t = time.time()
tensor = convert_tensor(np_array, 'cupy', 'cuda:0')
print(f'[{time.time()-t}] {tensor}')

# PyTorch -> CuPy
tensor = torch.rand(N, device='cuda:0')
t = time.time()
cp_array = convert_tensor(tensor, 'cupy', device='cuda:0')
print(f'[{time.time()-t}] {cp_array}')

# CuPy -> PyTorch (通过 DLPack)
cp_array = cp.random.rand(N)
t = time.time()
torch_tensor = convert_tensor(cp_array, 'torch')
print(f'[{time.time()-t}] {torch_tensor}')
相关推荐
四口鲸鱼爱吃盐11 小时前
Pytorch | 从零构建GoogleNet对CIFAR10进行分类
人工智能·pytorch·分类
leaf_leaves_leaf11 小时前
win11用一条命令给anaconda环境安装GPU版本pytorch,并检查是否为GPU版本
人工智能·pytorch·python
夜雨飘零111 小时前
基于Pytorch实现的说话人日志(说话人分离)
人工智能·pytorch·python·声纹识别·说话人分离·说话人日志
四口鲸鱼爱吃盐12 小时前
Pytorch | 从零构建MobileNet对CIFAR10进行分类
人工智能·pytorch·分类
苏言の狗12 小时前
Pytorch中关于Tensor的操作
人工智能·pytorch·python·深度学习·机器学习
四口鲸鱼爱吃盐17 小时前
Pytorch | 利用VMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
四口鲸鱼爱吃盐17 小时前
Pytorch | 利用PI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
love you joyfully1 天前
目标检测与R-CNN——pytorch与paddle实现目标检测与R-CNN
人工智能·pytorch·目标检测·cnn·paddle
这个男人是小帅2 天前
【AutoDL】通过【SSH远程连接】【vscode】
运维·人工智能·pytorch·vscode·深度学习·ssh
四口鲸鱼爱吃盐2 天前
Pytorch | 利用MI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python