基于Pytorch的MAML学习

基于 MAML模型无关的元学习代码完整复现(Pytorch版)_miguemath的博客-CSDN博客_元学习代码 miguemath 博主的代码,进行MAML的学习,解决了一些error,供大家参考。

一、CUDA tensor格式的数据无法改成numpy

error:“TypeError: can‘t convert cuda:0 device type tensor to numpy. ......”

这是在想把CUDA tensor格式的数据改成numpy时发生的。因为 numpy不能读取CUDA tensor,所以需要先将其转换成cpu float-tensor随后再转到numpy格式。

解决方法:

(1)把numpy 1.21降为numpy1.19就好了。

pip install numpy==1.19

但是对我不起作用,因此选择方法(2)。

(2)我所用的解决方法——修改torch的源码。

在torch文件夹下,找到_tensor.py,寻找错误代码self.numpy()。

将报错代码self.numpy()改为self.cpu().detach().numpy()即可。如果改为self.cpu().numpy(),有可能出现本文-四的错误。

     if dtype is None:
         return self.cpu().detach().numpy()
     else:
         return self.cpu().detach().numpy().astype(dtype, copy=False)

二、损失函数计算

error:"nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Int'

是数据类型导致的错误,需要进行数据转换。

例如在我的代码中,是由于y_spt的原因。

找到损失函数计算的代码:

loss = F.cross_entropy(y_hat, y_spt)

在该行代码前面,添加一行,形成:

y_spt = y_spt.to(torch.int64)
loss = F.cross_entropy(y_hat, y_spt)

三、CUDA out of memory

(一)error:RuntimeError: CUDA out of memory

这个问题是由于PyTorch占用的GPU空间没有释放,导致下次运行时,出现CUDA out of memory。

在win系统下找到 Anaconda Powershell Prompt,在shell窗口下输入:

nvidia-smi

若出错,见本章第二部分 nvidia-smi : 无法将“nvidia-smi”项识别为 cmdlet、函数、脚本文件或可运行程序

本条命令是查看系统进程的,会显示GPU的使用情况,以及占用GPU的应用程序。

找到运行程序占用, 输入:

taskkill -PID 进程号 -F

结束占用进程,比如

taskkill -PID 32608 -F

即可释放GPU的占用空间。

(二)nvidia-smi : 无法将“nvidia-smi”项识别为 cmdlet、函数、脚本文件或可运行程序

这个问题是由于nvidia-smi.exe的文件路径没有添加到环境变量导致的,解决方法就是找到该文件路径后添加进环境变量。

一般nvidia-smi.exe的位置都在C:\Windows\System32中,可以在C:\Windows\System32中再ctrl+f,寻找到具体的位置。

找到位置之后,复制位置,打开高级系统设置,点环境变量。

找到系统变量中的path,双击打开编辑

点击新建,把C:\Windows\System32添加进去,保存。

再重新打开WindowsPowerShell,运行nvidia-smi,无错误,成功解决问题!

四、不能对需要grad的张量进行numpy

error:Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.

当计算中的数据类型为tensor时,想要获取其具体的数值,由于它带梯度值时,不能直接转为numpy格式,所以最好不论如何都调用一下xx.detach().numpy(),其中xx是要转换的数据。

解决方法:

def __array__(self, dtype=None):
      if has_torch_function_unary(self):
          return handle_torch_function(Tensor.__array__, (self,), self, dtype=dtype)
      if dtype is None:
          return self.cpu().numpy()
      else:
          return self.cpu().numpy().astype(dtype, copy=False)

改为

 def __array__(self, dtype=None):