提交 16b2c6dc 编写于 作者: Y Yibing Liu

Add py api for sequence_slice_op

test=develop
上级 2c9839c8
...@@ -370,8 +370,8 @@ void ParseEvents(const std::vector<std::vector<Event>>& events, ...@@ -370,8 +370,8 @@ void ParseEvents(const std::vector<std::vector<Event>>& events,
std::vector<std::vector<Event>> merged_events_list; std::vector<std::vector<Event>> merged_events_list;
if (merge_thread) { if (merge_thread) {
std::vector<Event> merged_events; std::vector<Event> merged_events;
for (int i = 0; i < events.size(); ++i) { for (size_t i = 0; i < events.size(); ++i) {
for (int j = 0; j < events[i].size(); ++j) { for (size_t j = 0; j < events[i].size(); ++j) {
merged_events.push_back(events[i][j]); merged_events.push_back(events[i][j]);
} }
} }
......
...@@ -64,6 +64,7 @@ __all__ = [ ...@@ -64,6 +64,7 @@ __all__ = [
'reduce_prod', 'reduce_prod',
'sequence_first_step', 'sequence_first_step',
'sequence_last_step', 'sequence_last_step',
'sequence_slice',
'dropout', 'dropout',
'split', 'split',
'ctc_greedy_decoder', 'ctc_greedy_decoder',
...@@ -1901,6 +1902,72 @@ def sequence_last_step(input): ...@@ -1901,6 +1902,72 @@ def sequence_last_step(input):
return sequence_pool(input=input, pool_type="last") return sequence_pool(input=input, pool_type="last")
def sequence_slice(input, offset, length, name=None):
"""
**Sequence Slice Layer**
The layer crops a subsequence from given sequence with given start
offset and subsequence length.
It only supports sequence data (LoDTensor with lod_level equal to 1).
.. code-block:: text
- Case:
Given the input Variable **input**,
input.data = [[a1, a2], [b1, b2], [c1, c2], [d1, d2], [e1, e2]],
input.lod = [[0, 3, 5]], input.dims = (5, 2)
with offset.data = [[0], [1]], length.data = [[2], [1]],
the output Variable will be
out.data = [[a1, a2], [b1, b2], [e1, e2]],
out.lod = [[0, 2, 3]], out.dims = (3, 2)
NOTE: The first dimension size of input, the size of offset and Length,
should be equal. The offset start from 0.
Args:
input(Variable): The input Variable which consists of the complete
sentences.
offset(Variable): The offset to slice each sequence.
length(Variable): The length of each subsequence.
name(str|None): A name for this layer(optional). If set None, the
layer will be named automatically.
Returns:
Variable: The subsequences.
Examples:
.. code-block:: python
import numpy as np
seqs = fluid.layers.data(name='x', shape=[10, 5],
dtype='float32', lod_level=1)
offset = fluid.layers.assign(input=np.array([[0, 1]]).astype("int32"))
length = fluid.layers.assign(input=np.array([[2, 1]]).astype("int32"))
subseqs = fluid.layers.sequence_slice(input=seqs, offset=offset,
length=length)
"""
helper = LayerHelper("sequence_slice", **locals())
dtype = helper.input_dtype()
out = helper.create_tmp_variable(dtype)
offset.stop_gradient = True
length.stop_gradient = True
helper.append_op(
type="sequence_slice",
inputs={"X": input,
"Offset": offset,
"Length": length},
outputs={"Out": out})
return out
@templatedoc() @templatedoc()
def pool2d(input, def pool2d(input,
pool_size=-1, pool_size=-1,
......
...@@ -406,6 +406,19 @@ class TestBook(unittest.TestCase): ...@@ -406,6 +406,19 @@ class TestBook(unittest.TestCase):
self.assertIsNotNone(out) self.assertIsNotNone(out)
print(str(program)) print(str(program))
def test_sequence_slice(self):
program = Program()
with program_guard(program):
import numpy as np
seqs = layers.data(
name='x', shape=[10, 5], dtype='float32', lod_level=1)
offset = layers.assign(input=np.array([[0, 1]]).astype('int32'))
length = layers.assign(input=np.array([[2, 1]]).astype('int32'))
out = layers.sequence_slice(
input=seqs, offset=offset, length=length)
self.assertIsNotNone(out)
print(str(program))
def test_lod_reset(self): def test_lod_reset(self):
program = Program() program = Program()
with program_guard(program): with program_guard(program):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册