1. 용어 설명
- 토큰(token)
- 텍스트를 나누는 단위
- 토큰화(tokenization): 토큰으로 나누는 작업
- n-gram
- 문장에서 추출한 N개(또는 그 이하)의 연속된 단어 그룹
- 같은 개념이 '문자'에도 적용 가능
2. 문자 수준 원-핫 인코딩
import numpy as np
samples = ['The cat sat on the mat.',
'The dog ate my homeworks.']
token_index = {}
for sample in samples:
for word in sample.split():
if word not in token_index:
token_index[word] = len(token_index) + 1
max_len = 10
results = np.zeros(shape = (len(samples), max_len,
max(token_index.values()) + 1))
# 원-핫 인코딩
for i, sample in enumerate(samples):
for j, word in list(enumerate(sample.split()))[:max_len]:
index = token_index.get(word)
results[i, j, index] = 1.
results
# 출력 결과
array([[[0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # The
[0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], # cat
[0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.], # sat
[0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.], # on
[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.], # the
[0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], # mat
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]],
[[0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # The
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.], # dog
[0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.], # ate
[0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.], # my
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.], # homeworks
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]])
3. 케라스를 사용한 단어 수준 원-핫 인코딩
- fit_on_texts()
- texts_to_sequences()
- texts_to_matrix()
from tensorflow.keras.preprocessing.text import Tokenizer
samples = ['The cat sat on the mat.',
'The dog ate my homeworks.']
tokenizer = Tokenizer(num_words = 1000)
tokenizer.fit_on_texts(samples)
sequences = tokenizer.texts_to_sequences(samples)
ohe_results = tokenizer.texts_to_matrix(samples, mode = 'binary')
word_index = tokenizer.word_index
print(len(word_index))
# 출력 결과
9
# 9개의 토큰을 가지고 있음
# 단어의 순서
sequences
# 출력 결과
[[1, 2, 3, 4, 1, 5], [1, 6, 7, 8, 9]]
# 원-핫 인코딩 결과
print(ohe_results.shape)
print(ohe_results)
# 출력 결과
(2, 1000)
[[0. 1. 1. ... 0. 0. 0.]
[0. 1. 0. ... 0. 0. 0.]]
word_index
# 출력 결과
{'the': 1,
'cat': 2,
'sat': 3,
'on': 4,
'mat': 5,
'dog': 6,
'ate': 7,
'my': 8,
'homeworks': 9}
# 단어 인덱스에 따라 sequences의 값이 정해짐
- 토큰화 예제
- OOV: Out Of Vocabulary
- 새로운 문장에서 기존에 토큰화한 문장에 존재하지 않으면 OOV로 대체됨
from tensorflow.keras.preprocessing.text import Tokenizer
samples = ["I'm the smartest student.",
"I'm the best student."]
tokenizer = Tokenizer(num_words = 10, oov_token = '<OOV>')
tokenizer.fit_on_texts(samples)
sequences = tokenizer.texts_to_sequences(samples)
binary_results = tokenizer.texts_to_matrix(samples, mode = 'binary')
print(tokenizer.word_index)
# 출력 결과
# 현재 tokenizer에 대한 word_index
{'<OOV>': 1, "i'm": 2, 'the': 3, 'student': 4, 'smartest': 5, 'best': 6}
binary_results
# 출력 결과
array([[0., 0., 1., 1., 1., 1., 0., 0., 0., 0.],
[0., 0., 1., 1., 1., 0., 1., 0., 0., 0.]])
- 테스트
test = ["I'm the fastest student."]
test_seq = tokenizer.texts_to_sequences(test)
print("word index:", tokenizer.word_index)
print("Test Text:", test)
print("Test Seq:", test_seq)
# 출력 결과
word index: {'<OOV>': 1, "i'm": 2, 'the': 3, 'student': 4, 'smartest': 5, 'best': 6}
Test Text: ["I'm the fastest student."]
Test Seq: [[2, 3, 1, 4]]
# fastest는 vocabulary에 없는 oov(out-of-vocabulary) 값이므로 1로 표시됨
4. 원-핫 단어 벡터와 단어 임베딩
- 원-핫 단어 벡터
- 데이터가 희소(sparse)
- 고차원
- 단어 임베딩
- 밀집(dense)
- 저차원
5. 단어 임베딩
- 단어 간 벡터 사이의 거리가 가까운, 즉 비슷한 단어들끼리 임베딩
- 거리 외에 임베딩 공간의 특정 방향도 의미를 가질 수 있음
- Embedding Layer
- 특정 단어를 나타내는 정수 인덱스를 밀집 벡터(dense vector)로 매핑하는 딕셔너리 레이어
- 입력: (samples, sqquence_length)
- 출력: (samples, sequences_length, dim)
from tensorflow.keras.layers import Embedding
embedding_layer = Embedding(1000, 64)
embedding_layer
# 출력 결과
<keras.layers.core.embedding.Embedding at 0x265f5b12fa0>
# embedding 객체가 출력됨
6. 예제: IMDB 데이터
- 인터넷 영화 데이터베이스(Internet Movie Database)
- 양극단의 리뷰 5만개로 이루어진 데이터셋
- 훈련 데이터: 25,000개
- 테스트 데이터: 25,000개
- modules import
from tensorflow.keras.datasets import imdb
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Dense, Flatten
- 데이터 로드
num_words = 1000
max_len = 20
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words = num_words)
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
# 출력 결과
(25000,)
(25000,)
(25000,)
(25000,)
- 데이터 확인
- 긍정: 1
- 부정: 0
print(x_train[0])
print(y_train[0])
# 출력 결과
# 리뷰 데이터의 sequence와 긍정/부정 결과 출력
[1, 14, 22, 16, 43, 530, 973, 2, 2, 65, 458, 2, 66, 2, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 2, 2, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2, 19, 14, 22, 4, 2, 2, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 2, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2, 2, 16, 480, 66, 2, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 2, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 2, 15, 256, 4, 2, 7, 2, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 2, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2, 56, 26, 141, 6, 194, 2, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 2, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 2, 88, 12, 16, 283, 5, 16, 2, 113, 103, 32, 15, 16, 2, 19, 178, 32]
1
- 참고) IMDB 데이터셋에서 가장 많이 사용된 단어
word_index = {}
for key, val in imdb.get_word_index().items():
word_index[val] = key
for i in range(1, 6):
print(word_index[i])
# 출력 결과
the
and
a
of
to
- 데이터 전처리
- 모든 데이터를 같은 길이로 맞추기
- pad_sequence()
- 데이터가 maxlen보다 길면 데이터를 자름
- 데이터가 길면 padding 설정
- pre: 데이터 앞에 0으로 채움
- post: 데이터 뒤에 0으로 채움
- pad_sequence()
- 모든 데이터(문장 하나하나)가 같은 길이로 맞춰져야 Embedding 레이어 사용가능
from tensorflow.keras.preprocessing.sequence import pad_sequences
pad_x_train = pad_sequences(x_train, maxlen = max_len, padding = 'pre')
pad_x_test = pad_sequences(x_test, maxlen = max_len, padding = 'pre')
print(len(x_train[0]))
print(len(pad_x_train[0]))
# 출력 결과
218
20
# 최대 길이만큼 줄어듬
print(x_train[0])
print(pad_x_train[0])
# 출력 결과
[1, 14, 22, 16, 43, 530, 973, 2, 2, 65, 458, 2, 66, 2, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 2, 2, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2, 19, 14, 22, 4, 2, 2, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 2, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2, 2, 16, 480, 66, 2, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 2, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 2, 15, 256, 4, 2, 7, 2, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 2, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2, 56, 26, 141, 6, 194, 2, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 2, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 2, 88, 12, 16, 283, 5, 16, 2, 113, 103, 32, 15, 16, 2, 19, 178, 32]
[ 65 16 38 2 88 12 16 283 5 16 2 113 103 32 15 16 2 19 178 32]
- 모델 구성
model = Sequential()
model.add(Embedding(input_dim = num_words, output_dim = 32, input_length = max_len))
model.add(Flatten())
model.add(Dense(1, activation = 'sigmoid'))
model.summary()
# 출력 결과
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 20, 32) 32000
flatten (Flatten) (None, 640) 0
dense (Dense) (None, 1) 641
=================================================================
Total params: 32,641
Trainable params: 32,641
Non-trainable params: 0
_________________________________________________________________
- 모델 컴파일 및 학습
model.compile(optimizer = 'rmsprop',
loss = 'binary_crossentropy',
metrics = ['accuracy'])
history = model.fit(pad_x_train, y_train,
epochs = 10,
batch_size = 32,
validation_split = 0.2)
- 시각화
import matplotlib.pyplot as plt
hist_dict = history.history
plt.plot(hist_dict['loss'], 'b--', label = 'Train Loss')
plt.plot(hist_dict['val_loss'], 'r:', label = 'Validation Loss')
plt.legend()
plt.grid()
plt.figure()
plt.plot(hist_dict['accuracy'], 'b--', label = 'Train Accuracy')
plt.plot(hist_dict['val_accuracy'], 'r:', label = 'Validation Accuracy')
plt.legend()
plt.grid()
plt.show()
- 모델 평가
model.evaluate(pad_x_test, y_test)
# 출력 결과
loss: 0.5986 - accuracy: 0.7085
[0.5986294150352478, 0.7085199952125549]
- 단어의 수를 늘린 후 재학습
num_words = 1000
max_len = 500
pad_x_train_2 = pad_sequences(x_train, maxlen = max_len, padding = 'pre')
pad_x_test_2 = pad_sequences(x_test, maxlen = max_len, padding = 'pre')
print(x_train[0])
print(pad_x_train_2[0])
# 출력 결과
[1, 14, 22, 16, 43, 530, 973, 2, 2, 65, 458, 2, 66, 2, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 2, 2, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2, 19, 14, 22, 4, 2, 2, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 2, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2, 2, 16, 480, 66, 2, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 2, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 2, 15, 256, 4, 2, 7, 2, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 2, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2, 56, 26, 141, 6, 194, 2, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 2, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 2, 88, 12, 16, 283, 5, 16, 2, 113, 103, 32, 15, 16, 2, 19, 178, 32]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 14 22 16 43 530
973 2 2 65 458 2 66 2 4 173 36 256 5 25 100 43 838 112
50 670 2 9 35 480 284 5 150 4 172 112 167 2 336 385 39 4
172 2 2 17 546 38 13 447 4 192 50 16 6 147 2 19 14 22
4 2 2 469 4 22 71 87 12 16 43 530 38 76 15 13 2 4
22 17 515 17 12 16 626 18 2 5 62 386 12 8 316 8 106 5
4 2 2 16 480 66 2 33 4 130 12 16 38 619 5 25 124 51
36 135 48 25 2 33 6 22 12 215 28 77 52 5 14 407 16 82
2 8 4 107 117 2 15 256 4 2 7 2 5 723 36 71 43 530
476 26 400 317 46 7 4 2 2 13 104 88 4 381 15 297 98 32
2 56 26 141 6 194 2 18 4 226 22 21 134 476 26 480 5 144
30 2 18 51 36 28 224 92 25 104 4 226 65 16 38 2 88 12
16 283 5 16 2 113 103 32 15 16 2 19 178 32]
# 500이라는 최대 길이 맞추고 남은 공간을 0으로 채움, pre이므로 앞쪽에 채움
model = Sequential()
model.add(Embedding(input_dim = num_words, output_dim = 32, input_length = max_len))
model.add(Flatten())
model.add(Dense(1, activation = 'sigmoid'))
model.compile(optimizer = 'rmsprop',
loss = 'binary_crossentropy',
metrics = ['accuracy'])
history2 = model.fit(pad_x_train_2, y_train,
epochs = 10,
batch_size = 32,
validation_split = 0.2)
hist_dict_2 = history2.history
plt.plot(hist_dict_2['loss'], 'b--', label = 'Train Loss')
plt.plot(hist_dict_2['val_loss'], 'r:', label = 'Validation Loss')
plt.legend()
plt.grid()
plt.figure()
plt.plot(hist_dict_2['accuracy'], 'b--', label = 'Train Accuracy')
plt.plot(hist_dict_2['val_accuracy'], 'r:', label = 'Validation Accuracy')
plt.legend()
plt.grid()
plt.show()
model.evaluate(pad_x_test_2, y_test)
# 출력 결과
loss: 0.5295 - accuracy: 0.8316
[0.5295160412788391, 0.8316400051116943]
- 위의 결과도 정확도로 봤을때는 나쁘지 않지만 과적합이 됨
- 그 이유는
- 단어 간 관계나 문장 구조 등 의미적 연결 고려 x
- 시퀀스 전체를 고려한 특성을 학습하는 것은 Embedding 층 위에 RNN층이나 1D 합성곱을 추가하는 것이 좋음
● 단어 임베딩의 종류
- LSA
- Word2Vec
- Blove
- FastText
- etc...
7. Word2Vec
- 분류 등과 같이 별도의 레이블 없이 텍스트 자체만 있어도 학습이 가능
- Word2Vec의 방식(주변 단어의 관계를 이용)
- CBOW(Continuous Bag-Of-Word)
- 주변 단어의 임베딩을 더해서 대상 단어를 예측
- Skip-Gram
- 대상 단어의 임베딩으로 주변 단어를 예측
- 일반적으로 CBOW보다 성능이 좋은 편
- 한번에 여러 단어를 예측해야하기 때문에 비효율적
- 최근에는 negative sampling이라는 방법 사용
- CBOW(Continuous Bag-Of-Word)
8. 구텐베르크 프로젝트 예제
import requests
import re
- 데이터 다운로드
res = requests.get('https://www.gutenberg.org/files/2591/2591-0.txt')
res
# 출력 결과
<Response [200]>
# 200이면 잘 응답한 것
# 404면 오류 발생한 것
- 데이터 전처리
grimm = res.text[2801:530661]
grimm = re.sub(r'[^a-zA-Z\. ]', ' ', grimm)
sentences = grimm.split('. ')
data = [s.split() for s in sentences]
len(data) # 3468
data[0]
# 출력 결과
['SECOND',
'STORY',
'THE',
'SALAD',
'THE',
'STORY',
'OF',
'THE',
'YOUTH',
'WHO',
'WENT',
'FORTH',
'TO',
'LEARN',
'WHAT',
'FEAR',
'WAS',
'KING',
'GRISLY',
'BEARD',
'IRON',
'HANS',
'CAT',
'SKIN',
'SNOW',
...
'tree',
'which',
'bore',
'golden',
'apples']
# gensim 패키지로부터 Word2Vec을 불러오기
from gensim.models.word2vec import Word2Vec
# sg인자에 0을 넘겨주면 CBOW, 1을 넘겨주면 Skip-gram
# 최소 3번은 등장한 단어, 동시 처리의 수는 4개
model = Word2Vec(data, sg = 1, vector_size = 100, window = 3, min_count = 3, workers = 4)
- 모델 저장 및 로드
# 저장
model.save('word2vec.model')
# 로드
pretrained_model = Word2Vec.load('word2vec.model')
- 단어를 벡터로 변환
- wv
pretrained_model.wv['princess']
# 출력 결과
array([-0.19268924, 0.17087255, -0.13460916, 0.20450976, 0.03542079,
-0.31665406, 0.13296 , 0.54076153, -0.18337499, -0.21417093,
0.02725333, -0.31845513, 0.01819889, 0.10720193, 0.16601542,
-0.19728081, 0.05753807, -0.12273175, -0.17903367, -0.22576232,
0.2438455 , 0.13664703, 0.18498562, -0.1679803 , 0.07735273,
-0.00432668, -0.00775897, -0.08363435, -0.12566872, -0.07055762,
0.02887373, -0.08917326, 0.17351009, -0.18784055, -0.20769958,
0.19657052, 0.01372425, -0.074237 , -0.10052767, -0.11275681,
0.06725535, -0.09701315, 0.02844668, 0.05958825, -0.02586031,
-0.01711333, -0.11226629, -0.08671231, 0.1945969 , 0.01690222,
0.07196116, -0.08172472, -0.05373074, -0.14637838, 0.16281295,
0.06222549, 0.10643765, 0.07477342, -0.16238536, 0.03527208,
-0.04292673, 0.04597842, 0.13826323, -0.19217554, -0.25257504,
0.10983958, 0.03293723, 0.4319519 , -0.21335553, 0.24770555,
-0.00888118, 0.02231867, 0.17330043, -0.10485211, 0.35415375,
-0.08000654, 0.01478033, -0.03938808, -0.06453493, 0.02249427,
-0.21435274, -0.01287377, -0.2137464 , 0.21174915, -0.1006554 ,
0.00902446, 0.05607878, 0.16368881, 0.13859129, -0.01395336,
0.09382439, 0.08065708, -0.056269 , 0.09765122, 0.188912 ,
0.1668056 , -0.01361183, -0.14287405, -0.11452819, -0.20357099],
dtype=float32)
# 'princess'라는 단어를 벡터로 변환한 값
- 유추 또는 유비(analogy)
- wv.similarity()에 두 단어를 넣어주면 코사인 유사도를 구할 수 있음
pretrained_model.wv.similarity('king', 'prince')
# 출력 결과
0.8212076
- wv.most_similar()에 단어를 넘겨주면 가장 유사한 단어를 추출할 수 있음
pretrained_model.wv.most_similar('king')
# 출력 결과
[('daughter', 0.9241937398910522),
('son', 0.9213796257972717),
('woman', 0.9177201390266418),
('man', 0.897368848323822),
('queen', 0.8747967481613159),
('miller', 0.8610494136810303),
('old', 0.8595746755599976),
('young', 0.8504902124404907),
('wolf', 0.8450464010238647),
('But', 0.8406485319137573)]
- wv.most_similar()에 positive와 negetive라는 옵션을 넘길 수 있음
# 'man + princess - woman'을 벡터 계산을 한 값을 출력
# man이고 princess인데 woman이 아닌 단어
pretrained_model.wv.most_similar(positive = ['man', 'princess'], negative = ['woman'])
# 출력 결과
[('bird', 0.9595717787742615),
('prince', 0.9491060376167297),
('cook', 0.9410891532897949),
('bride', 0.9401964545249939),
('huntsman', 0.9375050067901611),
('mouse', 0.9356588125228882),
('cat', 0.9344455003738403),
('giant', 0.9341970682144165),
('gardener', 0.9327394366264343),
('maid', 0.9326624870300293)]
- gensim으로 학습된 단어 임베딩을 Keras에서 불러오기
from keras.models import Sequential
from keras.layers import Embedding
num_words, emb_dim = pretrained_model.wv.vectors.shape
print(num_words)
print(emb_dim)
# 출력 결과
2446
100
- gensim으로 학습된 단어 임베딩을 Keras의 임베딩 레이어의 가중치로 설정
emb = Embedding(input_dim = num_words, output_dim = emb_dim,
trainable = False, weights = [pretrained_model.wv.vectors])
model = Sequential()
model.add(emb)
model.summary()
# 출력 결과
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_3 (Embedding) (None, None, 100) 244600
=================================================================
Total params: 244,600
Trainable params: 0
Non-trainable params: 244,600
_________________________________________________________________
# princess에 대한 결과 벡터
i = pretrained_model.wv.index_to_key.index('princess')
model.predict([i])
# 출력 결과
array([[-0.19268924, 0.17087255, -0.13460916, 0.20450976, 0.03542079,
-0.31665406, 0.13296 , 0.54076153, -0.18337499, -0.21417093,
0.02725333, -0.31845513, 0.01819889, 0.10720193, 0.16601542,
-0.19728081, 0.05753807, -0.12273175, -0.17903367, -0.22576232,
0.2438455 , 0.13664703, 0.18498562, -0.1679803 , 0.07735273,
-0.00432668, -0.00775897, -0.08363435, -0.12566872, -0.07055762,
0.02887373, -0.08917326, 0.17351009, -0.18784055, -0.20769958,
0.19657052, 0.01372425, -0.074237 , -0.10052767, -0.11275681,
0.06725535, -0.09701315, 0.02844668, 0.05958825, -0.02586031,
-0.01711333, -0.11226629, -0.08671231, 0.1945969 , 0.01690222,
0.07196116, -0.08172472, -0.05373074, -0.14637838, 0.16281295,
0.06222549, 0.10643765, 0.07477342, -0.16238536, 0.03527208,
-0.04292673, 0.04597842, 0.13826323, -0.19217554, -0.25257504,
0.10983958, 0.03293723, 0.4319519 , -0.21335553, 0.24770555,
-0.00888118, 0.02231867, 0.17330043, -0.10485211, 0.35415375,
-0.08000654, 0.01478033, -0.03938808, -0.06453493, 0.02249427,
-0.21435274, -0.01287377, -0.2137464 , 0.21174915, -0.1006554 ,
0.00902446, 0.05607878, 0.16368881, 0.13859129, -0.01395336,
0.09382439, 0.08065708, -0.056269 , 0.09765122, 0.188912 ,
0.1668056 , -0.01361183, -0.14287405, -0.11452819, -0.20357099]],
dtype=float32)
'Python > Deep Learning' 카테고리의 다른 글
[딥러닝-케라스] 케라스 순환신경망(RNN, LSTM, GRU) (0) | 2023.06.03 |
---|---|
[딥러닝-케라스] 케라스 텍스트 처리 및 임베딩(2) (0) | 2023.05.18 |
[딥러닝-케라스] 케라스 전이학습 (1) | 2023.05.17 |
[딥러닝-케라스] 케라스 CIFAR10 CNN 모델 (0) | 2023.05.16 |
[딥러닝-케라스] 케라스 Fashion MNIST CNN 모델 (0) | 2023.05.14 |