遇到+容易忘的各种问题记录

2023/03/28
才知道,pytorch里的torch.Tensor是默认Float。torch.tensor才可以设置dtype
前段时间记录的一些内容:

  • lmdb close readonly:多进程只读的时候要设置readonly=True,lock=False
  • mp.Pool在一个Dataset里没法去做多进程,因为会有self参数的传入。在外部可以。initargs中因为每个是单独的进程,所以可以用global。可以在init里让每个进程有独立的数据库连接
  • np.max和np.sum,前者会慢一些,因为是条件选择
  • gpu和cpu的计算精度不同,cpu是double gpu是float。所以模型放到gpu上计算出来的数据可能会有不同。
  • 教训:一定要跑下源代码看下效果
  • 发现向collate_fn传参的方式:pytorch中collate_fn函数的使用&如何向collate_fn函数传参。我之前一直以为没法传参。。= =。
  • 教训:一定要做模块测试。不然debug很想死。
  • __file__可以读取当前py文件名
  • os.path的各种函数:join,relpath,dirname,abspath。创建文件夹os.makedirs
  • 好看地输出json,加indent=2:
with open(os.path.join(params.exp_dir, "params.json"), 'w') as fout:
    json.dump(vars(params), fout, indent=2)
  • debug卡死的时候看下是不是多进程num_workers不是0了
  • torch的squeeze如果不加参数会把所有的都squeeze了
import torch

a = torch.Tensor([[1]])
b = torch.Tensor([[1, 2]])

aa = a.squeeze()
aaa = a.squeeze(0)
bb = b.squeeze()
bbb = b.squeeze(0)
print(aa, aaa)  # tensor(1.) tensor([1.])
print(bb, bbb)  # tensor([1., 2.]) tensor([1., 2.])

比如上面这个代码,aa的结果是单个数值了

  • numpy中两个矩阵比较是否相等不可以用====比较的是每个位置上的值然后返回True/False的矩阵。所以如果要比较ab两个矩阵是否全部相等(a==b).all(),比较ab两个矩阵至少有一个元素相等(a==b).any()

2023/03/30

  • 使用tqdm的时候发现一个问题:当前处理的三元组是第462个,但是bug终止后显示界面是456、460等各种情况。所以不能根据tqdm最后控制台显示的数据判断当前在处理第几个数据。一定要用enumerate来看。

2023/03/31

  • pickle存储ndarray报错TypeError: a bytes-like object is required, not '_io.BufferedReader'
    最终做法:
import pickle
with open('a.txt', "wb") as f:
    pickle.dump(split['pos'], f)
with open('a.txt', "rb") as f:
    f = f.read()
    ans = pickle.loads(f)
  • collate_fn常用的代码,用于把输入数据整成一列一列:
def collate_fn(self, samples):
    # The input `samples` is a list of pairs
    graphs_pos, g_labels_pos, r_labels_pos = map(list, zip(*samples))
  • dgl的几个属性获得
    节点/边个数:g.number_of_nodes(),g.number_of_edges()
    ndata/edata_schemes:g.node_attr_schemes(),g1.edge_attr_schemes()
    节点/边:g.nodes(),g.edges()
  • 比较dgl对象。因为dgl不能直接通过==来比较,也不能像numpy一样用(array1==array2).all()比较,所以只能单独比较里面的所有元素:
assert g1.node_attr_schemes() == g2.node_attr_schemes()  # map 比较
assert g1.edge_attr_schemes() == g2.edge_attr_schemes()
def same(t1, t2):
    return (t1 == t2).cpu().detach().numpy().all()  # tensor比较 转换为numpy
assert same(g1.nodes(), g2.nodes())
assert same(g1.edges()[0], g2.edges()[0])
assert same(g1.edges()[1], g2.edges()[1])
  • pycharm自动生成函数注释:Settings->Tools->Python Integrated Tools->Docstrings,常选reStructuredText
  • 模块测试报错:python: __main__ is not a package,是因为用了相对应用.xxxpackage,但是.代表的就是__main__
    此外,常用的确保当前文件是执行文件的代码是if __name__ == '__main__':
  • 对lmdb的env下的数据读取做了个测试:
    情况1:每次读取都open/close env
    情况2:打开一个env,后面全部读取,最后关闭
    测试数据是读100000条dict信息,时间对比是:10s vs 0.45 s
    因此可见 open close很耗时

2023/04/01

  • 在看rank里的一个常见代码:rank = np.argwhere(np.argsort(curr_scores)[::-1] == 0) + 1
    y=np.argsort(x)是对x从小到大排序后的下标,此时x[y[0]]是x里最小的数;但是目标是找score最大的,所以通过[::-1]倒序,此时x[y[0]]是x里最大的数
    np.argwhere(x)是找x里非零元素的下标

2023/04/03

2023/04/04

  • 遇到一个bug,在y=x1矩阵乘x2的情况下,y[:7]==x1[:7]矩阵乘x2[:7]可能不成立,在毕设代码中发现的,后续在本地windows系统上做了一个实现,随机生成了22x32和32x32的float32矩阵,然后检查了上述情况,发现在取比较小的矩阵的时候比如[:3]就不会出错,但是大了就错;但是后续发现在服务器上运行、同学在linux系统上运行都不会有问题,只有在windows系统上出问题;但是我的毕设代码是放在服务器上跑的。。目前问题不知道是怎么造成的。把问题抛给师兄了。。。
  • 关于dgl中的update_all中的前两个参数message_func和。去年年底已经看懂了,今年看的时候又全忘了。。很懵
    message_func是返回每条边的信息,输入是一个EdgeBatch,是当前图g内的所有节点,返回需要返回一个字典,字典内是每条边的属性值,比如{'h':h,'feat':feat},h和feat应该是(edge_num, dim)的大小,确保每条边都有属性。
    reduce_func,GraIL代码里是是返回了一个nn.Module:Aggregator,forward的接收参数是node,是一个NodeBatch,官网的说法是接收同一群节点的node们。我画图理解了下,应该是指有相同邻居集合的一批节点们。比如有如下边:
    1->4,2->4
    1->5,2->5,3->5
    1->6,2->6,3->6
    易得56两个点有相同的邻居集合,那么56构成一个NodeBatch,而4的邻居是{1,2}不是{1,2,3},所以4是单独的一个NodeBatch。
    node可以通过mailbox获得邻居传来的信息,比如node.mailbox['h],上述node是{5,6}的时候h的大小就是(2,3,dim),2是NodeBatch里的节点个数,3是邻居集合里邻居的个数。所以node.mailbox['h'][i,j,:]表示的就是当前NodeBatch里节点i的j邻居传过来的信息。

2023/04/05

  • 突然理解了一行一直不理解的代码!return g.ndata.pop('h')。GraIL里我去年一直不理解为什么要pop掉然后在模型框架里重新接收。然后刚刚从师兄那知道,大多数表示学习的输入emb是可学习的,上一个epoch的训练结果数据可以用到下一epoch。

2023/04/06

  • ccproxy问题,记得在HTTP/RSTP协议右边的ip也填上校园网的ip,不然虽然能连上本机但是还是连不了网
  • pip报错Cannot uninstall 'certifi'. It is a distutils installed project and thus we cannot accurately determine ...。直接安装:pip install xxx --ignore-installed

2023/04/12

  • 把分数映射到01区间,可以用softmax和sigmoid。二分类的时候softmax和sigmoid是一样的,sigmoid是特殊的softmax。如果正负样本不是1:1,推荐用sigmoid。

2023/04/17

  • debug遇到报错:unable to get repr for <class 'dgl.frame.Frame'>{DGLError}Invalid edge ID 4861,没有搜到结果,但是有人说换成cpu,因为gpu可能不会显示真实错误。但是,鹅,我换了还是显示不了错误。。。
    Heterogeneous Graph 异构图,可以有不同类型的节点和边,具有独立的ID空间和特征。
    后续debug后发现,从一个异构图里抽取子图的时候会获得EID和NID,但是之后这个就不会变了;对于合并起来的图这个ID是没有效果的。因此我每次抽取之后重构EID和NID的数据:
@staticmethod
def reconstructID(subgraph):
    if subgraph is not None:
        subgraph.edata[dgl.EID] = torch.tensor(range(len(subgraph.edges()[0])), dtype=torch.long)
        subgraph.ndata[dgl.NID] = torch.tensor(range(len(subgraph.nodes())), dtype=torch.long)

最后发现还是有点问题,在aggregator的传播部分抽取到的nodebatch是不一样的,目前不知道为什么;但是我发现可以直接不要_ID这个东西。。解决一切。。。

@staticmethod
def reconstructID(subgraph):
    if subgraph is not None:
        if subgraph.ndata.get(dgl.NID) is not None:
            subgraph.ndata.pop(dgl.NID)
        if subgraph.edata.get(dgl.EID) is not None:
            subgraph.edata.pop(dgl.EID)
  • 比较两份代码参数都初始化为固定值后还是不一样:因为只记得固定weight但是忘了固定bias。。

2023/04/20

  • 学习了装饰器,感觉有点好使。
    类内装饰器:
def decorator_valid(function):
    def decorated(self, *args, **kwargs):
        self.model.eval()
        data = function(self, *args, **kwargs)
        self.model.train()
        return data
    return decorated

如果不要类内的,把decorated和function函数里的self参数删掉就可以了。

2023/04/27

  • debug比较两个对象,pycharm里debug变量直接复制然后右键比较。为了统一比较,直接统一初始化变量:
nn.init.constant(m.weight, 1)

2023/05/05

  • 过滤负三元组容易错的问题。①正确三元组不能过滤掉,label是False!②算auc的时候记得正确三元组的label是True!

2023/05/17

  • 在bash里通过sed传参,修改properties文件的内容:
sed -i 's/^PATH_TRAINING=.*/PATH_TRAINING='${PATH_TRAINING//"/"/"\/"}'/' $PROP
sed -i 's/name=.*/name='${VARIABLE}'/' output.txt

注意!sed命令里无法识别/,所以需要转义为\/

  • 在bash里对一个字符串变量替换内容:
${VARIABLE/"a"/"b"}
${VARIABLE//"a"/"b"}

第一行表示把第一个字符a修改为b,第二行表示把所有的a修改为b。

2023/07/25

  • 路径函数:
    找到当前路径相对于某个文件的路径(比如根目录):
  1. 先通过os.getcwd()得到当前py的的绝对路径
  2. 通过os.path.relpath(os.getcwd(), 'src')得到当前py相对于src的路径

2023/07/28

  • 安装环境报错:You may need to close and restart your shell after running 'conda init'
    解决方式:用source activate env_name 而不是conda activate env_name
  • 安装环境报错:PackagesNotFoundError: The following packages are not available from current channels
    解决方式:进入环境后搜索可用的包,conda search -f package_name
  • 安装环境:指定环境下载
    比如conda install -c conda-forge package_name,c是channel的缩写,意思是从https://anaconda.org/conda-forge里下载该包
    完整写法就是conda install --channel https://conda.anaconda.org/conda-forge package_name
  • 安装环境报错:conda search找到包后install报错找不到包
    解决方式:conda config --set offline false参考链接
    还有建议用mamba的,但是问题是我用conda也安不上mamba。。
    后续:因为是在autodl上找的服务器,所以要按帮助文档做一下部分事情。。我没做。。所以安装环境报错。。参考链接

2023/09/15

  • python url下载github上的资源报错:http.client.RemoteDisconnected: Remote end closed connection without response
    尝试了一些方式无果。然后看到下载的url是https开头的。
    电光火石间,突然想到我的.bashrc文件和.condarc文件里的https的代理都是http开头的,所以协议没对上。
    解决方式:代理改成https开头的就能下了
posted @   反射狐  阅读(87)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示