关于paddle的安装官方提供了两种方法:
由于安装并没有遇到困难,所以就不在此详述,参考官方进行安装即可。
我们可以从官方下载源码,进行paddle的hello world实验。
需要强调的是paddle源码更新升级比较快,极有可能出现源码与此讲解或者官方文档冲突的情况。甚至自己的源码demo都会因为其他部门的变化而变得不可执行。这点需要注意
首先从方法论的角度结合Amazon电子产品评论数据(此问题等同于情感标注问题,根据评论者的态度分为正样本和负样本,即二分类问题)来看paddle的处理流程。任何一个paddle的处理流程都包括如下5个基础部分。
1.数据格式准备:
2.数据向模型传送:
3.网络结构:
4.训练模型:
5.预测
#!/bin/sh
wget http://m1-idl-gpu2-bak31.m1.baidu.com:8088/data/amazon.tar
tar -xf amazon.tar
rm -rf amazon.tar
传送数据的主要代码在/demo/quick_start的dataprovider.py中,代码利用了Python的@(装饰者模式)方法。代码如下:
import os
import sys
from paddle.trainer.PyDataProviderWrapper import *
UNK_IDX = 0
@init_hook_wrapper
def hook(obj, dictionary, **kwargs):
obj.word_dict = dictionary
obj.slots = [SparseNonValueSlot(len(obj.word_dict)), IndexSlot(2)]
@provider(init_hook=hook)
def process_bow(obj, file_name):
with open(file_name, 'r') as fdata:
for line in fdata:
label, comment = line.strip().split('\t')
words = comment.split()
word_slot = [obj.word_dict.get(w, UNK_IDX) for w in words]
yield word_slot, int(label)
@init_hook_wrapper
def hook2(obj, dictionary, **kwargs):
obj.word_dict = dictionary
obj.slots = [IndexSlot(len(obj.word_dict)), IndexSlot(2)]
@provider(use_seq=True, init_hook=hook2)
def process(obj, file_name):
with open(file_name, 'r') as fdata:
for line in fdata:
label, comment = line.strip().split('\t')
words = comment.split()
word_slot = [obj.word_dict.get(w, UNK_IDX) for w in words]
yield word_slot, [int(label)]
@init_hook_wrapper
def hook3(obj, dictionary, **kwargs):
obj.word_dict = dictionary
obj.slots = [IndexSlot(len(obj.word_dict))]
@provider(use_seq=True, init_hook=hook3)
def process_pre(obj, file_name):
with open(file_name, 'r') as fdata:
for line in fdata:
comment = line.strip()
word_slot = [obj.word_dict.get(w, UNK_IDX) for w in comment]
yield word_slot
from paddle.trainer_config_helpers import *
dict_file = "./data/dict.txt"
word_dict = dict()
with open(dict_file, 'r') as f:
for i, line in enumerate(f):
w = line.strip().split()[0]
word_dict[w] = i
define_py_data_sources('data/train.list',
'data/test.list',
module="dataprovider",
obj="process_bow",
args={"dictionary": word_dict},
train_async=True)
data = data_layer(name="word", size=len(word_dict))
label = data_layer(name="label", size=2)
embedding = embedding_layer(input=data, size=128)
avg = pooling_layer(input=embedding, pooling_type=AvgPooling())
output = fc_layer(input=avg, size=2, act=SoftmaxActivation())
cls = classification_cost(input=output, label=label)
关于在代码中优化算法和其他参数的设置可以在setting中实现:
settings(
batch_size=128,
learning_rate=2e-3,
learning_method=AdamOptimizer(),
regularization=L2Regularization(8e-4),
gradient_clipping_threshold=25
)
训练脚本:训练的命令行脚本保存在了run.sh文件中。如下:
#!/bin/sh
cfg=trainer_config.lr.py
#cfg=trainer_config.emb.py
#cfg=trainer_config.cnn.py
#cfg=trainer_config.lstm.py
paddle train \
--config=$cfg \
--save_dir=./output \
--trainer_count=4 \
--log_period=20 \
--num_passes=15 \
--use_gpu=false \
--show_parameter_stats_period=100 \
--test_all_data_in_one_period=1 \
2>&1 | tee 'train.log'
预测可以使用有标签的数据对训练好的模型进行评价,也可以直接使用没有label的数据集进行预测。
在测试脚本中将会测试配置文件中test.list指定的数据。
paddle train \
--use_gpu=false \
--job=test \
--init_model_path=./output/pass-x
其中x需要修改为具体训练好的模型。
因为只有时序模型加入了预测的代码,我这里也已时序模型为例说明如何预测没有label的数据。脚本如下:
model="output/pass-x"
paddle train \
--config=trainer_config.lstm.py \
--use_gpu=false \
--job=test \
--init_model_path=$model \
--config_args=is_predict=1 \
--predict_output_dir=. \
其中x需要修改为具体训练好的模型。 得到的标签数据保存在rank-00000中。