Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GaussianNLLLoss API. #50843

Merged
merged 32 commits into from
Apr 13, 2023
Merged

Conversation

Atlantisming
Copy link
Contributor

PR types

New features

PR changes

APIs

Describe

rfc 文档链接:PaddlePaddle/community#372
中文文档链接:PaddlePaddle/docs#5623

@paddle-bot
Copy link

paddle-bot bot commented Feb 23, 2023

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@paddle-bot paddle-bot bot added contributor External developers status: proposed labels Feb 23, 2023
@Atlantisming
Copy link
Contributor Author

@GGBond8488 你好,重新提交了pr


# Entries of var must be non-negative
# print(paddle.any(var < 0))
# if paddle.any(var < 0):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此处静态图时判断var返回为LoDTensor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是一个比较老的概念,但是应该不会影响这一段的检查

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可能是我对静态图不了解,paddle.any(var < 0)是否在静态图时可能输出的是节点信息?我在测试静态图时这段检查会进入到判断语句内层返回Error。相同代码的动态图可以通过测试。

Copy link
Contributor Author

@Atlantisming Atlantisming Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

测试返回的错误代码
if paddle.any(var < 0): \ print('var',var) \ print(paddle.any(var < 0)) \ raise ValueError("var has negative entry/entries")
输出的结果:
var var Var : LOD_TENSOR.shape(10, 2).dtype(float32).stop_gradient(True) E.E var any_1.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False) var var Var : LOD_TENSOR.shape(10, 2).dtype(float32).stop_gradient(True) var any_3.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False)

Copy link
Contributor Author

@Atlantisming Atlantisming Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是一个比较老的概念,但是应该不会影响这一段的检查

尝试了cond()函数,发现在组网时都会调用cond()函数里设计的tru_func()false_func()并抛出函数内的错误。
然后我找了一下其他人是否有在lossfunc中使用到raise ValueError,可以发现在python\paddle\nn\functional\loss.py中的triplet_margin_with_distance_lossline 3526有关于节点内参数的值的判断。如您所说的不会影响到检查。
但是使用Print()进行检查发现节点内的数据无误。

print(paddle.any(var < 0))
var_res = paddle.static.Print(paddle.any(var < 0))
# if paddle.any(var < 0):
#     raise ValueError("var has negative entry/entries")
================================================
Variable: any_1.tmp_0
  - lod: {}
  - place: Place(cpu)
  - shape: [1]
  - layout: NCHW
  - dtype: bool
  - data: [0]
Variable: any_3.tmp_0
  - lod: {}
  - place: Place(cpu)
  - shape: [1]
  - layout: NCHW
  - dtype: bool
  - data: [0]

进程已结束,退出代码0
var any_0.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False)
var any_2.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False)
I0227 16:33:39.522938 20040 interpretercore.cc:273] New Executor is Running.


Ran 1 test in 0.204s

OK

如果不添加判断的代码,则可以正常通过测试
如果添加了判断代码,仍会进入到判断语句中返回错误。

Error
Traceback (most recent call last):
  File "D:\PyWorkspace\Paddle\python\paddle\fluid\tests\unittests\test_gaussian_nll_loss.py", line 130, in test_static_case
    out1,var_res = F.gaussian_nll_loss(
  File "D:\Anaconda\envs\paddle_devcpu\lib\site-packages\paddle\nn\functional\loss.py", line 4003, in gaussian_nll_loss
    raise ValueError("var has negative entry/entries")
ValueError: var has negative entry/entries

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果语句修改为

if not paddle.all(var > 0):
    raise ValueError("var has negative entry/entries")

也可以通过测试。。但是会不会还是判断的是节点

Copy link
Contributor

@GGBond8488 GGBond8488 Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你的判断是正确的,在静态图里面,组网阶段是没有办法拿到var的数据的,所以这个检查在静态图下会报错,现在有两种解决方案:

  1. 增加c++ 层 的kernel,在kernel层实现计算,并实现对数据的检查,kernel运行在计算阶段,可以拿到对应的数据
  2. https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/static/nn/control_flow.py#L43,利用这里 的Assert OP进行数值判断和提示

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是一个比较老的概念,但是应该不会影响这一段的检查

尝试了cond()函数,发现在组网时都会调用cond()函数里设计的tru_func()false_func()并抛出函数内的错误。 然后我找了一下其他人是否有在lossfunc中使用到raise ValueError,可以发现在python\paddle\nn\functional\loss.py中的triplet_margin_with_distance_lossline 3526有关于节点内参数的值的判断。如您所说的不会影响到检查。 但是使用Print()进行检查发现节点内的数据无误。

print(paddle.any(var < 0))
var_res = paddle.static.Print(paddle.any(var < 0))
# if paddle.any(var < 0):
#     raise ValueError("var has negative entry/entries")
================================================
Variable: any_1.tmp_0
  - lod: {}
  - place: Place(cpu)
  - shape: [1]
  - layout: NCHW
  - dtype: bool
  - data: [0]
Variable: any_3.tmp_0
  - lod: {}
  - place: Place(cpu)
  - shape: [1]
  - layout: NCHW
  - dtype: bool
  - data: [0]

进程已结束,退出代码0
var any_0.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False)
var any_2.tmp_0 : LOD_TENSOR.shape(1,).dtype(bool).stop_gradient(False)
I0227 16:33:39.522938 20040 interpretercore.cc:273] New Executor is Running.


Ran 1 test in 0.204s

OK

如果不添加判断的代码,则可以正常通过测试 如果添加了判断代码,仍会进入到判断语句中返回错误。

Error
Traceback (most recent call last):
  File "D:\PyWorkspace\Paddle\python\paddle\fluid\tests\unittests\test_gaussian_nll_loss.py", line 130, in test_static_case
    out1,var_res = F.gaussian_nll_loss(
  File "D:\Anaconda\envs\paddle_devcpu\lib\site-packages\paddle\nn\functional\loss.py", line 4003, in gaussian_nll_loss
    raise ValueError("var has negative entry/entries")
ValueError: var has negative entry/entries

这里的cond,控制流会对控制流的分支都进行组网,所以会发现true_fn以及false_fn都会抛出异常
而Print()实际上也是一个op,也在进行组网,只是在计算阶段会执行和打印

'gaussian_nll_loss',
)
condition = paddle.all(var > 0)
Assert(condition)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

补充Assert的参数,把var的名字的数据填进去,提示更友好一点

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

loss = F.multi_label_soft_margin_loss(input, target, var, reduction='none')
print(loss)

loss = F.multi_label_soft_margin_loss(input, target, var, reduction='mean')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

示例代码不对

loss = F.multi_label_soft_margin_loss(input, target, var, reduction='none')
print(loss)

loss = F.multi_label_soft_margin_loss(input, target, var, reduction='mean')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

示例代码不对

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

抱歉,git流程还是不熟悉,之前的例子丢失了,我现在来补充

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return [np.mean(loss)]


class TestGaussianNLLLossAPI(unittest.TestCase):
Copy link
Contributor

@GGBond8488 GGBond8488 Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其他的没问题了,这个单测不同的场景分写成不同的test_case吧(把这些用例写到单独的class里面),方便后续直接定位是哪个case不通过。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

GGBond8488
GGBond8488 previously approved these changes Mar 7, 2023
Copy link
Contributor

@GGBond8488 GGBond8488 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jeff41404
Copy link
Contributor

code is fine, but rfc need to be modified in chapter 5: paddle.nn.functional.gaussian_nll_loss(input, target, var, full=None, eps=1e-6, reduction: str="mean", name:str=None, ) -> Tensor:full=None should be full=False?

@Atlantisming
Copy link
Contributor Author

code is fine, but rfc need to be modified in chapter 5: paddle.nn.functional.gaussian_nll_loss(input, target, var, full=None, eps=1e-6, reduction: str="mean", name:str=None, ) -> Tensor:full=None should be full=False?

Yes, sorry for my carelessness.

@luotao1
Copy link
Contributor

luotao1 commented Mar 9, 2023

@Atlantisming 可以提个 PR 修改下 RFC

output (Tensor): If ``reduction`` is ``'none'``, the shape of output is same as ``input`` , else the shape of output is [1].

Examples::
.. code-block:: python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code-block这行下空一行吧,否则解析会出错
image

A callable object of GaussianNLLLoss.

Examples::
.. code-block:: python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同样的,下方空一行吧,保持一致

sunzhongkai588
sunzhongkai588 previously approved these changes Mar 28, 2023
Copy link
Contributor

@sunzhongkai588 sunzhongkai588 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

class GaussianNLLLoss(Layer):
r"""Gaussian negative log likelihood loss.

The targets are treated as samples from Gaussian distributions with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

英文文档这里的描述参考一下其他loss的描述,重新组织一下文案,可以参考 BCELoss,上面functional下的也一样

The targets are treated as samples from Gaussian distributions with
expectations and variance predicted by the neural network. For a
The ``label`` is treated as samples from Gaussian distributions with
expectations ``input`` and ``variance`` predicted by the neural network. For a
``label`` tensor modelled as having Gaussian distribution with a tensor
of expectations ``input`` and a tensor of positive ``variance`` the loss is:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这一段用自己的话描述一下吧,不要直接借鉴


Gaussian negative log likelihood loss among ``input``, ``variance`` and
``label``. Note that the ``label`` is treated as samples from Gaussian distributions.
One of the interpretations is this class is used to train a neural network predicts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里应该是function 不是class, One of the interpretations 是不是去掉更好点 @sunzhongkai588 再看看

@luotao1
Copy link
Contributor

luotao1 commented Apr 10, 2023

同时请修复下 PR-CI-Codestyle-Check 失败的问题

@@ -17,7 +17,7 @@
import numpy as np

import paddle
import paddle.fluid.core as core
import paddle.fluid as core
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

按照提示修改

variance (Tensor): tensor of positive variance(s), :math:`(N, *)` or :math:`(*)`, same shape as the input, or same shape as the input but
with one dimension equal to 1, or same shape as the input but with one fewer
dimension (to allow for broadcasting). One for each of the expectations
in the input (heteroscedastic), or a single one (homoscedastic), available dtype is float32, float64.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

该行和上一行进行左对齐,否则会解析错误
image

class GaussianNLLLoss(Layer):
r"""Create a callable object of 'GaussianNLLLoss' to calculate Gaussian negative log likelihood loss.

This class create a callable object of Gaussian negative log likelihood loss among ``input``,``variance`` and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variance前空一格

Copy link
Contributor

@sunzhongkai588 sunzhongkai588 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@luotao1 luotao1 merged commit 802129b into PaddlePaddle:develop Apr 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API contributor External developers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants