Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
b7c179a8
P
Paddle
项目概览
机器未来
/
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看板
提交
b7c179a8
编写于
6月 26, 2018
作者:
K
Kexin Zhao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix lodtensor.py
上级
6b95a8a8
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
73 addition
and
57 deletion
+73
-57
python/paddle/fluid/lod_tensor.py
python/paddle/fluid/lod_tensor.py
+31
-26
python/paddle/fluid/tests/test_lod_tensor.py
python/paddle/fluid/tests/test_lod_tensor.py
+42
-31
未找到文件。
python/paddle/fluid/lod_tensor.py
浏览文件 @
b7c179a8
...
...
@@ -18,15 +18,16 @@ import numpy as np
__all__
=
[
'create_lod_tensor'
,
'create_random_int_lodtensor'
]
def
create_lod_tensor
(
data
,
lod
,
place
):
def
create_lod_tensor
(
data
,
recursive_seq_lens
,
place
):
"""
Create a lod tensor from a numpy array, a list, or an existing lod tensor.
Create a lod tensor by doing the following:
1. Check that the length-based input lod is valid.
1. Check that the length-based level of detail (LoD) also known as
recursive_sequence_lengths of the input is valid.
2. Convert
the length-based lod
to a offset-based LoD.
2. Convert
recursive_sequence_lengths
to a offset-based LoD.
3. Copy the data from a numpy array, a list or a existing lod tensor to
CPU or GPU device (based on input place).
...
...
@@ -40,9 +41,9 @@ def create_lod_tensor(data, lod, place):
represent two sentences, one of 2 words, and one of 3 words.
Then :code:`data` can be a numpy array of integers with shape (5, 1).
:code:`
lod
` will be [[2, 3]], indicating the length(# of words) in each
sentence. This length-based
input lod
[[2, 3]] will be converted to
offset-based
lod
[[0, 2, 5]] inside the function call.
:code:`
recursive_seq_lens
` will be [[2, 3]], indicating the length(# of words) in each
sentence. This length-based
:code:`recursive_seq_lens`
[[2, 3]] will be converted to
offset-based
LoD
[[0, 2, 5]] inside the function call.
Please reference :ref:`api_guide_low_level_lod_tensor` for more details
regarding LoD.
...
...
@@ -50,32 +51,34 @@ def create_lod_tensor(data, lod, place):
Args:
data(numpy.ndarray|list|LoDTensor): a numpy array or a LoDTensor or a
list holding the data to be copied.
lod(list): a list of lists indicating the length-based LoD info
specified by the user.
recursive_seq_lens(list): a list of lists indicating the length-based level of detail
info
specified by the user.
place(Place): CPU or GPU place indicating where the data in the new
LoDTensor will be stored.
Returns:
A fluid LoDTensor object with tensor data and
lod
info.
A fluid LoDTensor object with tensor data and
recursive_seq_lens
info.
"""
if
isinstance
(
data
,
core
.
LoDTensor
):
return
create_lod_tensor
(
np
.
array
(
data
),
lod
,
place
)
return
create_lod_tensor
(
np
.
array
(
data
),
recursive_seq_lens
,
place
)
elif
isinstance
(
data
,
list
):
# When input data is a list, it only deal with the case where the base element
# is an index of shape [1] and dtype int64 (e.g., word id). Hence, the generated
# LoDTensor will be of shape [n, 1] and dtype int64, where `n` is the total number
# of words or other indexes in the sequence.
new_
lod
=
[]
new_
recursive_seq_lens
=
[]
for
seq
in
data
:
new_lod
.
append
(
len
(
seq
))
assert
[
new_lod
]
==
lod
,
"data and lod do not match"
new_recursive_seq_lens
.
append
(
len
(
seq
))
assert
[
new_recursive_seq_lens
]
==
recursive_seq_lens
,
"data and recursive_seq_lens do not match"
flattened_data
=
np
.
concatenate
(
data
,
axis
=
0
).
astype
(
"int64"
)
flattened_data
=
flattened_data
.
reshape
([
len
(
flattened_data
),
1
])
return
create_lod_tensor
(
flattened_data
,
lod
,
place
)
return
create_lod_tensor
(
flattened_data
,
recursive_seq_lens
,
place
)
elif
isinstance
(
data
,
np
.
ndarray
):
tensor
=
core
.
LoDTensor
()
tensor
.
set
(
data
,
place
)
tensor
.
set_recursive_sequence_lengths
(
lod
)
tensor
.
set_recursive_sequence_lengths
(
recursive_seq_lens
)
assert
tensor
.
has_valid_recursive_sequence_lengths
(
),
"the provided lod info is invalid"
return
tensor
...
...
@@ -84,7 +87,8 @@ def create_lod_tensor(data, lod, place):
"data should be either a LoDTensor, a Numpy array or a list"
)
def
create_random_int_lodtensor
(
lod
,
base_shape
,
place
,
low
,
high
):
def
create_random_int_lodtensor
(
recursive_seq_lens
,
base_shape
,
place
,
low
,
high
):
"""
Create a LoDTensor containing random integers.
...
...
@@ -95,7 +99,7 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
The function does the following:
1. Calculate the overall shape of the LoDTensor based on the length-based
:code:`
lod
` input and the shape of the basic element in
:code:`
recursive_seq_lens
` input and the shape of the basic element in
:code:`base_shape`.
2. Create a numpy array of this shape.
...
...
@@ -105,12 +109,13 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
Suppose we want LoDTensor to hold data for sequences of word, where each
word is represented by an integer. If we want to create a LoDTensor to
represent two sentences, one of 2 words, and one of 3 words. Then
'base_shape' is [1], input length-based 'lod' is [[2, 3]]. Then the overall
shape of the LoDTensor would be [5, 1], holding 5 words for two sentences.
'base_shape' is [1], input length-based 'recursive_seq_lens' is [[2, 3]].
Then the overall shape of the LoDTensor would be [5, 1], holding 5 words
for two sentences.
Args:
lod(list): a list of lists indicating the length-based LoD info
specified by the user.
recursive_seq_lens(list): a list of lists indicating the length-based
level of detail info
specified by the user.
base_shape(list): the shape of the basic element to be held by the
LoDTensor.
place(Place): CPU or GPU place indicating where the data in the new
...
...
@@ -119,11 +124,11 @@ def create_random_int_lodtensor(lod, base_shape, place, low, high):
high(int): the upper bound of the random integers.
Returns:
A fluid LoDTensor object with tensor data and
lod
info.
A fluid LoDTensor object with tensor data and
recursive_seq_lens
info.
"""
assert
isinstance
(
base_shape
,
list
),
"base_shape should be a list"
# append the total number of basic elements to the front of its shape
overall_shape
=
[
sum
(
lod
[
-
1
])]
+
base_shape
overall_shape
=
[
sum
(
recursive_seq_lens
[
-
1
])]
+
base_shape
# the range of integer data elements is [low, high]
data
=
np
.
random
.
random_integers
(
low
,
high
,
overall_shape
).
astype
(
"int64"
)
return
create_lod_tensor
(
data
,
lod
,
place
)
return
create_lod_tensor
(
data
,
recursive_seq_lens
,
place
)
python/paddle/fluid/tests/test_lod_tensor.py
浏览文件 @
b7c179a8
...
...
@@ -19,18 +19,21 @@ import unittest
class
TestLoDTensor
(
unittest
.
TestCase
):
def
test_pybind_
lod
(
self
):
def
test_pybind_
recursive_seq_lens
(
self
):
tensor
=
fluid
.
LoDTensor
()
lod
=
[]
tensor
.
set_recursive_sequence_lengths
(
lod
)
lod
=
[[],
[
1
],
[
3
]]
self
.
assertRaises
(
Exception
,
tensor
.
set_recursive_sequence_lengths
,
lod
)
lod
=
[[
0
],
[
2
],
[
3
]]
self
.
assertRaises
(
Exception
,
tensor
.
set_recursive_sequence_lengths
,
lod
)
recursive_seq_lens
=
[]
tensor
.
set_recursive_sequence_lengths
(
recursive_seq_lens
)
recursive_seq_lens
=
[[],
[
1
],
[
3
]]
self
.
assertRaises
(
Exception
,
tensor
.
set_recursive_sequence_lengths
,
recursive_seq_lens
)
recursive_seq_lens
=
[[
0
],
[
2
],
[
3
]]
self
.
assertRaises
(
Exception
,
tensor
.
set_recursive_sequence_lengths
,
recursive_seq_lens
)
lod
=
[[
1
,
2
,
3
]]
tensor
.
set_recursive_sequence_lengths
(
lod
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
lod
)
recursive_seq_lens
=
[[
1
,
2
,
3
]]
tensor
.
set_recursive_sequence_lengths
(
recursive_seq_lens
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
recursive_seq_lens
)
tensor
.
set
(
np
.
random
.
random
([
6
,
1
]),
fluid
.
CPUPlace
())
self
.
assertTrue
(
tensor
.
has_valid_recursive_sequence_lengths
())
tensor
.
set
(
np
.
random
.
random
([
9
,
1
]),
fluid
.
CPUPlace
())
...
...
@@ -38,13 +41,14 @@ class TestLoDTensor(unittest.TestCase):
# Each level's sum should be equal to the number of items in the next level
# Moreover, last level's sum should be equal to the tensor height
lod
=
[[
2
,
3
],
[
1
,
3
,
1
,
2
,
2
]]
tensor
.
set_recursive_sequence_lengths
(
lod
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
lod
)
recursive_seq_lens
=
[[
2
,
3
],
[
1
,
3
,
1
,
2
,
2
]]
tensor
.
set_recursive_sequence_lengths
(
recursive_seq_lens
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
recursive_seq_lens
)
tensor
.
set
(
np
.
random
.
random
([
8
,
1
]),
fluid
.
CPUPlace
())
self
.
assertFalse
(
tensor
.
has_valid_recursive_sequence_lengths
())
lod
=
[[
2
,
3
],
[
1
,
3
,
1
,
2
,
1
]]
tensor
.
set_recursive_sequence_lengths
(
lod
)
recursive_seq_lens
=
[[
2
,
3
],
[
1
,
3
,
1
,
2
,
1
]]
tensor
.
set_recursive_sequence_lengths
(
recursive_seq_lens
)
self
.
assertTrue
(
tensor
.
has_valid_recursive_sequence_lengths
())
tensor
.
set
(
np
.
random
.
random
([
9
,
1
]),
fluid
.
CPUPlace
())
self
.
assertFalse
(
tensor
.
has_valid_recursive_sequence_lengths
())
...
...
@@ -52,35 +56,42 @@ class TestLoDTensor(unittest.TestCase):
def
test_create_lod_tensor
(
self
):
# Create LoDTensor from a list
data
=
[[
1
,
2
,
3
],
[
3
,
4
]]
wrong_lod
=
[[
2
,
2
]]
correct_lod
=
[[
3
,
2
]]
self
.
assertRaises
(
AssertionError
,
create_lod_tensor
,
data
,
wrong_lod
,
wrong_recursive_seq_lens
=
[[
2
,
2
]]
correct_recursive_seq_lens
=
[[
3
,
2
]]
self
.
assertRaises
(
AssertionError
,
create_lod_tensor
,
data
,
wrong_recursive_seq_lens
,
fluid
.
CPUPlace
())
tensor
=
create_lod_tensor
(
data
,
correct_recursive_seq_lens
,
fluid
.
CPUPlace
())
tensor
=
create_lod_tensor
(
data
,
correct_lod
,
fluid
.
CPUPlace
())
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
correct_lod
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
correct_recursive_seq_lens
)
# Create LoDTensor from numpy array
data
=
np
.
random
.
random
([
10
,
1
])
lod
=
[[
2
,
1
],
[
3
,
3
,
4
]]
tensor
=
create_lod_tensor
(
data
,
lod
,
fluid
.
CPUPlace
())
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
lod
)
recursive_seq_lens
=
[[
2
,
1
],
[
3
,
3
,
4
]]
tensor
=
create_lod_tensor
(
data
,
recursive_seq_lens
,
fluid
.
CPUPlace
())
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
recursive_seq_lens
)
# Create LoDTensor from another LoDTensor, they are differnt instances
new_lod
=
[[
2
,
2
,
1
],
[
1
,
2
,
2
,
3
,
2
]]
new_tensor
=
create_lod_tensor
(
tensor
,
new_lod
,
fluid
.
CPUPlace
())
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
lod
)
self
.
assertEqual
(
new_tensor
.
recursive_sequence_lengths
(),
new_lod
)
new_recursive_seq_lens
=
[[
2
,
2
,
1
],
[
1
,
2
,
2
,
3
,
2
]]
new_tensor
=
create_lod_tensor
(
tensor
,
new_recursive_seq_lens
,
fluid
.
CPUPlace
())
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
recursive_seq_lens
)
self
.
assertEqual
(
new_tensor
.
recursive_sequence_lengths
(),
new_recursive_seq_lens
)
def
test_create_random_int_lodtensor
(
self
):
# The shape of a word, commonly used in speech and NLP problem, is [1]
shape
=
[
1
]
lod
=
[[
2
,
3
,
5
]]
recursive_seq_lens
=
[[
2
,
3
,
5
]]
dict_size
=
10000
low
=
0
high
=
dict_size
-
1
tensor
=
create_random_int_lodtensor
(
lod
,
shape
,
tensor
=
create_random_int_lodtensor
(
recursive_seq_lens
,
shape
,
fluid
.
CPUPlace
(),
low
,
high
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
lod
)
self
.
assertEqual
(
tensor
.
recursive_sequence_lengths
(),
recursive_seq_lens
)
self
.
assertEqual
(
tensor
.
shape
(),
[
10
,
1
])
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录