提交 72e1fb1f 编写于 作者: Z Zeyu Chen

add comments for ernie classification

上级 761572f7
...@@ -40,11 +40,14 @@ args = parser.parse_args() ...@@ -40,11 +40,14 @@ args = parser.parse_args()
# yapf: enable. # yapf: enable.
if __name__ == '__main__': if __name__ == '__main__':
# Select a finetune strategy
strategy = hub.BERTFinetuneStrategy( strategy = hub.BERTFinetuneStrategy(
weight_decay=args.weight_decay, weight_decay=args.weight_decay,
learning_rate=args.learning_rate, learning_rate=args.learning_rate,
warmup_strategy="linear_warmup_decay", warmup_strategy="linear_warmup_decay",
) )
# Setup runing config for PaddleHub Finetune API
config = hub.RunConfig( config = hub.RunConfig(
use_cuda=True, use_cuda=True,
num_epoch=args.num_epoch, num_epoch=args.num_epoch,
...@@ -54,6 +57,7 @@ if __name__ == '__main__': ...@@ -54,6 +57,7 @@ if __name__ == '__main__':
# loading Paddlehub BERT # loading Paddlehub BERT
module = hub.Module(name="ernie") module = hub.Module(name="ernie")
# Sentence classification dataset reader
reader = hub.reader.ClassifyReader( reader = hub.reader.ClassifyReader(
dataset=hub.dataset.ChnSentiCorp(), # download chnsenticorp dataset dataset=hub.dataset.ChnSentiCorp(), # download chnsenticorp dataset
vocab_path=module.get_vocab_path(), vocab_path=module.get_vocab_path(),
......
...@@ -40,11 +40,14 @@ args = parser.parse_args() ...@@ -40,11 +40,14 @@ args = parser.parse_args()
# yapf: enable. # yapf: enable.
if __name__ == '__main__': if __name__ == '__main__':
# Select a finetune strategy
strategy = hub.BERTFinetuneStrategy( strategy = hub.BERTFinetuneStrategy(
weight_decay=args.weight_decay, weight_decay=args.weight_decay,
learning_rate=args.learning_rate, learning_rate=args.learning_rate,
warmup_strategy="linear_warmup_decay", warmup_strategy="linear_warmup_decay",
) )
# Setup runing config for PaddleHub Finetune API
config = hub.RunConfig( config = hub.RunConfig(
eval_interval=100, eval_interval=100,
use_cuda=True, use_cuda=True,
...@@ -55,6 +58,7 @@ if __name__ == '__main__': ...@@ -55,6 +58,7 @@ if __name__ == '__main__':
# loading Paddlehub ERNIE # loading Paddlehub ERNIE
module = hub.Module(name="ernie") module = hub.Module(name="ernie")
# Sequence Label dataset reader
reader = hub.reader.SequenceLabelReader( reader = hub.reader.SequenceLabelReader(
dataset=hub.dataset.MSRA_NER(), dataset=hub.dataset.MSRA_NER(),
vocab_path=module.get_vocab_path(), vocab_path=module.get_vocab_path(),
......
...@@ -27,6 +27,8 @@ import numpy as np ...@@ -27,6 +27,8 @@ import numpy as np
from paddlehub.common.logger import logger from paddlehub.common.logger import logger
from paddlehub.finetune.strategy import BERTFinetuneStrategy, DefaultStrategy from paddlehub.finetune.strategy import BERTFinetuneStrategy, DefaultStrategy
from paddlehub.finetune.checkpoint import load_checkpoint, save_checkpoint from paddlehub.finetune.checkpoint import load_checkpoint, save_checkpoint
from paddlehub.finetune.evaluate import evaluate_cls_task,
evaluate_seq_labeling_task
from visualdl import LogWriter from visualdl import LogWriter
import paddlehub as hub import paddlehub as hub
...@@ -135,17 +137,17 @@ def _finetune_seq_label_task(task, ...@@ -135,17 +137,17 @@ def _finetune_seq_label_task(task,
exe=exe) exe=exe)
if do_eval and global_step % config.eval_interval == 0: if do_eval and global_step % config.eval_interval == 0:
evaluate_seq_label( evaluate_seq_label_task(
task, task,
data_reader, data_reader,
feed_list, feed_list,
phase="dev", phase="test",
config=config) config=config)
evaluate_seq_label( evaluate_seq_label_task(
task, task,
data_reader, data_reader,
feed_list, feed_list,
phase="test", phase="dev",
config=config) config=config)
# NOTE: current saved checkpoint machanism is not completed, it can't # NOTE: current saved checkpoint machanism is not completed, it can't
...@@ -157,52 +159,13 @@ def _finetune_seq_label_task(task, ...@@ -157,52 +159,13 @@ def _finetune_seq_label_task(task,
exe=exe) exe=exe)
if do_eval: if do_eval:
evaluate_seq_label( evaluate_seq_label_task(
task, data_reader, feed_list, phase="dev", config=config)
evaluate_seq_label_task(
task, data_reader, feed_list, phase="test", config=config) task, data_reader, feed_list, phase="test", config=config)
logger.info("PaddleHub finetune finished.") logger.info("PaddleHub finetune finished.")
def evaluate_seq_label(task, data_reader, feed_list, phase="test", config=None):
fetch_list = [
task.variable("labels").name,
task.variable("infers").name,
task.variable("seq_len").name,
task.variable("loss").name
]
logger.info("Evaluation on {} dataset start".format(phase))
inference_program = task.inference_program()
batch_size = config.batch_size
place, dev_count = _get_running_device_info(config)
exe = fluid.Executor(place=place)
with fluid.program_guard(inference_program):
data_feeder = fluid.DataFeeder(feed_list=feed_list, place=place)
num_eval_examples = acc_sum = loss_sum = 0
test_reader = data_reader.data_generator(
batch_size=batch_size, phase=phase)
eval_time_begin = time.time()
eval_step = 0
total_label, total_infer, total_correct = 0.0, 0.0, 0.0
for batch in test_reader():
num_batch_examples = len(batch)
eval_step += 1
np_labels, np_infers, np_lens, _ = exe.run(
feed=data_feeder.feed(batch), fetch_list=fetch_list)
label_num, infer_num, correct_num = chunk_eval(
np_labels, np_infers, np_lens, 7, dev_count)
total_infer += infer_num
total_label += label_num
total_correct += correct_num
precision, recall, f1 = calculate_f1(total_label, total_infer,
total_correct)
eval_time_used = time.time() - eval_time_begin
eval_speed = eval_step / eval_time_used
logger.info(
"[%s evaluation] F1-Score=%f, precision=%f, recall=%f [step/sec: %.2f]"
% (phase, f1, precision, recall, eval_speed))
def _finetune_cls_task(task, data_reader, feed_list, config=None, def _finetune_cls_task(task, data_reader, feed_list, config=None,
do_eval=False): do_eval=False):
main_program = task.main_program() main_program = task.main_program()
...@@ -287,7 +250,7 @@ def _finetune_cls_task(task, data_reader, feed_list, config=None, ...@@ -287,7 +250,7 @@ def _finetune_cls_task(task, data_reader, feed_list, config=None,
exe=exe) exe=exe)
if do_eval and global_step % config.eval_interval == 0: if do_eval and global_step % config.eval_interval == 0:
eval_loss, eval_acc, eval_perf = evaluate( eval_loss, eval_acc, eval_perf = evaluate_cls_task(
task, task,
data_reader, data_reader,
feed_list, feed_list,
...@@ -313,7 +276,8 @@ def _finetune_cls_task(task, data_reader, feed_list, config=None, ...@@ -313,7 +276,8 @@ def _finetune_cls_task(task, data_reader, feed_list, config=None,
exe=exe) exe=exe)
if do_eval: if do_eval:
evaluate(task, data_reader, feed_list, phase="test", config=config) evaluate_cls_task(
task, data_reader, feed_list, phase="test", config=config)
logger.info("PaddleHub finetune finished.") logger.info("PaddleHub finetune finished.")
...@@ -321,150 +285,10 @@ def finetune_and_eval(task, data_reader, feed_list, config=None): ...@@ -321,150 +285,10 @@ def finetune_and_eval(task, data_reader, feed_list, config=None):
if task.task_type == "sequence_labeling": if task.task_type == "sequence_labeling":
_finetune_seq_label_task( _finetune_seq_label_task(
task, data_reader, feed_list, config, do_eval=True) task, data_reader, feed_list, config, do_eval=True)
# if it's image_classification and text classificaiton
else: else:
_finetune_cls_task(task, data_reader, feed_list, config, do_eval=True) _finetune_cls_task(task, data_reader, feed_list, config, do_eval=True)
def finetune(task, data_reader, feed_list, config=None): def finetune(task, data_reader, feed_list, config=None):
_finetune_cls_task(task, data_reader, feed_list, config, do_eval=False) _finetune_cls_task(task, data_reader, feed_list, config, do_eval=False)
def evaluate(task, data_reader, feed_list, phase="test", config=None):
logger.info("Evaluation on {} dataset start".format(phase))
inference_program = task.inference_program()
main_program = task.main_program()
loss = task.variable("loss")
accuracy = task.variable("accuracy")
batch_size = config.batch_size
place, dev_count = _get_running_device_info(config)
exe = fluid.Executor(place=place)
with fluid.program_guard(inference_program):
data_feeder = fluid.DataFeeder(feed_list=feed_list, place=place)
num_eval_examples = acc_sum = loss_sum = 0
test_reader = data_reader.data_generator(
batch_size=batch_size, phase=phase)
eval_time_begin = time.time()
eval_step = 0
for batch in test_reader():
num_batch_examples = len(batch)
eval_step += 1
loss_v, accuracy_v = exe.run(
feed=data_feeder.feed(batch),
fetch_list=[loss.name, accuracy.name])
num_eval_examples += num_batch_examples
acc_sum += accuracy_v * num_batch_examples
loss_sum += loss_v * num_batch_examples
eval_time_used = time.time() - eval_time_begin
avg_loss = loss_sum / num_eval_examples
avg_acc = acc_sum / num_eval_examples
eval_speed = eval_step / eval_time_used
logger.info(
"[%s dataset evaluation result] loss=%.5f acc=%.5f [step/sec: %.2f]" %
(phase, avg_loss, avg_acc, eval_speed))
return avg_loss, avg_acc, eval_speed
# Sequence label evaluation functions
def chunk_eval(np_labels, np_infers, np_lens, tag_num, dev_count=1):
def extract_bio_chunk(seq):
chunks = []
cur_chunk = None
null_index = tag_num - 1
for index in range(len(seq)):
tag = seq[index]
tag_type = tag // 2
tag_pos = tag % 2
if tag == null_index:
if cur_chunk is not None:
chunks.append(cur_chunk)
cur_chunk = None
continue
if tag_pos == 0:
if cur_chunk is not None:
chunks.append(cur_chunk)
cur_chunk = {}
cur_chunk = {"st": index, "en": index + 1, "type": tag_type}
else:
if cur_chunk is None:
cur_chunk = {"st": index, "en": index + 1, "type": tag_type}
continue
if cur_chunk["type"] == tag_type:
cur_chunk["en"] = index + 1
else:
chunks.append(cur_chunk)
cur_chunk = {"st": index, "en": index + 1, "type": tag_type}
if cur_chunk is not None:
chunks.append(cur_chunk)
return chunks
null_index = tag_num - 1
num_label = 0
num_infer = 0
num_correct = 0
labels = np_labels.reshape([-1]).astype(np.int32).tolist()
infers = np_infers.reshape([-1]).astype(np.int32).tolist()
all_lens = np_lens.reshape([dev_count, -1]).astype(np.int32).tolist()
base_index = 0
for dev_index in range(dev_count):
lens = all_lens[dev_index]
max_len = 0
for l in lens:
max_len = max(max_len, l)
for i in range(len(lens)):
seq_st = base_index + i * max_len + 1
seq_en = seq_st + (lens[i] - 2)
infer_chunks = extract_bio_chunk(infers[seq_st:seq_en])
label_chunks = extract_bio_chunk(labels[seq_st:seq_en])
num_infer += len(infer_chunks)
num_label += len(label_chunks)
infer_index = 0
label_index = 0
while label_index < len(label_chunks) \
and infer_index < len(infer_chunks):
if infer_chunks[infer_index]["st"] \
< label_chunks[label_index]["st"]:
infer_index += 1
elif infer_chunks[infer_index]["st"] \
> label_chunks[label_index]["st"]:
label_index += 1
else:
if infer_chunks[infer_index]["en"] \
== label_chunks[label_index]["en"] \
and infer_chunks[infer_index]["type"] \
== label_chunks[label_index]["type"]:
num_correct += 1
infer_index += 1
label_index += 1
base_index += max_len * len(lens)
return num_label, num_infer, num_correct
def calculate_f1(num_label, num_infer, num_correct):
if num_infer == 0:
precision = 0.0
else:
precision = num_correct * 1.0 / num_infer
if num_label == 0:
recall = 0.0
else:
recall = num_correct * 1.0 / num_label
if num_correct == 0:
f1 = 0.0
else:
f1 = 2 * precision * recall / (precision + recall)
return precision, recall, f1
...@@ -148,7 +148,7 @@ def create_img_classification_task(feature, ...@@ -148,7 +148,7 @@ def create_img_classification_task(feature,
return task return task
def create_seq_labeling_task(feature, labels, seq_len, num_classes=None): def create_seq_labeling_task(feature, labels, seq_len, num_classes):
logits = fluid.layers.fc( logits = fluid.layers.fc(
input=feature, input=feature,
size=num_classes, size=num_classes,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册