[NLP] 자연어처리 임베딩 모델 총정리 (word2vec부터 BERT까지)
############## 포지셔널 인코딩 레이어 ################
한번에 들어온 단어들의 위치를 알려주는 벡터(positional Encoding)값을 더해주는 역할
d_model : 임베딩 벡터의 차원
pos : 입력 문장에서의 임베딩 벡터의 위치
i : 임베딩 벡터 내의 차원의 인덱스
def get_angles(self, position, i, d_model):
angles = 1 / tf.pow(10000, (2 * (i // 2)) / tf.cast(d_model, tf.float32))
return position * angles
tf.pow()
: 거듭제곱 값을 계산 sines = tf.math.sin(angle_rads[:, 0::2])
# 스케일드 닷 프로덕트 어텐션 함수
def scaled_dot_product_attention(query, key, value, mask):
# 어텐션 가중치는 Q와 K의 닷 프로덕트
matmul_qk = tf.matmul(query, key, transpose_b=True)
# 가중치를 정규화
depth = tf.cast(tf.shape(key)[-1], tf.float32)
logits = matmul_qk / tf.math.sqrt(depth)
# 패딩에 마스크 추가
if mask is not None:
logits += (mask * -1e9)
# softmax적용
attention_weights = tf.nn.softmax(logits, axis=-1)
# 최종 어텐션은 가중치와 V의 닷 프로덕트
output = tf.matmul(attention_weights, value)
return output
print("슝=3")
멀티 헤드 어텐션 구현하기 부분 중
class MultiHeadAttention(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads, name="multi_head_attention"):
super(MultiHeadAttention, self).__init__(name=name)
self.num_heads = num_heads
self.d_model = d_model
assert d_model % self.num_heads == 0
self.depth = d_model // self.num_heads
self.query_dense = tf.keras.layers.Dense(units=d_model)
self.key_dense = tf.keras.layers.Dense(units=d_model)
self.value_dense = tf.keras.layers.Dense(units=d_model)
self.dense = tf.keras.layers.Dense(units=d_model)
def split_heads(self, inputs, batch_size):
inputs = tf.reshape(
inputs, shape=(batch_size, -1, self.num_heads, self.depth))
return tf.transpose(inputs, perm=[0, 2, 1, 3])
def call(self, inputs):
query, key, value, mask = inputs['query'], inputs['key'], inputs[
'value'], inputs['mask']
batch_size = tf.shape(query)[0]
# Q, K, V에 각각 Dense를 적용합니다
query = self.query_dense(query)
key = self.key_dense(key)
value = self.value_dense(value)
# 병렬 연산을 위한 머리를 여러 개 만듭니다
query = self.split_heads(query, batch_size)
key = self.split_heads(key, batch_size)
value = self.split_heads(value, batch_size)
# 스케일드 닷 프로덕트 어텐션 함수
scaled_attention = scaled_dot_product_attention(query, key, value, mask)
scaled_attention = tf.transpose(scaled_attention, perm=[0, 2, 1, 3])
# 어텐션 연산 후에 각 결과를 다시 연결(concatenate)합니다
concat_attention = tf.reshape(scaled_attention,
(batch_size, -1, self.d_model))
# 최종 결과에도 Dense를 한 번 더 적용합니다
outputs = self.dense(concat_attention)
return outputs
print("슝=3")
assert
assert-가정설정문
assert는 뒤의 조건이 True가 아니면 AssertError를 발생한다.
>>> a = 3
>>> assert a == 2
#결과
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
왜 assert가 필요한 것일까?
어떤 함수는 성능을 높이기 위해 반드시 정수만을 입력받아 처리하도록 만들 수 있다. 이런 함수를 만들기 위해서는 반드시 함수에 정수만 들어오는지 확인할 필요가 있다. 이를 위해 if문을 사용할 수도 있고 '예외 처리'를 사용할 수도 있지만 '가정 설정문'을 사용하는 방법도 있다.
tf.reshape(
inputs, shape = (batch_size, -1, self.num_heads, self.depth)
)
# 최종 결과에도 Dense를 한 번 더 적용합니다
outputs = self.dense(concat_attention)
mask = tf.cast(tf.math_equal(x, 0), tf.float32)
look ahead masking 함수
def create_look_ahead_mask(x):
seq_len = tf.shape(x)[1]
look_ahead_mask = 1 - tf.linalg.band_part(tf.ones((seq_len, seq_len)), -1, 0)
padding_mask = create_padding_mask(x)
return tf.maximum(look_ahead_mask, padding_mask)
print("슝=3")
트랜스포머 인코딩 층
inputs = tf.keras.Input(shape(None, d_model), name = 'inputs')
...
attention = tf.keras.layers.LayerNormalization(
tf.keras.Input()
tf.keras.layers.LayerNormalization()
outputs = tf.keras.layers.Dense(units = d_model)(outputs)
왜 유닛을 디모델로 잡는지? - Dense의 unit값이 뭘 의미하는지 먼저 확인
shape = (1, None, None),
tf의 shape 내용 확인 차원- 행-열???
outputs_sequence = tf.expand_dims(START_TOKEN, 0)
Q,A 동일한 것 찾기
data[data.duplicated(subset = ['Q','A'])]