Python问题记录

近期重新拾起python做一些工作,太久不搞很多细节忘记了,近期记录一下遇到的问题,未来重新温习python的时候会试图解释这些问题。问题感觉有点蠢。。。

问题1:关于包调用

下好jieba分词,然后运行一个demo就报错了

# -*- coding: utf-8 -*-
import jieba 
text = "美国总统拜登当地时间26日又语出惊人。据路透社报道,拜登当天在波兰的演 讲中,称俄罗斯总统普京“不能继续掌权了”。白宫官员随后出来解释,克里姆林宫同日 也作出回应,称“这不是由拜登决定的”。报道称,在华沙皇家城堡发表的讲话中,拜登在谴责普京后表示“看在上帝的份上,这个人不能继续掌权了”。对此,路透社表示,该言论引发了华盛顿方面对局势升级的担忧,美国一直避免直接对乌克兰进行军事干预,并明确表示不支持政权更迭。随后,一名白宫官员对拜登这番话进行解释,称拜登的言论并不代表华盛顿政策的转变,其目的是让世界为乌克兰问题上的长期冲突做好准备。该官员称,拜登意为“不能 允许普京对其邻国或该地区行使权力”,而不是在讨论普京在俄罗斯的权力或俄 罗斯的政权 更迭问题。同日,路透社称,被问及拜登这一言论时,俄罗斯总统新闻秘书佩斯科夫作出回应,称“这不是由拜登决定的。俄罗斯总统是由俄罗斯人选举产生的”。此前 ,俄罗斯安全会议副主席梅德韦杰夫接受俄媒采访时曾表示,俄特别军事行动既定目标包括实现乌克兰去军事化、去纳粹化、成为中立国家、不奉行反俄政策。俄开展特别军事行动首先是因为其设定的目标未能通过外交方式实现。他表示,社会调查显示,四分之三的俄罗斯民众支持在乌开展特别军事行动。西方国家企图通过制裁影响俄民众,煽动他们反对政府,结果适得其反。"
result = jieba.analyse.extract_tags(text, topK=20, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v', 'nr', 'nt'))
print(result)

报错信息如下:
AttributeError: module 'jieba' has no attribute 'analyse'
随后我输入print(jieba)能够看到jieba的安装位置,发现文件下其实有analyse文件夹,但却无法调用。
后找到解决方案

import jieba
改为
import jieba.analyse

后我回忆起之前想要调用某个包下的子包的时候,需要使用 import jieba.*等方式。最近事情有点多,后续python重新温习一遍

问题2:Pytorch 索引问题

在学习李沐的手动实现softmax代码的时候,遇到了一个索引问题。找了一些资料,但是没有找到和我问题类似的用法,我就自己琢磨了一下,然后记录了下来。

y = torch.tensor([0, 2])
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y_hat[[0, 1], y]
>> tensor([0.1000, 0.5000])

y_hat[[0, 1], y]这个操作中,第一个维度选择了第0个维度和第1个维度,然后传入了和第一个维度等长的参数y,y中的每一个数字,都能够当作第一个维度中每个数组的索引。
该例子中,选出了第0行的数组后,选择了索引为0的数,确定下来了0.1, 然后选择了第1行的数组,选择了索引为2的数,确定了0.5
然后我认为,第一个维度选择了[0,1],那我直接传入:不也一样吗?然后我就出问题了

y_hat # (256, 10)
y # (256)
# 正确的写法
y_hat[range(len(y_hat)), y] #(256, )
# 我的写法
y_hat[:, y] # (256, 256)

离谱!然后我找了个例子琢磨了琢磨

y = torch.tensor([0, 1 , 2, 1, 0]) # (5, )
y_hat = torch.tensor([[0.1, 0.3, 0.6], 
                      [0.3, 0.2, 0.5], 
                      [0.2, 0.5, 0.3], 
                      [0.6, 0.2, 0.2], 
                      [0.9, 0.1, 0.1]]) # (5, 3)
y_hat[:, y] # (5, 5)
>> tensor([[0.1000, 0.3000, 0.6000, 0.3000, 0.1000],
           [0.3000, 0.2000, 0.5000, 0.2000, 0.3000],
           [0.2000, 0.5000, 0.3000, 0.5000, 0.2000],
           [0.6000, 0.2000, 0.2000, 0.2000, 0.6000],
           [0.9000, 0.1000, 0.1000, 0.1000, 0.9000]])
# y 换一下看看
y = torch.tensor([0, 0, 1, 2, 0]) # (5, )
y_hat[:, y] # (5, 5)
y_hat[:, y] # (5, 5)
>> tensor([[0.1000, 0.1000, 0.3000, 0.6000, 0.1000],
           [0.3000, 0.3000, 0.2000, 0.5000, 0.3000],
           [0.2000, 0.2000, 0.5000, 0.3000, 0.2000],
           [0.6000, 0.6000, 0.2000, 0.2000, 0.6000],
           [0.9000, 0.9000, 0.1000, 0.1000, 0.9000]])

小结论

第一个例子中,y整个数组作为了y_hat第0个维度所有数组的索引, 因为y是[0, 1, 2, 1, 0],所以选择了y_hat 第0行里面[0.1, 0.3, 0.6, 0.3, 0.1],在第二组里面y是[0, 0, 1, 2, 0], 所以选择了y_hat 第0行里面的[0.1, 0.1, 0.3, 0.6, 0.1]
有点不太会说了,总之这两种方法有区别,记录一下!
原本正确的写法,和torch.gather()的作用类似!

问题3:Pytorch中的存储问题 RuntimeError: CUDA error: out of memory

CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

最近遇到了两次类似的问题,之前没有发现过,但是网上也没有方案,记录一下

两次问题都出现在 torch.tensor 和 Dataset的加载上

第一次出现,加载Dataset

因为数据集较大,每次初始化dataset的时候都需要30min时间,这样在debug的时候十分难受,于是就想到在构建好dataset之后存储到本地文件里,然后使用的时候直接读取,这样就非常快!

在使用DataLoader的时候会传入一参数叫做collate_fn的函数,这个被定义在了dataset中。在读取到Dataset之后,使用类似dataset.collate_fn等方法传递给DataLoader就能使用了。
这个collate_fn在对dataset中的数据处理的时候,使用了self.device将其中的tensor放到GPU上!这里的self.device是初始化dataset的时候传入的,因此就算我现在使用的时候设定cuda也是不会起作用的。例如当初构建dataset的时候传入了cuda:0, 那么读取后,collate_fn函数内部使用的就是当初的cuda:0, 而不会是现在你指定的cuda:xxx。此时若cuda:0没空间了,就会报错,如果后续不将数据转移到同一个GPU上,应该还会报别的错误。

第二次出现,加载torch.tensor

因为比赛需要将训练一个中间结果存下来,这是使用torch.save()存下来的,传进去的是一个tensor,并且指定了cuda,因此和上面一样,当我使用torch.load的时候还是会加载到原本的cuda上面,如果之前的GPU没有莫得显存的话,还是会报错!

结论

以后存东西要么搞回到CPU,要么转成numpy的数据结构存。

posted @ 2022-04-08 23:36  アイラ  阅读(228)  评论(0)    收藏  举报