Керас: тренировка загруженной модели в 6 раз медленнее - PullRequest
0 голосов
/ 03 октября 2019

TensorFlow 2.0 (версия для графического процессора), CUDA 10.0, NVIDIA GeForce RTX 2060, Windows 10 (1903)

Я занимаюсь классификацией текста. Я использую символьные вложения и LSTM для кодирования каждого слова в вектор. Вот моя модель:

import tensorflow as tf
from tensorflow.keras.models import Sequential, Model, load_model, model_from_json
from tensorflow.keras.layers import Input, Embedding, LSTM, TimeDistributed, Multiply, Masking, Concatenate, Dense
from tensorflow.keras.utils import to_categorical

import numpy as np

import re

.

target_word_length = 15
target_sentence_length = 100
mask_embedding = 27

def NetEncoder(string):

    d = dict(zip('abcdefghijklmnopqrstuvwxyz', range(1,27)))

    text_enc = []

    for w in re.findall('[a-z]+', string.lower()):
        word_enc = []
        for c in w:
            word_enc.append(d[c])
        if len(word_enc) < target_word_length:
            for i in range(target_word_length - len(word_enc)):
                word_enc.append(0)
        text_enc.append(word_enc)

    const = []
    for i in range(target_word_length):
        const.append(0)
    const[0] = mask_embedding

    sentence_length = len(text_enc)
    if sentence_length < target_sentence_length:
        for i in range(target_sentence_length - sentence_length):
            text_enc.append(const)
        mask = []
        for i in range(target_sentence_length):
            if i < sentence_length:
                mask.append([1])
            else:
                mask.append([0])

    return [np.array(text_enc, dtype=np.float32), np.array(mask, dtype=np.float32)]

.

emb = Sequential([
    Embedding(28, 3, mask_zero=True, input_shape=(target_word_length,)),
    LSTM(16, return_sequences=False)
])

input_1 = Input(shape=(target_sentence_length, target_word_length))
mask_1 = Input(shape=(target_sentence_length, 1))
net_1 = TimeDistributed(emb)(input_1)
net_1 = Multiply()([net_1, mask_1])
net_1 = Masking(mask_value=np.full(16, 0.))(net_1)
net_1 = LSTM(64, return_sequences=False)(net_1)

input_2 = Input(shape=(target_sentence_length, target_word_length))
mask_2 = Input(shape=(target_sentence_length, 1))
net_2 = TimeDistributed(emb)(input_2)
net_2 = Multiply()([net_2, mask_2])
net_2 = Masking(mask_value=np.full(16, 0.))(net_2)
net_2 = LSTM(64, return_sequences=False)(net_2)

cat = Concatenate()([net_1, net_2])
clf = Dense(32, activation='relu')(cat)
clf = Dense(2, activation='softmax')(clf)

model = Model(inputs=[input_1, mask_1, input_2, mask_2], outputs=clf)

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

[input_1, mask_1] = NetEncoder('Hello Max')
[input_2, mask_2] = NetEncoder('Hello Max')
Y = to_categorical([0], num_classes=2)

model.fit([[input_1], [mask_1], [input_2], [mask_2]], Y, epochs=10)

Время тренировки: 23 мс на выборку

Train on 1 samples
Epoch 1/10
4/1 [==============================================] - 16s 4s/sample - loss: 0.6840 - accuracy: 0.7500
Epoch 2/10
4/1 [==============================================] - 0s 23ms/sample - loss: 0.6618 - accuracy: 1.0000
Epoch 3/10
4/1 [==============================================] - 0s 23ms/sample - loss: 0.6335 - accuracy: 1.0000

Время прогнозирования: 63 мс на выборку

%%time
model.predict([[input_1], [mask_1], [input_2], [mask_2]])

Время стены: массив 63 мс

([[1.0000000e + 00, 2.6085422e-08]], dtype = float32)

Сохранение и загрузка модели (# 1)

model.save('model.h5', save_format='tf', include_optimizer=False)

model_1 = load_model('model.h5')

Время прогнозирования составляетниже: 37 против 63 мс. Но выходные данные немного отличаются.

%%time
model_1.predict([[input_1], [mask_1], [input_2], [mask_2]])

Время стены: массив 37,4 мс

([[1.000000e + 00, 2.608547e-08]], dtype= float32)

model_1.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model_1.fit([[input_1], [mask_1], [input_2], [mask_2]], Y, epochs=10)

Обучение идет в 6 раз медленнее: 139 против 23 мс для образца!

Train on 1 samples
Epoch 1/10
4/1 [==============================================] - 4s 1s/sample - loss: 0.0000e+00 - accuracy: 1.0000
Epoch 2/10
4/1 [==============================================] - 1s 133ms/sample - loss: 0.0000e+00 - accuracy: 1.0000
Epoch 3/10
4/1 [==============================================] - 1s 139ms/sample - loss: 0.0000e+00 - accuracy: 1.0000

Сохранить и загрузить модель (# 2)

model.save_weights('model_V2.h5')
model_json = model.to_json()
with open('model_V2.json', "w") as json_file:
    json_file.write(model_json)
json_file.close()

json_file = open("model_V2.json", 'r')
loaded_model_json = json_file.read()
json_file.close()

model_2 = model_from_json(loaded_model_json)
#model_2.load_weights("model_V2.h5")

model_2.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model_2.fit([[input_1], [mask_1], [input_2], [mask_2]], Y, epochs=10)

Время обучения: 149 против 23 мс для образца!

Train on 1 samples
Epoch 1/10
4/1 [==============================================] - 4s 1s/sample - loss: 0.6805 - accuracy: 0.7500
Epoch 2/10
4/1 [==============================================] - 1s 145ms/sample - loss: 0.6526 - accuracy: 1.0000
Epoch 3/10
4/1 [==============================================] - 1s 149ms/sample - loss: 0.6186 - accuracy: 1.0000

В чем проблема?

...