PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.23k stars 5.58k forks source link

静态图如何将tensor转为numpy #31972

Closed rock4you closed 1 year ago

rock4you commented 3 years ago

PaddlePaddle 1.8.4,实现GHM Loss 在计算损失函数的时候,中间需要进行如下操作: g = fluid.layers.abs(logit - label) #g的尺寸 N * class_num ; 判断g的每个位置是否在某个取值区间,从而得到一个与g同尺寸的 True/False 矩阵M; 对矩阵M进行统计,得到与g相同尺寸的权重矩阵W

简单的做法是将g转为numpy,不过文档中没有找到相关的教程,所以问题是:静态图,如何将tensor转为numpy 或者提供其他能够解决上述问题的方式。

paddle-bot-old[bot] commented 3 years ago

您好,我们已经收到了您的问题,会安排技术人员尽快解答您的问题,请耐心等待。请您再次检查是否提供了清晰的问题描述、复现代码、环境&版本、报错信息等。同时,您也可以通过查看官网API文档常见问题历史IssueAI社区来寻求解答。祝您生活愉快~

Hi! We've received your issue and please be patient to get responded. We will arrange technicians to answer your questions as soon as possible. Please make sure that you have posted enough message to demo your request. You may also check out the APIFAQGithub Issue and AI community to get the answer.Have a nice day!

chenwhql commented 3 years ago

将g加到exectuor的fetch list里面,fetch回来默认就是numpy

rock4you commented 3 years ago

将g加到exectuor的fetch list里面,fetch回来默认就是numpy

有没有示例代码?

chenwhql commented 3 years ago

您的executor.run怎么写的,加到fetch list里就行 image

rock4you commented 3 years ago

您的executor.run怎么写的,加到fetch list里就行 image

损失函数里只传进来两个参数,logit和label,还要把train_program传进来才行?

chenwhql commented 3 years ago

没太懂,您方便贴下关键代码吗

rock4you commented 3 years ago
def ghm_loss(logit, label, ignore_mask=None, num_classes=2):                                                                                                                                                  
    logit = fluid.layers.transpose(logit, [0, 2, 3, 1])                                                         
    logit = fluid.layers.reshape(logit, [-1, num_classes])                                                      
    logit = fluid.layers.sigmoid(logit)                                                                                                                                               
    weights = fluid.layers.zeros_like(logit)                                                 
    label = fluid.layers.transpose(label, [0, 2, 3, 1])                                                         
    label = fluid.layers.reshape(label, [-1, 1])                                                                
    label = fluid.layers.cast(label, 'int64')                                                                                                                                                                                                                                                  
    gg = fluid.layers.abs(logit - label) 
    g = np.array(gg)                                                                                                                                                                                                     
    bins = 10                                                                                                   
    edges = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0001 ]                                           
    valid = label > -1                                                        
    valid = fluid.layers.cast(valid, 'int64')                                                                   
    total = max(fluid.layers.reduce_sum(valid), 1.0)                                
    n = 0                                                                                                                                                                                
    for i in range( bins ):                                                                                     
        inds = (g >= edges[i]) & (g < edges[i+1]) & valid                                                       
        num_in_bin = inds.sum()                                                         
        if num_in_bin > 0:                                                                                      
            weights[inds] = total / num_in_bin                                                                  
            n += 1                                                                                                                                                                                                     
    if n > 0:                                                                                                   
        weights = weights / n                                                                                                                                                                             
    label = fluid.layers.squeeze(label, axes=[-1])                                                              
    label_one_hot = fluid.one_hot(input=label, depth=num_classes)                                                                                                                                            
    weight = fluid.layers.reshape(weights, [-1, num_classes])                                                   
    weighted_label_one_hot = fluid.layers.elementwise_mul(label_one_hot, weight)                                
    probs = fluid.layers.softmax(logit)    
chenwhql commented 3 years ago

也需要executor相关的

rock4you commented 3 years ago

也需要executor相关的

损失函数是独立的文件,是需要train.py里的exec吗

rock4you commented 3 years ago
loss, lr, pred, grts, masks = exe.run(                                                      
                        program=compiled_train_prog,                                                            
                        fetch_list=fetch_list,                                                                  
                        return_numpy=True)
chenwhql commented 3 years ago

噢那您需要在这里把g作为结果返回,传到train.py的exe.run的fetch_list参数中,不需要传program进来

rock4you commented 3 years ago

噢那您需要在这里把g作为结果返回,传到train.py的exe.run的fetch_list参数中,不需要传program进来

能帮忙写一下吗?没太明白

chenwhql commented 3 years ago

不知道您其他代码怎么组织的,大概类似这样

def ghm_loss(logit, label, ignore_mask=None, num_classes=2):                                                                                                                                                  
    logit = fluid.layers.transpose(logit, [0, 2, 3, 1])                                                         
    logit = fluid.layers.reshape(logit, [-1, num_classes])                                                      
    logit = fluid.layers.sigmoid(logit)                                                                                                                                               
    weights = fluid.layers.zeros_like(logit)                                                 
    label = fluid.layers.transpose(label, [0, 2, 3, 1])                                                         
    label = fluid.layers.reshape(label, [-1, 1])                                                                
    label = fluid.layers.cast(label, 'int64')                                                                                                                                                                                                                                                  
    gg = fluid.layers.abs(logit - label) 

    bins = 10                                                                                                   
    edges = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0001 ]                                           
    valid = label > -1                                                        
    valid = fluid.layers.cast(valid, 'int64')                                                                   
    total = max(fluid.layers.reduce_sum(valid), 1.0)                                
    n = 0                                                                                                                                                                                
    for i in range( bins ):                                                                                     
        inds = (g >= edges[i]) & (g < edges[i+1]) & valid                                                       
        num_in_bin = inds.sum()                                                         
        if num_in_bin > 0:                                                                                      
            weights[inds] = total / num_in_bin                                                                  
            n += 1                                                                                                                                                                                                     
    if n > 0:                                                                                                   
        weights = weights / n                                                                                                                                                                             
    label = fluid.layers.squeeze(label, axes=[-1])                                                              
    label_one_hot = fluid.one_hot(input=label, depth=num_classes)                                                                                                                                            
    weight = fluid.layers.reshape(weights, [-1, num_classes])                                                   
    weighted_label_one_hot = fluid.layers.elementwise_mul(label_one_hot, weight)                                
    probs = fluid.layers.softmax(logit) 

    return gg

# train.py

gg = ghm_loss(...)
fetch_list.append(gg.name)

loss, lr, pred, grts, masks, gg_numpy = exe.run(                                                      
                        program=compiled_train_prog,                                                            
                        fetch_list=fetch_list,                                                                  
                        return_numpy=True)
rock4you commented 3 years ago

好的,我试试,非常感谢

chenwhql commented 3 years ago
gg = fluid.layers.abs(logit - label) 
g = np.array(gg)   

这种写法是不行的,静态图在exe.run之前,属于组网阶段,这些变量都没有实际值的

rock4you commented 3 years ago

ok

rock4you commented 3 years ago
gg = fluid.layers.abs(logit - label) 
g = np.array(gg)   

这种写法是不行的,静态图在exe.run之前,属于组网阶段,这些变量都没有实际值的

损失函数在train.py line 237 这里被调用, https://github.com/PaddlePaddle/PaddleSeg/blob/release/v0.7.0/pdseg/train.py#L237

exe.run在 train.py line 330 https://github.com/PaddlePaddle/PaddleSeg/blob/release/v0.7.0/pdseg/train.py#L330

想要根据gg内部的值,计算出一个weight,再结合label计算损失,应该怎么改呢?

chenwhql commented 3 years ago

这是组网的一部分,那你要用paddle API接着组网,比如你想怎么计算就要在gg那个地方接着写

weight = gg * 2
cross_entropy(weight, label)

要理解静态图声明计算的过程和实际执行是分开的,你先用API组网,声明你想要进行的计算,exe.run的时候才会执行

rock4you commented 3 years ago

上面我定义的那个ghm_loss函数,需要用到两个变量logit, label,这两个变量是在model_builder.py中才有,在train.py中并没有定义,没法直接这么写吧?有没有现成的例子可以参考的?

chenwhql commented 3 years ago

Seg模型实现不是很熟悉,这个麻烦 @chenjiaoAngel 找PaddleSeg的同学帮这位同学看看

LutaoChu commented 3 years ago

@rock4you 你好,我看你的代码中对g的操作只有比较

(g >= edges[i]) & (g < edges[i+1])

推荐使用fluid.layers.greater_than,和fluid.layers.less_than,不推荐转numpy,能用paddle op实现尽量用paddle op

rock4you commented 3 years ago

那这里的edges[i] 数值怎么转variable呢?

LutaoChu commented 3 years ago

这里不需要转吧 如果不支持的话试试slice op

rock4you commented 3 years ago

TypeError: The type of 'y' in greater_equal must be (<class 'paddle.fluid.framework.Variable'>, <class 'paddle.fluid.core_avx.VarBase'>), but received <class 'int'>.

rock4you commented 3 years ago

这里不需要转吧 如果不支持的话试试slice op

具体怎么写呢?我这里需要拿Variable和一个float类型的变量值进行对比

LutaoChu commented 3 years ago

定义的部分改写成如下 edges = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0001 ] ) edges = paddle.assign(edges)

rock4you commented 3 years ago

inds = fluid.layers.greater_equal(x=gg, y=edges[i]) & fluid.layers.less_than(x=gg, y=edges[i+1]) & valid
TypeError: unsupported operand type(s) for &: 'Variable' and 'Variable' 这里说两个Variable之间不能进行 “与运算”, 有没有对应的解决办法?

LutaoChu commented 3 years ago

你可以用paddle.logical_and实现“与运算” https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/fluid/layers/logical_and_cn.html#logical-and

rock4you commented 3 years ago

这么好的算子,竟然没法搜到

chairman-lu commented 1 year ago

有没有方法能在paddle静态图模式下将numpy.ndarray转为paddle.tensor呢