forked from selfedu-rus/neural-network
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lesson 20. RNN chars prediction.py
62 lines (44 loc) · 2.85 KB
/
lesson 20. RNN chars prediction.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import numpy as np
import re
from tensorflow.keras.layers import Dense, SimpleRNN, Input
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.text import Tokenizer
with open('train_data_true', 'r', encoding='utf-8') as f:
text = f.read()
text = text.replace('\ufeff', '') # убираем первый невидимый символ
text = re.sub(r'[^А-я ]', '', text) # заменяем все символы кроме кириллицы на пустые символы
# парсим текст, как последовательность символов
num_characters = 34 # 33 буквы + пробел
tokenizer = Tokenizer(num_words=num_characters, char_level=True) # токенизируем на уровне символов
tokenizer.fit_on_texts([text]) # формируем токены на основе частотности в нашем тексте
print(tokenizer.word_index)
inp_chars = 6
data = tokenizer.texts_to_matrix(text) # преобразуем исходный текст в массив OHE
n = data.shape[0] - inp_chars # так как мы предсказываем по трем символам - четвертый
X = np.array([data[i:i + inp_chars, :] for i in range(n)])
Y = data[inp_chars:] # предсказание следующего символа
print(data.shape)
model = Sequential()
model.add(Input((inp_chars,
num_characters))) # при тренировке в рекуррентные модели keras подается сразу вся последовательность, поэтому в input теперь два числа. 1-длина последовательности, 2-размер OHE
model.add(SimpleRNN(128, activation='tanh')) # рекуррентный слой на 500 нейронов
model.add(Dense(num_characters, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
history = model.fit(X, Y, batch_size=32, epochs=100)
def buildPhrase(inp_str, str_len=50):
for i in range(str_len):
x = []
for j in range(i, i + inp_chars):
x.append(tokenizer.texts_to_matrix(inp_str[j])) # преобразуем символы в One-Hot-encoding
x = np.array(x)
inp = x.reshape(1, inp_chars, num_characters)
pred = model.predict(inp) # предсказываем OHE четвертого символа
d = tokenizer.index_word[pred.argmax(axis=1)[0]] # получаем ответ в символьном представлении
inp_str += d # дописываем строку
return inp_str
res = buildPhrase("утренн")
print(res)