Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
32fe5a49
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
32fe5a49
编写于
10月 26, 2021
作者:
H
HydrogenSulfate
提交者:
GitHub
10月 26, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cherry pick CrossEntropy's bug fix (#36647)
上级
d2be870a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
86 addition
and
19 deletion
+86
-19
python/paddle/fluid/tests/unittests/test_cross_entropy_loss.py
...n/paddle/fluid/tests/unittests/test_cross_entropy_loss.py
+50
-0
python/paddle/nn/functional/loss.py
python/paddle/nn/functional/loss.py
+36
-19
未找到文件。
python/paddle/fluid/tests/unittests/test_cross_entropy_loss.py
浏览文件 @
32fe5a49
...
@@ -1175,6 +1175,56 @@ class CrossEntropyLoss(unittest.TestCase):
...
@@ -1175,6 +1175,56 @@ class CrossEntropyLoss(unittest.TestCase):
self
.
assertTrue
(
np
.
allclose
(
static_ret
,
expected
))
self
.
assertTrue
(
np
.
allclose
(
static_ret
,
expected
))
self
.
assertTrue
(
np
.
allclose
(
dy_ret_value
,
expected
))
self
.
assertTrue
(
np
.
allclose
(
dy_ret_value
,
expected
))
def
test_cross_entropy_loss_2d_with_weight_axis_change_mean
(
self
):
input_np
=
np
.
random
.
random
(
size
=
(
2
,
3
,
2
,
2
)).
astype
(
self
.
dtype
)
#NCHW
label_np
=
np
.
random
.
randint
(
0
,
3
,
size
=
(
2
,
2
,
2
)).
astype
(
np
.
int64
)
#NHW
weight_np
=
np
.
random
.
random
(
size
=
(
3
,
)).
astype
(
self
.
dtype
)
#C
paddle
.
enable_static
()
prog
=
fluid
.
Program
()
startup_prog
=
fluid
.
Program
()
place
=
fluid
.
CUDAPlace
(
0
)
if
fluid
.
core
.
is_compiled_with_cuda
(
)
else
fluid
.
CPUPlace
()
with
fluid
.
program_guard
(
prog
,
startup_prog
):
input
=
fluid
.
data
(
name
=
'input'
,
shape
=
[
2
,
3
,
2
,
2
],
dtype
=
self
.
dtype
)
label
=
fluid
.
data
(
name
=
'label'
,
shape
=
[
2
,
2
,
2
],
dtype
=
'int64'
)
weight
=
fluid
.
data
(
name
=
'weight'
,
shape
=
[
3
],
dtype
=
self
.
dtype
)
cross_entropy_loss
=
paddle
.
nn
.
loss
.
CrossEntropyLoss
(
weight
=
weight
,
reduction
=
'mean'
,
axis
=
1
)
# specify the class channels to axis 1
ret
=
cross_entropy_loss
(
input
,
label
)
exe
=
fluid
.
Executor
(
place
)
static_ret
=
exe
.
run
(
prog
,
feed
=
{
'input'
:
input_np
,
'label'
:
label_np
,
"weight"
:
weight_np
},
fetch_list
=
[
ret
])
self
.
assertIsNotNone
(
static_ret
)
with
fluid
.
dygraph
.
guard
():
cross_entropy_loss
=
paddle
.
nn
.
loss
.
CrossEntropyLoss
(
weight
=
fluid
.
dygraph
.
to_variable
(
weight_np
),
reduction
=
'mean'
,
axis
=
1
)
dy_ret
=
cross_entropy_loss
(
fluid
.
dygraph
.
to_variable
(
input_np
),
fluid
.
dygraph
.
to_variable
(
label_np
))
dy_ret_value
=
dy_ret
.
numpy
()
self
.
assertIsNotNone
(
dy_ret_value
)
expected
=
cross_entropy_loss_2d
(
np
.
transpose
(
input_np
,
[
0
,
2
,
3
,
1
]),
label_np
,
weight
=
weight_np
,
reduction
=
'mean'
)[
0
]
self
.
assertTrue
(
np
.
allclose
(
static_ret
,
dy_ret_value
))
self
.
assertTrue
(
np
.
allclose
(
static_ret
,
expected
))
self
.
assertTrue
(
np
.
allclose
(
dy_ret_value
,
expected
))
def
test_cross_entropy_loss_2d_with_weight_mean_ignore_exceedlabel
(
self
):
def
test_cross_entropy_loss_2d_with_weight_mean_ignore_exceedlabel
(
self
):
N
=
4
N
=
4
C
=
3
C
=
3
...
...
python/paddle/nn/functional/loss.py
浏览文件 @
32fe5a49
...
@@ -1668,12 +1668,13 @@ def cross_entropy(input,
...
@@ -1668,12 +1668,13 @@ def cross_entropy(input,
format
(
invalid_label
[
0
],
0
))
format
(
invalid_label
[
0
],
0
))
# TODO: Temporarily use paddle.nonzero instead of paddle.max
# TODO: Temporarily use paddle.nonzero instead of paddle.max
# to detect and find out possible illegal label values
# to detect and find out possible illegal label values
if
len
(
paddle
.
nonzero
(
valid_label
>=
input
.
shape
[
-
1
]))
>
0
:
if
len
(
paddle
.
nonzero
(
valid_label
>=
input
.
shape
[
axis
]))
>
0
:
invalid_label
=
paddle
.
gather_nd
(
invalid_label
=
paddle
.
gather_nd
(
valid_label
,
paddle
.
nonzero
(
valid_label
>=
input
.
shape
[
-
1
]))
valid_label
,
paddle
.
nonzero
(
valid_label
>=
input
.
shape
[
axis
]))
raise
ValueError
(
raise
ValueError
(
"Target({}) is out of class_dimension's upper bound({})"
.
"Target({}) is out of class_dimension's upper bound({})"
.
format
(
invalid_label
[
0
],
input
.
shape
[
-
1
]
-
1
))
format
(
invalid_label
[
0
],
input
.
shape
[
axis
]
-
1
))
_
,
out
=
_C_ops
.
softmax_with_cross_entropy
(
_
,
out
=
_C_ops
.
softmax_with_cross_entropy
(
input
,
label
,
'soft_label'
,
soft_label
,
'ignore_index'
,
input
,
label
,
'soft_label'
,
soft_label
,
'ignore_index'
,
...
@@ -1700,19 +1701,28 @@ def cross_entropy(input,
...
@@ -1700,19 +1701,28 @@ def cross_entropy(input,
out
=
_C_ops
.
elementwise_mul
(
out
,
weight_gather_reshape
)
out
=
_C_ops
.
elementwise_mul
(
out
,
weight_gather_reshape
)
else
:
else
:
if
input
.
shape
[
-
1
]
!=
weight
.
shape
[
-
1
]:
if
input
.
shape
[
axis
]
!=
weight
.
shape
[
-
1
]:
raise
ValueError
(
raise
ValueError
(
"input's class_dimension({}) must equal to
\
"input's class_dimension({}) must equal to
"
weight's class_dimension({})
\
"weight's class_dimension({}) "
when weight is provided"
"when weight is provided"
\
.
format
(
input
.
shape
[
-
1
],
weight
.
shape
[
-
1
]))
.
format
(
input
.
shape
[
axis
],
weight
.
shape
[
-
1
]))
ignore_weight_mask
=
paddle
.
cast
((
label
!=
ignore_index
),
ignore_weight_mask
=
paddle
.
cast
((
label
!=
ignore_index
),
out
.
dtype
)
out
.
dtype
)
if
ignore_weight_mask
.
ndim
>
1
and
ignore_weight_mask
.
shape
[
if
ignore_weight_mask
.
ndim
>
1
and
ignore_weight_mask
.
shape
[
-
1
]
==
1
:
axis
]
==
1
:
ignore_weight_mask
.
squeeze_
(
-
1
)
# TODO: Temporarily use squeeze instead of squeeze_
weight_gather
=
_C_ops
.
gather_nd
(
weight
,
valid_label
)
ignore_weight_mask
=
paddle
.
squeeze
(
ignore_weight_mask
,
axis
)
if
axis
!=
-
1
and
axis
!=
valid_label
.
ndim
-
1
:
temp_perm
=
list
(
range
(
axis
%
valid_label
.
ndim
))
\
+
list
(
range
((
axis
%
valid_label
.
ndim
+
1
)
,
valid_label
.
ndim
))
\
+
[
axis
%
valid_label
.
ndim
]
weight_gather
=
_C_ops
.
gather_nd
(
weight
,
valid_label
.
transpose
(
temp_perm
))
else
:
weight_gather
=
_C_ops
.
gather_nd
(
weight
,
valid_label
)
weight_gather
=
_C_ops
.
elementwise_mul
(
weight_gather
,
weight_gather
=
_C_ops
.
elementwise_mul
(
weight_gather
,
ignore_weight_mask
)
ignore_weight_mask
)
input_shape
=
list
(
label
.
shape
)
input_shape
=
list
(
label
.
shape
)
...
@@ -1807,20 +1817,27 @@ def cross_entropy(input,
...
@@ -1807,20 +1817,27 @@ def cross_entropy(input,
weight_gather_reshape
=
reshape
(
weight_gather
,
shape
=
out_shape
)
weight_gather_reshape
=
reshape
(
weight_gather
,
shape
=
out_shape
)
out
=
paddle
.
cast
(
out
,
weight_gather_reshape
.
dtype
)
out
=
paddle
.
cast
(
out
,
weight_gather_reshape
.
dtype
)
else
:
else
:
if
input
.
shape
[
-
1
]
!=
weight
.
shape
[
-
1
]:
if
input
.
shape
[
axis
]
!=
weight
.
shape
[
-
1
]:
raise
ValueError
(
"input's class_dimension({}) must equal to "
\
raise
ValueError
(
"input's class_dimension({}) must equal to "
"weight's class_dimension({}) "
\
"weight's class_dimension({}) "
"when weight is provided"
"when weight is provided"
\
.
format
(
input
.
shape
[
-
1
],
weight
.
shape
[
-
1
]))
.
format
(
input
.
shape
[
axis
],
weight
.
shape
[
-
1
]))
valid_label
=
paddle
.
where
(
label
==
ignore_index
,
valid_label
=
paddle
.
where
(
label
==
ignore_index
,
paddle
.
zeros_like
(
label
),
label
)
paddle
.
zeros_like
(
label
),
label
)
ignore_weight_mask
=
paddle
.
cast
((
label
!=
ignore_index
),
ignore_weight_mask
=
paddle
.
cast
((
label
!=
ignore_index
),
input
.
dtype
)
input
.
dtype
)
if
ignore_weight_mask
.
ndim
>
1
and
ignore_weight_mask
.
shape
[
if
ignore_weight_mask
.
ndim
>
1
and
ignore_weight_mask
.
shape
[
-
1
]
==
1
:
axis
]
==
1
:
ignore_weight_mask
=
paddle
.
squeeze
(
ignore_weight_mask
,
-
1
)
ignore_weight_mask
=
paddle
.
squeeze
(
ignore_weight_mask
,
axis
)
weight_gather
=
paddle
.
gather_nd
(
weight
,
valid_label
)
if
axis
!=
-
1
and
axis
!=
valid_label
.
ndim
-
1
:
temp_perm
=
list
(
range
(
axis
%
valid_label
.
ndim
))
\
+
list
(
range
((
axis
%
valid_label
.
ndim
+
1
),
valid_label
.
ndim
))
\
+
[
axis
%
valid_label
.
ndim
]
weight_gather
=
paddle
.
gather_nd
(
weight
,
paddle
.
transpose
(
valid_label
,
temp_perm
))
else
:
weight_gather
=
paddle
.
gather_nd
(
weight
,
valid_label
)
weight_gather
=
paddle
.
multiply
(
weight_gather
,
ignore_weight_mask
)
weight_gather
=
paddle
.
multiply
(
weight_gather
,
ignore_weight_mask
)
input_shape
=
list
(
label
.
shape
)
input_shape
=
list
(
label
.
shape
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录