<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      script type="text/javascript" src="http://latex.codecogs.com/latex.js">

      colab上基于tensorflow2的BERT中文文本多分類(lèi)finetuning

      整體背景

      本文實(shí)現(xiàn)了在colab環(huán)境下基于tf-nightly-gpu的BERT中文多分類(lèi),如果你在現(xiàn)階段有實(shí)現(xiàn)類(lèi)似的功能的需求,相信這篇文章會(huì)給你帶來(lái)一些幫助。

      準(zhǔn)備工作

      1.環(huán)境:

      硬件環(huán)境:

      直接使用谷歌提供的免費(fèi)訓(xùn)練環(huán)境colab,選擇GPU

      軟件環(huán)境:

      tensorflow:tensorflow2.1.0版本對(duì)BERT的支持有些問(wèn)題,現(xiàn)象是可以訓(xùn)練但預(yù)測(cè)時(shí)無(wú)法正常加載模型(稍后代碼里會(huì)詳述),因此改為選擇tf-nightly(主線版本隨時(shí)會(huì)有新變更,如果擔(dān)心有影響可以選擇打tag的dev版本,如筆者驗(yàn)證2.2.0.dev20200218是可以的)

      預(yù)訓(xùn)練模型:基于tf2.x的中文預(yù)訓(xùn)練模型(https://tfhub.dev/tensorflow/bert_zh_L-12_H-768_A-12/1)【注:谷歌基于tf1.x版本公布過(guò)一個(gè)中文預(yù)訓(xùn)練模型(BERT-base,Chinese),根據(jù)注釋其在tf2.0環(huán)境下應(yīng)該無(wú)法使用】

      分類(lèi)代碼邏輯:谷歌已經(jīng)幫我們準(zhǔn)備好了基于BERT的分類(lèi)主程序,其不隨tensorflow一起提供,而是單獨(dú)放在了tensorflow/models下面。models目前也分為發(fā)布版和主線版本,本文為了保證分類(lèi)代碼邏輯的穩(wěn)定,選擇發(fā)布版models v2.1.0【注:models主線版本近期(2020年2月)有頻繁變更,可以看到的是正在對(duì)BERT分類(lèi)邏輯做小規(guī)模的重構(gòu)優(yōu)化,所以當(dāng)models 2.2.0的時(shí)候,可能分類(lèi)邏輯會(huì)有較大變化】

      適配代碼:谷歌提供的代碼肯定不能直接滿足我們自己的需求,所以要對(duì)代碼進(jìn)行修改調(diào)整,本文也提供了基于models2.1.0版本修改出來(lái)的BERT分類(lèi)適配代碼

      2.訓(xùn)練數(shù)據(jù):

      本文從百度百科上爬取了10w左右的詞條,按照人物(human)、自然(nature)、地點(diǎn)(poi)、組織(org)、生活(life)等等標(biāo)注成大概十幾個(gè)類(lèi)別。把每個(gè)百科詞條中的信息按照標(biāo)題、概述、正文、infobox等分別提取出來(lái)并進(jìn)行簡(jiǎn)單的清洗操作后,直接連接到一起形成一個(gè)長(zhǎng)文本。再與百度百科id以及分類(lèi)標(biāo)簽按照"id\tinfo\tlabel"的格式組織成3列,形成類(lèi)似于這種格式的訓(xùn)練數(shù)據(jù):

      bkid    info    label

      ---------------

      1         xxxx    life

      2        xxxx    human

      ……

      實(shí)際數(shù)據(jù)看起來(lái)是這樣的:

       數(shù)據(jù)準(zhǔn)備好后重新洗牌并按照70%:20%:10%的比例拆分成訓(xùn)練集、驗(yàn)證集和測(cè)試集。

      代碼適配

      bert相關(guān)代碼都在tensorflow/models下面,將models 2.1.0壓縮包下載下來(lái)后后,BERT分類(lèi)代碼位于:models2.1.0/official/nlp/bert目錄下

      復(fù)制代碼
      $ tree .
      .
      |-- bert_cloud_tpu.md
      |-- classifier_data_lib.py # 分類(lèi)數(shù)據(jù)方法庫(kù)
      |-- common_flags.py # 通用命令行參數(shù)
      |-- create_finetuning_data.py # 生成tfrecord格式的微調(diào)數(shù)據(jù)(依賴(lài)classifier_data_lib.py)
      |-- create_pretraining_data.py # 生成預(yù)訓(xùn)練數(shù)據(jù)(只有重新預(yù)訓(xùn)練整個(gè)模型時(shí)才使用,本次不用)
      |-- custom_metrics.py # 自定義文件,用于計(jì)算自定義metrics
      |-- do_pred_data.py # 自定義文件,用于生成預(yù)測(cè)數(shù)據(jù)
      |-- do_predict.py # 自定義文件,用于模型訓(xùn)練完成后執(zhí)行預(yù)測(cè)
      |-- export_tfhub.py
      |-- export_tfhub_test.py
      |-- __init__.py
      |-- input_pipeline.py # 用于加載tfrecord格式的訓(xùn)練數(shù)據(jù)
      |-- model_saving_utils.py # 用于模型保存
      |-- README.md
      |-- run_classifier.py # finetune分類(lèi)主程序
      |-- run_pretraining.py # 預(yù)訓(xùn)練主程序(本次不用)
      |-- run_squad.py # squad主程序(本次不用)
      |-- squad_lib.py
      |-- squad_lib_sp.py
      |-- tf1_checkpoint_converter_lib.py
      |-- tf2_albert_encoder_checkpoint_converter.py
      |-- tf2_encoder_checkpoint_converter.py
      |-- tokenization.py # 分詞器
      |-- tokenization_test.py
      `-- utils.py #自定義文件,用于繪制自定義metrics圖表
      
      0 directories, 25 files
      復(fù)制代碼

      主要修改點(diǎn)有二:

      1. 添加自定義的數(shù)據(jù)處理器及處理邏輯

      2. 原finetune代碼只有訓(xùn)練集和驗(yàn)證集的代碼流程,本文在整個(gè)訓(xùn)練結(jié)束后添加了測(cè)試集的相關(guān)流程。

      3. 原代碼只系統(tǒng)了訓(xùn)練邏輯,本文添加了訓(xùn)練完成之后的預(yù)測(cè)邏輯(暫未包括生產(chǎn)環(huán)境部署)。

      下面對(duì)主要修改點(diǎn)進(jìn)行說(shuō)明:

      1.數(shù)據(jù)格式轉(zhuǎn)換邏輯:

      tensorflow推薦使用tfrecord格式的數(shù)據(jù),因此將數(shù)據(jù)集轉(zhuǎn)換成tfrecord格式并保存下來(lái),便于后續(xù)重復(fù)使用

      文件1:create_finetuning_data.py 

      a. 添加新的數(shù)據(jù)處理器:

       1 def generate_classifier_dataset():
       2   """Generates classifier dataset and returns input meta data."""
       3   assert FLAGS.input_data_dir and FLAGS.classification_task_name
       4 
       5   processors = { 
       6       "cola": classifier_data_lib.ColaProcessor,
       7       "mnli": classifier_data_lib.MnliProcessor,
       8       "mrpc": classifier_data_lib.MrpcProcessor,
       9       "qnli": classifier_data_lib.QnliProcessor,
      10       "sst-2": classifier_data_lib.SstProcessor,
      11       "xnli": classifier_data_lib.XnliProcessor,
      12       "bdbk": classifier_data_lib.BdbkProcessor, # 添加新的數(shù)據(jù)處理器
      13   }
      14 ......

       

      文件2:classifier_data_lib.py

      a. 添加新Processor的處理邏輯:

      谷歌預(yù)設(shè)的數(shù)據(jù)處理器以及后續(xù)的分類(lèi)邏輯中,都只使用了訓(xùn)練集和驗(yàn)證集,本文在此基礎(chǔ)上,增加了測(cè)試集和預(yù)測(cè)集的數(shù)據(jù)處理和使用

       1 class BdbkProcessor(DataProcessor):
       2     """Processor for bdbk data set."""
       3 
       4     def get_train_examples(self, data_dir):
       5         """See base class."""
       6         return self._create_examples(self._read_tsv(os.path.join(data_dir, "train.tsv")), "train")
       7 
       8     def get_dev_examples(self, data_dir):
       9         """See base class."""
      10         return self._create_examples(self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev")
      11 
      12     def get_test_examples(self, data_dir):
      13         """See base class."""
      14         return self._create_examples(self._read_tsv(os.path.join(data_dir, "test.tsv")), "test")
      15 
      16     def get_predict_examples(self, data_dir):
      17         return self._create_examples(self._read_tsv(os.path.join(data_dir, "predict.tsv")), "predict")
      18 
      19     def get_labels(self):
      20         """See base class."""
      21         return [
      22             'human',
      23             'poi',
      24             'nature',
      25             ... 此處根據(jù)你的需要,定義自己的類(lèi)別標(biāo)簽
      26         ]
      27     @staticmethod
      28     def get_processor_name():
      29         """See base class."""
      30         return "BDBK"
      31 
      32     def _create_examples(self, lines, set_type):
      33         """Creates examples for the training and dev sets."""
      34         examples = []
      35         for (i, line) in enumerate(lines):
      36             guid = "%s-%s" % (set_type, i)
      37             if i == 0: # 如果你的數(shù)據(jù)有標(biāo)題行,就加上這兩句代碼跳過(guò)
      38                 continue
      39             text_a = self.process_text_fn(line[1]) # line[1]列是文本
      40             label = self.process_text_fn(line[2]) if len(line) >= 3 else "na" # line[2]列是標(biāo)簽
      41             examples.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
      42         return examples

       

      2.訓(xùn)練、驗(yàn)證及測(cè)試邏輯:

      對(duì)tfrecord數(shù)據(jù)讀取、模型訓(xùn)練結(jié)果存儲(chǔ)等功能進(jìn)行調(diào)整

      文件1:run_classifier.py

      run_classifier是分類(lèi)主程序入口,涵蓋了預(yù)訓(xùn)練模型加載、分類(lèi)模型構(gòu)建及編譯、輸入數(shù)據(jù)讀取、模型訓(xùn)練和評(píng)估、產(chǎn)出訓(xùn)練結(jié)果等全過(guò)程。

      其中分類(lèi)模型構(gòu)建環(huán)節(jié)中沒(méi)有添加其他分類(lèi)網(wǎng)絡(luò),即直接用BERT預(yù)訓(xùn)練模型的輸出對(duì)接dropout(抑制過(guò)擬合)層后,直接接fc層產(chǎn)出各個(gè)類(lèi)別的概率。此處也可以自定義其他網(wǎng)絡(luò)結(jié)構(gòu),比如BERT的輸出對(duì)接一個(gè)TextCNN,然后再接fc層(這種網(wǎng)絡(luò)結(jié)構(gòu)也可以理解成BERT作為word embedding層,TextCNN作為分類(lèi)模型)。本文中采用第一種默認(rèn)結(jié)構(gòu),即BERT+dropout+fc,網(wǎng)絡(luò)模型結(jié)構(gòu)如下:

      a. 添加一些epoch結(jié)尾的評(píng)估m(xù)etrics,便于評(píng)估訓(xùn)練效果

       1     eval_data_list = list(evaluation_dataset.as_numpy_iterator())
       2     custom_metric = custom_metrics.Metrics(labels_list, valid_data=eval_data_list[0])
       3 
       4     if custom_callbacks is not None:
       5       custom_callbacks += [custom_metric, summary_callback, checkpoint_callback]
       6     else:
       7       custom_callbacks = [custom_metric, summary_callback, checkpoint_callback]
       8 
       9     history = bert_model.fit(
      10         x=training_dataset,
      11         validation_data=evaluation_dataset,
      12         steps_per_epoch=steps_per_epoch,
      13         epochs=epochs,
      14         validation_steps=eval_steps,
      15         callbacks=custom_callbacks)
      16 
      17     return bert_model, history, custom_metric

      文件2:model_saving_utils.py

      a. 在export_bert_model()最后添加訓(xùn)練結(jié)果保存邏輯

          # tf.train.Checkpoint API was used via custom training loop logic.
          else:
            checkpoint = tf.train.Checkpoint(model=model)
      
            # Restores the model from latest checkpoint.
            latest_checkpoint_file = tf.train.latest_checkpoint(checkpoint_dir)
            assert latest_checkpoint_file
            logging.info('Checkpoint file %s found and restoring from '
                         'checkpoint', latest_checkpoint_file)
            checkpoint.restore(
                latest_checkpoint_file).assert_existing_objects_matched()
      
        model.save(model_export_path, include_optimizer=True, overwrite=True, save_format='h5') # 添加訓(xùn)練結(jié)果保存
        return

      b. 新增custom_metrics.py,用于在on_epoch_end中計(jì)算自定義metrics

      from sklearn.metrics import f1_score, recall_score, precision_score, classification_report
      from tensorflow.keras.callbacks import Callback
      import numpy as np
      
      class Metrics(Callback):
          def __init__(self, labels_list, valid_data):
              super(Metrics, self).__init__()
              self.validation_data = valid_data
              self.val_f1s = []
              self.val_recalls = []
              self.val_precisions = []
              self.reports = []
              self.labels_list = labels_list
      
          def on_epoch_end(self, epoch, logs=None):
              logs = logs or {}
              val_predict = np.argmax(self.model.predict(self.validation_data[0]), -1) 
              val_targ = self.validation_data[1]
              if len(val_targ.shape) == 2 and val_targ.shape[1] != 1:
                  val_targ = np.argmax(val_targ, -1) 
      
              # 分別計(jì)算macro f1, recall, precision
              _val_precision = precision_score(val_targ, val_predict, average='macro')
              self.val_precisions.append(_val_precision)
              logs['val_precision'] = _val_precision
      
      
              _val_recall = recall_score(val_targ, val_predict, average='macro')
              self.val_recalls.append(_val_recall)
              logs['val_recall'] = _val_recall
      
              _val_f1 = f1_score(val_targ, val_predict, average='macro')
              self.val_f1s.append(_val_f1)
              logs['val_f1'] = _val_f1
              remain_list = []
              val_union = np.union1d(val_targ, val_predict)
              for i, v in enumerate(self.labels_list):
                  if i in val_union:
                      remain_list.append(v)
              # 一并計(jì)算三個(gè)指標(biāo)
              report = classification_report(val_targ,
                                             val_predict,
                                             target_names=remain_list,
                                             output_dict=True)
      
          def get(self, metrics, of_class):
              return [report[str(of_class)][metrics] for report in self.reports]

      c. 新增utils.py,用于繪制訓(xùn)練結(jié)果圖

      #-*- encoding:utf-8 -*-
      import pickle
      import matplotlib.pyplot as plt 
      import matplotlib.style as style
      
      class MetricPlot(object):
          def __init__(self, file_pickle_path):
              self.file_pickle = file_pickle_path
      
          def draw_all_curves(self):
              with open(self.file_pickle + '/metric/metric.pickle', 'rb') as f:
                  metric_data = pickle.load(f)
                  reports = metric_data['reports']
                  style.use("bmh")
      
                  class_list = []
                  for report in reports:
                      class_list.extend(list(report.keys()))
                  class_list = list(set(class_list))
                  class_list.remove('accuracy')
                  class_list.remove('macro avg')
                  class_list.remove('weighted avg')
      
                  # 每個(gè)類(lèi)別分別打印precision、recall、f1
                  class_num = len(class_list)
                  # 每個(gè)類(lèi)別分別打印precision、recall、f1
                  class_num = len(class_list)
                  plt.figure(figsize=(8, class_num * 4))
                  for i, v in enumerate(class_list):
                      plt.subplot(class_num, 1, i + 1)
                      for m in {'precision', 'recall', 'f1-score'}:
                          plt.plot([report[v][m] for report in reports],
                                 label='Class {0} {1}'.format(v, m))
                          plt.legend(loc='lower right')
                          plt.ylabel('Class {}'.format(v))
                          plt.title('Class {} Curves'.format(v))
                  plt.show()
      
          def draw_metric_curves(self):
              with open(self.file_pickle + '/metric/metric.pickle', 'rb') as f:
                  metric_data = pickle.load(f)
                  f1 = metric_data['f1']
                  recall = metric_data['recall']
                  precision = metric_data['precision']
      
                  epochs = len(f1)
      
                  style.use("bmh")
                  plt.figure(figsize=(8, 12))
      
                  plt.subplot(3, 1, 1)
                  plt.plot(range(1, epochs+1), f1, label='Val F1')
                  plt.legend(loc='lower right')
                  plt.ylabel('F1')
                  plt.title('Validation F1 Curve')
      
                  plt.subplot(3, 1, 2)
                  plt.plot(range(1, epochs+1), recall, label='Val Recall')
                  plt.legend(loc='lower right')
                  plt.ylabel('Recall')
                  plt.title('Validation Recall Curve')
      
                  plt.subplot(3, 1, 3)
                  plt.plot(range(1, epochs+1), precision, label='Val Precision')
                  plt.legend(loc='lower right')
                  plt.ylabel('Precision')
                  plt.title('Validation Precision Curve')
                  plt.xlabel('epoch')
                  plt.show()
          def draw_history_curves(self):
              """Plot the learning curves of loss and macro f1 score 
              for the training and validation datasets.
      
              Args:
                  history: history callback of fitting a tensorflow keras model 
              """
              with open(self.file_pickle + '/history/hist.pickle', 'rb') as f:
                  history = pickle.load(f)
      
                  loss = history['loss']
                  val_loss = history['val_loss']
                  accuracy = history['test_accuracy']
                  val_accuracy = history['val_test_accuracy']
      
                  epochs = len(loss)
      
                  style.use("bmh")
                  plt.figure(figsize=(8, 8)) 
      
                  plt.subplot(2, 1, 1)
                  plt.plot(range(1, epochs+1), loss, label='Training Loss')
                  plt.plot(range(1, epochs+1), val_loss, label='Validation Loss')
                  plt.legend(loc='upper right')
                  plt.plot(range(1, epochs+1), val_loss, label='Validation Loss')
                  plt.legend(loc='upper right')
                  plt.ylabel('Loss')
                  plt.title('Training and Validation Loss')
      
                  plt.subplot(2, 1, 2)
                  plt.plot(range(1, epochs+1), accuracy, label='Training Accuracy')
                  plt.plot(range(1, epochs+1), val_accuracy, label='Validation Accuracy')
                  plt.legend(loc='lower right')
                  plt.ylabel('Accuracy')
                  plt.title('Training and Validation Accuracy')
                  plt.show()

      主要的代碼邏輯修改介紹完畢,下面介紹在colab上操作的流程。

      三、colab操作:

      1.環(huán)境部署:

      # 安裝tf-nightly-gpu,目前master各版本應(yīng)該均可用(至少2.2.0.dev20200218親測(cè)可用)
      # 如選擇發(fā)布版2.1.0,在預(yù)測(cè)階段(重新load_model)會(huì)觸發(fā)tf底層的一個(gè)bug(https://github.com/tensorflow/neural-structured-learning/issues/41),導(dǎo)致加載模型失敗
      !pip install tf-nightly-gpu
      # 下載并解壓tensorflow models2.1.0
      !wget https://github.com/tensorflow/models/archive/v2.1.0.tar.gz
      !tar xzf v2.1.0.tar.gz && rm v2.1.0.tar.gz
      # 安裝models需要的依賴(lài)
      !pip install -r /content/models-2.1.0/official/requirements.txt

      2.將修改代碼上傳到colab,并放置到對(duì)應(yīng)的目錄

      # 下載數(shù)據(jù)集合和修改適配的文件
      %rm -rf bert_multiclass_zh_model2-1-0/
      %rm -rf process_dir
      # 此處將修改好的代碼傳到colab上
      <下載代碼>
      %mv /content/bert_multiclass_zh_model2-1-0/code/utils.py /content/ %mv /content/bert_multiclass_zh_model2-1-0/code/*.py /content/models-2.1.0/official/nlp/bert/ %mv /content/bert_multiclass_zh_model2-1-0/process_dir /content/

      3. 為了對(duì)數(shù)據(jù)有更直觀的了解,可以用下面代碼對(duì)數(shù)據(jù)的分布進(jìn)行觀察

       1 import pandas as pd
       2 import matplotlib.pyplot as plt
       3 import matplotlib.style as style
       4 import seaborn as sns
       5 
       6 style.use("fivethirtyeight")
       7 plt.figure(figsize=(8, 12))
       8 
       9 show_data_dict = {
      10     'train': pd.read_csv("/content/process_dir/train_data/train.tsv", "\t"), 
      11     'dev': pd.read_csv("/content/process_dir/train_data/dev.tsv", "\t")
      12 }
      13 
      14 # Get label frequencies in descending order
      15 length = len(show_data_dict)
      16 cnt = 0
      17 for k, v in show_data_dict.items():
      18     cnt += 1
      19     plt.subplot(length, 1, cnt)
      20     label_freq = v['label'].apply(lambda s: str(s)).value_counts().sort_values(ascending=False)
      21     # Bar plot
      22     sns.barplot(y=label_freq.index, x=label_freq.values, order=label_freq.index)
      23     plt.title("{} label frequency".format(k), fontsize=14)
      24     plt.xlabel("")
      25     plt.xticks(fontsize=12)
      26     plt.yticks(fontsize=12)
      27 plt.show()

      執(zhí)行后可以看到數(shù)據(jù)分布情況:

       

       

       4.生成tfrecord格式的數(shù)據(jù):

       1 !python ./models/official/nlp/bert/create_finetuning_data.py \
       2     --input_data_dir=${BASE_DIR}/train_data \
       3     --vocab_file=${BASE_DIR}/hub/vocab.txt \
       4     --train_data_output_path=${BASE_DIR}/train_data/${TASK_NAME}_train.tf_record \
       5     --eval_data_output_path=${BASE_DIR}/train_data/${TASK_NAME}_eval.tf_record \
       6     --test_data_output_path=${BASE_DIR}/train_data/${TASK_NAME}_test.tf_record \
       7     --meta_data_file_path=${BASE_DIR}/train_data/${TASK_NAME}_meta_data \
       8     --fine_tuning_task_type=classification \
       9     --max_seq_length=128 \
      10     --classification_task_name=${TASK_NAME}

      6. 啟動(dòng)訓(xùn)練:

       1 !python ./models/official/nlp/bert/run_classifier.py \
       2     --mode='train_and_eval' \
       3     --input_meta_data_path=${BASE_DIR}/train_data/${TASK_NAME}_meta_data \
       4     --train_data_path=${BASE_DIR}/train_data/${TASK_NAME}_train.tf_record \
       5     --eval_data_path=${BASE_DIR}/train_data/${TASK_NAME}_eval.tf_record \
       6     --test_data_path=${BASE_DIR}/train_data/${TASK_NAME}_test.tf_record \
       7     --bert_config_file=${BASE_DIR}/hub/bert_config.json \
       8     --train_batch_size=64 \
       9     --eval_batch_size=128 \
      10     --test_batch_size=256 \
      11     --steps_per_loop=1 \
      12     --learning_rate=2e-5 \
      13     --num_train_epochs=2 \
      14     --model_dir=${BASE_DIR}/output \
      15     --hub_module_url=https://tfhub.dev/tensorflow/bert_zh_L-12_H-768_A-12/1 \
      16     --use_keras_compile_fit=True \
      17     --distribution_strategy=mirrored \
      18     --num_gpus=1 \
      19     --save_history_path=${BASE_DIR}/history/hist.pickle \
      20     --save_metric_path=${BASE_DIR}/metric/metric.pickle \
      21     --model_export_path=${BASE_DIR}/export_model/save_model.h5 \
      22     --test_result_dir=${BASE_DIR}/test_result/test_ret

      因?yàn)樵趓un_classifiert.py中model.fit()之前增加了一行model.summary(),所以訓(xùn)練開(kāi)始前的日志中可見(jiàn)訓(xùn)練圖層次結(jié)構(gòu)等信息

      整個(gè)模型參數(shù)都設(shè)置為是trainable的(默認(rèn)值),筆者嘗試過(guò)修改代碼來(lái)freeze BERT自帶的102267649個(gè)參數(shù),但訓(xùn)練10個(gè)epoch后,accuracy仍達(dá)不到90%以上,感覺(jué)效果不是很好。具體原因還未深究。

      7. 查看訓(xùn)練結(jié)果:

      日志中可以查看訓(xùn)練中,每個(gè)batch結(jié)束后的訓(xùn)練loss、accuracy;每個(gè)epoch結(jié)束后的val loss、val accuracy;以及整個(gè)訓(xùn)練結(jié)束后的test accuracy

      INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
      I0223 04:38:43.759790 140623330674560 cross_device_ops.py:414] Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
      INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
      I0223 04:38:43.761969 140623330674560 cross_device_ops.py:414] Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
      Train for 1093 steps, validate for 313 steps
      Epoch 1/2
      1093/1093 [==============================] - 1161s 1s/step - loss: 0.4250 - accuracy: 0.8925 - val_loss: 0.1785 - val_accuracy: 0.9474
      Epoch 2/2
      1093/1093 [==============================] - 1144s 1s/step - loss: 0.1220 - accuracy: 0.9664 - val_loss: 0.1622 - val_accuracy: 0.9532
      I0223 05:18:29.677855 140623330674560 run_classifier.py:420] test_accuracy: 0.951200008392334

       

      查看原代碼里定義的metrics(loss、accuracy),以及自定義的metrics(各類(lèi)別的F1、precise、recall等)

      1 import utils
      2 
      3 mp = utils.MetricPlot('/content/process_dir/')
      4 mp.draw_history_curves()
      5 mp.draw_metric_curves()
      6 mp.draw_all_curves()

       

       

      訓(xùn)練完成之后,就可以進(jìn)行預(yù)測(cè)了。

      首先參考create_finetune_data.py,將待預(yù)測(cè)數(shù)據(jù)轉(zhuǎn)換為tfrecord格式并存儲(chǔ)

      # 預(yù)測(cè),生成待預(yù)測(cè)數(shù)據(jù)
      !python ./models-2.1.0/official/nlp/bert/do_pred_data.py \
          --input_data_dir=${PRED_DATA_DIR} \
          --vocab_file=${BASE_DIR}/model/hub_config/vocab.txt \
          --predict_data_output_path=${PRED_DATA_DIR}/${TASK_NAME}_predict.tf_record \
          --meta_data_file_path=${PRED_DATA_DIR}/${TASK_NAME}_meta_data \
          --max_seq_length=128

      然后參照run_classifier.py,讀取待預(yù)測(cè)tfrecord數(shù)據(jù),加載之前訓(xùn)練好的模型(save_model.h5),開(kāi)始預(yù)測(cè),將結(jié)果保存在文件中

      # 開(kāi)始預(yù)測(cè)
      !python ./models-2.1.0/official/nlp/bert/do_predict.py \
          --input_meta_data_path=${PRED_DATA_DIR}/${TASK_NAME}_meta_data \
          --predict_data_path=${PRED_DATA_DIR}/${TASK_NAME}_predict.tf_record \
          --bert_config_file=${BASE_DIR}/model/hub_config/bert_config.json \
          --predict_batch_size=32 \
          --hub_module_url=https://tfhub.dev/tensorflow/bert_zh_L-12_H-768_A-12/1 \
          --model_export_path=${BASE_DIR}/model/saved_model/save_model.h5 \
          --predict_output_dir=${PRED_DATA_DIR}/result \
      # 如果選擇tf2.1.0版本,則此處會(huì)觸發(fā)tf底層的一個(gè)bug(https://github.com/tensorflow/neural-structured-learning/issues/41),導(dǎo)致加載模型失敗

      最終訓(xùn)練出來(lái)的文件內(nèi)容是這樣的:第一列是標(biāo)簽的編號(hào),第二列是標(biāo)簽,由于是串行訓(xùn)練,因此輸出的標(biāo)簽和輸入的預(yù)測(cè)文本是一一對(duì)齊的。

      1    poi
      4    webfic
      7    science
      0    human
      0    human
      0    human
      1    poi
      7    science

      至此,整個(gè)finetuneing訓(xùn)練+預(yù)測(cè)過(guò)程全部結(jié)束。歡迎拍磚指導(dǎo)~~~~

      稍后再研究一下如何部署到生產(chǎn)環(huán)境…… 

       
      posted @ 2020-01-22 16:21  玄天妙地  Views(4592)  Comments(5)    收藏  舉報(bào)
      主站蜘蛛池模板: 麻豆国产传媒精品视频| 视频网站在线观看不卡| 国产成人8X人网站视频| 日韩中文字幕高清有码| 国产成人啪精品视频免费APP | 久久人人爽人人爽人人片av| 国产一区二区丰满熟女人妻 | 成人无码潮喷在线观看| 99国精品午夜福利视频不卡99 | 丁香五月激情图片| 国产91午夜福利精品| 亚洲中文字幕在线观看| 婷婷综合久久狠狠色成人网| 在线观看人成视频免费| 久久久久久久一线毛片| 先锋影音男人av资源| 亚洲精品一区| 蜜臀av入口一区二区三区| 中文字幕国产精品日韩| 亚洲精品天堂一区二区| 亚洲精品国产综合麻豆久久99 | 久久精品国产99精品国产2021| 狠狠色丁香婷婷综合尤物| 亚洲国产精品自在拍在线播放蜜臀| 亚洲美免无码中文字幕在线| 亚洲天堂成人网在线观看| 成熟少妇XXXXX高清视频| 高清性欧美暴力猛交| 无码人妻精品一区二区三区下载| 国产av综合一区二区三区| 国产精品免费AⅤ片在线观看| 水蜜桃视频在线观看免费18| 国产做a爱片久久毛片a片| 国产尤物精品自在拍视频首页| 部精品久久久久久久久| 免费看欧美日韩一区二区三区| 男人天堂亚洲天堂女人天堂| av午夜久久蜜桃传媒软件| 国产一区二区午夜福利久久 | 五月婷婷久久中文字幕| 免费国产高清在线精品一区|