Closed hccho2 closed 4 years ago
@hccho2 님 정말 능력자시네요! 디버깅을 위해 다음처럼 코드를 실행했습니다.
import sys
sys.path.append('models')
import tensorflow as tf
from preprocess import get_tokenizer, post_processing
from bilm import Batcher, BidirectionalLanguageModel, weight_layers
options_fname = "data/sentence-embeddings/elmo/pretrain-ckpt/options.json"
pretrain_model_fname = "data/sentence-embeddings/elmo/pretrain-ckpt/elmo.model"
vocab_fpath = "data/sentence-embeddings/elmo/pretrain-ckpt/elmo-vocab.txt"
max_characters_per_token = 30
bilm = BidirectionalLanguageModel(options_fname, pretrain_model_fname)
ids_placeholder = tf.placeholder(tf.int32, shape=(None, None, max_characters_per_token), name='input')
labels_placeholder = tf.placeholder(tf.int32, shape=(None))
embeddings_op = bilm(ids_placeholder)
input_lengths = embeddings_op['lengths']
dropout_keep_prob = tf.constant(1.0, dtype=tf.float32)
elmo_embeddings = weight_layers("elmo_embeddings",
embeddings_op,
l2_coef=0.0,
use_top_only=False,
do_layer_norm=True)
features = tf.nn.dropout(elmo_embeddings['weighted_op'], dropout_keep_prob)
lstm_cell_fw = tf.nn.rnn_cell.LSTMCell(num_units=512,
cell_clip=5,
proj_clip=5)
lstm_cell_bw = tf.nn.rnn_cell.LSTMCell(num_units=512,
cell_clip=5,
proj_clip=5)
lstm_output, _ = tf.nn.bidirectional_dynamic_rnn(cell_fw=lstm_cell_fw,
cell_bw=lstm_cell_bw,
inputs=features,
sequence_length=input_lengths,
dtype=tf.float32)
output_fw, output_bw = lstm_output
H = tf.contrib.layers.fully_connected(inputs=output_fw + output_bw, num_outputs=256, activation_fn=tf.nn.tanh)
attention_score = tf.nn.softmax(tf.contrib.layers.fully_connected(inputs=H, num_outputs=1, activation_fn=None))
attention_score2 = tf.nn.softmax(tf.contrib.layers.fully_connected(inputs=H, num_outputs=1, activation_fn=None), axis=1)
sess = tf.Session()
batcher = Batcher(lm_vocab_file=vocab_fpath, max_token_length=max_characters_per_token)
dummy_data = batcher.batch_sentences([["a", "b", "cd"], ["ef", "g"]])
sess.run(tf.global_variables_initializer())
sess.run(attention_score, feed_dict={ids_placeholder: dummy_data})
sess.run(attention_score2, feed_dict={ids_placeholder: dummy_data})
현재 코드는 attention_score
, 버그 수정 제안 주신 것은 attention_score2
입니다. 다음 코드 실행 결과를 보면 아시다시피 shape는 같지만 안에 있는 내용이 말씀하신 것과 정확히 일치합니다.
코드를 고쳐서 커밋해 두겠습니다. 아울러 ELMo 튜닝 점수표 역시 전자책과 정오표에 반영해 두겠습니다. 제보 정말 진심!!! 감사드립니다!
확인 감사합니다. 제가 말씀드린 것이 버그라면, page254~255에 있는 make_word_embedding_graph()에 있는 attention_score도 같이 수정되어야 될 것 같습니다.
@hccho2 님 말씀하신 attention 버그를 수정해 코드 6-13(random embedding tuning), 코드 6-15(fasttext embedding tuning), 코드 6-23(ELMo embedding tuning)에 해당하는 실험을 다시 진행했습니다. random/fasttext embedding tuning은 make_input
버그를 수정한 내용까지 반영한 결과입니다. 그 결과를 간략히 나타내면 다음과 같습니다(accuracy, loss 변동분은 기존 도서 제시 내용 대비 변화량을 나타냅니다).
1epoch
model | accuracy 변동분(%P) | loss 변동분 |
---|---|---|
random | +9.28 | -0.1019 |
fasttext | +2.72 | -0.1156 |
ELMo | +6.00 | -0.1808 |
최고 성적 (버그 수정 후)
model | accuracy 변동분(%P) |
---|---|
random | +1.62 |
fasttext | +1.44 |
elmo | +0.02 |
요컨대 attention 버그 수정으로 임베딩 종류를 가리지 않고 초기 학습 정확도가 확 높아지고 loss가 감소하는 것으로 나타났습니다. 다만 ELMo의 경우 ELMo 내부에 attention 역할을 수행하는 장치가 이미 있어서인지, attention 버그 수정으로 최고점이 갱신되었다고 말하기 어려운 것 같습니다. 다시 한번 감사드립니다.
page 265. tune_utils.py에서 make_elmo_graph()에서
이렇게 되어 있는데, softmax를 취하면서, 모든 값이 1이 되어 버립니다.
이렇게 되어야 될 것 같습니다.