List, Numpy,Ndarrary

Numpy
不要使用rank为1的,在python中(5,)既不是行向量也不是列向量,they are rank 1 arrays
行向量和列向量一定有两个括号,即(5,1)(1,5)
使用assert和.shape帮助Debug
在这里插入图片描述
可以用reshape消除rank1array


list,numpy,pytorch互转

首先要理解框架:
list是Python自带的容器,可以当作数组使用。但列表中的元素可以是任何对象,因此列表中保存的是对象的指针,这样一来,为了保存一个简单的列表[1,2,3]。就需要三个指针和三个整数对象。对于数值运算来说,这种结构显然不够高效。
numpy下的ndarray就是我们在c语言中常用的数值数组。以下常用掌握的ndarray:
生成均匀分布的array:
arange(最小值,最大值,步长)(左闭右开) : 创建等差数列
linspace(最小值,最大值,元素数量)
生成特殊数组
np.ones: 创建一个数组, 其中的元素全为 1
np.zeros: 创建元素全为 0 的数组, 类似 np.ones
np.eye: 创建一个对角线为 1 其他为 0 的矩阵.
np.identity: 创建一个主对角线为 1 其他为 0 的方阵.
获取数组的属性
a.ndim 维度的数量
a.shape
a.size 全部元素的数量
在这里插入图片描述
Tensor和ndarray都能输出shape。

Tensor:
无论使用哪个深度学习框架,它的张量类(在MXNet中为ndarray, 在PyTorch和TensorFlow中为tensor)都与Numpy的ndarray类似。 但深度学习框架又比Numpy的ndarray多一些重要功能:
首先,Numpy 是强大的数据操作工具,而NumPy仅支持CPU计算不能在GPU上运行,需将ndarray转换成tensor才行。
其次,这些模块下的张量类支持自动微分,张量对象具有梯度追踪的功能,这也是区别于ndarray的关键。
这些功能使得张量类更适合深度学习。

NumPy 中的很多函数对于 PyTorch 的张量(torch.Tensor)和 NumPy 数组(np.ndarray)都是适用的。这是因为 PyTorch 设计时考虑到了与 NumPy 的兼容性,因此提供了对张量进行 NumPy 风格的操作。

下面考虑Tensor在CPU和GPU上的特殊性:
只有Tensor自带.to方法,用于方便的转换。
pytorch 自带的函数比如torch.cat(),只需要保证所有的数据都在同一端即可。
但是numpy带的函数要求数据在host端,它的函数被设计用于处理主机端的内存中的数据。
所以这样一来一回,基本上是一套:

data = data.detach().cpu().numpy()
res = np.stack(data) //此时res是ndarrary的类型,要转回tensor
res = torch.Tensor(res).to(device)

标准:要写detach,更健壮。这样可以确保不会意外的发生梯度计算
total_loss += loss.detach().cpu().numpy()

一些Tips:

  1. 在使用numpy的一些函数的时候,比如:np.stack 会隐式地调用这些 PyTorch 张量的 .numpy() 方法,将其转换为 NumPy 数组,并在堆叠操作中使用。
    np.stack(res, axis=0) 将 res 中的张量沿着第一个轴(时间步)堆叠,产生一个 NumPy 数组(np.ndarray)。这一步中,PyTorch 张量被转换为 NumPy 数组。
    torch.tensor(res) 将 NumPy 数组转换回 PyTorch 张量。这一步是为了将结果转换回 PyTorch 张量,因为后续的计算或处理需要使用 PyTorch。

  2. PyTorch 在执行 .numpy() 操作时会自动进行梯度的去除。这是因为 NumPy 操作不会跟踪梯度,所以在转换为 NumPy 数组之前,PyTorch 会确保相应的梯度信息被移除。

  3. Python 的列表(list)可以包含任何类型的对象,包括 CPU 上的数据、GPU 上的 PyTorch 张量、自定义对象等。列表不对元素的类型做出限制,因此你可以在列表中存储各种类型的数据。List不区分里面的数据到底是哪一端的。

  4. cuda(‘cuda:1’) 是 PyTorch 中用于将张量移动到 GPU 的一种方法,而 .to(‘cuda:1’) 是通用的设备迁移方法,可以将张量移动到指定的设备上,包括 GPU。两者的效果是相同的。

Related Error:

TypeError: flatten() takes from 0 to 1 positional arguments but 2 were given
原因是没有调用tensor的flatten方法,而是去调用了ndarray的flatten方法,所以还是要区分好这两个。有一些共同点。
TypeError: can’t convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

spikes = []
spikes.append(output)改成:
spikes.append(output.cpu().numpy())后才能正常输出
spikes_array = np.array(spikes)
print(spikes_array.shape)

这种if其实都没有必要
在这里插入图片描述
再看一些代码优化:
原:

pred = torch.cat(predicted_list, dim=2)
pred = pred.clone().detach().to(device=torch.device('cuda))

改:
predicted_list是列表,经过torch.cat肯定变成了tensor,直接后面加to(device)

pred = torch.cat(predicted_list, dim=2).to(device)

这篇博客讲了ndarray和tensor底层数据共享的特点,很重要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值