国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從Word2Vec到Bert

leeon / 2130人閱讀

摘要:采用作為特征提取器,并采用雙向語言模型。此外,預(yù)訓(xùn)練的數(shù)據(jù)規(guī)模非常龐大。輸入部分處理輸入是一個線性序列,兩個句子通過分隔符分割,前后兩端分別增加標(biāo)識符號。輸出處理評價(jià)從模型或者方法的角度來看,借鑒了以及,主要提出了語言模型和。

Word2Vec模型

Word2Vec有兩種訓(xùn)練方法:CBOWSkip-gram。CBOW的核心思想是上下文預(yù)測某個單詞,Skip-gram正好相反,輸入單詞,要求網(wǎng)絡(luò)預(yù)測它的上下文。

如上圖所示,一個單詞表達(dá)成word embedding后,很容易找到詞義相近的其它詞匯。

word embedding使用:句子中的單詞以one-hot的形式作為輸入,然后乘以學(xué)好的word embedding矩陣Q,就直接取出單詞對應(yīng)的word embedding了。word embedding矩陣Q其實(shí)就是網(wǎng)絡(luò)one-hot層到embedding層映射的網(wǎng)絡(luò)參數(shù)矩陣。所以,word embedding等價(jià)于把one-hot層到embedding層的網(wǎng)絡(luò)用預(yù)訓(xùn)練好的參數(shù)矩陣Q初始化了。不過,word embedding只能初始化第一層網(wǎng)絡(luò)參數(shù),再高層就無能為力了。下游NLP任務(wù)使用word embedding的時候與圖像類似,有兩種方法,一種是frozen:word embedding層的網(wǎng)絡(luò)參數(shù)固定不動;另一種是fine-tuning,即:word embedding這層參數(shù)使用新的訓(xùn)練集合訓(xùn)練。

word embedding存在的問題

如圖所示,多義詞bank有兩種含義,但是word embedding在對bank這個詞進(jìn)行編碼的時候無法區(qū)分這兩個含義。盡管上下文環(huán)境中出現(xiàn)的單詞相同,但是在語言模型訓(xùn)練的時候,不論什么上下文的句子經(jīng)過word2vec,都是預(yù)測相同的單詞bank,而同一個單詞占用的同一行的參數(shù)空間,這導(dǎo)致兩種不同的上下文信息都會編碼到相同的word embedding空間去。所以,word embedding無法區(qū)分多義詞的不同語義,這是它一個比較嚴(yán)重的問題。

Bert

Bert采用transformer作為特征提取器,并采用雙向語言模型。此外,Bert預(yù)訓(xùn)練的數(shù)據(jù)規(guī)模非常龐大。

NLP的四大類任務(wù):

序列標(biāo)注:中文分詞,詞性標(biāo)注,命名實(shí)體識別,語義角色標(biāo)注等。特點(diǎn)是,句子中的每個單詞要求模型根據(jù)上下文給出一個分類類別。

分類任務(wù):文本分類,情感計(jì)算。特點(diǎn)是,不管文章有多長,總體給出一個分類類別即可。

句子關(guān)系判斷:問答,語義改寫,自然語言推理等任務(wù)。特點(diǎn)是,給定兩個句子,模型判斷兩個句子是否具有某種語義關(guān)系。

生成式任務(wù):機(jī)器翻譯,文本摘要,寫詩造句,看圖說話等。特點(diǎn)是,輸入文本后,需要自主生成另外一種文字。

對于句子關(guān)系類任務(wù),加上一個其實(shí)符號和終結(jié)符號,句子之間加上分隔符號即可。對輸出來說,把第一個起始符號對應(yīng)的transformer最后一層位置上串聯(lián)一個softmax分類層。

對于分類問題,增加起始和終結(jié)符號,輸出部分和句子關(guān)系類任務(wù)類似。

序列標(biāo)注問題:輸入部分和單句分類問題一樣,只需要輸出部分transformer最后一層每個單詞對應(yīng)位置都進(jìn)行分類即可。

從這里可以看出,NLP四大類任務(wù)都可以比較方便的改造bert能夠接受的方式,這意味著bert具有很強(qiáng)的普適性。

bert構(gòu)造雙向語言模型

Masked雙向語言模型,隨機(jī)選擇語料中15%的單詞,其中80%替換成mask標(biāo)記,10%隨機(jī)替換另一個單詞,10%不做改動。
Next Sentence Prediction,分兩種情況選擇句子,一種是在語料中選擇真正順序相連的兩個句子;另一種方式是,第二個句子隨機(jī)選擇拼接到第一個句子的后面。要求模型做句子關(guān)系預(yù)測,判斷第二個句子是不是真的第一個句子的后續(xù)句子。這么做的目的是,在很多NLP任務(wù)中是句子關(guān)系判斷任務(wù),單詞預(yù)測顆粒度的訓(xùn)練到不了句子關(guān)系這個層級,增加這個任務(wù)有助于下游句子關(guān)系判斷任務(wù)。由此可以看到,bert的預(yù)訓(xùn)練是個多任務(wù)過程。

bert輸入部分處理

bert輸入是一個線性序列,兩個句子通過分隔符分割,前后兩端分別增加標(biāo)識符號。每個單詞有三個embedding。

位置embedding:NLP中單詞順序是重要特征,需要對位置進(jìn)行編碼。

單詞embedding

句子embedding:前面提到的訓(xùn)練數(shù)據(jù)都是由兩個句子構(gòu)成,那么每個句子有個句子整體的embedding對應(yīng)每個單詞。

三者疊加,就形成了bert的輸入。

bert輸出處理

bert評價(jià)

從模型或者方法的角度來看,bert借鑒了ELMO,GPT以及CBOW,主要提出了masked語言模型和next sentence prediction。訓(xùn)練采用兩階段模型,第一階段雙向語言模型預(yù)訓(xùn)練,第二階段采用具體任務(wù)fine-tuning或者做特征集成;第二是特征提取采用transformer作為特征提取器而不是rnn或cnn。bert最大的兩點(diǎn)是效果好普適性強(qiáng),幾乎所有的NLP任務(wù)都可以套用bert這種兩階段解決思路。

案例實(shí)現(xiàn):Predicting Movie Review Sentiment with BERT on TF Hub

bert已經(jīng)添加到TF-Hub模塊,可以快速集成到現(xiàn)有項(xiàng)目中。bert層可以替代之前的elmo,glove層,并且通過fine-tuning,bert可以同時提供精度,訓(xùn)練速度的提升。
此案例中,我們將在tensorflow中使用bert訓(xùn)練一個模型用于判斷電影評論的情緒是消極還是積極。

導(dǎo)入模塊
from sklearn.model_selection import train_test_split
import pandas as pd
import tensorflow as tf
import tensorflow_hub as hub
from datetime import datetime
!pip install bert-tensorflow

import bert
from bert import run_classifier
from bert import optimization
from bert import tokenization
數(shù)據(jù)下載



# 讀取文件,創(chuàng)建dataframe
def load_directory_data(directory):
  data={}
  data["sentence"]=[]
  data["sentiment"]=[]

  for file_path in os.listdir(directory):
    with tf.gfile.GFile(os.path.join(directory,file_path),"r") as f:
      data["sentence"].append(f.read())
      data["sentiment"].append(re.match("d+_(d+).txt",file_path).group(1))

  return pd.DataFrame.from_dict(data)

# 添加新列,并打亂數(shù)據(jù)
def load_dataset(directory):

  # 積極情緒文件
  pos_df=load_directory_data(os.path.join(directory,"pos"))

  # 消極情緒
  neg_df=load_directory_data(os.path.join(directory,"neg"))

  pos_df["polarity"]=1
  neg_df["polarity"]=0

  # sample 參數(shù)frac,返回的比例,如:df中有10行數(shù)據(jù),想返回30%,設(shè)置值為:0.3
  return pd.concat([pos_df,neg_df]).sample(frac=1).reset_index(drop=True)

# 下載并加載數(shù)據(jù)
def download_and_load_datasets(force_download=False):
  dataset=tf.keras.utils.get_file(
    fname="aclImdb.tar.gz",
    origin="http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz",
    extract=True
  )

  train_df=load_dataset(os.path.join(os.path.dirname(dataset),"aclImdb","train"))
  test_df=load_dataset(os.path.join(os.path.dirname(dataset),"aclImdb","test"))

  return train_df,test_df

train,test=download_and_load_datasets()
# 去前5000個樣本
train=train.sample(5000)
test=test.sample(5000)

DATA_COLUMN="sentence"
LABEL_COLUMN="polarity"

label_list=[0,1]
數(shù)據(jù)處理

我們需要將數(shù)據(jù)轉(zhuǎn)換成bert能夠處理的格式。我們首先創(chuàng)建InputExample構(gòu)造函數(shù):

test_a:我們要分類的數(shù)據(jù),如:DATA_COLUMN

test_b:用于句子關(guān)系判斷,如:問答,翻譯等

label:數(shù)據(jù)標(biāo)簽

train_InputExample=train.apply(lambda x:bert.run_classifier.InputExample(
  guid=None,
  text_a=x[DATA_COLUMN],
  text_b=None,
  label=x[LABEL_COLUMN]
),axis=1)
test_InputExample=test.apply(lambda x:bert.run_classifier.InputExample(
  guid=None,
  text_a=x[DATA_COLUMN],
  text_b=None,
  label=x[LABEL_COLUMN]
),axis=1)

接下來,我們需要處理數(shù)據(jù)以適合bert進(jìn)行訓(xùn)練。步驟依次如下:

單詞全部小寫

將文本轉(zhuǎn)換成序列(如:‘sally says hi’ -> ["sally","says","hi"])

將單詞分解為wordpieces(如:‘calling’->["call","##ing"])

用bert提供的詞匯文件進(jìn)行單詞索引映射

添加‘CLS’,"SEP"標(biāo)記符

每次輸入添加‘index’和‘segment’標(biāo)記

# lowercase bert版本
BERT_MODEL_HUB="https://tfhub.dev/google/bert_uncased_L-12_H-768_A-12/1"

# 獲取詞表文件,小寫數(shù)據(jù)處理
def create_tokenizer_from_hub_module():
  with tf.Graph().as_default():
    bert_module = hub.Module(BERT_MODEL_HUB)
    tokenization_info = bert_module(signature="tokenization_info", as_dict=True)
    with tf.Session() as sess:
      vocab_file,do_lower_case=sess.run([tokenization_info["vocab_file"],tokenization_info["do_lower_case"]])
  return bert.tokenization.FullTokenizer(
    vocab_file=vocab_file,
    do_lower_case=do_lower_case
  )

tokenizer=create_tokenizer_from_hub_module()

# 序列最長
MAX_SEQ_LENGTH=128
# 將訓(xùn)練,測試數(shù)據(jù)特征轉(zhuǎn)換成bert需要的格式
train_features=bert.run_classifier.convert_examples_to_features(train_InputExample,label_list,MAX_SEQ_LENGTH,tokenizer)
test_features=bert.run_classifier.convert_examples_to_features(test_InputExample,label_list,MAX_SEQ_LENGTH,tokenizer)
創(chuàng)建模型
def create_model(is_predicting,input_ids,input_mask,segment_ids,labels,num_labels):

  # 創(chuàng)建分類模型
  bert_module=hub.Module(
    BERT_MODEL_HUB,
    trainable=True
  )
  bert_inputs=dict(
    input_ids=input_ids,
    input_mask=input_mask,
    segment_ids=segment_ids
  )
  bert_outputs=bert_module(
    inputs=bert_inputs,
    signature="tonkens",
    as_dict=True
  )
  output_layer=bert_outputs["pooled_output"]
  hidden_size=output_layer.shape[-1].value

  output_weights=tf.get_variable(
    "output_weights",[num_labels,hidden_size],
    initializer=tf.truncated_normal_initializer(stddev=0.02)
  )
  output_bias=tf.get_variable(
    "output_bias",[num_labels],initializer=tf.zeros_initializer()
  )

  with tf.variable_scope("loss"):
    # dropout用于防止過擬合,僅訓(xùn)練時使用
    output_layer=tf.nn.dropout(output_layer,keep_prob=0.9)

    logits=tf.matmul(output_layer,output_weights,transpose_b=True)
    logits=tf.nn.bias_add(logits,output_bias)
    log_prob=tf.nn.log_softmax(logits,axis=-1)

    # 將標(biāo)簽轉(zhuǎn)為one-hot格式
    one_hot_labels=tf.one_hot(labels,depth=num_labels)
    predcited_labels=tf.squeeze(tf.argmax(log_prob,axis=-1))

    if is_predicting:
      return (predcited_labels,log_prob)
    per_example_loss=-tf.reduce_sum(one_hot_labels*log_prob,axis=-1)
    loss=tf.reduce_mean(per_example_loss)

    return (loss,predcited_labels,log_prob)
創(chuàng)建InputFn
def model_fn_builder(num_labels,learning_rate,num_train_steps,num_warmup_steps):
  def model_fn(features,labels,mode,params):

    input_idx=features["input_idx"]
    input_mask=features["input_mask"]
    segment_ids=features["segment_ids"]
    lable_ids=features["labels_ids"]

    is_predicting=(mode == tf.estimator.ModeKeys.PREDICT)

    if not is_predicting:
      (loss,predicted_labels,log_probs)=create_model(
        is_predicting,input_idx,input_mask,segment_ids,lable_ids,num_labels
      )
      train_op = bert.optimization.create_optimizer(
        loss, learning_rate, num_train_steps, num_warmup_steps, use_tpu=False)
      def metric_fn(label_ids,predicted_labels):
        accuracy=tf.metrics.accuracy(labels=lable_ids,predictions=predicted_labels)
        f1_score = tf.contrib.metrics.f1_score(
          label_ids,
          predicted_labels)
        auc = tf.metrics.auc(
          label_ids,
          predicted_labels)
        recall = tf.metrics.recall(
          label_ids,
          predicted_labels)
        precision = tf.metrics.precision(
          label_ids,
          predicted_labels)
        true_pos = tf.metrics.true_positives(
          label_ids,
          predicted_labels)
        true_neg = tf.metrics.true_negatives(
          label_ids,
          predicted_labels)
        false_pos = tf.metrics.false_positives(
          label_ids,
          predicted_labels)
        false_neg = tf.metrics.false_negatives(
          label_ids,
          predicted_labels)
        return {
          "eval_accuracy": accuracy,
          "f1_score": f1_score,
          "auc": auc,
          "precision": precision,
          "recall": recall,
          "true_positives": true_pos,
          "true_negatives": true_neg,
          "false_positives": false_pos,
          "false_negatives": false_neg
        }
      eval_metrics=metric_fn(lable_ids,predicted_labels)

      if mode == tf.estimator.ModeKeys.TRAIN:
        return tf.estimator.EstimatorSpec(
          mode=mode,
          loss=loss,
          train_op=train_op
        )
      else:
        return tf.estimator.EstimatorSpec(
          mode=mode,
          loss=loss,
          eval_metric_ops=eval_metrics
        )
    else:
      (predicted_labels, log_probs) = create_model(
        is_predicting, input_idx, input_mask, segment_ids, lable_ids, num_labels)

      predictions = {
        "probabilities": log_probs,
        "labels": predicted_labels
      }
      return tf.estimator.EstimatorSpec(mode, predictions=predictions)
  return model_fn
參數(shù)配置
BATCH_SIZE=32
LEARNING_RATE=2e-5
NUM_TRAIN_EPOCHS=3
WARMUP_PROPORTION=0.1
SAVE_CHECKEPOINTS_STEPS=500
SAVE_SUMMARY_STEPS=100

# 計(jì)算train,warmup總訓(xùn)練步數(shù)
num_train_steps=int(len(train_features)/BATCH_SIZE*NUM_TRAIN_EPOCHS)
num_warmup_steps=int(num_train_steps*WARMUP_PROPORTION)

# 設(shè)置模型保存路徑/次數(shù),圖信息保存次數(shù)
run_config=tf.estimator.RunConfig(
  model_dir=OUTPUT_DIR,
  save_checkpoints_steps=SAVE_CHECKEPOINTS_STEPS,
  save_summary_steps=SAVE_SUMMARY_STEPS
)
模型訓(xùn)練,驗(yàn)證
modle_fn=model_fn_builder(
  num_labels=len(label_list),
  learning_rate=LEARNING_RATE,
  num_train_steps=num_train_steps,
  num_warmup_steps=num_train_steps
)
estimator=tf.estimator.Estimator(
  model_fn=modle_fn,
  config=run_config,
  params={"batch_size":BATCH_SIZE}
)
train_input_fn=bert.run_classifier.input_fn_builder(
  features=train_features,
  seq_length=MAX_SEQ_LENGTH,
  is_training=True,
  drop_remainder=False
)
estimator.train(input_fn=train_input_fn,max_steps=num_train_steps)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/19963.html

相關(guān)文章

發(fā)表評論

0條評論

閱讀需要支付1元查看
<