predict.py 6.4 KB
Newer Older
1
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
Z
zhangjinchao01 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import numpy as np
from optparse import OptionParser
18 19
from py_paddle import swig_paddle, DataProviderConverter
from paddle.trainer.PyDataProvider2 import integer_value_sequence
Z
zhangjinchao01 已提交
20 21 22
from paddle.trainer.config_parser import parse_config
"""
Usage: run following command to show help message.
23
  python predict.py -h
Z
zhangjinchao01 已提交
24 25 26 27 28
"""
UNK_IDX = 0


class Prediction():
Y
Yu Yang 已提交
29 30
    def __init__(self, train_conf, dict_file, model_dir, label_file,
                 predicate_dict_file):
Z
zhangjinchao01 已提交
31 32 33 34 35 36 37 38
        """
        train_conf: trainer configure.
        dict_file: word dictionary file name.
        model_dir: directory of model.
        """

        self.dict = {}
        self.labels = {}
Y
Yu Yang 已提交
39
        self.predicate_dict = {}
Z
zhangjinchao01 已提交
40
        self.labels_reverse = {}
Z
zhangjinchao01 已提交
41
        self.load_dict_label(dict_file, label_file, predicate_dict_file)
Z
zhangjinchao01 已提交
42 43 44

        len_dict = len(self.dict)
        len_label = len(self.labels)
Z
zhangjinchao01 已提交
45
        len_pred = len(self.predicate_dict)
Z
zhangjinchao01 已提交
46 47

        conf = parse_config(
Y
Yu Yang 已提交
48 49
            train_conf, 'dict_len=' + str(len_dict) + ',label_len=' +
            str(len_label) + ',pred_len=' + str(len_pred) + ',is_predict=True')
Z
zhangjinchao01 已提交
50 51 52 53
        self.network = swig_paddle.GradientMachine.createFromConfigProto(
            conf.model_config)
        self.network.loadParameters(model_dir)

54
        slots = [
Y
Yu Yang 已提交
55 56 57 58 59
            integer_value_sequence(len_dict), integer_value_sequence(len_dict),
            integer_value_sequence(len_dict), integer_value_sequence(len_dict),
            integer_value_sequence(len_dict), integer_value_sequence(len_dict),
            integer_value_sequence(len_pred), integer_value_sequence(2)
        ]
60
        self.converter = DataProviderConverter(slots)
Z
zhangjinchao01 已提交
61

Z
zhangjinchao01 已提交
62
    def load_dict_label(self, dict_file, label_file, predicate_dict_file):
Z
zhangjinchao01 已提交
63 64 65 66 67 68 69 70 71 72
        """
        Load dictionary from self.dict_file.
        """
        for line_count, line in enumerate(open(dict_file, 'r')):
            self.dict[line.strip()] = line_count

        for line_count, line in enumerate(open(label_file, 'r')):
            self.labels[line.strip()] = line_count
            self.labels_reverse[line_count] = line.strip()

Z
zhangjinchao01 已提交
73 74
        for line_count, line in enumerate(open(predicate_dict_file, 'r')):
            self.predicate_dict[line.strip()] = line_count
Y
Yu Yang 已提交
75

Z
zhangjinchao01 已提交
76 77 78 79 80 81
    def get_data(self, data_file):
        """
        Get input data of paddle format.
        """
        with open(data_file, 'r') as fdata:
            for line in fdata:
Z
zhangjinchao01 已提交
82
                sentence, predicate, ctx_n2, ctx_n1, ctx_0, ctx_p1, ctx_p2, mark, label = line.strip(
Z
zhangjinchao01 已提交
83 84 85
                ).split('\t')
                words = sentence.split()
                sen_len = len(words)
Y
Yu Yang 已提交
86

Z
zhangjinchao01 已提交
87
                word_slot = [self.dict.get(w, UNK_IDX) for w in words]
Y
Yu Yang 已提交
88 89
                predicate_slot = [self.predicate_dict.get(predicate, UNK_IDX)
                                  ] * sen_len
Z
zhangjinchao01 已提交
90
                ctx_n2_slot = [self.dict.get(ctx_n2, UNK_IDX)] * sen_len
Z
zhangjinchao01 已提交
91 92 93
                ctx_n1_slot = [self.dict.get(ctx_n1, UNK_IDX)] * sen_len
                ctx_0_slot = [self.dict.get(ctx_0, UNK_IDX)] * sen_len
                ctx_p1_slot = [self.dict.get(ctx_p1, UNK_IDX)] * sen_len
Z
zhangjinchao01 已提交
94
                ctx_p2_slot = [self.dict.get(ctx_p2, UNK_IDX)] * sen_len
Z
zhangjinchao01 已提交
95 96 97

                marks = mark.split()
                mark_slot = [int(w) for w in marks]
Y
Yu Yang 已提交
98

Z
zhangjinchao01 已提交
99 100
                yield word_slot, ctx_n2_slot, ctx_n1_slot, \
                      ctx_0_slot, ctx_p1_slot, ctx_p2_slot, predicate_slot, mark_slot
Z
zhangjinchao01 已提交
101

Z
zhangjinchao01 已提交
102
    def predict(self, data_file, output_file):
Z
zhangjinchao01 已提交
103 104 105 106 107
        """
        data_file: file name of input data.
        """
        input = self.converter(self.get_data(data_file))
        output = self.network.forwardTest(input)
Z
zhangjinchao01 已提交
108
        lab = output[0]["id"].tolist()
Z
zhangjinchao01 已提交
109

Z
zhangjinchao01 已提交
110
        with open(data_file, 'r') as fin, open(output_file, 'w') as fout:
Z
zhangjinchao01 已提交
111 112 113 114 115 116
            index = 0
            for line in fin:
                sen = line.split('\t')[0]
                len_sen = len(sen.split())
                line_labels = lab[index:index + len_sen]
                index += len_sen
117 118
                fout.write(sen + '\t' + ' '.join(
                    [self.labels_reverse[i] for i in line_labels]) + '\n')
Z
zhangjinchao01 已提交
119 120 121


def option_parser():
Y
Yu Yang 已提交
122 123 124
    usage = (
        "python predict.py -c config -w model_dir "
        "-d word dictionary -l label_file -i input_file  -p pred_dict_file")
Z
zhangjinchao01 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    parser = OptionParser(usage="usage: %s [options]" % usage)
    parser.add_option(
        "-c",
        "--tconf",
        action="store",
        dest="train_conf",
        help="network config")
    parser.add_option(
        "-d",
        "--dict",
        action="store",
        dest="dict_file",
        help="dictionary file")
    parser.add_option(
        "-l",
        "--label",
        action="store",
        dest="label_file",
        default=None,
        help="label file")
Z
zhangjinchao01 已提交
145 146 147 148 149 150 151
    parser.add_option(
        "-p",
        "--predict_dict_file",
        action="store",
        dest="predict_dict_file",
        default=None,
        help="predict_dict_file")
Z
zhangjinchao01 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164
    parser.add_option(
        "-i",
        "--data",
        action="store",
        dest="data_file",
        help="data file to predict")
    parser.add_option(
        "-w",
        "--model",
        action="store",
        dest="model_path",
        default=None,
        help="model path")
Z
zhangjinchao01 已提交
165 166 167 168 169 170 171 172

    parser.add_option(
        "-o",
        "--output_file",
        action="store",
        dest="output_file",
        default=None,
        help="output file")
Z
zhangjinchao01 已提交
173 174 175 176 177 178 179 180 181 182
    return parser.parse_args()


def main():
    options, args = option_parser()
    train_conf = options.train_conf
    data_file = options.data_file
    dict_file = options.dict_file
    model_path = options.model_path
    label_file = options.label_file
Z
zhangjinchao01 已提交
183 184
    predict_dict_file = options.predict_dict_file
    output_file = options.output_file
Z
zhangjinchao01 已提交
185 186

    swig_paddle.initPaddle("--use_gpu=0")
Y
Yu Yang 已提交
187 188 189
    predict = Prediction(train_conf, dict_file, model_path, label_file,
                         predict_dict_file)
    predict.predict(data_file, output_file)
Z
zhangjinchao01 已提交
190 191 192 193


if __name__ == '__main__':
    main()