Я пытаюсь обучить RNN предсказывать происхождение имен. Набор данных взят из учебника по Pytorch, и мне, в основном, нужно переделать учебник, используя tenorflow / keras.
Набор данных:
!wget https://download.pytorch.org/tutorial/data.zip
!unzip data.zip
data = []
for filename in glob('data/names/*.txt'):
origin = filename.split('/')[-1].split('.txt')[0]
names = open(filename).readlines()
for name in names:
data.append((name.strip(), origin))
names, origins = zip(*data)
names_train, names_test, origins_train, origins_test = train_test_split(names, origins, test_size=0.25, shuffle=True, random_state=123)
for name, origin in zip(names_train[:20], origins_train[:20]):
print(name.ljust(20), origin)
Bazhinov Russian
Wasem Arabic
Tumashev Russian
Andreyanov Russian
Dobrovolsky Russian
Xie Chinese
Zhvykin Russian
Belkov Russian
Rahletzky Russian
Jakuba Russian
Kalinchuk Russian
Jankin Russian
Vanslov Russian
Seif Arabic
Asghar Arabic
Osladil Czech
Brand German
Findley English
Cameron English
Tsalikov Russian
Предварительная обработка данных:
encoder_train = tf.keras.preprocessing.text.Tokenizer(char_level=True)
encoder_train.fit_on_texts(names_train)
encoder_test = tf.keras.preprocessing.text.Tokenizer(char_level=True)
encoder_test.fit_on_texts(names_test)
sequences = encoder_train.texts_to_sequences(names_train)
sequences= tf.keras.preprocessing.sequence.pad_sequences(sequences)
sequences_test= encoder_test.texts_to_sequences(names_test)
sequences_test= tf.keras.preprocessing.sequence.pad_sequences(sequences_test)
encoder_org_train = tf.keras.preprocessing.text.Tokenizer(lower=False)
encoder_org_train.fit_on_texts(origins_train)
encoder_org_test = tf.keras.preprocessing.text.Tokenizer(lower=False)
encoder_org_test.fit_on_texts(origins_test)
origins_vec_train = encoder_org_train.texts_to_sequences(origins_train)
origins_vec_train = np.asarray(origins_vec_train)
origins_vec_test = encoder_org_test.texts_to_sequences(origins_test)
origins_vec_test = np.asarray(origins_vec_test)
embedding_input_dim = max(encoder_train.index_word) + 1
embedding_output_dim = 32
RNN Модель:
model = tf.keras.models.Sequential(layers=[
tf.keras.layers.Embedding(input_dim=embedding_input_dim,
output_dim=embedding_output_dim,
mask_zero=True),
tf.keras.layers.LSTM(64, return_sequences= True),
tf.keras.layers.LSTM(32),
tf.keras.layers.Dense(19, activation='sigmoid')
])
model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(),
optimizer=tf.keras.optimizers.Adam(lr=0.075),
metrics=['accuracy'])
history = model.fit(sequences, origins_vec_train, epochs=10, batch_size= 200, validation_data= (sequences_test, origins_vec_test))
Моя модель работает нормально, и я получаю лучшая точность, чем я надеялся изначально. По сути, сейчас я пытаюсь создать функцию, которая принимает строковый ввод и выводит начало координат на основе обучения сети (т.е. input = 'Sergey', output = 'Russian'). Функция для этого в учебнике по Pytorch требует нескольких других функций. Я хочу воссоздать эту функцию:
def predict(input_line, n_predictions=3):
print('\n> %s' % input_line)
with torch.no_grad():
output = evaluate(lineToTensor(input_line))
# Get top N categories
topv, topi = output.topk(n_predictions, 1, True)
predictions = []
for i in range(n_predictions):
value = topv[0][i].item()
category_index = topi[0][i].item()
print('(%.2f) %s' % (value, all_categories[category_index]))
predictions.append([value, all_categories[category_index]])
в контексте созданной мной нейронной сети.