train_v2.py 6.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
#
# 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.

H
hedaoyuan 已提交
15
import sys
H
hedaoyuan 已提交
16 17
import paddle.trainer_config_helpers.attrs as attrs
from paddle.trainer_config_helpers.poolings import MaxPooling
H
hedaoyuan 已提交
18
import paddle.v2 as paddle
19 20


Y
Yu Yang 已提交
21
def convolution_net(input_dim, class_dim=2, emb_dim=128, hid_dim=128):
22 23 24 25 26 27 28 29 30 31 32 33
    data = paddle.layer.data("word",
                             paddle.data_type.integer_value_sequence(input_dim))
    emb = paddle.layer.embedding(input=data, size=emb_dim)
    conv_3 = paddle.networks.sequence_conv_pool(
        input=emb, context_len=3, hidden_size=hid_dim)
    conv_4 = paddle.networks.sequence_conv_pool(
        input=emb, context_len=4, hidden_size=hid_dim)
    output = paddle.layer.fc(input=[conv_3, conv_4],
                             size=class_dim,
                             act=paddle.activation.Softmax())
    lbl = paddle.layer.data("label", paddle.data_type.integer_value(2))
    cost = paddle.layer.classification_cost(input=output, label=lbl)
H
hedaoyuan 已提交
34 35 36 37 38 39 40
    return cost


def stacked_lstm_net(input_dim,
                     class_dim=2,
                     emb_dim=128,
                     hid_dim=512,
Y
Yu Yang 已提交
41
                     stacked_num=3):
H
hedaoyuan 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    """
    A Wrapper for sentiment classification task.
    This network uses bi-directional recurrent network,
    consisting three LSTM layers. This configure is referred to
    the paper as following url, but use fewer layrs.
        http://www.aclweb.org/anthology/P15-1109

    input_dim: here is word dictionary dimension.
    class_dim: number of categories.
    emb_dim: dimension of word embedding.
    hid_dim: dimension of hidden layer.
    stacked_num: number of stacked lstm-hidden layer.
    is_predict: is predicting or not.
                Some layers is not needed in network when predicting.
    """
    assert stacked_num % 2 == 1

    layer_attr = attrs.ExtraLayerAttribute(drop_rate=0.5)
    fc_para_attr = attrs.ParameterAttribute(learning_rate=1e-3)
    lstm_para_attr = attrs.ParameterAttribute(initial_std=0., learning_rate=1.)
    para_attr = [fc_para_attr, lstm_para_attr]
    bias_attr = attrs.ParameterAttribute(initial_std=0., l2_rate=0.)
64 65 66 67 68 69 70 71 72 73 74 75
    relu = paddle.activation.Relu()
    linear = paddle.activation.Linear()

    data = paddle.layer.data("word",
                             paddle.data_type.integer_value_sequence(input_dim))
    emb = paddle.layer.embedding(input=data, size=emb_dim)

    fc1 = paddle.layer.fc(input=emb,
                          size=hid_dim,
                          act=linear,
                          bias_attr=bias_attr)
    lstm1 = paddle.layer.lstmemory(
H
hedaoyuan 已提交
76 77 78 79
        input=fc1, act=relu, bias_attr=bias_attr, layer_attr=layer_attr)

    inputs = [fc1, lstm1]
    for i in range(2, stacked_num + 1):
80 81 82 83 84 85
        fc = paddle.layer.fc(input=inputs,
                             size=hid_dim,
                             act=linear,
                             param_attr=para_attr,
                             bias_attr=bias_attr)
        lstm = paddle.layer.lstmemory(
H
hedaoyuan 已提交
86 87 88 89 90 91 92
            input=fc,
            reverse=(i % 2) == 0,
            act=relu,
            bias_attr=bias_attr,
            layer_attr=layer_attr)
        inputs = [fc, lstm]

93 94 95 96 97 98 99
    fc_last = paddle.layer.pooling(input=inputs[0], pooling_type=MaxPooling())
    lstm_last = paddle.layer.pooling(input=inputs[1], pooling_type=MaxPooling())
    output = paddle.layer.fc(input=[fc_last, lstm_last],
                             size=class_dim,
                             act=paddle.activation.Softmax(),
                             bias_attr=bias_attr,
                             param_attr=para_attr)
H
hedaoyuan 已提交
100

101 102
    lbl = paddle.layer.data("label", paddle.data_type.integer_value(2))
    cost = paddle.layer.classification_cost(input=output, label=lbl)
103 104 105 106 107
    return cost


if __name__ == '__main__':
    # init
Y
Yu Yang 已提交
108
    paddle.init(use_gpu=False, trainer_count=4)
109 110

    # network config
H
hedaoyuan 已提交
111
    print 'load dictionary...'
112
    word_dict = paddle.dataset.imdb.word_dict()
H
hedaoyuan 已提交
113 114
    dict_dim = len(word_dict)
    class_dim = 2
H
hedaoyuan 已提交
115 116 117 118 119

    # Please choose the way to build the network
    # by uncommenting the corresponding line.
    cost = convolution_net(dict_dim, class_dim=class_dim)
    # cost = stacked_lstm_net(dict_dim, class_dim=class_dim, stacked_num=3)
120 121 122 123

    # create parameters
    parameters = paddle.parameters.create(cost)

H
hedaoyuan 已提交
124
    # create optimizer
H
hedaoyuan 已提交
125 126 127 128
    adam_optimizer = paddle.optimizer.Adam(
        learning_rate=2e-3,
        regularization=paddle.optimizer.L2Regularization(rate=8e-4),
        model_average=paddle.optimizer.ModelAverage(average_window=0.5))
129

H
hedaoyuan 已提交
130
    # End batch and end pass event handler
131 132
    def event_handler(event):
        if isinstance(event, paddle.event.EndIteration):
H
hedaoyuan 已提交
133
            if event.batch_id % 100 == 0:
H
hedaoyuan 已提交
134
                print "\nPass %d, Batch %d, Cost %f, %s" % (
135
                    event.pass_id, event.batch_id, event.cost, event.metrics)
H
hedaoyuan 已提交
136 137 138
            else:
                sys.stdout.write('.')
                sys.stdout.flush()
H
hedaoyuan 已提交
139 140
        if isinstance(event, paddle.event.EndPass):
            result = trainer.test(
Y
Yu Yang 已提交
141
                reader=paddle.batch(
142 143
                    lambda: paddle.dataset.imdb.test(word_dict),
                    batch_size=128),
Y
Yu Yang 已提交
144 145
                feeding={'word': 0,
                         'label': 1})
H
hedaoyuan 已提交
146
            print "\nTest with Pass %d, %s" % (event.pass_id, result.metrics)
147

H
hedaoyuan 已提交
148
    # create trainer
149 150 151 152 153
    trainer = paddle.trainer.SGD(cost=cost,
                                 parameters=parameters,
                                 update_equation=adam_optimizer)

    trainer.train(
Y
Yu Yang 已提交
154
        reader=paddle.batch(
H
hedaoyuan 已提交
155
            paddle.reader.shuffle(
156
                lambda: paddle.dataset.imdb.train(word_dict), buf_size=1000),
H
hedaoyuan 已提交
157
            batch_size=100),
158
        event_handler=event_handler,
Y
Yu Yang 已提交
159 160
        feeding={'word': 0,
                 'label': 1},
161
        num_passes=10)