A.I
딥러닝 레이어에 대한 이해 본문
Embedding, Recurrent¶
단어의 분산 표현(Distributed Representation)¶
모든 단어를 고정 차원의 벡터로 표현할 때, 유사한 맥락에서 나타나는 단어는 그 의미도 비슷하다라는 것인데 이것을 분포 가설(distribution hypothesis)이라고 합니다.
이런 방식으로 얻어지는 단어 벡터를 단어의 분산 표현(Distributed Representation)이라고 합니다. 위에서 활용했던 방법들과는 달리, 벡터의 특정 차원이 특정 의미를 담고 있는 것이 아니라 의미가 벡터의 여러 차원에 분산되어 있으리라고 여기게 됩니다.
분산 표현을 사용하면 희소 표현과는 다르게 단어 간의 유사도를 계산으로 구할 수 있다는 장점이 있습니다
Embedding layer는 단어의 분산 표현을 구현하기 위한 레이어입니다. [ n x k ] 형태의 분산 표현으로 만들 수 있는데 Weight이고 파라미터라고 할 수 있습니다.
Embedding layer에는 ELMo, Word2Vec, Glove, FastText 등이 있습니다.
Embedding Layer¶
- 원-핫 인코딩의 개념
- 단어를 직접 연결해주는 것이기때문에 신경망 설계를 할 때, 어떤 연산 결과를 Embedding 레이어에 연결시키는 것은 불가능!
In [1]:
import tensorflow as tf
vocab = { # 사용할 단어 사전 정의
"i": 0,
"need": 1,
"some": 2,
"more": 3,
"coffee": 4,
"cake": 5,
"cat": 6,
"dog": 7
}
sentence = "i i i i need some more coffee coffee coffee"
# 위 sentence
_input = [vocab[w] for w in sentence.split()] # [0, 0, 0, 0, 1, 2, 3, 4, 4, 4]
vocab_size = len(vocab) # 8
one_hot = tf.one_hot(_input, vocab_size)
print(one_hot.numpy()) # 원-핫 인코딩 벡터를 출력해 봅시다.
[[1. 0. 0. 0. 0. 0. 0. 0.] [1. 0. 0. 0. 0. 0. 0. 0.] [1. 0. 0. 0. 0. 0. 0. 0.] [1. 0. 0. 0. 0. 0. 0. 0.] [0. 1. 0. 0. 0. 0. 0. 0.] [0. 0. 1. 0. 0. 0. 0. 0.] [0. 0. 0. 1. 0. 0. 0. 0.] [0. 0. 0. 0. 1. 0. 0. 0.] [0. 0. 0. 0. 1. 0. 0. 0.] [0. 0. 0. 0. 1. 0. 0. 0.]]
In [2]:
distribution_size = 2 # 보기 좋게 2차원으로 분산 표현
linear = tf.keras.layers.Dense(units=distribution_size, use_bias=False)
one_hot_linear = linear(one_hot)
print("Linear Weight")
print(linear.weights[0].numpy())
print("\nOne-Hot Linear Result")
print(one_hot_linear.numpy())
Linear Weight [[ 0.5096015 -0.5759542 ] [ 0.43113136 -0.77376693] [ 0.64637697 -0.67302275] [ 0.35817683 -0.6138781 ] [-0.12972629 0.14492309] [-0.75768995 0.5639281 ] [-0.6927495 0.24326408] [-0.5807368 -0.10037243]] One-Hot Linear Result [[ 0.5096015 -0.5759542 ] [ 0.5096015 -0.5759542 ] [ 0.5096015 -0.5759542 ] [ 0.5096015 -0.5759542 ] [ 0.43113136 -0.77376693] [ 0.64637697 -0.67302275] [ 0.35817683 -0.6138781 ] [-0.12972629 0.14492309] [-0.12972629 0.14492309] [-0.12972629 0.14492309]]
In [3]:
some_words = tf.constant([[3, 57, 35]])
# 3번 단어 / 57번 단어 / 35번 단어로 이루어진 한 문장입니다.
print("Embedding을 진행할 문장:", some_words.shape)
embedding_layer = tf.keras.layers.Embedding(input_dim=64, output_dim=100)
# 총 64개의 단어를 포함한 Embedding 레이어를 선언할 것이고,
# 각 단어는 100차원으로 분산표현 할 것입니다.
print("Embedding된 문장:", embedding_layer(some_words).shape)
print("Embedding Layer의 Weight 형태:", embedding_layer.weights[0].shape)
Embedding을 진행할 문장: (1, 3) Embedding된 문장: (1, 3, 100) Embedding Layer의 Weight 형태: (64, 100)
Recurrent 레이어 (1) RNN¶
- RNN에 대한 설명
- RNN의 입력으로 들어가는 모든 단어만큼 Weight를 만드는 게 아니라 (입력의 차원, 출력의 차원)에 해당하는 단 하나의 Weight를 순차적으로 업데이트
In [4]:
sentence = "What time is it ?"
dic = {
"is": 0,
"it": 1,
"What": 2,
"time": 3,
"?": 4
}
print("RNN에 입력할 문장:", sentence)
sentence_tensor = tf.constant([[dic[word] for word in sentence.split()]])
print("Embedding을 위해 단어 매핑:", sentence_tensor.numpy())
print("입력 문장 데이터 형태:", sentence_tensor.shape)
embedding_layer = tf.keras.layers.Embedding(input_dim=len(dic), output_dim=100)
emb_out = embedding_layer(sentence_tensor)
print("\nEmbedding 결과:", emb_out.shape)
print("Embedding Layer의 Weight 형태:", embedding_layer.weights[0].shape)
# 모든 Step에 대한 Output이 필요한 경우 (return_sequences=True)
# 최종 Step에 대한 Output만 필요한 경우 (return_sequences=False)
rnn_seq_layer = \
tf.keras.layers.SimpleRNN(units=64, return_sequences=True, use_bias=False)
rnn_seq_out = rnn_seq_layer(emb_out)
print("\nRNN 결과 (모든 Step Output):", rnn_seq_out.shape)
print("RNN Layer의 Weight 형태:", rnn_seq_layer.weights[0].shape)
rnn_fin_layer = tf.keras.layers.SimpleRNN(units=64, use_bias=False)
rnn_fin_out = rnn_fin_layer(emb_out)
print("\nRNN 결과 (최종 Step Output):", rnn_fin_out.shape)
print("RNN Layer의 Weight 형태:", rnn_fin_layer.weights[0].shape)
RNN에 입력할 문장: What time is it ? Embedding을 위해 단어 매핑: [[2 3 0 1 4]] 입력 문장 데이터 형태: (1, 5) Embedding 결과: (1, 5, 100) Embedding Layer의 Weight 형태: (5, 100) RNN 결과 (모든 Step Output): (1, 5, 64) RNN Layer의 Weight 형태: (100, 64) RNN 결과 (최종 Step Output): (1, 64) RNN Layer의 Weight 형태: (100, 64)
Recurrent 레이어 (2) LSTM¶
- 기울기 소실 문제를 해결하기 위해 고안된 RNN 레이어
- LSTM에 대한 설명
In [5]:
lstm_seq_layer = tf.keras.layers.LSTM(units=64, return_sequences=True, use_bias=False)
lstm_seq_out = lstm_seq_layer(emb_out)
print("\nLSTM 결과 (모든 Step Output):", lstm_seq_out.shape)
print("LSTM Layer의 Weight 형태:", lstm_seq_layer.weights[0].shape)
lstm_fin_layer = tf.keras.layers.LSTM(units=64, use_bias=False)
lstm_fin_out = lstm_fin_layer(emb_out)
print("\nLSTM 결과 (최종 Step Output):", lstm_fin_out.shape)
print("LSTM Layer의 Weight 형태:", lstm_fin_layer.weights[0].shape)
LSTM 결과 (모든 Step Output): (1, 5, 64) LSTM Layer의 Weight 형태: (100, 256) LSTM 결과 (최종 Step Output): (1, 64) LSTM Layer의 Weight 형태: (100, 256)
양방향(Bidirectional) RNN¶
- 진행 방향이 반대인 RNN을 2개 겹쳐놓은 형태
- 문장 분석이나 생성보다는 주로 기계번역 같은 테스크에 유리
- tf.keras.layers.Bidirectional()를 사용
In [6]:
import tensorflow as tf
sentence = "What time is it ?"
dic = {
"is": 0,
"it": 1,
"What": 2,
"time": 3,
"?": 4
}
sentence_tensor = tf.constant([[dic[word] for word in sentence.split()]])
embedding_layer = tf.keras.layers.Embedding(input_dim=len(dic), output_dim=100)
emb_out = embedding_layer(sentence_tensor)
print("입력 문장 데이터 형태:", emb_out.shape)
bi_rnn = \
tf.keras.layers.Bidirectional(
tf.keras.layers.SimpleRNN(units=64, use_bias=False, return_sequences=True)
)
bi_out = bi_rnn(emb_out)
print("Bidirectional RNN 결과 (최종 Step Output):", bi_out.shape)
입력 문장 데이터 형태: (1, 5, 100) Bidirectional RNN 결과 (최종 Step Output): (1, 5, 128)
'파이썬 & AI 학습' 카테고리의 다른 글
활성화 함수의 이해 (0) | 2021.03.17 |
---|---|
파이썬 데이터베이스 만들기 Pandas (0) | 2021.03.14 |
Hadoop & Spark (0) | 2021.03.10 |
Linear, Convolution layer (0) | 2021.03.06 |
MapReduce 원리 (0) | 2021.03.04 |