인프런 커뮤니티 질문&답변
length_penalty 부분이 없는 것 같습니다.
작성
·
22
0
130강 끝날 즈음에 다음 섹션이 아니라 length_penalty에 대한 설명을 해주신다고 하셨는데 없는 것 같습니다!
답변 1
0
안녕하십니까,
아, 이걸 설명하는 걸 빼먹었군요. 알려 주셔서 감사합니다.
일단 글로 먼저 말씀드립니다. 추가 영상은 시간이 나는대로 작성하겠습니다.
single_translate_beam() 과 같은 decode 시 고려해야 할 사항이, 문장을 생성하는 토큰들이 늘어날 수록 토큰 생성 확률(확률값은 1보다 작음)을 곱하게 되어서(여기서는 로그 확률로서, 확률값이 1보다 작아서, 로그 확률은 음수값이 됨) 토큰 개수가 작은, 짧은 길이의 문장들만 선호되는 현상이 발생하게 됩니다.
이를 개선하기 위한 방식이 짧은 길이의 문장들은 penalty를 주는 방법인데, 일반적으로 누적 로그 확률을 문장 길이(토큰 수, length)로 나누되, penalty 적용 강도를 적용 할 수 있도록 합니다.
이를 위해, 아래와 같은 length_penalty_fn() 함수를 통해 beam 선택 시 짧은 길이의 문장들은 penalty를 주되, alpha값으로 적용 강도를 조정합니다.
def length_penalty_fn(length, alpha):
return length ** alpha
여기서 alpha가 바로 length_penalty 값입니다.
final score filtering은 누적 로그확률 / length_penalty_fn 함수 반환값을 적용하게 됩니다. alpha가 0 이면 length penalty가 없으며(length ** alpha = 1임), a가 클수록 length penalty가 커집니다. 1로 설정하면 짧은 문장 편향은 사라지지만, 반복/미사여구 사용이 많아지는 과도한 보정이 됩니다. 1 이상은 사용하지 않고, 보통 0.6 ~ 0.8 정도 적용합니다.
결국 single_translate_beam(...)에서 sorted로 candidates 들을 key에서 정의한 lambda 함수, 즉 누적 로그 확률을 length_penalty_fn()으로 나눈 기준으로 sescending 정렬한 결과를 beam_width 갯수만큼 추출하여 최종 beams를 만들게 됩니다.
beams = sorted(
candidates,
key=lambda x: x[1]/length_penalty_fn(x[0].shape[1], length_penalty), # x[1]은 누적 로그 확률. x[0][0]
reverse=True,
)[:beam_width]
감사합니다.




