Google Pretrained Word2Vec
- Sentiment Analysis #2 에서 Word Embedding Layer을 사용
- 사전의 단어 개수 X 워드 벡터 사이즈만큼의 크기를 가진 학습 파라미터
- 감성분류 모델이 학습이 잘 되었다면, Embedding 레이어에 학습된 워드 벡터들도 의미 공간상에 유의미한 형태로 학습되었을 것
!pip list | grep gensim
gensim 4.0.1
import os
from os.path import join
os.getcwd()
'/Volumes/GoogleDrive/My Drive/Colab_Notebook/aiffel_lms/E7_text_sentiment'
root_path = '/Volumes/GoogleDrive/My Drive/Colab_Notebook/aiffel_lms/E7_text_sentiment/data'
- Model_1의 Embedding Layer weights 확인
model_1.summary()
Model: "model1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
word_embedding (Embedding) (None, None, 16) 160000
_________________________________________________________________
lstm_5 (LSTM) (None, 32) 6272
_________________________________________________________________
dense_26 (Dense) (None, 8) 264
_________________________________________________________________
dense_27 (Dense) (None, 1) 9
=================================================================
Total params: 166,545
Trainable params: 166,545
Non-trainable params: 0
_________________________________________________________________
embedding_layer = model_1.layers[0]
weights = embedding_layer.get_weights()[0]
print(weights.shape)
(10000, 16)
- 워드 벡터 파일을 저장할 디렉토리를 먼저 생성
word2vec_file_path = join(root_path, 'word2vec.txt')
f = open(word2vec_file_path, 'w')
f.write('{} {}\n'.format(vocab_size-4, word_vector_dim))
vectors = model_1.get_weights()[0]
for i in range(4,vocab_size):
f.write('{} {}\n'.format(index_to_word[i], ' '.join(map(str, list(vectors[i, :])))))
f.close()
- gensim에서 제공하는 패키지를 이용해, 위에 남긴 임베딩 파라미터를 읽어서 word vector로 활용할 수 있음
from gensim.models.keyedvectors import Word2VecKeyedVectors
word_vectors = Word2VecKeyedVectors.load_word2vec_format(word2vec_file_path, binary=False)
vector = word_vectors['computer']
vector
array([ 0.05835353, 0.02972049, 0.00399579, 0.01061273, -0.03945053,
-0.06081106, -0.00823087, -0.07572383, -0.05524068, -0.01307657,
0.00311514, -0.0067417 , -0.07293623, -0.01328314, 0.02848107,
-0.00361134], dtype=float32)
- gensim을 활용하여 워드 벡터가 의미벡터 공간상에 유의미하게 학습되었는지 확인하는 방법 중에, 단어를 하나 주고 그와 가장 유사한 단어와 그 유사도를 확인하는 방법
word_vectors.similar_by_word("love")
[('remakes', 0.9091728925704956),
('stardom', 0.898648202419281),
('jealousy', 0.8963329792022705),
('brutality', 0.8921096324920654),
('der', 0.8868229985237122),
('expressions', 0.8729190826416016),
('live', 0.872138261795044),
('sheila', 0.8695423007011414),
('depicts', 0.8669462203979492),
('sack', 0.8613362312316895)]
- 유사한 다른 단어를 잘 찾았다고 느껴지지는 않음
- 간단한 데이터로 감성분류 테스크를 학습한 것으로는 워드 벡터가 유의미하게 학습되기는 어려워 보임
- 구글에서 제공하는 Word2Vec이라는 사전학습된(Pretrained) 워드 임베딩 모델을 가져다 활용하고자 함
- Word2Vec은 1억 개의 단어로 구성된 Google News dataset을 바탕으로 학습된 것
- 총 300만 개의 단어를 각각 300차원의 벡터로 표현한 것
- 학습된 Word2Vec이라는 것도 Embedding Layer와 원리는 동일
- 전이학습 떄문에 사전학습된 임베딩을 활용하는 것이 유리한 것
from gensim.models import KeyedVectors
word2vec_path =
word2vec = KeyedVectors.load_word2vec_format(word2vec_path, binary=True, limit=1000000)
vector = word2vec['computer']
vector
- 300dim의 벡터로 이루어진 300만 개의 단어
- 이 단어 사전을 메모리에 모두 로딩하면 메모리 사용이 너무 높아짐
- KeyedVectors.load_word2vec_format 메소드로 워드 벡터를 로딩할 때 가장 많이 사용되는 상위 100만 개만 limt으로 조건을 주어 로딩
word2vec.similar_by_word("love")
vocab_size = 10000
word_vector_dim = 300
embedding_matrix = np.random.rand(vocab_size, word_vector_dim)
for i in range(4,vocab_size):
if index_to_word[i] in word2vec:
embedding_matrix[i] = word2vec[index_to_word[i]]
from tensorflow.keras.initializers import Constant
vocab_size = 10000
word_vector_dim = 300
model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size,
word_vector_dim,
embeddings_initializer=Constant(embedding_matrix),
input_length=maxlen,
trainable=True))
model.add(keras.layers.Conv1D(16, 7, activation='relu'))
model.add(keras.layers.MaxPooling1D(5))
model.add(keras.layers.Conv1D(16, 7, activation='relu'))
model.add(keras.layers.GlobalMaxPooling1D())
model.add(keras.layers.Dense(8, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
epochs=20
history = model.fit(partial_x_train,
partial_y_train,
epochs=epochs,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)
results = model.evaluate(x_test, y_test, verbose=2)
print(results)