PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.2k stars 5.57k forks source link

Check failed: starts->getData()[newBatchSize_] == input.getBatchSize() #10877

Closed Angus07 closed 6 years ago

Angus07 commented 6 years ago

Check failed: starts->getData()[newBatchSize_] == input.getBatchSize() (6 vs. 30) c++预测的时候出现这个问题 我的网络结构输入是: data1 = paddle.layer.data("title1", paddle.data_type.integer_value_sequence(dict_dim)) data2 = paddle.layer.data("title2", paddle.data_type.integer_value_sequence(dict_dim)) data3 = paddle.layer.data("title3", paddle.data_type.integer_value_sequence(dictdim)) 三个域的输入。 然后输入了3个序列,都是句子,每个id代表一个词,比如[2,3,4,5,...] [2,6,7,...] [2,8, 6,..] 其中这三个序列的长度分别是30,5,6,然后就报了这个错 Check failed: starts->getData()[newBatchSize] == input.getBatchSize() (6 vs. 30)

预测代码如下:

    CHECK(paddle_arguments_resize(_in_args, feats.size()));
    std::cerr << feats.size() <<  std::endl;
    for (unsigned int i = 0; i < feats.size(); i++ ) {
        paddle_ivector sentence = paddle_ivector_create(feats[i].data(),
                                                        (uint64_t)feats[i].size(), false, false);
        int seq_pos_array[] = {0, (uint64_t)feats[i].size()};
        paddle_ivector seq_pos = paddle_ivector_create(seq_pos_array,
                                                       sizeof(seq_pos_array) / sizeof(int), false, false);
        //paddle_ivector ivec = paddle_ivector_create_none();
        CHECK(paddle_arguments_set_ids(_in_args, i, sentence));
        CHECK(paddle_arguments_set_sequence_start_pos(_in_args, i , 0, seq_pos));
    }
    CHECK(paddle_gradient_machine_forward(_thread_local_machine,
                                          _in_args, _out_args, false));
panyx0718 commented 6 years ago

能给更多的信息吗?

Superjomn commented 6 years ago

是给入的数据维度不一致

Superjomn commented 6 years ago

读入数据本身是没问题的,但貌似, 这三个数据之后的操作出了问题,不同长度的序列体现在 batch size上,这里三个数据有不同的batch size,如果接着用类似 sum/average 这类需要所有input的batch size相同的op,就会报错

Angus07 commented 6 years ago

该如何解决呢?python 预测时没有遇到这个问题

Superjomn commented 6 years ago

可以贴下python 的代码,怀疑3个系列给入顺序,python和c++不同

Angus07 commented 6 years ago
def convolution_net(dict_dim, class_dim, emb_dim,
                    hid_dim, is_infer=False):
    """
    cnn network definition

    :param dict_dim: size of word dictionary
    :type input_dim: int
    :params class_dim: number of instance class
    :type class_dim: int
    :params emb_dim: embedding vector dimension
    :type emb_dim: int
    :params hid_dim: number of same size convolution kernels
    :type hid_dim: int
    """
    data1 = paddle.layer.data("title1",
                             paddle.data_type.integer_value_sequence(dict_dim))
    data2 = paddle.layer.data("title2",
                         paddle.data_type.integer_value_sequence(dict_dim))
    data3 = paddle.layer.data("title3",
                             paddle.data_type.integer_value_sequence(dict_dim))

    if not is_infer:
        lbl = paddle.layer.data("label", paddle.data_type.dense_vector(class_dim,int))

    emb1 = paddle.layer.embedding(input=data1, size=emb_dim, \
                                  param_attr=ParamAttr(name='shared_emb_l1'))
    emb2 = paddle.layer.embedding(input=data2, size=emb_dim, \
                                  param_attr=ParamAttr(name='shared_emb_l1'))
    emb3 = paddle.layer.embedding(input=data3, size=emb_dim, \
                                  param_attr=ParamAttr(name='shared_emb_l1'))

    # embedding layer
    seq_pool1 = paddle.layer.pooling(input=emb1, pooling_type=paddle.pooling.Avg())
    seq_pool1_fc = paddle.layer.fc(input=seq_pool1, size=128, act=paddle.activation.Relu(), \
                                   bias_attr=True, name='seq_pool_fc1_l1')

    seq_pool2 = paddle.layer.pooling(input=emb2, pooling_type=paddle.pooling.Avg())
    seq_pool2_fc = paddle.layer.fc(input=seq_pool2, size=64, act=paddle.activation.Relu(), \
                                   bias_attr=True, name='seq_pool_fc2_l1')

    seq_pool3 = paddle.layer.pooling(input=emb3, pooling_type=paddle.pooling.Avg())
    seq_pool3_fc = paddle.layer.fc(input=seq_pool3, size=64, act=paddle.activation.Relu(), \
                                   bias_attr=True, name='seq_pool_fc3_l1')

    # convolution layers with max pooling
    conv_1_win3 = paddle.networks.sequence_conv_pool(
        input=emb1, context_len=3, hidden_size=hid_dim, fc_bias_attr=True, \
        fc_act=paddle.activation.Relu(), pool_type=paddle.pooling.Max(), \
        name='sequence_conv_pool1_l1')
    conv_1_win4 = paddle.networks.sequence_conv_pool(
        input=emb1, context_len=5, hidden_size=hid_dim, fc_bias_attr=True, \
        fc_act=paddle.activation.Relu(), pool_type=paddle.pooling.Max(), \
        name='sequence_conv_pool2_l1')
    conv_1_win5 = paddle.networks.sequence_conv_pool(
        input=emb1, context_len=7, hidden_size=hid_dim, fc_bias_attr=True, \
        fc_act=paddle.activation.Relu(), pool_type=paddle.pooling.Max(), \
        name='sequence_conv_pool3_l1')

    # fc and output layer

    concated_vector = paddle.layer.concat([conv_1_win3, conv_1_win4, conv_1_win5, \
                                           seq_pool1_fc, seq_pool2_fc, seq_pool3_fc])

    concated_vector = paddle.layer.batch_norm(input=concated_vector, \
                      act=paddle.activation.Relu(), name='batch_norm_l1')
    hidden = paddle.layer.fc(input=concated_vector, size=2000, \
                      act=paddle.activation.Relu(), bias_attr=True, name='fc1_l1')
    #hidden = paddle.layer.dropout(input=hidden, dropout_rate=0.5)

    prob = paddle.layer.fc(input=hidden, size=class_dim, \
                      act=paddle.activation.Sigmoid(), bias_attr=True, name='fc2_l1')

    if is_infer:
        return prob
    else:
        return paddle.layer.multi_binary_label_cross_entropy_cost(
            input=prob, label=lbl), prob, lbl
Angus07 commented 6 years ago

def infer_a_batch(self, test_batch, ids_2_label): """ infer_a_batch """ if test_batch == []: return

    feeding = {"title1": 0, "title2": 1, "title3": 2}

    probs = self.inferer.infer(input=test_batch, feeding=feeding, field=["value"])
    assert len(probs) == len(test_batch)
Angus07 commented 6 years ago

def predict_reader(url, title_seg, content_seg, word_dict): """ Reader interface for predicting data

:param url: url.
:type url: str
:param title_seg: title_seg,
:type title_seg: seg str,
:param content_seg: content_seg,
:type content_seg: seg str,
:param word_dict: word dict
    the dictionary must has a "UNK" in it.
:type word_dict: Python dict
"""

UNK_ID = word_dict["<UNK>"]
PAD_ID = -1

try:
    title_slot = title_seg.split(chr(1))
    title = ''.join(title_slot[0].split())
    content_slot = content_seg.split(chr(1))
    content = ''.join(content_slot[0].split())

    word_ids1 = [
                word_dict.get(w, UNK_ID)
                for w in title_slot[0].split()[0:500]
                ]
    if word_ids1 == []:
        word_ids1 = [PAD_ID]
    word_ids2 = [
                word_dict.get(w, UNK_ID)
                for w in title_slot[1].split()[0:500]
                ]
    if word_ids2 == []:
        word_ids2 = [PAD_ID]
    word_ids3 = [
                word_dict.get(w, UNK_ID)
                for w in title_slot[2].split()[0:500]
                ]
    if word_ids3 == []:
        word_ids3 = [PAD_ID]
    word_ids4 = [
                ]
    if word_ids4 == []:
        word_ids4 = [PAD_ID]
    word_ids5 = [
                ]
    if word_ids5 == []:
        word_ids5 = [PAD_ID]
    word_ids6 = [
                ]
    if word_ids6 == []:
        word_ids6 = [PAD_ID]

except Exception, e:
    return []
return word_ids1, word_ids2, word_ids3, \
       url, title, content
Angus07 commented 6 years ago

我没看出有什么不同,都是按照前后顺序读入的。

Superjomn commented 6 years ago

怀疑是CAPI传入的input顺序与 model protobuf 里的顺序不同.

参考 https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/tests/test_layer.py#L49 打印出网络结构,里面有 input layer names,与你这里

data1,data2,data3,data7 对比,如果顺序不同,按照这里重新组织下 CAPI 里对应input的顺序。

@shanyi15 辛苦添加下CAPI添加多个input slots 需要查看 Protobuf 中 Input layer names 的文档

Angus07 commented 6 years ago

第一,打印出来,顺序就是这个顺序。 input_layer_names: "title1_l1" input_layer_names: "title2_l1" input_layer_names: "title3l1" 第二,我打乱了CAPI的顺序。 之前是30 ,5,6,报错是 Check failed: starts->getData()[newBatchSize] == input.getBatchSize() (6 vs. 30) 现在我输入6,5,30 报错 Check failed: starts->getData()[newBatchSize_] == input.getBatchSize() (6 vs. 5)

qingqing01 commented 6 years ago

@Angus07 已Hi上帮助解决了,如果没问题,可否关闭Issue?