序列模型的實現細節

2021-01-12 機器學習算法與自然語言處理

機器學習算法與自然語言處理出品

@公眾號原創專欄作者 鎢額音

學校 | 西湖大學文本智能實驗室研究助理


本文首發於 TFSEQ Part II: 序列模型的實現細節,留檔。

本文內容

介紹 tf.placeholder 和 tf.data 兩種構建數據 pipeline 的方案,並提供了性能上的分析。介紹了 tf.data 的參數設置以及使用時的考量。最後總結了一個簡單的 NLP dataset 模板,以及分享了一些 tf.data 的使用技巧。

介紹了 bucketing 的原理和實現,並分析了其對收斂效果的影響。

介紹了變長序列 attention 的常見實現錯誤,並分享了一個簡單的數值穩定實現

介紹了對長句的處理方案。討論了長句導致的內存溢出問題以及解決方案。介紹了 使用 TBPTT 對序列任務進行加速的方案,並對其與 BPTT 的區別進行了分析。

前言

序列模型組件如 RNN 和 Attention 在自然語言處理中有廣泛的應用。但由於序列長度不一且變化範圍較大,為保證效率和穩定性,有許多實現上的細節需要考慮。同樣的理論在不同實現下效果往往會有神秘的差異,甚至會出現不能收斂的情況。本文總結了一些用 Tensorflow 實現序列模型的一些做法,並分析了效率和精度上的權衡。

本文假設讀者已經有深度學習在自然語言處理應用上的基本知識,並用 Tensorflow 實現過一些序列模型。為了避免翻譯帶來的歧義,部分術語會直接使用英文表述(使用中文的話會在括號裡加上英文術語),所以中英混雜的文風難以避免。為了討論方便,以下先做一些術語的規定。

min-batch SGD 是一種迭代式優化(iterative optimization)的算法,每一次迭代都包括以下三個步驟:

讀取 mini-batch,使用模型進行前饋計算(feedforward or forward)

計算 loss,並利用 loss 的值進行反向傳播(backpropagation or backprop),得到各個參數的梯度(gradient)

根據算出的梯度,利用選定的優化算法(Tensorflow 中稱為 Optimizer),如標準 SGD 或者更加流行的 Adam 對參數進行更新。

數據集通常會先進行隨機打亂(shuffle),然後再將整個數據集分成固定大小(batch size)的mini-batch。這是為了保證模型見到的數據是獨立同分布的(i.i.d., independent and identically distributed),從而達到無偏的梯度估計。整個數據集全部輸入並訓練一遍稱為一個 epoch。通常每個 epoch 開始之前都會將數據集 shuffle 一遍。

1. 數據預處理的加速

數據預處理的過程即從原始數據到將切分好的 mini-batch 載入模型的整個過程。tensorflow 的文檔將整個流程劃分為 Extract,Transform 和 Load(ETL)

A typical TensorFlow training input pipeline can be framed as an ETL process: 1. Extract: Read data from persistent storage — either local (e.g. HDD or SSD) or remote (e.g. GCS or HDFS). 2. Transform: Use CPU cores to parse and perform preprocessing operations on the data such as image decompression, data augmentation transformations (such as random crop, flips, and color distortions), shuffling, and batching. 3. Load: Load the transformed data onto the accelerator device(s) (for example, GPU(s) or TPU(s)) that execute the machine learning model.

1.1 Placeholder 模式

tensorflow 最初推薦使用的是 tf.placeholder 模式。這個模式的流程如下:

Extract:先將整個數據集讀入內存

Transform:在Python中將數據轉化成 numpy 的矩陣

Load:使用 tf.placeholder 將 numpy 數據拷貝到 tensorflow 的內存中,再從 tensorflow 拷貝到 GPU 中。

tf.placeholder 模式的圖示,虛線框值指的是計算操作,實線框指的是存儲。曲線數指系統線程數。所有步驟共享同一線程。

這種模式雖然簡單,但缺點也很多:

當數據集很大的時候,可能無法將整個數據集載入內存。

python 代碼的運行速度較慢,多線程由於 python GIL 的存在無法有效並行

多了不必要的拷貝

最明顯的缺點是,在整個處理流程中 GPU 一直是閒置的。

所以 tensorflow 如今主推的是 tf.data api,tf.placeholder的介紹已經很難在文檔中找到了。但在實際線上服務的時候,tf.placeholder 仍然是把數據載入模型的主要方式。

1.2 Input pipeline

input pipeline 在 tensorflow 早期就已經存在,真正做到易用還是從 tensorflow 1.2 發布 tf.contrib.data 接口開始,其前身是雜亂無章的 QueueRunner 和 Queue。

為了解決 tf.placeholder 的效率問題,tensorflow 採用了 cache 和 pipeline 的思想。

Extract:將數據集順序讀入一個固定長度的 queue 中。如果 queue 中的數據達到其容量上線,則阻塞直到下遊任務讀取數據空出容量。

Transform:從 extract 的 queue 中讀取(dequeue)一定量的數據,開啟多條線程並行處理數據,將得到的 mini-batch 放在一個固定長度的 queue 中。

Load:從 transform 後的 queue 中讀取(dequeue) 一個 mini-batch,傳到 GPU。新版本的tensorflow 還提供了 tf.contrib.data.prefetch_to_device 接口,支持將上一步的queue 放在 GPU 內存裡,從而進一步減少等待時間。

通過維護一個固定長度的 queue 作為 cache 來解決內存佔用的問題。三個步驟通過 cache 獨立開來,有獨立的線程去維護,需要調整參數保證各個 queue 不會排空,從而避免阻塞。為了加快處理速度,transform 這一步還加入了多線程支持。

下圖總結了各個步驟的核心函數,圖中寫出的參數是核心參數。

tf.data 模式的圖示,虛線框值指的是計算操作,實線框指的是存儲。曲線數指系統線程數。所有步驟都有各自的線程。

對於文本數據而言,一個典型的 dataset 如下

def build_dataset(filenames,
parse_func,
filter_func,
pad_id,
batch_size,
buffer_size,
shuffle=False,
repeat=False):
dataset = tf.data.TextLineDataset(filenames, buffer_size=buffer_size)
if shuffle:
dataset = dataset.shuffle(buffer_size)
if repeat:
# repeat forever
dataset = dataset.repeat()
# filter invalid lines out
dataset = dataset.filter(lambda line: filter_func(line))
dataset = dataset.map(lambda line: parse_func(line),
num_parallel_calls=1)
# suppose element is (word_ids, length)
dataset = dataset.padded_batch(batch_size,
padded_shapes=(
tf.TensorShape([None]),
tf.TensorShape([])),
padding_values=(pad_id, 0))
dataset = dataset.prefetch(8)
return dataset

1.3 Data pipeline 的優化

理解上述過程後,對 buffer_size 和 num_parallel_calls 這兩個參數的調試目標就是在保證 cache 不被排空的基礎上,儘量少地佔用計算資源(如果你還有別的任務要跑的話)。tf.data.Dataset.prefetch 通常只放在最後一步,其 buffer_size 一般設成 8 左右。對於不複雜的 Transform,tf.data.Dataset.map 的 num_parallel_calls 一般設成 1~2。

pipeline 的運行和模型訓練是獨立的,所以只需要保證處理數據的速度比訓練的速度快即可,而這在文本數據處理中很容易做到。由於 tensorflow 對文本處理的支持不好,建議將比較複雜的文本處理先離線做好存成數據文件,再用 tensorflow 讀取。

需要注意的是 tf.data.Dataset.shuffle 的使用。因為 shuffle 是在 Queue 上做的,當 buffer_size 比較小時,對數據集的 shuffle 會不夠充分。實際使用時建議先將硬碟中的數據全局 shuffle 一遍:shuf data.txt > shuf_data.txt,並將 buffer_size 設大一點。

1.4 Data pipeline 的技巧

在你的訓練流程中,如果 GPU 的計算需要依賴沒有 GPU 實現的操作,而這部分操作又不會很重的話,可以把它放在 input pipeline 中,充分利用 tf.data.Dataset.prefetch 的 cache 功能。這裡舉兩個例子:

在實現 GPU 版 word2vec 時,可以把 negative sampling 部分放在 input pipeline 中。

在實現多卡訓練的時候,如果只維護一條 input pipeline,可以將大 batch 切分的處理放在 input pipeline 裡做。個人發現這比這個討論提到的方案都要好一些。

def split_batches(num_splits, batches):
batch_size = tf.shape(batches[0])[0]
# evenly distributed sizes
divisible_sizes = tf.fill([num_splits],
tf.floor_div(batch_size, num_splits))
remainder_sizes = tf.sequence_mask(tf.mod(batch_size, num_splits),
maxlen=num_splits,
dtype=tf.int32)
frag_sizes = divisible_sizes + remainder_sizes
batch_frags_list = []
for batch in batches:
batch_frags = tf.split(batch, frag_sizes, axis=0)
batch_frags_list.append(batch_frags)

frag_batches_list = zip(*batch_frags_list)
# fix corner case
for i, frag_batches in enumerate(frag_batches_list):
if len(frag_batches) == 1:
frag_batches_list[i] = frag_batches[0]
return frag_batches_list

dataset = dataset.map(lambda seqs_batch, lengths_batch:
split_batches(num_splits,
[seqs_batch, lengths_batch]),
num_parallel_calls=4)

更多的建議(如fused transformation)可以參照官方文檔。

2. 變長序列的處理

2.1 處理 mini-batch 中的序列長度變化:Padding 和 Bucketing

由於數據集中的序列的長度不一,我們需要對 mini-batch 中的短句進行補長(padding)的操作:可用指定的符號(token)拼到短句末位,將短句補到 mini-batch 裡面最長句子的長度。這是因為模型的大部分操作都是基於矩陣運算。補長用的符號對應的特徵通常會在後續的計算開始前置零。一般補長操作都是在做完詞表映射後做的。

當 mini-batch 中的句長範圍過大的時候(如1~100),GPU 大部分時間都在處理最長的句子,短句有效的部分很快就處理完了。為了更充分利用GPU的並行計算資源,我們可以控制 mini-batch 的句長範圍。

Bucketing 的想法就是在構建 mini-batch 之前,先將序列按長度分組(bucket),然後再從每個 bucket 裡面隨機選取序列構建 mini-batch。按長度分組的操作可以通過簡單的 hash 實現。

Bucketing + padding 可以藉由 tf.data 接口實現:

def bucket_pad_batch(dataset, pad_id):
# dataset element is (seq, length). seq is an integer tuple.
def key_func(seq, length):
bucket_id = length // bucket_width
return tf.to_int64(bucket_id)

def reduce_func(unused_key, windowed_data):
return windowed_data.padded_batch(
batch_size,
padded_shapes=(
tf.TensorShape([None]),
tf.TensorShape([]), # 表示不做 padding
),
padding_values=(pad_id,
0, # 因為不做padding,這只是佔位符
))
dataset = dataset.apply(tf.contrib.data.group_by_window(
key_func=key_func,
reduce_func=reduce_func,
window_size=batch_size))
return dataset

當數據集的句長分布範圍較大的時候,bucketing 可以顯著提升訓練速度。

但 bucketing 分組的操作會妨礙 shuffle 的效果,使訓練數據偏離 i.i.d.(Independent and identically distributed) 的假設,使梯度估計有偏,在訓練過程中使 loss 的抖動加劇,模型的收斂性變差。實際使用中需要調整 bucket 的數量,對訓練速度和收斂性能進行 trade-off。在這篇水文中有這個圖可以參考:

Bucket 數量對訓練速度和收斂速度的影響。圖來自Accelerating recurrent neural network training using sequence bucketing and multi-GPU data parallelization

2.2 變長序列的 Soft Attention

soft attention 的計算方法如下:

其中  為第  個詞的權重, 為 attention key 和第  個詞算出來的相似度。我們可以簡單地調用 tf.nn.softmax 進行計算。attention 後的句子特徵為

其中  是第  個詞的特徵向量。

# 實現 1
# feat_seqs: shape=[batch_size, maxlen, feature] # 每個詞的特徵
# sims: shape=[batch_size, maxlen] # 每個詞的 attention 相似度
# lengths: shape=[batch_size] # 句長

atns = tf.nn.softmax(sims) # [batch_size, maxlen]

atns = tf.expand_dims(atns, axis=-1) # [batch_size, maxlen, 1]
feat_seqs = tf.transpose(feat_seqs, [0,2,1]) # [batch_size, feature, maxlen]
feat = tf.matmul(feat_seqs, atns)

在 mini batch 訓練過程中,大多數序列後面都會帶上佔位符 <pad>,如果不做處理的話,上述實現對 attention 權重的計算應為下式:

 代表佔位符對應的相似度, 代表詞對應的相似度。 為上述代碼計算的 attention 權重。attention 後的特徵則變成了

如果佔位符的特徵不為 ,算出來的句子表徵就會偏離真實的表徵。但即使佔位符的特徵都為 ,  這一項的存在也會將句子的特徵向量的模  變小: 

常見的錯誤解決方案是直接將  置為零:

# 實現 2
# feat_seqs: shape=[batch_size, maxlen, feature] # 每個詞的特徵
# sims: shape=[batch_size, maxlen] # 每個詞的 attention 相似度
# lengths: shape=[batch_size] # 句長

mask = tf.sequence_mask(seq_lens, maxlen=shape[seq_axis], dtype=tf.float32)
atns = tf.nn.softmax(sims*mask) # [batch_size, maxlen]

atns = tf.expand_dims(atns, axis=-1) # [batch_size, maxlen, 1]
feat_seqs = tf.transpose(feat_seqs, [0,2,1]) # [batch_size, feature, maxlen]
feat = tf.matmul(feat_seqs, atns)

但由於 ,實際上 <pad> 的特徵還是會對句子特徵產生影響。

比較正確的做法是將  置為零:

# 實現 3
# feat_seqs: shape=[batch_size, maxlen, feature] # 每個詞的特徵
# sims: shape=[batch_size, maxlen] # 每個詞的 attention 相似度
# lengths: shape=[batch_size] # 句長

mask = tf.sequence_mask(seq_lens, maxlen=shape[seq_axis], dtype=tf.float32)
exp_sims = tf.exp(sims)*mask
atns = exp_sims/tf.reduce_sum(exp_sims, axis=-1, keepdims=True)

atns = tf.expand_dims(atns, axis=-1) # [batch_size, maxlen, 1]
feat_seqs = tf.transpose(feat_seqs, [0,2,1]) # [batch_size, feature, maxlen]
feat = tf.matmul(feat_seqs, atns)

但由於 tf.float32 的範圍為  有 overflow 的風險。我們可以使用下面這個常用的 trick:

其中  為常數,通常取  來防止 overflow。

然而這種做法也是不穩定的,此時存在 underflow 的風險。對參數隨機初始化後,各個詞的  通常非常相近,在  variance 較小的情況下  ,最後導致所有 attention 權重之和  遠遠偏離 1。這裡的 overflow 或者 underflow 是導致模型出現 NAN 或者發散的元兇之一。

我們可以動態調整  ,以及將數值計算轉化到 tf.float64 進行計算。我們也可以直接使用 tf.clip_by_value 將最小值取為一個很小的數,防止全部變成 0。

所幸 Tensorflow 的 tf.nn.softmax 對 softmax 的實現是數值穩定的。同時注意到這個 trick:

所以我們只需將 實現1 的 atns 中對應 <pad> 的值置零,再重新對非零的值做歸一化便可:

# 實現 4
# feat_seqs: shape=[batch_size, maxlen, feature] # 每個詞的特徵
# sims: shape=[batch_size, maxlen] # 每個詞的 attention 相似度
# lengths: shape=[batch_size] # 句長

mask = tf.sequence_mask(seq_lens, maxlen=shape[seq_axis], dtype=tf.float32)
atns = tf.nn.softmax(sims) # [batch_size, maxlen]
atns = mask*atns
atns = atns/tf.reduce_sum(atns, axis=-1, keepdims=True)

atns = tf.expand_dims(atns, axis=-1) # [batch_size, maxlen, 1]
feat_seqs = tf.transpose(feat_seqs, [0,2,1]) # [batch_size, feature, maxlen]
feat = tf.matmul(feat_seqs, atns)

2.3 過長句子的處理

2.3.1 處理 GPU 內存限制

RNN 的訓練用的是 BPTT(Back-propagation through time),每次 forward 的時候需要將每一個 step 的中間狀態保存在內存中。GPU 內存的限制導致我們無法處理過長的序列(~4000)。

當過長的句子在訓練數據中佔少數時,我們可以通過簡單的截斷操作,只保留序列的前  位進行處理。但當長句的佔比較多的時候,截斷會丟失很多訓練信息。我們可以通過設置 tf.nn.dynamic_rnn 函數中的 swap_memory=True 來解決 GPU 內存限制的問題。這個操作會將所有 step 的中間狀態放在 CPU 的內存中。

2.3.2 序列任務的加速:TBPTT(Truncated Back-propagation through time)

如果你的任務從序列的一部分就能夠構建監督信號(如 language modeling,或者其他序列預測任務),用整句長句(~4000)的 loss 去構建一個 gradient 便顯得有點浪費。我們可以將長句  切成短句:,並在處理完每一個短句後便更新模型。在和 BPTT 同樣的計算量下,一個長句子可以更新  次參數(BPTT 只能更新一次)。TBPTT 在像語言模型這種序列預測任務中很流行。

2.3.2.1 TBPTT 第一種實現

一個簡單的實現是把切割出來的短句當成獨立的句子直接訓練: 每個子序列  的初始狀態(initial state)都設成全零向量(或者事先指定的默認向量)。和 BPTT 相比,這種方法會去掉數據集中的長程依賴(long term dependency):

TBPTT 第一種實現圖示

假設子句  的順序沒有被打亂,切出的短句句長 , 圖中  指第  位的詞, 為計算第  步梯度使用的 loss,從對應的子句  的詞(紅框內)構建。initial state 是 RNN 計算每個子句  時的初始狀態。可以看到在子句間切換時,子句依賴的信息被 initial state 的置零打斷了。

即便如此,這種方案的好處是可以讓模型冷啟動的性能更好:RNN 形成頭幾個詞的表徵時不能過分依賴初始狀態,需要很快地將輸入的有效信息放到 RNN cell 中。如果訓練完的序列模型是作為短文本任務的特徵提取器(如ELMo),冷啟動的性能將是比較重要的考量。

2.3.2.2 TBPTT 第二種實現

為了保存數據集中的長程依賴(long term dependency),我們可以將更新的 batch 順序限制為 ,並將  的 final state 作為  的 initial state。這裡的本意是使用 state 的傳遞保存子句間的依賴,也是大部分 language modeling 任務的做法。

看起來這種實現像是保存了長程依賴。但在實際訓練時,模型並沒有用長程依賴的信息去訓練。從監督信號的角度來看,因為 loss 最多由句長為  的子句構建,模型最多只能學到長度為  的依賴。見下圖:

TBPTT 第二種實現圖示

但 TBPTT 和 BPTT 的差異還不只長程依賴的學習這一點。記 RNN 的函數為

 為使用參數  在子句  上進行 forward 計算後的  為對應的每一步的輸出。再記  和  分別為計算第  和第  個子句的 loss 所用的參數。

在 TBPTT 中,RNN 計算所用參數為

在 BPTT 中,RNN 計算所用參數為

注意  的上標的不同。兩種使用的初始化狀態是用不同的參數計算出來的。假如在 TBPTT 中計算不同子句的 loss 後不會更新參數,那麼 ,進而, RNN 的計算是一樣的。但實際上參數在處理完每個子句後都會被更新,所以 。由於 RNN 是非線性系統, 的差異會隨著子句長度  的增大而很快被放大。

TBPTT 還可以拓展成一般形式,實現會更加複雜,但實際效果和方案2差不多。感興趣的讀者可以參考這篇文章。

下面是構建計算圖的代碼片段:

# 兩個重要變量:
# reset_flags: 是否需要要使用default_h
# max_batch_size: 如果輸入的batch_size可變,這個值是最大可能的batch_size
def build_state_var(name):
return tf.get_local_variable(name,
[max_batch_size, state_size],
initializer=tf.zeros_initializer(),
trainable=False)

cache_h = build_state_var("cache_h")
default_h = build_state_var("default_h")
initial_state = tf.where(reset_flags,
x=default_h[:batch_size, :],
y=cache_h[:batch_size, :])
outputs, final_state = tf.nn.dynamic_rnn(gru_cell,
embed_seqs,
seq_lens,
initial_state=initial_state)

# 構建train_op
# ...
# 將cache update綁定train_op
with tf.control_dependencies([train_op]):
cache_update = tf.assign(initial_state, final_state)

以及 input pipeline 切分子句的代碼片段:

def truncate_dateset(batched_dataset, chunk_length):
# input batch_dataset element: (ids_batch, length_batch)
# output batch_dataset element: (reset_flag, ids_batch, length_batch)
# do not shuffle the output dataset!!!
def truncate_map(ids_batch, length_batch):
chunk_nums = tf.ceil(tf.truediv(length_batch, chunk_length))
chunk_nums = tf.cast(chunk_nums, dtype=tf.int32)
max_chunk_num = tf.reduce_max(chunk_nums)
batch_size = tf.shape(length_batch)[0]

divisible_lens = tf.sequence_mask(chunk_nums - 1, dtype=tf.int32) * chunk_length
remainder_lens = tf.expand_dims(length_batch - chunk_length * (chunk_nums - 1), 1)
chunck_lengths = tf.reverse_sequence(tf.concat([remainder_lens, divisible_lens],
axis=1),
seq_lengths=chunk_nums,
seq_axis=1)
ids_batch = ids_batch
reset_flags = tf.concat([tf.ones([batch_size, 1], dtype=tf.bool),
tf.zeros([batch_size, max_chunk_num - 1],
dtype=tf.bool)],
axis=1)

def get_batch(index):
chunk_reset_flag = reset_flags[:, index]
chunk_length_batch = chunck_lengths[:, index]
chunk_ids_batch = ids_batch[:, index * chunk_length:(index + 1) * chunk_length]
return chunk_reset_flag, chunk_length_batch, chunk_ids_batch

indices = tf.range(0, max_chunk_num)
return tf.data.Dataset.from_tensor_slices(indices).map(get_batch)

return batched_dataset.flat_map(truncate_map)



推薦閱讀:

【長文詳解】從Transformer到BERT模型

賽爾譯文 | 從頭開始了解Transformer

百聞不如一碼!手把手教你用Python搭一個Transformer

相關焦點

  • 如何使用XGBoost模型進行時間序列預測
    XGBoost也可以被用於時間序列預測,儘管它需要將時間序列數據集先轉換成監督學習問題。它需要用到一種被稱為前進式驗證的特殊方法來評估模型,因為使用k折驗證來評估模型容易導致偏向樂觀的結果。本教程中,你將探索如何為時間序列預測開發一個XGBoost模型。
  • 時間序列模型
    ARMA-GARCH模型名字貌似長了點,看著暈,其實他是兩個模型的合體,一個叫ARMA,一個叫GARCH。別著急,我們來各個擊破。ARMA模型這個模型是時間序列模型中的一個重要模型,不僅在金融領域,在其他領域都有廣泛的應用。
  • 時間序列模型(三)——馬爾可夫模型
    很多教材都會單獨介紹馬爾可夫模型,但它是一種時間序列模型,可以用時間序列模型的思維來學習,並和其它時間序列模型做比較。       狀態空間指的是序列數據的狀態。(最少要有兩種狀態)理論上來說,這個空間可以是離散的,或者是連續的。本文主要討論最重要的離散狀態的情況。
  • 從時間序列ariam模型到Prophet模型的應用
    所遇問題前兩個星期,我的一個朋友(任職於上海的一家數據公司的機器學習崗位)在工作中有一個華為手機各價位銷售趨勢預測的項目,需要用到時間序列,找到我一起做一下協助。了解完數據的特點,我首先想到的是用時間序列裡的arima模型,把2017年1月,2018年1月的數據作為訓練集,2019年1月的數據作為測試集,跑入模型,預測2020年1月的數據,同理用2017年2月,2018年2月的數據作為訓練集,2019年2月的數據作為測試集,預測2020年2月的數據,用這個思路分別來預測2020年1月,2月,3月,4月,5月,6月的數據
  • 時間序列的LSTM模型預測——基於Keras
    一、問題背景    現實生活中,在一系列時間點上觀測數據是司空見慣的活動,在農業、商業、氣象軍事和醫療等研究領域都包含大量的時間序列數據。時間序列的預測指的是基於序列的歷史數據,以及可能對結果產生影響的其他相關序列,對序列未來的可能取值做出預測。
  • 如何讓神經聲碼器高效地用於序列到序列聲學模型
    如何讓神經聲碼器高效地用於序列到序列聲學模型 IT創事記 發表於 2021-01-07 16:01:32 往往在放下手機之後你才會意識到,電話那頭的客服其實是個機器人;或者準確地說,是「一位」智能客服。
  • SAS時間序列模型預測未來航班數量
    時間序列模型利用歷史資料進行延伸預測,也稱歷史引伸預測法。
  • 時間序列深度學習:狀態 LSTM 模型預測太陽黑子(上)
    在本文中,我們展示了使用稱為 LSTM(長短期記憶)的特殊類型深度學習模型,該模型對涉及自相關性的序列預測問題很有用。我們分析了一個名為「太陽黑子」的著名歷史數據集(太陽黑子是指太陽表面形成黑點的太陽現象)。我們將展示如何使用 LSTM 模型預測未來 10 年的太陽黑子數量。
  • R語言ARIMA集成模型預測時間序列分析
    p=18493 本文我們使用4個時間序列模型對每周的溫度序列建模。第一個是通過auto.arima獲得的,然後兩個是SARIMA模型,最後一個是Buys-Ballot方法。我們使用以下數據k=620n=nrow(elec)futu=(k+1):ny=electricite$Load[1:k]plot(y,type="l")我們開始對溫度序列進行建模(溫度序列對電力負荷的影響很大)
  • 特徵工程自動化 時間序列的數據是關鍵
    【IT168 資訊】今天介紹一個通用框架,用於開發時間序列模型,生成特徵並對數據進行預處理,並探索使這一過程自動化的潛力,以便將先進的機器學習算法應用於幾乎所有的時間序列問題。目前大多數機器學習算法都不具有時間意識,不容易應用於時間序列和預測問題。
  • R語言arma模型診斷_arma模型實現模型r語言 - CSDN
    ,如果有兩個等長的序列片段,則返回第一個。ur.df.01(x)              #對原序列進行判斷【一般的ARIMA模型】d=scan("a1.5.txt")               #導入數據prop=ts(d,start=1950,freq=1)      #轉化為時間序列數據
  • 為文本摘要模型添加注意力機制:採用LSTM的編解碼器模型實現
    常用的序列-序列模型(編碼器-解碼器)的整體結構如下圖所示該模型由編碼器、中間矢量和解碼器三部分組成。編碼器該編碼器基本上由一系列LSTM/GRU單元組成(請查看LSTM/GRU文檔以更好地理解架構)。
  • 豐富細節刻線,MG比例海牛高達模型
    恰到好處的刻線增加可以使整個高達模型變得質感十足,於是有很多手藝好的模友開始為自己的高達模型進行刻線豐富,接下來為大家帶來的是キラキラ的豐富細節刻線,MG比例海牛高達模型。大家感覺這個刻線數量怎麼樣?海牛高達是高達系列中人氣較高的機設,成為了很多模友必入的機型,無論是牛高達還是海牛高達模型拼裝完成之後表現效果都比較不錯。如果在原有不錯的基礎上增加細節會變成什麼樣呢?這款改的海牛高達模型會給您答案。無論是增加重甲還是沒有增加重甲的時候,這款海牛高達的細節刻線都比較突出,感覺提升了高達模型的整體質感。
  • 四分之三的DNA序列如何被開啟的?Nature新論文報導人工智慧獲得的重要突破
    實現了期待已久的突破,未來也許可以應用於生物醫學中。科學家們早就知道,人類基因會依照我們DNA的精確順序傳遞的指令付諸行動,這些指令由四種不同類型的單個的鹼基分別編碼:A,C,G和T。眾所周知,將近25%的基因被類似於TATAAA的序列(稱為「 TATA框」)轉錄,那其它75%的基因是如何開啟的呢?這依然是一個謎。
  • 從字符級的語言建模開始,了解語言模型與序列建模的基本概念
    生成文本序列的通常方式是訓練模型在給定所有先前詞/字符的條件下預測下一個詞/字符出現的概率。此類模型叫作統計語言模型,這種模型會嘗試捕捉訓練文本的統計結構,本文從字符級語言模型和名字預測出發向讀者介紹了語言建模的核心概念。循環神經網絡(RNN)模型常用於訓練這種語言模型,因為它們使用高維隱藏狀態單元處理信息的能力非常強大,建模長期依賴關係的能力也非常強。
  • 自動化所提出基於腦功能影像時間序列的多尺度卷積循環神經網絡模型
    自動化所提出基於腦功能影像時間序列的多尺度卷積循環神經網絡模型 2019-10-28 自動化研究所 【字體:大 中 小】
  • 阿里雲高效基因序列檢索助力新冠肺炎病毒序列快速分析
    阿里雲AnalyticDB for MySQL團隊將基因序列片段轉化成對應的1024維特徵向量,將兩個基因片段的匹配問題,轉換成了兩個向量間的距離計算問題,從而大大降低了計算開銷,實現毫秒級返回相關基因片段,完成基因片段的首次篩選。然後,使用基因相似計算BLAST算法,完成基因相似度的精確排查,從而高效率完成基因序列的匹配計算。匹配算法從原來O(M+N)的複雜度降低到O(1)。
  • 360度視頻序列全景圖拼接系統的設計與實現
    由於成本較低,不需要昂貴的專業設備,利用序列圖像進行全景圖拼接是近年來的研究熱點,其中又分為對靜態序列圖像拼接的研究,以及對視頻序列拼接的研究。 靜態圖像序列中的每一張圖像都是單獨拍攝,能夠精確設置控焦距、曝光等拍攝參數,因而夠獲得較好的成像質量,但操作過程卻相對複雜。 視頻序列拍攝操作簡單,只需使用錄像設備旋轉一周錄製,但不能準確控制拍攝參數。
  • 直觀理解並使用Tensorflow實現Seq2Seq模型的注意機制
    採用帶注意機制的序列序列結構進行英印地語神經機器翻譯Seq2seq模型構成了機器翻譯、圖像和視頻字幕、文本摘要、聊天機器人以及任何你可能想到的包括從一個數據序列到另一個數據序列轉換的任務的基礎。如果您曾使用過谷歌Translate,或與Siri、Alexa或谷歌Assistant進行過互動,那麼你就是序列對序列(seq2seq)神經結構的受益者。
  • 李航等提出多粒度AMBERT模型,中文提升顯著
    對於英文,AMBERT 將單詞序列(細粒度標記)和短語序列(粗粒度標記)作為標記化後的輸入,其中使用一個編碼器處理單詞序列,另一個編碼器處理短語序列,並利用兩個編碼器之間的共享參數,最終分別創建單詞和短語的上下文表示序列。