# 如何開發一種編碼器 - 解碼器模型,注重Keras中的序列到序列預測
> 原文: [https://machinelearningmastery.com/encoder-decoder-attention-sequence-to-sequence-prediction-keras/](https://machinelearningmastery.com/encoder-decoder-attention-sequence-to-sequence-prediction-keras/)
用于循環神經網絡的編碼器 - 解碼器架構被證明在諸如機器翻譯和字幕生成之類的自然語言處理領域中的大量序列到序列預測問題上是強大的。
注意力是一種解決編碼器 - 解碼器架構在長序列上的限制的機制,并且通常加速學習并且提升模型的技能而沒有序列來排序預測問題。
在本教程中,您將了解如何使用Keras在Python中開發一個編碼器 - 解碼器循環神經網絡。
完成本教程后,您將了解:
* 如何設計一個小的可配置問題來評估編碼器 - 解碼器循環神經網絡有無注意。
* 如何設計和評估編碼器 - 解碼器網絡,有和沒有注意序列預測問題。
* 如何有力地比較編碼器 - 解碼器網絡的表現有沒有注意。
讓我們開始吧。

如何開發一個編碼器 - 解碼器模型,注意Keras中的序列到序列預測
照片由 [Angela和Andrew](https://www.flickr.com/photos/150568953@N07/34585914155/) ,保留一些權利。
## 教程概述
本教程分為6個部分;他們是:
1. 注意編碼器解碼器
2. 注意力的測試問題
3. 編碼器 - 解碼器沒有注意
4. 自定義Keras注意層
5. 注意編碼器解碼器
6. 模型比較
### Python環境
本教程假定您已安裝Python 3 SciPy環境。
您必須安裝帶有TensorFlow或Theano后端的Keras(2.0或更高版本)。
本教程還假設您安裝了scikit-learn,Pandas,NumPy和Matplotlib。
如果您需要有關環境的幫助,請參閱此帖子:
* [如何使用Anaconda設置用于機器學習和深度學習的Python環境](https://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/)
## 注意編碼器解碼器
用于循環神經網絡的編碼器 - 解碼器模型是用于序列到序列預測問題的架構。
它由兩個子模型組成,顧名思義:
* **編碼器**:編碼器負責逐步執行輸入時間步長并將整個序列編碼為稱為上下文向量的固定長度向量。
* **解碼器**:解碼器負責在從上下文向量讀取時逐步執行輸出時間步長。
該體系結構的問題在于長輸入或輸出序列的表現差。原因被認為是由于編碼器使用的固定大小的內部表示。
注意是解決此限制的體系結構的擴展。它的工作原理是首先提供從編碼器到解碼器的更豐富的上下文和學習機制,其中解碼器可以在預測輸出序列中的每個時間步長時學習在更豐富的編碼中注意的位置。
有關編碼器 - 解碼器架構的更多關注,請參閱帖子:
* [長期短期記憶循環神經網絡](https://machinelearningmastery.com/attention-long-short-term-memory-recurrent-neural-networks/)的注意事項
* [編碼器 - 解碼器循環神經網絡中的注意事項如何工作](https://machinelearningmastery.com/how-does-attention-work-in-encoder-decoder-recurrent-neural-networks/)
## 注意力的測試問題
在我們開發注意力模型之前,我們將首先定義一個可設計的可擴展測試問題,我們可以用它來確定注意力是否提供任何好處。
在這個問題中,我們將生成隨機整數序列作為輸入和匹配輸出序列,該輸出序列由輸入序列中的整數子集組成。
例如,輸入序列可能是[1,6,2,7,3],預期的輸出序列可能是序列[1,6]中的前兩個隨機整數。
我們將定義問題,使輸入和輸出序列長度相同,并根據需要用“0”值填充輸出序列。
首先,我們需要一個函數來生成隨機整數序列。我們將使用Python [randint()](https://docs.python.org/3/library/random.html)函數生成0和最大值之間的隨機整數,并使用此范圍作為問題的基數(例如,要素數或難度軸)。
下面的函數 _generate_sequence()_將生成一個固定長度和指定基數的隨機整數序列。
```py
from random import randint
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# generate random sequence
sequence = generate_sequence(5, 50)
print(sequence)
```
運行此示例將生成一個包含5個時間步長的序列,其中序列中的每個值都是0到49之間的隨機整數。
```py
[43, 3, 28, 34, 33]
```
接下來,我們需要一個函數[將一個熱編碼](https://machinelearningmastery.com/how-to-one-hot-encode-sequence-data-in-python/)的離散整數值轉換成二進制向量。
如果使用50的基數,則每個整數將由0個值的50個元素向量和指定整數值的索引中的1表示。
下面的 _one_hot_encode()_函數將對給定的整數序列進行熱編碼。
```py
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
```
我們還需要能夠解碼編碼序列。需要將預測從模型或編碼的預期序列轉換回我們可以讀取和評估的整數序列。
下面的 _one_hot_decode()_函數將一個熱編碼序列解碼回整數序列。
```py
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
```
我們可以在下面的例子中測試這些操作。
```py
from random import randint
from numpy import array
from numpy import argmax
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# generate random sequence
sequence = generate_sequence(5, 50)
print(sequence)
# one hot encode
encoded = one_hot_encode(sequence, 50)
print(encoded)
# decode
decoded = one_hot_decode(encoded)
print(decoded)
```
首先運行該示例打印隨機生成的序列,然后打印一個熱編碼版本,最后再打印解碼序列。
```py
[3, 18, 32, 11, 36]
[[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]]
[3, 18, 32, 11, 36]
```
最后,我們需要一個能夠創建輸入和輸出序列對的函數來訓練和評估模型。
下面命名為 _get_pair()_的函數將返回一個輸入和輸出序列對,給定指定的輸入長度,輸出長度和基數。輸入和輸出序列的長度和輸入序列的長度相同,但輸出序列將作為輸入序列的第一個 _n_ 字符,并用零值填充到所需長度。
然后對整數序列進行編碼,然后重新成形為循環神經網絡所需的3D格式,其尺寸為:_樣本_,_時間步長_和_特征_。在這種情況下,樣本總是1,因為我們只生成一個輸入 - 輸出對,時間步長是輸入序列長度,特征是每個時間步長的基數。
```py
# prepare data for the LSTM
def get_pair(n_in, n_out, n_unique):
# generate random sequence
sequence_in = generate_sequence(n_in, n_unique)
sequence_out = sequence_in[:n_out] + [0 for _ in range(n_in-n_out)]
# one hot encode
X = one_hot_encode(sequence_in, n_unique)
y = one_hot_encode(sequence_out, n_unique)
# reshape as 3D
X = X.reshape((1, X.shape[0], X.shape[1]))
y = y.reshape((1, y.shape[0], y.shape[1]))
return X,y
```
我們可以將它們放在一起并演示數據準備代碼。
```py
from random import randint
from numpy import array
from numpy import argmax
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# prepare data for the LSTM
def get_pair(n_in, n_out, n_unique):
# generate random sequence
sequence_in = generate_sequence(n_in, n_unique)
sequence_out = sequence_in[:n_out] + [0 for _ in range(n_in-n_out)]
# one hot encode
X = one_hot_encode(sequence_in, n_unique)
y = one_hot_encode(sequence_out, n_unique)
# reshape as 3D
X = X.reshape((1, X.shape[0], X.shape[1]))
y = y.reshape((1, y.shape[0], y.shape[1]))
return X,y
# generate random sequence
X, y = get_pair(5, 2, 50)
print(X.shape, y.shape)
print('X=%s, y=%s' % (one_hot_decode(X[0]), one_hot_decode(y[0])))
```
運行該示例生成單個輸入 - 輸出對并打印兩個陣列的形狀。
然后以解碼的形式打印生成的對,其中我們可以看到序列的前兩個整數在輸出序列中被再現,隨后是零值的填充。
```py
(1, 5, 50) (1, 5, 50)
X=[12, 20, 36, 40, 12], y=[12, 20, 0, 0, 0]
```
## 編碼器 - 解碼器沒有注意
在本節中,我們將在沒有注意的情況下使用編碼器 - 解碼器模型開發關于問題表現的基線。
我們將在5個時間步的輸入和輸出序列中修復問題定義,輸出序列中輸入序列的前2個元素和基數為50。
```py
# configure problem
n_features = 50
n_timesteps_in = 5
n_timesteps_out = 2
```
我們可以通過從編碼器LSTM模型獲得輸出,在Keras中開發一個簡單的編碼器 - 解碼器模型,對輸出序列中的時間步長重復n次,然后使用解碼器來預測輸出序列。
有關如何在Keras中定義編碼器 - 解碼器架構的更多詳細信息,請參閱帖子:
* [編碼器 - 解碼器長短期存儲器網絡](https://machinelearningmastery.com/encoder-decoder-long-short-term-memory-networks/)
我們將使用相同數量的單位配置編碼器和解碼器,在本例中為150.我們將使用梯度下降的有效Adam實現并優化分類交叉熵損失函數,因為該問題在技術上是一個多類別分類問題。
模型的配置是在經過一些試驗和錯誤之后找到的,并未進行優化。
下面列出了Keras中編碼器 - 解碼器架構的代碼。
```py
# define model
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(150, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
```
我們將在5,000個隨機輸入 - 輸出對的整數序列上訓練模型。
```py
# train LSTM
for epoch in range(5000):
# generate new random sequence
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
# fit model for one epoch on this sequence
model.fit(X, y, epochs=1, verbose=2)
```
一旦經過訓練,我們將在100個新的隨機生成的整數序列上評估模型,并且只在整個輸出序列與預期值匹配時才標記預測正確。
```py
# evaluate LSTM
total, correct = 100, 0
for _ in range(total):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
if array_equal(one_hot_decode(y[0]), one_hot_decode(yhat[0])):
correct += 1
print('Accuracy: %.2f%%' % (float(correct)/float(total)*100.0))
```
最后,我們將打印10個預期輸出序列和模型預測序列的例子。
將所有這些放在一起,下面列出了完整的示例。
```py
from random import randint
from numpy import array
from numpy import argmax
from numpy import array_equal
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import TimeDistributed
from keras.layers import RepeatVector
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# prepare data for the LSTM
def get_pair(n_in, n_out, cardinality):
# generate random sequence
sequence_in = generate_sequence(n_in, cardinality)
sequence_out = sequence_in[:n_out] + [0 for _ in range(n_in-n_out)]
# one hot encode
X = one_hot_encode(sequence_in, cardinality)
y = one_hot_encode(sequence_out, cardinality)
# reshape as 3D
X = X.reshape((1, X.shape[0], X.shape[1]))
y = y.reshape((1, y.shape[0], y.shape[1]))
return X,y
# configure problem
n_features = 50
n_timesteps_in = 5
n_timesteps_out = 2
# define model
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(150, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
# train LSTM
for epoch in range(5000):
# generate new random sequence
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
# fit model for one epoch on this sequence
model.fit(X, y, epochs=1, verbose=2)
# evaluate LSTM
total, correct = 100, 0
for _ in range(total):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
if array_equal(one_hot_decode(y[0]), one_hot_decode(yhat[0])):
correct += 1
print('Accuracy: %.2f%%' % (float(correct)/float(total)*100.0))
# spot check some examples
for _ in range(10):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
print('Expected:', one_hot_decode(y[0]), 'Predicted', one_hot_decode(yhat[0]))
```
運行此示例不會花費很長時間,可能需要幾分鐘的CPU,不需要GPU。
據報道該模型的準確率略低于20%。鑒于[神經網絡的隨機性](https://machinelearningmastery.com/randomness-in-machine-learning/),您的結果會有所不同;考慮運行幾次示例并取平均值。
```py
Accuracy: 19.00%
```
我們可以從樣本輸出中看到,模型確實在輸出序列中得到一個數字,對于大多數或所有情況都是正確的,并且只與第二個數字斗爭。正確預測所有零填充值。
```py
Expected: [47, 0, 0, 0, 0] Predicted [47, 47, 0, 0, 0]
Expected: [43, 31, 0, 0, 0] Predicted [43, 31, 0, 0, 0]
Expected: [14, 22, 0, 0, 0] Predicted [14, 14, 0, 0, 0]
Expected: [39, 31, 0, 0, 0] Predicted [39, 39, 0, 0, 0]
Expected: [6, 4, 0, 0, 0] Predicted [6, 4, 0, 0, 0]
Expected: [47, 0, 0, 0, 0] Predicted [47, 47, 0, 0, 0]
Expected: [39, 33, 0, 0, 0] Predicted [39, 39, 0, 0, 0]
Expected: [23, 2, 0, 0, 0] Predicted [23, 23, 0, 0, 0]
Expected: [19, 28, 0, 0, 0] Predicted [19, 3, 0, 0, 0]
Expected: [32, 33, 0, 0, 0] Predicted [32, 32, 0, 0, 0]
```
## 自定義Keras注意層
現在我們需要關注編碼器 - 解碼器模型。
在撰寫本文時,Keras沒有內置于庫中的注意力,但很快就會 [](https://github.com/fchollet/keras/pull/7980)。
在Keras正式提供關注之前,我們可以開發自己的實現或使用現有的第三方實現。
為了加快速度,讓我們使用現有的第三方實現。
[Zafarali Ahmed](http://www.zafarali.me/) [Datalogue](https://www.datalogue.io/) 的實習生為Keras開發了一個[自定義層](https://keras.io/layers/writing-your-own-keras-layers/),提供了關注支持,在一篇名為“[如何可視化您的復發的帖子中提出2017年Keras](https://medium.com/datalogue/attention-in-keras-1892773a4f22) 中關注的神經網絡和GitHub項目稱為“ [keras-attention](https://github.com/datalogue/keras-attention) ”。
自定義注意層稱為 _AttentionDecoder_ ,可在GitHub項目的 [custom_recurrents.py](https://github.com/datalogue/keras-attention/blob/master/models/custom_recurrents.py) 文件中找到。我們可以在項目的 [GNU Affero通用公共許可證v3.0許可證](https://github.com/datalogue/keras-attention/blob/master/LICENSE)下重用此代碼。
下面列出了自定義層的副本以確保完整性。將其復制并粘貼到當前工作目錄中名為“ _attention_decoder.py_ ”的新單獨文件中。
```py
import tensorflow as tf
from keras import backend as K
from keras import regularizers, constraints, initializers, activations
from keras.layers.recurrent import Recurrent, _time_distributed_dense
from keras.engine import InputSpec
tfPrint = lambda d, T: tf.Print(input_=T, data=[T, tf.shape(T)], message=d)
class AttentionDecoder(Recurrent):
def __init__(self, units, output_dim,
activation='tanh',
return_probabilities=False,
name='AttentionDecoder',
kernel_initializer='glorot_uniform',
recurrent_initializer='orthogonal',
bias_initializer='zeros',
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
**kwargs):
"""
Implements an AttentionDecoder that takes in a sequence encoded by an
encoder and outputs the decoded states
:param units: dimension of the hidden state and the attention matrices
:param output_dim: the number of labels in the output space
references:
Bahdanau, Dzmitry, Kyunghyun Cho, and Yoshua Bengio.
"Neural machine translation by jointly learning to align and translate."
arXiv preprint arXiv:1409.0473 (2014).
"""
self.units = units
self.output_dim = output_dim
self.return_probabilities = return_probabilities
self.activation = activations.get(activation)
self.kernel_initializer = initializers.get(kernel_initializer)
self.recurrent_initializer = initializers.get(recurrent_initializer)
self.bias_initializer = initializers.get(bias_initializer)
self.kernel_regularizer = regularizers.get(kernel_regularizer)
self.recurrent_regularizer = regularizers.get(kernel_regularizer)
self.bias_regularizer = regularizers.get(bias_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
self.kernel_constraint = constraints.get(kernel_constraint)
self.recurrent_constraint = constraints.get(kernel_constraint)
self.bias_constraint = constraints.get(bias_constraint)
super(AttentionDecoder, self).__init__(**kwargs)
self.name = name
self.return_sequences = True # must return sequences
def build(self, input_shape):
"""
See Appendix 2 of Bahdanau 2014, arXiv:1409.0473
for model details that correspond to the matrices here.
"""
self.batch_size, self.timesteps, self.input_dim = input_shape
if self.stateful:
super(AttentionDecoder, self).reset_states()
self.states = [None, None] # y, s
"""
Matrices for creating the context vector
"""
self.V_a = self.add_weight(shape=(self.units,),
name='V_a',
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint)
self.W_a = self.add_weight(shape=(self.units, self.units),
name='W_a',
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint)
self.U_a = self.add_weight(shape=(self.input_dim, self.units),
name='U_a',
initializer=self.kernel_initializer,
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint)
self.b_a = self.add_weight(shape=(self.units,),
name='b_a',
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
"""
Matrices for the r (reset) gate
"""
self.C_r = self.add_weight(shape=(self.input_dim, self.units),
name='C_r',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.U_r = self.add_weight(shape=(self.units, self.units),
name='U_r',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.W_r = self.add_weight(shape=(self.output_dim, self.units),
name='W_r',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.b_r = self.add_weight(shape=(self.units, ),
name='b_r',
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
"""
Matrices for the z (update) gate
"""
self.C_z = self.add_weight(shape=(self.input_dim, self.units),
name='C_z',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.U_z = self.add_weight(shape=(self.units, self.units),
name='U_z',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.W_z = self.add_weight(shape=(self.output_dim, self.units),
name='W_z',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.b_z = self.add_weight(shape=(self.units, ),
name='b_z',
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
"""
Matrices for the proposal
"""
self.C_p = self.add_weight(shape=(self.input_dim, self.units),
name='C_p',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.U_p = self.add_weight(shape=(self.units, self.units),
name='U_p',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.W_p = self.add_weight(shape=(self.output_dim, self.units),
name='W_p',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.b_p = self.add_weight(shape=(self.units, ),
name='b_p',
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
"""
Matrices for making the final prediction vector
"""
self.C_o = self.add_weight(shape=(self.input_dim, self.output_dim),
name='C_o',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.U_o = self.add_weight(shape=(self.units, self.output_dim),
name='U_o',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.W_o = self.add_weight(shape=(self.output_dim, self.output_dim),
name='W_o',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.b_o = self.add_weight(shape=(self.output_dim, ),
name='b_o',
initializer=self.bias_initializer,
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
# For creating the initial state:
self.W_s = self.add_weight(shape=(self.input_dim, self.units),
name='W_s',
initializer=self.recurrent_initializer,
regularizer=self.recurrent_regularizer,
constraint=self.recurrent_constraint)
self.input_spec = [
InputSpec(shape=(self.batch_size, self.timesteps, self.input_dim))]
self.built = True
def call(self, x):
# store the whole sequence so we can "attend" to it at each timestep
self.x_seq = x
# apply the a dense layer over the time dimension of the sequence
# do it here because it doesn't depend on any previous steps
# thefore we can save computation time:
self._uxpb = _time_distributed_dense(self.x_seq, self.U_a, b=self.b_a,
input_dim=self.input_dim,
timesteps=self.timesteps,
output_dim=self.units)
return super(AttentionDecoder, self).call(x)
def get_initial_state(self, inputs):
# apply the matrix on the first time step to get the initial s0.
s0 = activations.tanh(K.dot(inputs[:, 0], self.W_s))
# from keras.layers.recurrent to initialize a vector of (batchsize,
# output_dim)
y0 = K.zeros_like(inputs) # (samples, timesteps, input_dims)
y0 = K.sum(y0, axis=(1, 2)) # (samples, )
y0 = K.expand_dims(y0) # (samples, 1)
y0 = K.tile(y0, [1, self.output_dim])
return [y0, s0]
def step(self, x, states):
ytm, stm = states
# repeat the hidden state to the length of the sequence
_stm = K.repeat(stm, self.timesteps)
# now multiplty the weight matrix with the repeated hidden state
_Wxstm = K.dot(_stm, self.W_a)
# calculate the attention probabilities
# this relates how much other timesteps contributed to this one.
et = K.dot(activations.tanh(_Wxstm + self._uxpb),
K.expand_dims(self.V_a))
at = K.exp(et)
at_sum = K.sum(at, axis=1)
at_sum_repeated = K.repeat(at_sum, self.timesteps)
at /= at_sum_repeated # vector of size (batchsize, timesteps, 1)
# calculate the context vector
context = K.squeeze(K.batch_dot(at, self.x_seq, axes=1), axis=1)
# ~~~> calculate new hidden state
# first calculate the "r" gate:
rt = activations.sigmoid(
K.dot(ytm, self.W_r)
+ K.dot(stm, self.U_r)
+ K.dot(context, self.C_r)
+ self.b_r)
# now calculate the "z" gate
zt = activations.sigmoid(
K.dot(ytm, self.W_z)
+ K.dot(stm, self.U_z)
+ K.dot(context, self.C_z)
+ self.b_z)
# calculate the proposal hidden state:
s_tp = activations.tanh(
K.dot(ytm, self.W_p)
+ K.dot((rt * stm), self.U_p)
+ K.dot(context, self.C_p)
+ self.b_p)
# new hidden state:
st = (1-zt)*stm + zt * s_tp
yt = activations.softmax(
K.dot(ytm, self.W_o)
+ K.dot(stm, self.U_o)
+ K.dot(context, self.C_o)
+ self.b_o)
if self.return_probabilities:
return at, [yt, st]
else:
return yt, [yt, st]
def compute_output_shape(self, input_shape):
"""
For Keras internal compatability checking
"""
if self.return_probabilities:
return (None, self.timesteps, self.timesteps)
else:
return (None, self.timesteps, self.output_dim)
def get_config(self):
"""
For rebuilding models on load time.
"""
config = {
'output_dim': self.output_dim,
'units': self.units,
'return_probabilities': self.return_probabilities
}
base_config = super(AttentionDecoder, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
```
我們可以通過以下方式導入項目中來使用此自定義層:
```py
from attention_decoder import AttentionDecoder
```
如Bahdanau等人所述,該層實現了關注。在他們的論文“[神經機器翻譯中通過聯合學習來對齊和翻譯](https://arxiv.org/abs/1409.0473)。”
該代碼在原始帖子中得到了很好的解釋,并與LSTM和注意力方程相關聯。
該實現的限制是它必須輸出與輸入序列長度相同的序列,編碼器 - 解碼器架構被設計為克服的特定限制。
重要的是,新層管理由第二LSTM執行的重復解碼,以及由編碼器 - 解碼器模型中的密集輸出層執行的模型的softmax輸出,而沒有注意。這極大地簡化了模型的代碼。
值得注意的是,自定義層建立在Keras的 [Recurrent](https://github.com/fchollet/keras/blob/master/keras/legacy/layers.py#L762) 層上,在編寫本文時,它被標記為遺留代碼,并且可能會在某個時候從項目中刪除。
## 編碼器解碼器注意
現在我們已經可以使用我們的注意力實現,我們可以開發一個編碼器 - 解碼器模型,注意我們設計的序列預測問題。
具有關注層的模型定義如下。我們可以看到該層處理編碼器 - 解碼器模型本身的一些機制,使得定義模型更簡單。
```py
# define model
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features), return_sequences=True))
model.add(AttentionDecoder(150, n_features))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
```
而已。示例的其余部分是相同的。
下面列出了完整的示例。
```py
from random import randint
from numpy import array
from numpy import argmax
from numpy import array_equal
from keras.models import Sequential
from keras.layers import LSTM
from attention_decoder import AttentionDecoder
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# prepare data for the LSTM
def get_pair(n_in, n_out, cardinality):
# generate random sequence
sequence_in = generate_sequence(n_in, cardinality)
sequence_out = sequence_in[:n_out] + [0 for _ in range(n_in-n_out)]
# one hot encode
X = one_hot_encode(sequence_in, cardinality)
y = one_hot_encode(sequence_out, cardinality)
# reshape as 3D
X = X.reshape((1, X.shape[0], X.shape[1]))
y = y.reshape((1, y.shape[0], y.shape[1]))
return X,y
# configure problem
n_features = 50
n_timesteps_in = 5
n_timesteps_out = 2
# define model
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features), return_sequences=True))
model.add(AttentionDecoder(150, n_features))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
# train LSTM
for epoch in range(5000):
# generate new random sequence
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
# fit model for one epoch on this sequence
model.fit(X, y, epochs=1, verbose=2)
# evaluate LSTM
total, correct = 100, 0
for _ in range(total):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
if array_equal(one_hot_decode(y[0]), one_hot_decode(yhat[0])):
correct += 1
print('Accuracy: %.2f%%' % (float(correct)/float(total)*100.0))
# spot check some examples
for _ in range(10):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
print('Expected:', one_hot_decode(y[0]), 'Predicted', one_hot_decode(yhat[0]))
```
運行該示例在100個隨機生成的輸入 - 輸出對上打印模型的技能。在相同的資源和相同數量的訓練下,關注的模型表現得更好。
鑒于神經網絡的隨機性,您的結果可能會有所不同。嘗試運行幾次示例。
```py
Accuracy: 95.00%
```
通過抽查一些樣本輸出和預測序列,我們可以看到很少的錯誤,即使在前兩個元素中存在零值的情況下也是如此。
```py
Expected: [48, 47, 0, 0, 0] Predicted [48, 47, 0, 0, 0]
Expected: [7, 46, 0, 0, 0] Predicted [7, 46, 0, 0, 0]
Expected: [32, 30, 0, 0, 0] Predicted [32, 2, 0, 0, 0]
Expected: [3, 25, 0, 0, 0] Predicted [3, 25, 0, 0, 0]
Expected: [45, 4, 0, 0, 0] Predicted [45, 4, 0, 0, 0]
Expected: [49, 9, 0, 0, 0] Predicted [49, 9, 0, 0, 0]
Expected: [22, 23, 0, 0, 0] Predicted [22, 23, 0, 0, 0]
Expected: [29, 36, 0, 0, 0] Predicted [29, 36, 0, 0, 0]
Expected: [0, 29, 0, 0, 0] Predicted [0, 29, 0, 0, 0]
Expected: [11, 26, 0, 0, 0] Predicted [11, 26, 0, 0, 0]
```
## 模型比較
盡管我們從模型中獲得了更好的結果,但是每個模型的單次運行都會報告結果。
在這種情況下,我們通過多次重復評估每個模型并報告這些運行的平均表現來尋求更穩健的發現。有關評估神經網絡模型的這種強大方法的更多信息,請參閱帖子:
* [如何評估深度學習模型的技巧](https://machinelearningmastery.com/evaluate-skill-deep-learning-models/)
我們可以定義一個函數來創建每種類型的模型,如下所示。
```py
# define the encoder-decoder model
def baseline_model(n_timesteps_in, n_features):
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(150, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
return model
# define the encoder-decoder with attention model
def attention_model(n_timesteps_in, n_features):
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features), return_sequences=True))
model.add(AttentionDecoder(150, n_features))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
return model
```
然后,我們可以定義一個函數來擬合和評估擬合模型的準確性并返回準確度分數。
```py
# train and evaluate a model, return accuracy
def train_evaluate_model(model, n_timesteps_in, n_timesteps_out, n_features):
# train LSTM
for epoch in range(5000):
# generate new random sequence
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
# fit model for one epoch on this sequence
model.fit(X, y, epochs=1, verbose=0)
# evaluate LSTM
total, correct = 100, 0
for _ in range(total):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
if array_equal(one_hot_decode(y[0]), one_hot_decode(yhat[0])):
correct += 1
return float(correct)/float(total)*100.0
```
綜上所述,我們可以多次重復創建,訓練和評估每種類型的模型,并報告重復的平均準確度。為了減少運行時間,我們將重復每次模型評估10次,但如果您有資源,則可以將此值增加到30或100次。
The complete example is listed below.
```py
from random import randint
from numpy import array
from numpy import argmax
from numpy import array_equal
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import TimeDistributed
from keras.layers import RepeatVector
from attention_decoder import AttentionDecoder
# generate a sequence of random integers
def generate_sequence(length, n_unique):
return [randint(0, n_unique-1) for _ in range(length)]
# one hot encode sequence
def one_hot_encode(sequence, n_unique):
encoding = list()
for value in sequence:
vector = [0 for _ in range(n_unique)]
vector[value] = 1
encoding.append(vector)
return array(encoding)
# decode a one hot encoded string
def one_hot_decode(encoded_seq):
return [argmax(vector) for vector in encoded_seq]
# prepare data for the LSTM
def get_pair(n_in, n_out, cardinality):
# generate random sequence
sequence_in = generate_sequence(n_in, cardinality)
sequence_out = sequence_in[:n_out] + [0 for _ in range(n_in-n_out)]
# one hot encode
X = one_hot_encode(sequence_in, cardinality)
y = one_hot_encode(sequence_out, cardinality)
# reshape as 3D
X = X.reshape((1, X.shape[0], X.shape[1]))
y = y.reshape((1, y.shape[0], y.shape[1]))
return X,y
# define the encoder-decoder model
def baseline_model(n_timesteps_in, n_features):
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features)))
model.add(RepeatVector(n_timesteps_in))
model.add(LSTM(150, return_sequences=True))
model.add(TimeDistributed(Dense(n_features, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
return model
# define the encoder-decoder with attention model
def attention_model(n_timesteps_in, n_features):
model = Sequential()
model.add(LSTM(150, input_shape=(n_timesteps_in, n_features), return_sequences=True))
model.add(AttentionDecoder(150, n_features))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
return model
# train and evaluate a model, return accuracy
def train_evaluate_model(model, n_timesteps_in, n_timesteps_out, n_features):
# train LSTM
for epoch in range(5000):
# generate new random sequence
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
# fit model for one epoch on this sequence
model.fit(X, y, epochs=1, verbose=0)
# evaluate LSTM
total, correct = 100, 0
for _ in range(total):
X,y = get_pair(n_timesteps_in, n_timesteps_out, n_features)
yhat = model.predict(X, verbose=0)
if array_equal(one_hot_decode(y[0]), one_hot_decode(yhat[0])):
correct += 1
return float(correct)/float(total)*100.0
# configure problem
n_features = 50
n_timesteps_in = 5
n_timesteps_out = 2
n_repeats = 10
# evaluate encoder-decoder model
print('Encoder-Decoder Model')
results = list()
for _ in range(n_repeats):
model = baseline_model(n_timesteps_in, n_features)
accuracy = train_evaluate_model(model, n_timesteps_in, n_timesteps_out, n_features)
results.append(accuracy)
print(accuracy)
print('Mean Accuracy: %.2f%%' % (sum(results)/float(n_repeats)))
# evaluate encoder-decoder with attention model
print('Encoder-Decoder With Attention Model')
results = list()
for _ in range(n_repeats):
model = attention_model(n_timesteps_in, n_features)
accuracy = train_evaluate_model(model, n_timesteps_in, n_timesteps_out, n_features)
results.append(accuracy)
print(accuracy)
print('Mean Accuracy: %.2f%%' % (sum(results)/float(n_repeats)))
```
運行此示例將打印每個模型重復的準確性,以便您了解運行的進度。
```py
Encoder-Decoder Model
20.0
23.0
23.0
18.0
28.000000000000004
28.999999999999996
23.0
26.0
21.0
20.0
Mean Accuracy: 23.10%
Encoder-Decoder With Attention Model
98.0
91.0
94.0
93.0
96.0
99.0
97.0
94.0
99.0
96.0
Mean Accuracy: 95.70%
```
我們可以看到,即使平均超過10次運行,注意模型仍然表現出比沒有注意的編碼器 - 解碼器模型更好的表現,23.10%對95.70%。
此評估的一個很好的擴展是捕獲每個模型的每個時期的模型損失,取平均值,并比較損失如何隨著時間的推移而變化,無論是否受到關注。我希望這種追蹤能夠比非注意力模型更快,更快地顯示出更好的技能,進一步突出了這種方法的好處。
## 進一步閱讀
如果您希望深入了解,本節將提供有關該主題的更多資源。
* [長期短期記憶循環神經網絡](https://machinelearningmastery.com/attention-long-short-term-memory-recurrent-neural-networks/)的注意事項
* [編碼器 - 解碼器循環神經網絡中的注意事項如何工作](https://machinelearningmastery.com/how-does-attention-work-in-encoder-decoder-recurrent-neural-networks/)
* [編碼器 - 解碼器長短期存儲器網絡](https://machinelearningmastery.com/encoder-decoder-long-short-term-memory-networks/)
* [如何評估深度學習模型的技巧](https://machinelearningmastery.com/evaluate-skill-deep-learning-models/)
* [如何在Keras中注意循環神經網絡](https://medium.com/datalogue/attention-in-keras-1892773a4f22),2017。
* [keras-attention GitHub Project](https://github.com/datalogue/keras-attention)
* [通過共同學習對齊和翻譯的神經機器翻譯](https://github.com/datalogue/keras-attention),2015。
## 摘要
在本教程中,您了解了如何使用Keras在Python中開發編碼器 - 解碼器循環神經網絡。
具體來說,你學到了:
* 如何設計一個小的可配置問題來評估編碼器 - 解碼器循環神經網絡有無注意。
* 如何設計和評估編碼器 - 解碼器網絡,有和沒有注意序列預測問題。
* 如何有力地比較編碼器 - 解碼器網絡的表現有沒有注意。
你有任何問題嗎?
在下面的評論中提出您的問題,我會盡力回答。
- Machine Learning Mastery 應用機器學習教程
- 5競爭機器學習的好處
- 過度擬合的簡單直覺,或者為什么測試訓練數據是一個壞主意
- 特征選擇簡介
- 應用機器學習作為一個搜索問題的溫和介紹
- 為什么應用機器學習很難
- 為什么我的結果不如我想的那么好?你可能過度擬合了
- 用ROC曲線評估和比較分類器表現
- BigML評論:發現本機學習即服務平臺的聰明功能
- BigML教程:開發您的第一個決策樹并進行預測
- 構建生產機器學習基礎設施
- 分類準確性不夠:可以使用更多表現測量
- 一種預測模型的巧妙應用
- 機器學習項目中常見的陷阱
- 數據清理:將凌亂的數據轉換為整潔的數據
- 機器學習中的數據泄漏
- 數據,學習和建模
- 數據管理至關重要以及為什么需要認真對待它
- 將預測模型部署到生產中
- 參數和超參數之間有什么區別?
- 測試和驗證數據集之間有什么區別?
- 發現特征工程,如何設計特征以及如何獲得它
- 如何開始使用Kaggle
- 超越預測
- 如何在評估機器學習算法時選擇正確的測試選項
- 如何定義機器學習問題
- 如何評估機器學習算法
- 如何獲得基線結果及其重要性
- 如何充分利用機器學習數據
- 如何識別數據中的異常值
- 如何提高機器學習效果
- 如何在競爭機器學習中踢屁股
- 如何知道您的機器學習模型是否具有良好的表現
- 如何布局和管理您的機器學習項目
- 如何為機器學習準備數據
- 如何減少最終機器學習模型中的方差
- 如何使用機器學習結果
- 如何解決像數據科學家這樣的問題
- 通過數據預處理提高模型精度
- 處理機器學習的大數據文件的7種方法
- 建立機器學習系統的經驗教訓
- 如何使用機器學習清單可靠地獲得準確的預測(即使您是初學者)
- 機器學習模型運行期間要做什么
- 機器學習表現改進備忘單
- 來自世界級從業者的機器學習技巧:Phil Brierley
- 模型預測精度與機器學習中的解釋
- 競爭機器學習的模型選擇技巧
- 機器學習需要多少訓練數據?
- 如何系統地規劃和運行機器學習實驗
- 應用機器學習過程
- 默認情況下可重現的機器學習結果
- 10個實踐應用機器學習的標準數據集
- 簡單的三步法到最佳機器學習算法
- 打擊機器學習數據集中不平衡類的8種策略
- 模型表現不匹配問題(以及如何處理)
- 黑箱機器學習的誘惑陷阱
- 如何培養最終的機器學習模型
- 使用探索性數據分析了解您的問題并獲得更好的結果
- 什么是數據挖掘和KDD
- 為什么One-Hot在機器學習中編碼數據?
- 為什么你應該在你的機器學習問題上進行抽樣檢查算法
- 所以,你正在研究機器學習問題......
- Machine Learning Mastery Keras 深度學習教程
- Keras 中神經網絡模型的 5 步生命周期
- 在 Python 迷你課程中應用深度學習
- Keras 深度學習庫的二元分類教程
- 如何用 Keras 構建多層感知器神經網絡模型
- 如何在 Keras 中檢查深度學習模型
- 10 個用于 Amazon Web Services 深度學習的命令行秘籍
- 機器學習卷積神經網絡的速成課程
- 如何在 Python 中使用 Keras 進行深度學習的度量
- 深度學習書籍
- 深度學習課程
- 你所知道的深度學習是一種謊言
- 如何設置 Amazon AWS EC2 GPU 以訓練 Keras 深度學習模型(分步)
- 神經網絡中批量和迭代之間的區別是什么?
- 在 Keras 展示深度學習模型訓練歷史
- 基于 Keras 的深度學習模型中的dropout正則化
- 評估 Keras 中深度學習模型的表現
- 如何評價深度學習模型的技巧
- 小批量梯度下降的簡要介紹以及如何配置批量大小
- 在 Keras 中獲得深度學習幫助的 9 種方法
- 如何使用 Keras 在 Python 中網格搜索深度學習模型的超參數
- 用 Keras 在 Python 中使用卷積神經網絡進行手寫數字識別
- 如何用 Keras 進行預測
- 用 Keras 進行深度學習的圖像增強
- 8 個深度學習的鼓舞人心的應用
- Python 深度學習庫 Keras 簡介
- Python 深度學習庫 TensorFlow 簡介
- Python 深度學習庫 Theano 簡介
- 如何使用 Keras 函數式 API 進行深度學習
- Keras 深度學習庫的多類分類教程
- 多層感知器神經網絡速成課程
- 基于卷積神經網絡的 Keras 深度學習庫中的目標識別
- 流行的深度學習庫
- 用深度學習預測電影評論的情感
- Python 中的 Keras 深度學習庫的回歸教程
- 如何使用 Keras 獲得可重現的結果
- 如何在 Linux 服務器上運行深度學習實驗
- 保存并加載您的 Keras 深度學習模型
- 用 Keras 逐步開發 Python 中的第一個神經網絡
- 用 Keras 理解 Python 中的有狀態 LSTM 循環神經網絡
- 在 Python 中使用 Keras 深度學習模型和 Scikit-Learn
- 如何使用預訓練的 VGG 模型對照片中的物體進行分類
- 在 Python 和 Keras 中對深度學習模型使用學習率調度
- 如何在 Keras 中可視化深度學習神經網絡模型
- 什么是深度學習?
- 何時使用 MLP,CNN 和 RNN 神經網絡
- 為什么用隨機權重初始化神經網絡?
- Machine Learning Mastery 深度學習 NLP 教程
- 深度學習在自然語言處理中的 7 個應用
- 如何實現自然語言處理的波束搜索解碼器
- 深度學習文檔分類的最佳實踐
- 關于自然語言處理的熱門書籍
- 在 Python 中計算文本 BLEU 分數的溫和介紹
- 使用編碼器 - 解碼器模型的用于字幕生成的注入和合并架構
- 如何用 Python 清理機器學習的文本
- 如何配置神經機器翻譯的編碼器 - 解碼器模型
- 如何開始深度學習自然語言處理(7 天迷你課程)
- 自然語言處理的數據集
- 如何開發一種深度學習的詞袋模型來預測電影評論情感
- 深度學習字幕生成模型的溫和介紹
- 如何在 Keras 中定義神經機器翻譯的編碼器 - 解碼器序列 - 序列模型
- 如何利用小實驗在 Keras 中開發字幕生成模型
- 如何從頭開發深度學習圖片標題生成器
- 如何在 Keras 中開發基于字符的神經語言模型
- 如何開發用于情感分析的 N-gram 多通道卷積神經網絡
- 如何從零開始開發神經機器翻譯系統
- 如何在 Python 中用 Keras 開發基于單詞的神經語言模型
- 如何開發一種預測電影評論情感的詞嵌入模型
- 如何使用 Gensim 在 Python 中開發詞嵌入
- 用于文本摘要的編碼器 - 解碼器深度學習模型
- Keras 中文本摘要的編碼器 - 解碼器模型
- 用于神經機器翻譯的編碼器 - 解碼器循環神經網絡模型
- 淺談詞袋模型
- 文本摘要的溫和介紹
- 編碼器 - 解碼器循環神經網絡中的注意力如何工作
- 如何利用深度學習自動生成照片的文本描述
- 如何開發一個單詞級神經語言模型并用它來生成文本
- 淺談神經機器翻譯
- 什么是自然語言處理?
- 牛津自然語言處理深度學習課程
- 如何為機器翻譯準備法語到英語的數據集
- 如何為情感分析準備電影評論數據
- 如何為文本摘要準備新聞文章
- 如何準備照片標題數據集以訓練深度學習模型
- 如何使用 Keras 為深度學習準備文本數據
- 如何使用 scikit-learn 為機器學習準備文本數據
- 自然語言處理神經網絡模型入門
- 對自然語言處理的深度學習的承諾
- 在 Python 中用 Keras 進行 LSTM 循環神經網絡的序列分類
- 斯坦福自然語言處理深度學習課程評價
- 統計語言建模和神經語言模型的簡要介紹
- 使用 Keras 在 Python 中進行 LSTM 循環神經網絡的文本生成
- 淺談機器學習中的轉換
- 如何使用 Keras 將詞嵌入層用于深度學習
- 什么是用于文本的詞嵌入
- Machine Learning Mastery 深度學習時間序列教程
- 如何開發人類活動識別的一維卷積神經網絡模型
- 人類活動識別的深度學習模型
- 如何評估人類活動識別的機器學習算法
- 時間序列預測的多層感知器網絡探索性配置
- 比較經典和機器學習方法進行時間序列預測的結果
- 如何通過深度學習快速獲得時間序列預測的結果
- 如何利用 Python 處理序列預測問題中的缺失時間步長
- 如何建立預測大氣污染日的概率預測模型
- 如何開發一種熟練的機器學習時間序列預測模型
- 如何構建家庭用電自回歸預測模型
- 如何開發多步空氣污染時間序列預測的自回歸預測模型
- 如何制定多站點多元空氣污染時間序列預測的基線預測
- 如何開發時間序列預測的卷積神經網絡模型
- 如何開發卷積神經網絡用于多步時間序列預測
- 如何開發單變量時間序列預測的深度學習模型
- 如何開發 LSTM 模型用于家庭用電的多步時間序列預測
- 如何開發 LSTM 模型進行時間序列預測
- 如何開發多元多步空氣污染時間序列預測的機器學習模型
- 如何開發多層感知器模型進行時間序列預測
- 如何開發人類活動識別時間序列分類的 RNN 模型
- 如何開始深度學習的時間序列預測(7 天迷你課程)
- 如何網格搜索深度學習模型進行時間序列預測
- 如何對單變量時間序列預測的網格搜索樸素方法
- 如何在 Python 中搜索 SARIMA 模型超參數用于時間序列預測
- 如何在 Python 中進行時間序列預測的網格搜索三次指數平滑
- 一個標準的人類活動識別問題的溫和介紹
- 如何加載和探索家庭用電數據
- 如何加載,可視化和探索復雜的多變量多步時間序列預測數據集
- 如何從智能手機數據模擬人類活動
- 如何根據環境因素預測房間占用率
- 如何使用腦波預測人眼是開放還是閉合
- 如何在 Python 中擴展長短期內存網絡的數據
- 如何使用 TimeseriesGenerator 進行 Keras 中的時間序列預測
- 基于機器學習算法的室內運動時間序列分類
- 用于時間序列預測的狀態 LSTM 在線學習的不穩定性
- 用于罕見事件時間序列預測的 LSTM 模型體系結構
- 用于時間序列預測的 4 種通用機器學習數據變換
- Python 中長短期記憶網絡的多步時間序列預測
- 家庭用電機器學習的多步時間序列預測
- Keras 中 LSTM 的多變量時間序列預測
- 如何開發和評估樸素的家庭用電量預測方法
- 如何為長短期記憶網絡準備單變量時間序列數據
- 循環神經網絡在時間序列預測中的應用
- 如何在 Python 中使用差異變換刪除趨勢和季節性
- 如何在 LSTM 中種子狀態用于 Python 中的時間序列預測
- 使用 Python 進行時間序列預測的有狀態和無狀態 LSTM
- 長短時記憶網絡在時間序列預測中的適用性
- 時間序列預測問題的分類
- Python 中長短期記憶網絡的時間序列預測
- 基于 Keras 的 Python 中 LSTM 循環神經網絡的時間序列預測
- Keras 中深度學習的時間序列預測
- 如何用 Keras 調整 LSTM 超參數進行時間序列預測
- 如何在時間序列預測訓練期間更新 LSTM 網絡
- 如何使用 LSTM 網絡的 Dropout 進行時間序列預測
- 如何使用 LSTM 網絡中的特征進行時間序列預測
- 如何在 LSTM 網絡中使用時間序列進行時間序列預測
- 如何利用 LSTM 網絡進行權重正則化進行時間序列預測
- Machine Learning Mastery 線性代數教程
- 機器學習數學符號的基礎知識
- 用 NumPy 陣列輕松介紹廣播
- 如何從 Python 中的 Scratch 計算主成分分析(PCA)
- 用于編碼器審查的計算線性代數
- 10 機器學習中的線性代數示例
- 線性代數的溫和介紹
- 用 NumPy 輕松介紹 Python 中的 N 維數組
- 機器學習向量的溫和介紹
- 如何在 Python 中為機器學習索引,切片和重塑 NumPy 數組
- 機器學習的矩陣和矩陣算法簡介
- 溫和地介紹機器學習的特征分解,特征值和特征向量
- NumPy 對預期價值,方差和協方差的簡要介紹
- 機器學習矩陣分解的溫和介紹
- 用 NumPy 輕松介紹機器學習的張量
- 用于機器學習的線性代數中的矩陣類型簡介
- 用于機器學習的線性代數備忘單
- 線性代數的深度學習
- 用于機器學習的線性代數(7 天迷你課程)
- 機器學習的線性代數
- 機器學習矩陣運算的溫和介紹
- 線性代數評論沒有廢話指南
- 學習機器學習線性代數的主要資源
- 淺談機器學習的奇異值分解
- 如何用線性代數求解線性回歸
- 用于機器學習的稀疏矩陣的溫和介紹
- 機器學習中向量規范的溫和介紹
- 學習線性代數用于機器學習的 5 個理由
- Machine Learning Mastery LSTM 教程
- Keras中長短期記憶模型的5步生命周期
- 長短時記憶循環神經網絡的注意事項
- CNN長短期記憶網絡
- 逆向神經網絡中的深度學習速成課程
- 可變長度輸入序列的數據準備
- 如何用Keras開發用于Python序列分類的雙向LSTM
- 如何開發Keras序列到序列預測的編碼器 - 解碼器模型
- 如何診斷LSTM模型的過度擬合和欠擬合
- 如何開發一種編碼器 - 解碼器模型,注重Keras中的序列到序列預測
- 編碼器 - 解碼器長短期存儲器網絡
- 神經網絡中爆炸梯度的溫和介紹
- 對時間反向傳播的溫和介紹
- 生成長短期記憶網絡的溫和介紹
- 專家對長短期記憶網絡的簡要介紹
- 在序列預測問題上充分利用LSTM
- 編輯器 - 解碼器循環神經網絡全局注意的溫和介紹
- 如何利用長短時記憶循環神經網絡處理很長的序列
- 如何在Python中對一個熱編碼序列數據
- 如何使用編碼器 - 解碼器LSTM來回顯隨機整數序列
- 具有注意力的編碼器 - 解碼器RNN體系結構的實現模式
- 學習使用編碼器解碼器LSTM循環神經網絡添加數字
- 如何學習長短時記憶循環神經網絡回聲隨機整數
- 具有Keras的長短期記憶循環神經網絡的迷你課程
- LSTM自動編碼器的溫和介紹
- 如何用Keras中的長短期記憶模型進行預測
- 用Python中的長短期內存網絡演示內存
- 基于循環神經網絡的序列預測模型的簡要介紹
- 深度學習的循環神經網絡算法之旅
- 如何重塑Keras中長短期存儲網絡的輸入數據
- 了解Keras中LSTM的返回序列和返回狀態之間的差異
- RNN展開的溫和介紹
- 5學習LSTM循環神經網絡的簡單序列預測問題的例子
- 使用序列進行預測
- 堆疊長短期內存網絡
- 什么是教師強制循環神經網絡?
- 如何在Python中使用TimeDistributed Layer for Long Short-Term Memory Networks
- 如何準備Keras中截斷反向傳播的序列預測
- 如何在使用LSTM進行訓練和預測時使用不同的批量大小
- Machine Learning Mastery 機器學習算法教程
- 機器學習算法之旅
- 用于機器學習的裝袋和隨機森林集合算法
- 從頭開始實施機器學習算法的好處
- 更好的樸素貝葉斯:從樸素貝葉斯算法中獲取最多的12個技巧
- 機器學習的提升和AdaBoost
- 選擇機器學習算法:Microsoft Azure的經驗教訓
- 機器學習的分類和回歸樹
- 什么是機器學習中的混淆矩陣
- 如何使用Python從頭開始創建算法測試工具
- 通過創建機器學習算法的目標列表來控制
- 從頭開始停止編碼機器學習算法
- 在實現機器學習算法時,不要從開源代碼開始
- 不要使用隨機猜測作為基線分類器
- 淺談機器學習中的概念漂移
- 溫和介紹機器學習中的偏差 - 方差權衡
- 機器學習的梯度下降
- 機器學習算法如何工作(他們學習輸入到輸出的映射)
- 如何建立機器學習算法的直覺
- 如何實現機器學習算法
- 如何研究機器學習算法行為
- 如何學習機器學習算法
- 如何研究機器學習算法
- 如何研究機器學習算法
- 如何在Python中從頭開始實現反向傳播算法
- 如何用Python從頭開始實現Bagging
- 如何用Python從頭開始實現基線機器學習算法
- 如何在Python中從頭開始實現決策樹算法
- 如何用Python從頭開始實現學習向量量化
- 如何利用Python從頭開始隨機梯度下降實現線性回歸
- 如何利用Python從頭開始隨機梯度下降實現Logistic回歸
- 如何用Python從頭開始實現機器學習算法表現指標
- 如何在Python中從頭開始實現感知器算法
- 如何在Python中從零開始實現隨機森林
- 如何在Python中從頭開始實現重采樣方法
- 如何用Python從頭開始實現簡單線性回歸
- 如何用Python從頭開始實現堆棧泛化(Stacking)
- K-Nearest Neighbors for Machine Learning
- 學習機器學習的向量量化
- 機器學習的線性判別分析
- 機器學習的線性回歸
- 使用梯度下降進行機器學習的線性回歸教程
- 如何在Python中從頭開始加載機器學習數據
- 機器學習的Logistic回歸
- 機器學習的Logistic回歸教程
- 機器學習算法迷你課程
- 如何在Python中從頭開始實現樸素貝葉斯
- 樸素貝葉斯機器學習
- 樸素貝葉斯機器學習教程
- 機器學習算法的過擬合和欠擬合
- 參數化和非參數機器學習算法
- 理解任何機器學習算法的6個問題
- 在機器學習中擁抱隨機性
- 如何使用Python從頭開始擴展機器學習數據
- 機器學習的簡單線性回歸教程
- 有監督和無監督的機器學習算法
- 用于機器學習的支持向量機
- 在沒有數學背景的情況下理解機器學習算法的5種技術
- 最好的機器學習算法
- 教程從頭開始在Python中實現k-Nearest Neighbors
- 通過從零開始實現它們來理解機器學習算法(以及繞過壞代碼的策略)
- 使用隨機森林:在121個數據集上測試179個分類器
- 為什么從零開始實現機器學習算法
- Machine Learning Mastery 機器學習入門教程
- 機器學習入門的四個步驟:初學者入門與實踐的自上而下策略
- 你應該培養的 5 個機器學習領域
- 一種選擇機器學習算法的數據驅動方法
- 機器學習中的分析與數值解
- 應用機器學習是一種精英政治
- 機器學習的基本概念
- 如何成為數據科學家
- 初學者如何在機器學習中弄錯
- 機器學習的最佳編程語言
- 構建機器學習組合
- 機器學習中分類與回歸的區別
- 評估自己作為數據科學家并利用結果建立驚人的數據科學團隊
- 探索 Kaggle 大師的方法論和心態:對 Diogo Ferreira 的采訪
- 擴展機器學習工具并展示掌握
- 通過尋找地標開始機器學習
- 溫和地介紹預測建模
- 通過提供結果在機器學習中獲得夢想的工作
- 如何開始機器學習:自學藍圖
- 開始并在機器學習方面取得進展
- 應用機器學習的 Hello World
- 初學者如何使用小型項目開始機器學習并在 Kaggle 上進行競爭
- 我如何開始機器學習? (簡短版)
- 我是如何開始機器學習的
- 如何在機器學習中取得更好的成績
- 如何從在銀行工作到擔任 Target 的高級數據科學家
- 如何學習任何機器學習工具
- 使用小型目標項目深入了解機器學習工具
- 獲得付費申請機器學習
- 映射機器學習工具的景觀
- 機器學習開發環境
- 機器學習金錢
- 程序員的機器學習
- 機器學習很有意思
- 機器學習是 Kaggle 比賽
- 機器學習現在很受歡迎
- 機器學習掌握方法
- 機器學習很重要
- 機器學習 Q& A:概念漂移,更好的結果和學習更快
- 缺乏自學機器學習的路線圖
- 機器學習很重要
- 快速了解任何機器學習工具(即使您是初學者)
- 機器學習工具
- 找到你的機器學習部落
- 機器學習在一年
- 通過競爭一致的大師 Kaggle
- 5 程序員在機器學習中開始犯錯誤
- 哲學畢業生到機器學習從業者(Brian Thomas 采訪)
- 機器學習入門的實用建議
- 實用機器學習問題
- 使用來自 UCI 機器學習庫的數據集練習機器學習
- 使用秘籍的任何機器學習工具快速啟動
- 程序員可以進入機器學習
- 程序員應該進入機器學習
- 項目焦點:Shashank Singh 的人臉識別
- 項目焦點:使用 Mahout 和 Konstantin Slisenko 進行堆棧交換群集
- 機器學習自學指南
- 4 個自學機器學習項目
- álvaroLemos 如何在數據科學團隊中獲得機器學習實習
- 如何思考機器學習
- 現實世界機器學習問題之旅
- 有關機器學習的有用知識
- 如果我沒有學位怎么辦?
- 如果我不是一個優秀的程序員怎么辦?
- 如果我不擅長數學怎么辦?
- 為什么機器學習算法會處理以前從未見過的數據?
- 是什么阻礙了你的機器學習目標?
- 什么是機器學習?
- 機器學習適合哪里?
- 為什么要進入機器學習?
- 研究對您來說很重要的機器學習問題
- 你這樣做是錯的。為什么機器學習不必如此困難
- Machine Learning Mastery Sklearn 教程
- Scikit-Learn 的溫和介紹:Python 機器學習庫
- 使用 Python 管道和 scikit-learn 自動化機器學習工作流程
- 如何以及何時使用帶有 scikit-learn 的校準分類模型
- 如何比較 Python 中的機器學習算法與 scikit-learn
- 用于機器學習開發人員的 Python 崩潰課程
- 用 scikit-learn 在 Python 中集成機器學習算法
- 使用重采樣評估 Python 中機器學習算法的表現
- 使用 Scikit-Learn 在 Python 中進行特征選擇
- Python 中機器學習的特征選擇
- 如何使用 scikit-learn 在 Python 中生成測試數據集
- scikit-learn 中的機器學習算法秘籍
- 如何使用 Python 處理丟失的數據
- 如何開始使用 Python 進行機器學習
- 如何使用 Scikit-Learn 在 Python 中加載數據
- Python 中概率評分方法的簡要介紹
- 如何用 Scikit-Learn 調整算法參數
- 如何在 Mac OS X 上安裝 Python 3 環境以進行機器學習和深度學習
- 使用 scikit-learn 進行機器學習簡介
- 從 shell 到一本帶有 Fernando Perez 單一工具的書的 IPython
- 如何使用 Python 3 為機器學習開發創建 Linux 虛擬機
- 如何在 Python 中加載機器學習數據
- 您在 Python 中的第一個機器學習項目循序漸進
- 如何使用 scikit-learn 進行預測
- 用于評估 Python 中機器學習算法的度量標準
- 使用 Pandas 為 Python 中的機器學習準備數據
- 如何使用 Scikit-Learn 為 Python 機器學習準備數據
- 項目焦點:使用 Artem Yankov 在 Python 中進行事件推薦
- 用于機器學習的 Python 生態系統
- Python 是應用機器學習的成長平臺
- Python 機器學習書籍
- Python 機器學習迷你課程
- 使用 Pandas 快速和骯臟的數據分析
- 使用 Scikit-Learn 重新調整 Python 中的機器學習數據
- 如何以及何時使用 ROC 曲線和精確調用曲線進行 Python 分類
- 使用 scikit-learn 在 Python 中保存和加載機器學習模型
- scikit-learn Cookbook 書評
- 如何使用 Anaconda 為機器學習和深度學習設置 Python 環境
- 使用 scikit-learn 在 Python 中進行 Spot-Check 分類機器學習算法
- 如何在 Python 中開發可重復使用的抽樣檢查算法框架
- 使用 scikit-learn 在 Python 中進行 Spot-Check 回歸機器學習算法
- 使用 Python 中的描述性統計來了解您的機器學習數據
- 使用 OpenCV,Python 和模板匹配來播放“哪里是 Waldo?”
- 使用 Pandas 在 Python 中可視化機器學習數據
- Machine Learning Mastery 統計學教程
- 淺談計算正態匯總統計量
- 非參數統計的溫和介紹
- Python中常態測試的溫和介紹
- 淺談Bootstrap方法
- 淺談機器學習的中心極限定理
- 淺談機器學習中的大數定律
- 機器學習的所有統計數據
- 如何計算Python中機器學習結果的Bootstrap置信區間
- 淺談機器學習的Chi-Squared測試
- 機器學習的置信區間
- 隨機化在機器學習中解決混雜變量的作用
- 機器學習中的受控實驗
- 機器學習統計學速成班
- 統計假設檢驗的關鍵值以及如何在Python中計算它們
- 如何在機器學習中談論數據(統計學和計算機科學術語)
- Python中數據可視化方法的簡要介紹
- Python中效果大小度量的溫和介紹
- 估計隨機機器學習算法的實驗重復次數
- 機器學習評估統計的溫和介紹
- 如何計算Python中的非參數秩相關性
- 如何在Python中計算數據的5位數摘要
- 如何在Python中從頭開始編寫學生t檢驗
- 如何在Python中生成隨機數
- 如何轉換數據以更好地擬合正態分布
- 如何使用相關來理解變量之間的關系
- 如何使用統計信息識別數據中的異常值
- 用于Python機器學習的隨機數生成器簡介
- k-fold交叉驗證的溫和介紹
- 如何計算McNemar的比較兩種機器學習量詞的測試
- Python中非參數統計顯著性測試簡介
- 如何在Python中使用參數統計顯著性測試
- 機器學習的預測間隔
- 應用統計學與機器學習的密切關系
- 如何使用置信區間報告分類器表現
- 統計數據分布的簡要介紹
- 15 Python中的統計假設檢驗(備忘單)
- 統計假設檢驗的溫和介紹
- 10如何在機器學習項目中使用統計方法的示例
- Python中統計功效和功耗分析的簡要介紹
- 統計抽樣和重新抽樣的簡要介紹
- 比較機器學習算法的統計顯著性檢驗
- 機器學習中統計容差區間的溫和介紹
- 機器學習統計書籍
- 評估機器學習模型的統計數據
- 機器學習統計(7天迷你課程)
- 用于機器學習的簡明英語統計
- 如何使用統計顯著性檢驗來解釋機器學習結果
- 什么是統計(為什么它在機器學習中很重要)?
- Machine Learning Mastery 時間序列入門教程
- 如何在 Python 中為時間序列預測創建 ARIMA 模型
- 用 Python 進行時間序列預測的自回歸模型
- 如何回溯機器學習模型的時間序列預測
- Python 中基于時間序列數據的基本特征工程
- R 的時間序列預測熱門書籍
- 10 挑戰機器學習時間序列預測問題
- 如何將時間序列轉換為 Python 中的監督學習問題
- 如何將時間序列數據分解為趨勢和季節性
- 如何用 ARCH 和 GARCH 模擬波動率進行時間序列預測
- 如何將時間序列數據集與 Python 區分開來
- Python 中時間序列預測的指數平滑的溫和介紹
- 用 Python 進行時間序列預測的特征選擇
- 淺談自相關和部分自相關
- 時間序列預測的 Box-Jenkins 方法簡介
- 用 Python 簡要介紹時間序列的時間序列預測
- 如何使用 Python 網格搜索 ARIMA 模型超參數
- 如何在 Python 中加載和探索時間序列數據
- 如何使用 Python 對 ARIMA 模型進行手動預測
- 如何用 Python 進行時間序列預測的預測
- 如何使用 Python 中的 ARIMA 進行樣本外預測
- 如何利用 Python 模擬殘差錯誤來糾正時間序列預測
- 使用 Python 進行數據準備,特征工程和時間序列預測的移動平均平滑
- 多步時間序列預測的 4 種策略
- 如何在 Python 中規范化和標準化時間序列數據
- 如何利用 Python 進行時間序列預測的基線預測
- 如何使用 Python 對時間序列預測數據進行功率變換
- 用于時間序列預測的 Python 環境
- 如何重構時間序列預測問題
- 如何使用 Python 重新采樣和插值您的時間序列數據
- 用 Python 編寫 SARIMA 時間序列預測
- 如何在 Python 中保存 ARIMA 時間序列預測模型
- 使用 Python 進行季節性持久性預測
- 基于 ARIMA 的 Python 歷史規模敏感性預測技巧分析
- 簡單的時間序列預測模型進行測試,這樣你就不會欺騙自己
- 標準多變量,多步驟和多站點時間序列預測問題
- 如何使用 Python 檢查時間序列數據是否是固定的
- 使用 Python 進行時間序列數據可視化
- 7 個機器學習的時間序列數據集
- 時間序列預測案例研究與 Python:波士頓每月武裝搶劫案
- Python 的時間序列預測案例研究:巴爾的摩的年度用水量
- 使用 Python 進行時間序列預測研究:法國香檳的月銷售額
- 使用 Python 的置信區間理解時間序列預測不確定性
- 11 Python 中的經典時間序列預測方法(備忘單)
- 使用 Python 進行時間序列預測表現測量
- 使用 Python 7 天迷你課程進行時間序列預測
- 時間序列預測作為監督學習
- 什么是時間序列預測?
- 如何使用 Python 識別和刪除時間序列數據的季節性
- 如何在 Python 中使用和刪除時間序列數據中的趨勢信息
- 如何在 Python 中調整 ARIMA 參數
- 如何用 Python 可視化時間序列殘差預測錯誤
- 白噪聲時間序列與 Python
- 如何通過時間序列預測項目
- Machine Learning Mastery XGBoost 教程
- 通過在 Python 中使用 XGBoost 提前停止來避免過度擬合
- 如何在 Python 中調優 XGBoost 的多線程支持
- 如何配置梯度提升算法
- 在 Python 中使用 XGBoost 進行梯度提升的數據準備
- 如何使用 scikit-learn 在 Python 中開發您的第一個 XGBoost 模型
- 如何在 Python 中使用 XGBoost 評估梯度提升模型
- 在 Python 中使用 XGBoost 的特征重要性和特征選擇
- 淺談機器學習的梯度提升算法
- 應用機器學習的 XGBoost 簡介
- 如何在 macOS 上為 Python 安裝 XGBoost
- 如何在 Python 中使用 XGBoost 保存梯度提升模型
- 從梯度提升開始,比較 165 個數據集上的 13 種算法
- 在 Python 中使用 XGBoost 和 scikit-learn 進行隨機梯度提升
- 如何使用 Amazon Web Services 在云中訓練 XGBoost 模型
- 在 Python 中使用 XGBoost 調整梯度提升的學習率
- 如何在 Python 中使用 XGBoost 調整決策樹的數量和大小
- 如何在 Python 中使用 XGBoost 可視化梯度提升決策樹
- 在 Python 中開始使用 XGBoost 的 7 步迷你課程