change offset and length's rank to 2, dim[0] for batch size

release/0.11.0
wanghaox 7 years ago
commit 1d95173cfe

@ -32,6 +32,14 @@ class SequenceSliceOp : public framework::OperatorWithKernel {
"Output(Out) of SequenceSliceOp should not be null."); "Output(Out) of SequenceSliceOp should not be null.");
auto input_dims = ctx->GetInputDim("X"); auto input_dims = ctx->GetInputDim("X");
auto offset_dim = ctx->GetInputDim("Offset");
auto length_dim = ctx->GetInputDim("Length");
PADDLE_ENFORCE_EQ(offset_dim.size(), 2UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(length_dim.size(), 2UL,
"Only support one level sequence now.");
ctx->SetOutputDim("Out", input_dims); ctx->SetOutputDim("Out", input_dims);
} }
@ -95,7 +103,7 @@ It only supports sequence (LoD Tensor with level number is 1).
[d1, d2; [d1, d2;
e1, e2]] e1, e2]]
LoD(X) = {{0, 3, 5}}; Dims(X) = (5, 2) LoD(X) = {{0, 3, 5}}; Dims(X) = (5, 2)
Offset = [0, 1]; Length = [2, 1] Offset = [[0], [1]]; Length = [[2], [1]]
Out = [[a1, a2; Out = [[a1, a2;
b1, b2] b1, b2]

@ -48,42 +48,42 @@ class SequenceSliceOpKernel : public framework::OpKernel<T> {
auto* length = ctx.Input<Tensor>("Length"); auto* length = ctx.Input<Tensor>("Length");
auto* out = ctx.Output<LoDTensor>("Out"); auto* out = ctx.Output<LoDTensor>("Out");
auto lod = in->lod();
auto n = lod[0].size() - 1;
PADDLE_ENFORCE_EQ(lod.size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(
n, length->dims()[0],
"The size of input-sequence and length-array should be the same")
PADDLE_ENFORCE_EQ(
n, offset->dims()[0],
"The size of input-sequence and offset-array should be the same")
const int64_t* offset_data = offset->data<int64_t>(); const int64_t* offset_data = offset->data<int64_t>();
const int64_t* length_data = length->data<int64_t>(); const int64_t* length_data = length->data<int64_t>();
framework::Tensor offset_cpu;
framework::Tensor length_cpu;
if (platform::is_gpu_place(ctx.GetPlace())) { if (platform::is_gpu_place(ctx.GetPlace())) {
framework::Tensor offset_cpu;
offset_cpu.mutable_data<T>(offset->dims(), platform::CPUPlace()); offset_cpu.mutable_data<T>(offset->dims(), platform::CPUPlace());
offset_cpu.CopyFrom(*offset, platform::CPUPlace(), ctx.device_context()); offset_cpu.CopyFrom(*offset, platform::CPUPlace(), ctx.device_context());
offset_data = offset_cpu.data<int64_t>(); offset_data = offset_cpu.data<int64_t>();
framework::Tensor length_cpu;
length_cpu.mutable_data<T>(length->dims(), platform::CPUPlace()); length_cpu.mutable_data<T>(length->dims(), platform::CPUPlace());
length_cpu.CopyFrom(*length, platform::CPUPlace(), ctx.device_context()); length_cpu.CopyFrom(*length, platform::CPUPlace(), ctx.device_context());
length_data = length_cpu.data<int64_t>(); length_data = length_cpu.data<int64_t>();
} }
auto lod = in->lod();
auto n = lod[0].size() - 1;
PADDLE_ENFORCE_EQ(lod.size(), 1UL, "Only support one level sequence now.");
PADDLE_ENFORCE_EQ(offset->dims().size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(length->dims().size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(
n, length->dims()[0],
"The size of input-sequence and length-array should be the same")
PADDLE_ENFORCE_EQ(
n, offset->dims()[0],
"The size of input-sequence and offset-array should be the same")
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
PADDLE_ENFORCE_LT(0, offset_data[i], "The offset must greater than zero") PADDLE_ENFORCE_LT(0, offset_data[i],
PADDLE_ENFORCE_LT(0, length_data[i], "The length must greater than zero") "The offset must greater than zero")
PADDLE_ENFORCE_LT(lod[0][i] + offset_data[i] + length_data[i], PADDLE_ENFORCE_LT(0, length_data[i],
lod[0][i + 1], "The target tensor's length overflow") "The length must greater than zero")
} PADDLE_ENFORCE_LT(
lod[0][i] + offset_data[i] + length_data[i],
lod[0][i + 1],
"The target tensor's length overflow")}
out->mutable_data<T>(ctx.GetPlace()); out->mutable_data<T>(ctx.GetPlace());
auto out_lod = SequenceSliceLoD(*in, offset_data, length_data); auto out_lod = SequenceSliceLoD(*in, offset_data, length_data);

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
import logging import logging
from paddle.v2.framework.op import Operator, DynamicRecurrentOp from paddle.v2.fluid.op import Operator, DynamicRecurrentOp
import paddle.v2.framework.core as core import paddle.v2.fluid.core as core
import unittest import unittest
import numpy as np import numpy as np

@ -9,16 +9,16 @@ class TestSequenceSliceOp(OpTest):
# only supprot one level LoD # only supprot one level LoD
x = np.random.random(self.x_dim).astype('float32') x = np.random.random(self.x_dim).astype('float32')
lod = self.x_lod lod = self.x_lod
offset = np.array(self.offset).flatten().astype("int64") offset = np.array(self.offset).astype("int64")
length = np.array(self.length).flatten().astype("int64") length = np.array(self.length).astype("int64")
self.inputs = {'X': (x, lod), 'Offset': offset, 'Length': length} self.inputs = {'X': (x, lod), 'Offset': offset, 'Length': length}
outs = [] #np.zeros((100, 3, 2)).astype('float32') outs = [] #np.zeros((100, 3, 2)).astype('float32')
out_lod = [[0]] out_lod = [[0]]
out_lod_offset = 0 out_lod_offset = 0
for i in range(len(offset)): for i in range(len(offset)):
sub_x = x[lod[0][i] + offset[i]: lod[0] sub_x = x[lod[0][i] + offset[i, 0]: lod[0]
[i] + offset[i] + length[i], :] [i] + offset[i, 0] + length[i, 0], :]
out_lod_offset = out_lod_offset + len(sub_x) out_lod_offset = out_lod_offset + len(sub_x)
outs.append(sub_x) outs.append(sub_x)
out_lod[0].append(out_lod_offset) out_lod[0].append(out_lod_offset)
@ -28,8 +28,8 @@ class TestSequenceSliceOp(OpTest):
def init_test_case(self): def init_test_case(self):
self.x_dim = (100, 3, 2) self.x_dim = (100, 3, 2)
self.x_lod = [[0, 20, 40, 60, 80, 100]] self.x_lod = [[0, 20, 40, 60, 80, 100]]
self.offset = [1, 2, 3, 4, 5] self.offset = [[1], [2], [3], [4], [5]]
self.length = [10, 8, 6, 4, 2] self.length = [[10], [8], [6], [4], [2]]
def setUp(self): def setUp(self):
self.op_type = "sequence_slice" self.op_type = "sequence_slice"

Loading…
Cancel
Save