이러한 LSTM Autoencoder 구현의 차이점은 무엇입니까?
return_sequence
특히이 질문을 촉발시킨 것은 TensorFlow 버전의 LSTM 레이어에 대한 주장입니다.
문서는 다음과 같이 말합니다.
부울. 마지막 출력을 반환할지 여부입니다. 출력 시퀀스 또는 전체 시퀀스에서. 기본값 : False.
일부 구현, 특히이 인수를 사용하여 출력 시퀀스의 마지막 요소를 제외한 모든 항목을 자동 인코더의 '인코더'절반의 출력으로 제거하는 자동 인코더를 보았습니다.
다음은 세 가지 구현입니다. 매우 큰 차이처럼 보이지만 모두 자신을 똑같은 것이라고 부르기 때문에 차이의 원인을 이해하고 싶습니다.
예 1 (TensorFlow) :
이 구현은 시퀀스의 마지막 요소를 제외한 LSTM의 모든 출력을 제거한 다음 해당 요소를 몇 번 반복하여 시퀀스를 재구성합니다.
model = Sequential()
model.add(LSTM(100, activation='relu', input_shape=(n_in,1)))
# Decoder below
model.add(RepeatVector(n_out))
model.add(LSTM(100, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))
PyTorch에서 오토 인코더 구현을 살펴보면 작성자가이 작업을 수행하는 것을 볼 수 없습니다. 대신 인코더에 LSTM의 전체 출력을 사용합니다 (때로는 고밀도 레이어가 뒤 따르고 때로는 그렇지 않음).
예 1 (PyTorch) :
이 구현은 LSTM 계층이 적용되기 전에 임베딩을 훈련합니다 ... LSTM 기반 자동 인코더의 아이디어를 거의 무효화하는 것 같습니다 ... 시퀀스는 LSTM 계층에 도달 할 때 이미 인코딩되어 있습니다.
class EncoderLSTM(nn.Module):
def __init__(self, input_size, hidden_size, n_layers=1, drop_prob=0):
super(EncoderLSTM, self).__init__()
self.hidden_size = hidden_size
self.n_layers = n_layers
self.embedding = nn.Embedding(input_size, hidden_size)
self.lstm = nn.LSTM(hidden_size, hidden_size, n_layers, dropout=drop_prob, batch_first=True)
def forward(self, inputs, hidden):
# Embed input words
embedded = self.embedding(inputs)
# Pass the embedded word vectors into LSTM and return all outputs
output, hidden = self.lstm(embedded, hidden)
return output, hidden
예제 2 (PyTorch) :
이 예제 인코더는 먼저 하나의 LSTM 레이어로 입력을 확장 한 다음 숨겨진 노드 수가 더 적은 두 번째 LSTM 레이어를 통해 압축을 수행합니다. 확장 외에도 이것은 내가 찾은이 문서와 일치하는 것 같습니다.https://arxiv.org/pdf/1607.00148.pdf
그러나이 구현의 디코더에는 최종 조밀 계층이 없습니다. 디코딩은 인코딩을 원래 입력과 동일한 차원으로 다시 확장하는 두 번째 lstm 레이어를 통해 발생합니다. 여기에서보십시오 . 이것은 논문과 일치하지 않습니다 (논문이 권위 있는지 아닌지는 모르겠지만).
class Encoder(nn.Module):
def __init__(self, seq_len, n_features, embedding_dim=64):
super(Encoder, self).__init__()
self.seq_len, self.n_features = seq_len, n_features
self.embedding_dim, self.hidden_dim = embedding_dim, 2 * embedding_dim
self.rnn1 = nn.LSTM(
input_size=n_features,
hidden_size=self.hidden_dim,
num_layers=1,
batch_first=True
)
self.rnn2 = nn.LSTM(
input_size=self.hidden_dim,
hidden_size=embedding_dim,
num_layers=1,
batch_first=True
)
def forward(self, x):
x = x.reshape((1, self.seq_len, self.n_features))
x, (_, _) = self.rnn1(x)
x, (hidden_n, _) = self.rnn2(x)
return hidden_n.reshape((self.n_features, self.embedding_dim))
질문:
구현에서 이러한 불일치에 대해 궁금합니다. 그 차이는 상당히 큽니다. 이러한 모든 유효한 방법이 동일한 작업을 수행합니까? 아니면 "실제"LSTM 오토 인코더에서 이러한 잘못된 시도가 있습니까?
답변
LSTM 기반 오토 인코더의 아키텍처를 설계하는 공식적이거나 올바른 방법은 없습니다 ... 이름이 제공하는 유일한 세부 사항은 모델이 오토 인코더 여야하고 어딘가에 LSTM 계층을 사용해야한다는 것입니다.
찾은 구현은 동일한 작업에 사용될 수 있지만 각각 다르고 고유합니다.
그것들을 설명해 봅시다 :
TF 구현 :
- 입력에 채널 이 하나만 있다고 가정합니다. 이는 시퀀스의 각 요소 가 숫자 일 뿐이며 이미 전처리 되었음을 의미합니다 .
- 의 기본 동작
LSTM layer
에 Keras / TF는 출력에 LSTM의 마지막 출력, 당신은 출력에 모든 출력 단계를 설정할 수return_sequences
매개 변수를. - 이 경우 입력 데이터는 다음으로 축소되었습니다.
(batch_size, LSTM_units)
- LSTM의 마지막 출력은 물론 이전 출력의 함수라는 것을 고려하십시오 (특히 상태 저장 LSTM 인 경우).
Dense(1)
입력과 동일한 모양을 얻기 위해 마지막 레이어에 a 를 적용합니다 .
PyTorch 1 :
- LSTM에 공급되기 전에 입력에 임베딩을 적용합니다.
- 이것은 표준 관행이며 예를 들어 각 입력 요소를 벡터 형식으로 변환하는 데 도움이됩니다 (예를 들어 텍스트 시퀀스에서 벡터가 아닌 각 단어가 벡터 공간에 매핑되는 경우 word2vec 참조 ). 데이터가보다 의미있는 형식을 갖도록하는 것은 전처리 단계 일뿐입니다.
- 임베딩이 입력 시퀀스의 각 요소에 독립적 으로 적용 되기 때문에 LSTM 자동 인코더의 아이디어를 무너 뜨리지 않으므로 LSTM 레이어에 들어갈 때 인코딩되지 않습니다.
PyTorch 2 :
- 이 경우 입력 모양은
(seq_len, 1)
첫 번째 TF 예제와 같지 않으므로 디코더는 이후에 밀도가 필요하지 않습니다. 저자는 입력 모양과 동일한 LSTM 레이어의 여러 단위를 사용했습니다.
- 이 경우 입력 모양은
결국 학습하려는 데이터, 특히 성격 (텍스트, 오디오, 이미지), 입력 형태, 보유한 데이터 양 등에 따라 모델의 아키텍처를 선택합니다.