E-11

차보경·2022년 6월 15일
0

Training

목록 보기
1/2

[NLP] 자연어처리 임베딩 모델 총정리 (word2vec부터 BERT까지)

한글말뭉치정리

Attention과 Transformer

LSTM, GRU의 한계와 Attention의 등장


############## 포지셔널 인코딩 레이어 ################
한번에 들어온 단어들의 위치를 알려주는 벡터(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() : 거듭제곱 값을 계산
  • 자주쓰는 tf. 수학 코드
  • sines = tf.math.sin(angle_rads[:, 0::2])
  • Python array[::] 용법 : arr[::], arr[1:2:3], arr[::-1] 등으로 배열의 index에 접근하는 방법을 Extended Slices 라고 함.
    -arr[A:B:C]의 의미는, index A 부터 index B 까지 C의 간격으로 배열을 만들어라는 말입니다.만약 A가 None 이라면, 처음부터 라는 뜻이고B가 None 이라면, 할 수 있는 데까지 (C가 양수라면 마지막 index까지, C가 음수라면 첫 index까지가 되겠습니다.)라는 뜻입니다.마지막으로 C가 None 이라면 한 칸 간격으로 라는 뜻입니다.
  • 출처 : Wonkyung's blog:티스토리
  • tf.transpose(pos_encoding, [1, 2, 0])
  • pos_encoding = pos_encoding[tf.newaxis, ...]

# 스케일드 닷 프로덕트 어텐션 함수
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")
  • depth가 무엇을 나타내는지, tf.matmul은 무슨 함수인지, 패딩에 마스크는 왜 추가하는지

멀티 헤드 어텐션 구현하기 부분 중

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문을 사용할 수도 있고 '예외 처리'를 사용할 수도 있지만 '가정 설정문'을 사용하는 방법도 있다.

  • 위에 self.q/k/v.dense값 구할때 왜 unit으로 d_model을 넣어주지??? 나눈 depth로 넣어줘야하는거 아닌가??

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()
      attention = tf.keras.layers.LayerNormalization(
      epsilon = 1e-6)(input + attention)

  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'])]

profile
차보의 Data Engineer 도전기♥ (근데 기록을 곁들인)

0개의 댓글