直觀理解並使用Tensorflow實現Seq2Seq模型的注意機制

2021-01-11 deephub

採用帶注意機制的序列序列結構進行英印地語神經機器翻譯

Seq2seq模型構成了機器翻譯、圖像和視頻字幕、文本摘要、聊天機器人以及任何你可能想到的包括從一個數據序列到另一個數據序列轉換的任務的基礎。如果您曾使用過谷歌Translate,或與Siri、Alexa或谷歌Assistant進行過互動,那麼你就是序列對序列(seq2seq)神經結構的受益者。

我們這裡的重點是機器翻譯,基本上就是把一個句子x從一種語言翻譯成另一種語言的句子y。機器翻譯是seq2seq模型的主要用例,注意機制對機器翻譯進行了改進。關於這類主題的文章通常涉及用於實現的大代碼段和來自多個庫的大量API調用,對概念本身沒有直觀的理解。在這方面,我們既要講求理論,也要講求執行。除了實現之外,我們還將詳細了解seq2seq體系結構和注意力的每個組件表示什麼。本文中使用的代碼可以在最後的資源列表中找到。

目標

在Tensorflow中實現、訓練和測試一個英語到印地語機器翻譯模型。

對編碼器、解碼器、注意機制的作用形成直觀透徹的理解。

討論如何進一步改進現有的模型。

讀數據集

首先,導入所有需要的庫。在這個實現中使用的英語到印地語語料庫可以在Kaggle找到。一個名為「HindiEnglishTruncatedCorpus」的文件。將下載csv "。請確保在pd.readcsv()函數中放置了正確的文件路徑,該路徑對應於文件系統中的路徑。

import numpy as npimport pandas as pdfrom tensorflow.keras.preprocessing.text import Tokenizerfrom tensorflow.keras.preprocessing.sequence import pad_sequencesimport tensorflow as tffrom sklearn.model_selection import train_test_splitimport timefrom matplotlib import pyplot as pltimport osimport redata = pd.read_csv("./Hindi_English_Truncated_Corpus.csv")english_sentences = data["english_sentence"]hindi_sentences = data["hindi_sentence"]

讓我們快速看看我們正在處理的數據集的類型。這是相當簡單的。

數據預處理

在我們繼續我們的編碼器,解碼器和注意力實現之前,我們需要預處理我們的數據。請注意,預處理步驟也依賴於我們處理的數據類型。例如,在這裡考慮的數據集中,也有帶有空字符串的句子。我們需要相應地處理這類案例。如果使用其他數據集,也可能需要一些額外或更少的步驟。預處理步驟如下:

在單詞和標點符號之間插入空格

如果手頭上的句子是英語,我們就用空格替換除了(a-z, A-Z, 「.」, 「?」, 「!」, 「,」)

句子中去掉多餘的空格,關鍵字「sentencestart」和「sentenceend」分別添加到句子的前面和後面,讓我們的模型明確地知道句子開始和結束。

每個句子的以上三個任務都是使用preprocess_sentence()函數實現的。我們還在開始時初始化了所有的超參數和全局變量。請閱讀下面的超參數和全局變量。我們將在需要時使用它們。

# Global variables and Hyperparametersnum_words = 10000oov_token = '<UNK>'english_vocab_size = num_words + 1hindi_vocab_size = num_words + 1MAX_WORDS_IN_A_SENTENCE = 16test_ratio = 0.2BATCH_SIZE = 512embedding_dim = 64hidden_units = 1024learning_rate = 0.006epochs = 100def preprocess_sentence(sen, is_english):if (type(sen) != str): return '' sen = sen.strip('.') # insert space between words and punctuations sen = re.sub(r"([?.!,;])", r" \1 ", sen) sen = re.sub(r'[" "]+', " ", sen) # For english, replacing everything with space except (a-z, A-Z, ".", "?", "!", ",", "'") if(is_english == True): sen = re.sub(r"[^a-zA-Z?.!,']+", " ", sen) sen = sen.lower() sen = sen.strip() sen = 'sentencestart ' + sen + ' sentenceend' sen = ' '.join(sen.split()) return sen

對包含英語句子和印地語句子的每個數據點進行循環,確保不考慮帶有空字符串的句子,並且句子中的最大單詞數不大於MAXWORDSINASENTENCE的值。這一步是為了避免我們的矩陣是稀疏的。

下一步是對文本語料庫進行向量化。具體來說,fitontexts()為每個單詞分配一個唯一的索引。textstosequences()將一個文本句子轉換為一個數字列表或一個向量,其中數字對應於單詞的唯一索引。padsequences()通過添加剛好足夠數量的oovtoken(從vocab token中提取)來確保所有這些向量最後都具有相同的長度,使每個向量具有相同的長度。tokenize_statements()封裝了上面這些功能。

接下來,我們從完整的數據集中得到訓練集,然後對訓練集進行批處理。我們訓練模型所用的句子對總數為51712。

# Loop through each datapoint having english and hindi sentenceprocessed_e_sentences = []processed_h_sentences = []for (e_sen, h_sen) in zip(english_sentences, hindi_sentences):processed_e_sen = preprocess_sentence(e_sen, True) processed_h_sen = preprocess_sentence(h_sen, False) if(processed_e_sen == '' or processed_h_sen == '' or processed_e_sen.count(' ') > (MAX_WORDS_IN_A_SENTENCE-1) or processed_h_sen.count(' ') > (MAX_WORDS_IN_A_SENTENCE-1)): continue processed_e_sentences.append(processed_e_sen) processed_h_sentences.append(processed_h_sen)print("Sentence examples: ")print(processed_e_sentences[0])print(processed_h_sentences[0])print("Length of English processed sentences: " + str(len(processed_e_sentences)))print("Length of Hindi processed sentences: " + str(len(processed_h_sentences)))def tokenize_sentences(processed_sentences, num_words, oov_token): tokenizer = Tokenizer(num_words = num_words, oov_token = oov_token) tokenizer.fit_on_texts(processed_sentences) word_index = tokenizer.word_index sequences = tokenizer.texts_to_sequences(processed_sentences) sequences = pad_sequences(sequences, padding = 'post') return word_index, sequences, tokenizerenglish_word_index, english_sequences, english_tokenizer = tokenize_sentences(processed_e_sentences, num_words, oov_token)hindi_word_index, hindi_sequences, hindi_tokenizer = tokenize_sentences(processed_h_sentences, num_words, oov_token)# split into traning and validation setenglish_train_sequences, english_val_sequences, hindi_train_sequences, hindi_val_sequences = train_test_split(english_sequences, hindi_sequences, test_size = test_ratio)BUFFER_SIZE = len(english_train_sequences)# Batching the training setdataset = tf.data.Dataset.from_tensor_slices((english_train_sequences, hindi_train_sequences)).shuffle(BUFFER_SIZE)dataset = dataset.batch(BATCH_SIZE, drop_remainder = True)print("No. of batches: " + str(len(list(dataset.as_numpy_iterator()))))

編碼器Encoder

Seq2seq架構在原論文中涉及到兩個長短期內存(LSTM)。一個用於編碼器,另一個用於解碼器。請注意,在編碼器和解碼器中,我們將使用GRU(門控周期性單元)來代替LSTM,因為GRU的計算能力更少,但結果與LSTM幾乎相同。Encoder涉及的步驟:

輸入句子中的每個單詞都被嵌入並表示在具有embeddingdim(超參數)維數的不同空間中。換句話說,您可以說,在具有embeddingdim維數的空間中,詞彙表中的單詞的數量被投影到其中。這一步確保類似的單詞(例如。boat & ship, man & boy, run & walk等)都位於這個空間附近。這意味著「男人」這個詞和「男孩」這個詞被預測的機率幾乎一樣(不是完全一樣),而且這兩個詞的意思也差不多。

接下來,嵌入的句子被輸入GRU。編碼器GRU的最終隱藏狀態成為解碼器GRU的初始隱藏狀態。編碼器中最後的GRU隱藏狀態包含源句的編碼或信息。源句的編碼也可以通過所有編碼器隱藏狀態的組合來提供[我們很快就會發現,這一事實對於注意力的概念的存在至關重要]。

class Encoder(tf.keras.Model):def __init__(self, english_vocab_size, embedding_dim, hidden_units): super(Encoder, self).__init__() self.embedding = tf.keras.layers.Embedding(english_vocab_size, embedding_dim) self.gru = tf.keras.layers.GRU(hidden_units, return_sequences = True, return_state = True) def call(self, input_sequence): x = self.embedding(input_sequence) encoder_sequence_output, final_encoder_state = self.gru(x) # Dimensions of encoder_sequence_output => (BATCH_SIZE, MAX_WORDS_IN_A_SENTENCE, hidden_units) # Dimensions of final_encoder_state => (BATCH_SIZE, hidden_units) return encoder_sequence_output, final_encoder_state# initialize our encoderencoder = Encoder(english_vocab_size, embedding_dim, hidden_units)

解碼器Decoder ( 未使用注意力機制)

注意:在本節中,我們將了解解碼器的情況下,不涉及注意力機制。這對於理解稍後與解碼器一起使用的注意力的作用非常重要。

解碼器GRU網絡是生成目標句的語言模型。最終的編碼器隱藏狀態作為解碼器GRU的初始隱藏狀態。第一個給解碼器GRU單元來預測下一個的單詞是一個像「sentencestart」這樣的開始標記。這個標記用於預測所有num_words數量的單詞出現的概率。訓練時使用預測的概率張量和實際單詞的一熱編碼來計算損失。這種損失被反向傳播以優化編碼器和解碼器的參數。同時,概率最大的單詞成為下一個GRU單元的輸入。重複上述步驟,直到出現像「sentenceend」這樣的結束標記。

這種方法的問題是:

信息瓶頸:如上所述,編碼器的最終隱藏狀態成為解碼器的初始隱藏狀態。這就造成了信息瓶頸,因為源句的所有信息都需要壓縮到最後的狀態,這也可能會偏向於句子末尾的信息,而不是句子中很久以前看到的信息。

解決方案:我們解決了上述問題,不僅依靠編碼器的最終狀態來獲取源句的信息,還使用了編碼器所有輸出的加權和。那麼,哪個編碼器的輸出比另一個更重要?注意力機制就是為了解決這個問題。

添加注意力機制

注意力不僅為瓶頸問題提供了解決方案,還為句子中的每個單詞賦予了權重(相當字面意義)。源序列在編碼器輸出中有它自己的的信息,在解碼器中被預測的字在相應的解碼器隱藏狀態中有它自己的的信息。我們需要知道哪個編碼器的輸出擁有類似的信息,我們需要知道在解碼器隱藏狀態下,哪個編碼器輸出的信息與解碼器隱藏狀態下的相似。

因此,這些編碼器輸出和解碼器的隱藏狀態被用作一個數學函數的輸入,從而得到一個注意力向量分數。當一個單詞被預測時(在解碼器中的每個GRU單元),這個注意力分數向量在每一步都被計算出來。該向量確定每個編碼器輸出的權重,以找到加權和。

注意力的一般定義:給定一組向量「值」和一個向量「查詢」,注意力是一種計算基於查詢的加權值和的技術。

在我們的seq2seq架構上下文中,每個解碼器隱藏狀態(查詢)處理所有編碼器輸出(值),以獲得依賴於解碼器隱藏狀態(查詢)的編碼器輸出(值)的加權和。

加權和是值中包含的信息的選擇性摘要,查詢將確定關注哪些值。這個過程類似於將查詢投射到值空間中,以便在值空間中查找查詢(score)的上下文。較高的分數表示對應的值更類似於查詢。

根據注意力機制的原始論文,解碼器決定源句要注意的部分。通過讓解碼器有一個注意機制,我們將編碼器從必須將源句中的所有信息編碼為固定長度的向量的負擔中解脫出來。使用這種新方法,信息可以分布在整個序列中,解碼器可以相應地有選擇地檢索這些信息。

還記得我們剛才討論的數學函數嗎?有幾種方法可以找到注意力得分(相似度)。主要有以下幾點:

基本點積注意力(Dot Product Attention)

乘法注意力(multiplicative attention)

加性注意力(additive attention)

我們不會在這裡逐一深入講解。我們會在後續的文章中詳細接好。現在我們將考慮基本的點積注意,因為它是最容易掌握。你已經猜到了這類注意力的作用。從名稱判斷,它是輸入矩陣的點積。

注意,基本的點積注意有一個假設。它假設兩個輸入矩陣的維數在軸上要做點積的地方必須是相同的,這樣才能做點積。在我們的實現中,這個維度是由超參數hidden_units給出的,對於編碼器和解碼器都是一樣的。

上面講了太多的理論。現在讓我們回到代碼!我們將定義我們的Attention類。

將編碼器輸出張量與解碼器隱藏狀態進行點積,得到注意值。這是通過Tensorflow的matmul()函數實現的。我們取上一步得到的注意力分數的softmax。這樣做是為了規範化分數並在區間[0,1]內獲取值。編碼器輸出與相應的注意分數相乘,然後相加得到一個張量。這基本上是編碼器輸出的加權和,通過reduce_sum()函數實現。

class BasicDotProductAttention(tf.keras.layers.Layer):def __init__(self): super(BasicDotProductAttention, self).__init__() def call(self, decoder_hidden_state, encoder_outputs): # Dimensions of decoder_hidden_state => (BATCH_SIZE, hidden_units) # Dimensions of encoder_outputs => (BATCH_SIZE, MAX_WORDS_IN_A_SENTENCE, hidden_units) decoder_hidden_state_with_time_axis = tf.expand_dims(decoder_hidden_state, 2) # Dimensions of decoder_hidden_state_with_time_axis => (BATCH_SIZE, hidden_units, 1) attention_scores = tf.matmul(encoder_outputs, decoder_hidden_state_with_time_axis) # Dimensions of attention_scores => (BATCH_SIZE, MAX_WORDS_IN_A_SENTENCE, 1) attention_scores = tf.nn.softmax(attention_scores, axis = 1) weighted_sum_of_encoder_outputs = tf.reduce_sum(encoder_outputs * attention_scores, axis = 1) # Dimensions of weighted_sum_of_encoder_outputs => (BATCH_SIZE, hidden_units) return weighted_sum_of_encoder_outputs, attention_scores

解碼器Decoder ( 增加注意力機制)

代碼在decoder類中增加了以下步驟。

就像編碼器一樣,我們在這裡也有一個嵌入層用於目標語言中的序列。序列中的每一個單詞都在具有相似意義的相似單詞的嵌入空間中表示。

我們也得到的加權和編碼器輸出通過使用當前解碼隱藏狀態和編碼器輸出。這是通過調用我們的注意力層來實現的。

我們將以上兩步得到的結果(嵌入空間序列的表示和編碼器輸出的加權和)串聯起來。這個串聯張量被發送到我們的解碼器的GRU層。

這個GRU層的輸出被發送到一個稠密層,這個稠密層給出所有hindivocabsize的單詞出現的概率。具有高概率的單詞意味著模型認為這個單詞應該是下一個單詞。

class Decoder(tf.keras.Model):def __init__(self, hindi_vocab_size, embedding_dim, hidden_units): super(Decoder, self).__init__() self.embedding = tf.keras.layers.Embedding(hindi_vocab_size, embedding_dim) self.gru = tf.keras.layers.GRU(hidden_units, return_state = True) self.word_probability_layer = tf.keras.layers.Dense(hindi_vocab_size, activation = 'softmax') self.attention_layer = BasicDotProductAttention() def call(self, decoder_input, decoder_hidden, encoder_sequence_output): x = self.embedding(decoder_input) # Dimensions of x => (BATCH_SIZE, embedding_dim) weighted_sum_of_encoder_outputs, attention_scores = self.attention_layer(decoder_hidden, encoder_sequence_output) # Dimensions of weighted_sum_of_encoder_outputs => (BATCH_SIZE, hidden_units) x = tf.concat([weighted_sum_of_encoder_outputs, x], axis = -1) x = tf.expand_dims(x, 1) # Dimensions of x => (BATCH_SIZE, 1, hidden_units + embedding_dim) decoder_output, decoder_state = self.gru(x) # Dimensions of decoder_output => (BATCH_SIZE, hidden_units) word_probability = self.word_probability_layer(decoder_output) # Dimensions of word_probability => (BATCH_SIZE, hindi_vocab_size) return word_probability, decoder_state, attention_scores# initialize our decoderdecoder = Decoder(hindi_vocab_size, embedding_dim, hidden_units)

訓練

我們定義我們的損失函數和優化器。選擇了稀疏分類交叉熵和Adam優化器。每個訓練步驟如下:

從編碼器對象獲取編碼器序列輸出和編碼器最終隱藏狀態。編碼器序列輸出用於查找注意力分數,編碼器最終隱藏狀態將成為解碼器的初始隱藏狀態。對於目標語言中預測的每個單詞,我們將輸入單詞、前一個解碼器隱藏狀態和編碼器序列輸出作為解碼器對象的參數。返回單詞預測概率和當前解碼器隱藏狀態。將概率最大的字作為下一個解碼器GRU單元(解碼器對象)的輸入,當前解碼器隱藏狀態成為下一個解碼器GRU單元的輸入隱藏狀態。損失通過單詞預測概率和目標句中的實際單詞計算,並向後傳播在每個epoch中,每批調用上述訓練步驟,最後存儲並繪製每個epoch對應的損失。

附註:在第1步,為什麼我們仍然使用編碼器的最終隱藏狀態作為我們的解碼器的第一個隱藏狀態?

這是因為,如果我們這樣做,seq2seq模型將被優化為一個單一系統。反向傳播是端到端進行的。我們不想分別優化編碼器和解碼器。並且,沒有必要通過這個隱藏狀態來獲取源序列信息,因為我們已經有注意力機制了:)

optimizer = tf.keras.optimizers.Adam(learning_rate = learning_rate)loss_object = tf.keras.losses.SparseCategoricalCrossentropy(reduction='none')def loss_function(actual_words, predicted_words_probability):loss = loss_object(actual_words, predicted_words_probability) mask = tf.where(actual_words > 0, 1.0, 0.0) return tf.reduce_mean(mask * loss)def train_step(english_sequences, hindi_sequences): loss = 0 with tf.GradientTape() as tape: encoder_sequence_output, encoder_hidden = encoder(english_sequences) decoder_hidden = encoder_hidden decoder_input = hindi_sequences[:, 0] for i in range(1, hindi_sequences.shape[1]): predicted_words_probability, decoder_hidden, _ = decoder(decoder_input, decoder_hidden, encoder_sequence_output) actual_words = hindi_sequences[:, i] # if all the sentences in batch are completed if np.count_nonzero(actual_words) == 0: break loss += loss_function(actual_words, predicted_words_probability) decoder_input = actual_words variables = encoder.trainable_variables + decoder.trainable_variables gradients = tape.gradient(loss, variables) optimizer.apply_gradients(zip(gradients, variables)) return loss.numpy()all_epoch_losses = []training_start_time = time.time()for epoch in range(epochs): epoch_loss = [] start_time = time.time() for(batch, (english_sequences, hindi_sequences)) in enumerate(dataset): batch_loss = train_step(english_sequences, hindi_sequences) epoch_loss.append(batch_loss) all_epoch_losses.append(sum(epoch_loss)/len(epoch_loss)) print("Epoch No.: " + str(epoch) + " Time: " + str(time.time()-start_time))print("All Epoch Losses: " + str(all_epoch_losses))print("Total time in training: " + str(time.time() - training_start_time))plt.plot(all_epoch_losses)plt.xlabel("Epochs")plt.ylabel("Epoch Loss")plt.show()

測試

為了測試我們的模型在經過訓練後的執行情況,我們定義了一個函數,該函數接受一個英語句子,並按照模型的預測返回一個印地語句子。讓我們實現這個函數,我們將在下一節中看到結果的好壞。

我們接受英語句子,對其進行預處理,並將其轉換為長度為MAXWORDSINASENTENCE的序列或向量,如開頭的「預處理數據」部分所述。這個序列被輸入到我們訓練好的編碼器,編碼器返回編碼器序列輸出和編碼器的最終隱藏狀態。編碼器的最終隱藏狀態是解碼器的第一個隱藏狀態,解碼器的第一個輸入字是一個開始標記「sentencestart」。解碼器返回預測的字概率。概率最大的單詞成為我們預測的單詞,並被附加到最後的印地語句子中。這個字作為輸入進入下一個解碼器層。預測單詞的循環將繼續下去,直到解碼器預測結束標記「sentenceend」或單詞數量超過某個限制(我們將這個限制保持為MAXWORDSINASENTENCE的兩倍)。def get_sentence_from_sequences(sequences, tokenizer): return tokenizer.sequences_to_texts(sequences)# Testingdef translate_sentence(sentence): sentence = preprocess_sentence(sentence, True) sequence = english_tokenizer.texts_to_sequences([sentence])[0] sequence = tf.keras.preprocessing.sequence.pad_sequences([sequence], maxlen = MAX_WORDS_IN_A_SENTENCE, padding = 'post') encoder_input = tf.convert_to_tensor(sequence) encoder_sequence_output, encoder_hidden = encoder(encoder_input) decoder_input = tf.convert_to_tensor([hindi_word_index['sentencestart']]) decoder_hidden = encoder_hidden sentence_end_word_id = hindi_word_index['sentenceend'] hindi_sequence = [] for i in range(MAX_WORDS_IN_A_SENTENCE*2): predicted_words_probability, decoder_hidden, _ = decoder(decoder_input, decoder_hidden, encoder_sequence_output) # taking the word with maximum probability predicted_word_id = tf.argmax(predicted_words_probability[0]).numpy() hindi_sequence.append(predicted_word_id) # if the word 'sentenceend' is predicted, exit the loop if predicted_word_id == sentence_end_word_id: break decoder_input = tf.convert_to_tensor([predicted_word_id]) print(sentence) return get_sentence_from_sequences([hindi_sequence], hindi_tokenizer)# print translated sentenceprint(translate_sentence("Try multiple sentences here to check how good model is working!"))

結果

我們來看看結果。我運行的代碼與NVidia K80 GPU Kaggle,在上面的代碼。100個epoch,需要70分鐘的訓練。損失與epoch圖如下所示。

經過35個epoch的訓練後,我嘗試向我們的translate_sentence()函數中添加隨機的英語句子,結果有些令人滿意,但也有一定的問題。顯然,可以對超參數進行更多的優化。

但是在這裡,超參數並不是與實際翻譯有一些偏差的唯一原因。讓我們對更多可以實現以使我們的模型運行得更好的點進行小討論。

可能的改進

在實現我們的模型時,我們已經對編碼器、解碼器和注意力機制有了非常基本的了解。根據可用的時間和計算能力,以下是一些點,可以嘗試和測試,以知道如果他們工作時,實施良好:

使用堆疊GRU編碼器和解碼器

使用不同形式的注意力機制

使用不同的優化器

增加數據集的大小

採用Beam Search代替Greedy decoding

我們現在所使用的的解碼器被稱作貪婪解碼(Greedy decoding)。我們假設概率最高的單詞是最終預測的單詞,並輸入到下一個解碼器狀態。這種方法的問題是沒有辦法撤銷這個動作。Beam Search解碼從單詞概率分布中考慮最高k個可能的單詞,並檢查所有的可能性,我們會在明天的文章中介紹Beam Search。

作者:Ayush Jain

deephub翻譯組

相關焦點

  • 谷歌開放GNMT教程:如何使用TensorFlow構建自己的神經機器翻譯系統
    GitHub 連結:https://github.com/tensorflow/nmt機器翻譯,即跨語言間的自動翻譯,是機器學習社區最活躍的研究領域。在機器翻譯的眾多方法中,序列到序列(sequence-to-sequence,seq2seq)模型 [1, 2] 近期獲得巨大成功。
  • 基於seq2seq模型的中文糾錯任務
    深度學習近來在自然語言處理領域獲得了 廣泛運用,seq2seq 模型在諸多自然語言處理任務,如詞性標註、語義依存分析、 機器翻譯等,均取得了顯著的成績。本文首先對中文糾錯任務進行詳細的梳理, 包括錯誤的來源、目前的處理方法、相關的公開競賽、數據源等;第二,由於缺 少大規模公開的數據集,本文涉及顯示人工構造大規模糾錯數據集的算法;第三, 本文將深度學子中的 seq2seq 模型引入,處理中文糾錯任務,在基本的模型基礎 上引入 attention 機制(包括諸多變種)以及多任務學習的理念,嘗試多種組合, 並最終在構造數據集上 GLEU 評分達到了 0.75
  • 序列模型的實現細節
    本文總結了一些用 Tensorflow 實現序列模型的一些做法,並分析了效率和精度上的權衡。本文假設讀者已經有深度學習在自然語言處理應用上的基本知識,並用 Tensorflow 實現過一些序列模型。為了避免翻譯帶來的歧義,部分術語會直接使用英文表述(使用中文的話會在括號裡加上英文術語),所以中英混雜的文風難以避免。為了討論方便,以下先做一些術語的規定。
  • 分享TensorFlow Lite應用案例
    例如 seq2seq 模型中常用的 beam search。   補充的方式有兩種:   直接開發一個全新的 op;   在 TF Lite 之外的上層 api 中實現 (此時可能需要拆解模型)。   兩種方式各有優劣,具體的需要根據功能的複雜度和業務邏輯決定。
  • 推斷速度達seq2seq模型的100倍,谷歌開源文本生成新方法LaserTagger
    來源:機器之心作者:Eric Malmi等機器之心編譯參與:魔王、杜偉使用 seq2seq 模型解決文本生成任務伴隨著一些重大缺陷,谷歌研究人員提出新型文本生成方法 LaserTagger,旨在解決這些缺陷,提高文本生成的速度和效率。
  • TensorFlow 攜手 NVIDIA,使用 TensorRT 優化 TensorFlow Serving...
    目前,TensorFlow Serving 1.13 已實現對 TF-TRT 的支持,而不久後  TensorFlow 2.0 也將支持 TF-TRT 的實現。 TensorFlow 在官方博客中對這項成果進行了發布,雷鋒網 AI 科技評論編譯如下。
  • Tensorflow基礎教程15天之創建Tensor
    Tensor是Tensorflow中使用在計算圖中的最基本的數據單位,我們可以聲明Tensor為variable,或者為Tensor提供placeholer。但首先我們必須知道如何創建Tensor。zeros_similar = tf.zeros_like(constant_tsr)ones_similar = tf.ones_like(constant_tsr)注意:通過這種方法創建的Tensor,要首先初始化原Tensor,如果同時初始化系統會報錯。序列TensorTensorflow允許我們定義數組Tensor。
  • 資源| TensorFlow版本號升至1.0,正式版即將到來
    發布地址官網:https://www.tensorflow.org/versions/r1.0/GitHub:https://github.com/tensorflow/tensorflow/releases主要特性和提升TensorFlow Debugger (tfdbg):命令行接口和 API增加新的 python 3 docker 鏡像使
  • TensorFlow入門簡介,新手請看這裡!
    TensorFlow開源模型  TensorFlow團隊開源了大量模型,您可以在tensorflow/models repo中找到它們,其中發布的代碼不僅包括模型圖,還包括訓練模型,而且這些模型都是可以開箱即用的。此外您還可以通過「transfer learning(遷移學習)」的過程對一些模型進行優化。
  • 解析Transformer模型
    Softmax後的結果與Value向量相乘,得到最終結果MultiHead-Attention理解了自注意力機制後,我們可以很好的理解多頭注意力機制。簡單來說,多頭注意力其實就是合併了多個自注意力機制的結果
  • 如何使用TensorFlow Hub的ESRGAN模型來在安卓app中生成超分圖片
    注意在這裡我們使用了動態範圍量化(dynamic range quantization),並將輸入圖片的尺寸固定在50x50像素(我們已經將轉化後的模型上傳到 TFHub 上了): model = hub.load("https://tfhub.dev/captain-pool/esrgan-tf2/1") concrete_func = model.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY
  • TensorFlow 中文資源全集,學習路徑推薦
    /GitHub:https://github.com/tensorflow安裝教程中文安裝教程Mac安裝:http://www.cnblogs.com/tensorflownews/p/7298646.htmlubuntu 16.04 安裝 tensorflow-gpu:http://www.tensorflownews.com/2017/09/02/tensorflow-gpu-install-ubuntu
  • TensorFlow官方力推、GitHub爆款項目:用Attention模型自動生成...
    此處,我們使用一個基於Attention的模型。該模型能夠在生成字幕的時候,讓我們查看它在這個過程中所關注的是圖像的哪一部分。 tf.keras: https://www.tensorflow.org/guide/keras eager execution: https://www.tensorflow.org/guide/eager 這款筆記是一種
  • TensorFlow極速入門
    最後給出了在 tensorflow 中建立一個機器學習模型步驟,並用一個手寫數字識別的例子進行演示。1、tensorflow是什麼?tensorflow 是 google 開源的機器學習工具,在2015年11月其實現正式開源,開源協議Apache 2.0。
  • 用RNN和TensorFlow創作自己的《哈利波特》小說
    因此,我使用TensorFlow執行了一個簡單的文本生成模型來創作我自己的《哈利·波特》短篇小說。本文將介紹了我為實現它而編寫的完整代碼。各位巫師可以在這裡直接找到github代碼並自己運行它:https://github.com/amisha-jodhani/text-generator-harry-potter當你閒來無事時,它可以向無聊施一個驅逐咒。
  • TensorFlow極簡教程:創建、保存和恢復機器學習模型
    按照順序閱讀下列腳本:serial.pytensor.pybigdata.pySerial.py這個腳本的目的是說明 TensorFlow 模型的基本要點。這個腳本使你更容易理解模型是如何組合在一起的。我們使用 for 循環來定義數據與線之間的誤差。由於定義誤差的方式為循環,該腳本以序列化(串行)計算的方式運行。
  • 求解微分方程,用seq2seq就夠了,性能遠超 Mathematica、Matlab
    由於seq2seq模型的特點,作者所提方法能夠對同一個公式得出不止一個的運算結果,例如如下的微分方程該模型能夠反饋這麼多的結果:可以驗證一下,這些結果都是正確的,至多差一個常數 c。我們來看下這樣美好的結果,作者是如何做到的。(其實很簡單!)
  • 綜述科普|染色質調控區域的研究:對CHIP-seq和ATAC-seq發展的深入思考
    2.用於檢測組蛋白修飾的抗體對於許多表觀遺傳染色質測序技術是必不可少的:例如,在CHIP-seq中,需要對組蛋白和轉錄因子進行抗體特異性檢測。3.組蛋白修飾的異染色質形成和擴散機制以及組蛋白修飾的「記憶」和「消退」的研究還很少。