|
|
|
@ -27,9 +27,10 @@ static inline T NormalizeL1(T* x, size_t len) {
|
|
|
|
|
// (This comment is from the old LinearChainCRFLayer.)
|
|
|
|
|
// Right now, we just bet that sum won't be zero. If this really happens, we
|
|
|
|
|
// will figure out what should be done then.
|
|
|
|
|
PADDLE_ENFORCE(sum,
|
|
|
|
|
"The unnormalized probabilities of all possible unfinished "
|
|
|
|
|
"sequences must be greater than 0.");
|
|
|
|
|
PADDLE_ENFORCE_GT(
|
|
|
|
|
sum, 0., platform::errors::InvalidArgument(
|
|
|
|
|
"The unnormalized probabilities of all possible unfinished "
|
|
|
|
|
"sequences must be greater than 0."));
|
|
|
|
|
T s = 1. / sum;
|
|
|
|
|
for (size_t i = 0; i < len; ++i) x[i] *= s;
|
|
|
|
|
return sum;
|
|
|
|
@ -84,13 +85,19 @@ class LinearChainCRFOpKernel : public framework::OpKernel<T> {
|
|
|
|
|
const Tensor* label_length = ctx.Input<framework::Tensor>("Length");
|
|
|
|
|
length_data = label_length->data<int64_t>();
|
|
|
|
|
seq_num = label_length->numel();
|
|
|
|
|
PADDLE_ENFORCE_EQ(seq_num, emission_dims[0],
|
|
|
|
|
"the size of Input(length) must be equal to "
|
|
|
|
|
"emission_dims[0].");
|
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
|
seq_num, emission_dims[0],
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"the size of Input(length) must be equal to "
|
|
|
|
|
"emission_dims[0]. But input_size = %d, emission_dims[0] = %d.",
|
|
|
|
|
seq_num, emission_dims[0]));
|
|
|
|
|
auto label_dims = label->dims();
|
|
|
|
|
PADDLE_ENFORCE_EQ(seq_num, label_dims[0],
|
|
|
|
|
"the size of Input(length) must be equal to "
|
|
|
|
|
"label_dims[0].");
|
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
|
seq_num, label_dims[0],
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"the size of Input(length) must be equal to "
|
|
|
|
|
"label_dims[0]. But input_size = %d, label_dims[0] = %d.",
|
|
|
|
|
seq_num, label_dims[0]));
|
|
|
|
|
|
|
|
|
|
batch_size = emission_dims[0] * emission_dims[1];
|
|
|
|
|
tag_num = emission_dims[2];
|
|
|
|
@ -102,7 +109,9 @@ class LinearChainCRFOpKernel : public framework::OpKernel<T> {
|
|
|
|
|
math::set_constant(ctx.device_context(), alpha, 0.0);
|
|
|
|
|
} else {
|
|
|
|
|
in_lod = ctx.Input<LoDTensor>("Label")->lod();
|
|
|
|
|
PADDLE_ENFORCE_NE(in_lod.size(), 0, "Input(Label) must be a sequence.");
|
|
|
|
|
PADDLE_ENFORCE_NE(in_lod.size(), 0,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"Input(Label) must be a sequence."));
|
|
|
|
|
seq_num = in_lod[0].size() - 1;
|
|
|
|
|
batch_size = emission_dims[0];
|
|
|
|
|
tag_num = emission_dims[1];
|
|
|
|
@ -204,7 +213,8 @@ class LinearChainCRFOpKernel : public framework::OpKernel<T> {
|
|
|
|
|
const int64_t* lbl = label.data<int64_t>();
|
|
|
|
|
PADDLE_ENFORCE_LT(
|
|
|
|
|
static_cast<size_t>(*std::max_element(lbl, lbl + seq_length)), tag_num,
|
|
|
|
|
"An invalid tag label that execesses the largest tag number.");
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"An invalid tag label that execesses the largest tag number."));
|
|
|
|
|
|
|
|
|
|
// Calculate the nominator part, which depends on the label sequence.
|
|
|
|
|
ll += w[lbl[0]] /*start transition*/ + x[lbl[0]] +
|
|
|
|
@ -254,7 +264,9 @@ class LinearChainCRFGradOpKernel : public framework::OpKernel<T> {
|
|
|
|
|
{emission_dims[0] * emission_dims[1], emission_dims[2]});
|
|
|
|
|
} else {
|
|
|
|
|
in_lod = ctx.Input<LoDTensor>("Label")->lod();
|
|
|
|
|
PADDLE_ENFORCE_NE(in_lod.size(), 0, "Input(Label) must be a sequence.");
|
|
|
|
|
PADDLE_ENFORCE_NE(in_lod.size(), 0,
|
|
|
|
|
platform::errors::InvalidArgument(
|
|
|
|
|
"Input(Label) must be a sequence."));
|
|
|
|
|
seq_num = static_cast<int64_t>(in_lod[0].size() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|