Konwersja RNN TensorFlow na TensorFlow Lite

Przegląd

TensorFlow Lite obsługuje konwertowanie modeli RNN TensorFlow na łączone operacje LSTM TensorFlow Lite. Operacje łączone mają na celu maksymalizację wydajności ich bazowych implementacji jądra oraz zapewniają interfejs wyższego poziomu do definiowania złożonych przekształceń, takich jak kwantyzacja.

Ze względu na to, że w TensorFlow występuje wiele wariantów interfejsów API RNN, nasze podejście jest podzielone na dwa etapy:

  1. Zapewnij natywną obsługę standardowych interfejsów API TensorFlow RNN, takich jak Keras LSTM. To zalecana opcja.
  2. Udostępnij interfejs infrastruktury konwersji dla zdefiniowanych przez użytkownika implementacji RNN, które zostaną podłączone do TensorFlow Lite i zostaną przekonwertowane. Udostępniamy kilka gotowych przykładów takich konwersji z interfejsami RNN w Lingvo: LSTMCellSimple i LayerNormalizedLSTMCellSimple.

Interfejs API konwersji

Ta funkcja jest częścią wersji TensorFlow 2.3. Możesz też płacić co 2 tygodnie pip lub bezpośrednio z głowy.

Ta funkcja konwersji jest dostępna podczas konwersji na TensorFlow Lite za pomocą SavedModel lub bezpośrednio z modelu Keras. Zobacz przykładowe zastosowania.

Z zapisanego modelu

# build a saved model. Here concrete_function is the exported function
# corresponding to the TensorFlow model containing one or more
# Keras LSTM layers.
saved_model, saved_model_dir = build_saved_model_lstm(...)
saved_model.save(saved_model_dir, save_format="tf", signatures=concrete_func)

# Convert the model.
converter = TFLiteConverter.from_saved_model(saved_model_dir)
tflite_model = converter.convert()

Z modelu Keras

# build a Keras model
keras_model = build_keras_lstm(...)

# Convert the model.
converter = TFLiteConverter.from_keras_model(keras_model)
tflite_model = converter.convert()

Przykład

Colab zilustruje wykorzystanie LSTM do TensorFlow Lite dzięki interpreterowi TensorFlow Lite, który pokazuje pełne wykorzystanie.

Obsługiwane interfejsy API RNN TensorFlow

Obsługujemy gotowe do użycia konwersję z Keras LSTM na TensorFlow Lite. Szczegółowe informacje o tym, jak to działa, znajdziesz w artykule o interfejsie Keras LSTM i zasadach konwersji tutaj.

Ważne jest też wyróżnienie umowy LSTM dotyczącej TensorFlow Lite w odniesieniu do definicji operacji Keras:

  1. Wymiar 0 tensora wejściowego to rozmiar wsadu.
  2. Wymiar 0 tensora recurrent_weight to liczba danych wyjściowych.
  3. Transponowane są tensory weight i recurrent_kernel.
  4. Transponowana waga, transponowane tensory recurrent_kernel i bias są dzielone na 4 tensory o równych rozmiarach wzdłuż wymiaru 0. Odpowiadają one bramce wejściowej, zapomnianym bramce, komórce i bramce wyjściowej.

Wersje Keras LSTM

Czas główny

Użytkownicy mogą wybrać okres krótki lub wcale trwający. Keras LSTM dodaje atrybut „ważny” do funkcji „definicja”. W przypadku sekwencji jednokierunkowej możemy zmapować ją na główny atrybut czasu unidirecional_sequence_lstm.

Dwukierunkowa LSTM

Dwukierunkową LSTM można wdrożyć z użyciem 2 warstw Keras LSTM: jednej do przodu i do tyłu. Przykłady znajdziesz tutaj. Gdy znajdziemy atrybut go_backward, rozpoznamy go jako wsteczny LSTM i zgrupujemy go w przód i w tył. To kwestia w przyszłości. Obecnie w modelu TensorFlow Lite tworzy to 2 operacje UnidirectionalSequenceLSTM.

Przykłady zdefiniowanej przez użytkownika konwersji LSTM

TensorFlow Lite udostępnia też sposób konwertowania zdefiniowanych przez użytkownika implementacji LSTM. Przykładem tego, jak można to osiągnąć, jest technologia LSTM firmy Lingvo. Szczegółowe informacje o interfejsie lingvo.LSTMCellSimple i logice konwersji znajdziesz tutaj. Przykład innej definicji LSTM firmy Lingvo znajdziesz w interfejsie lingvo.LayerNormalizedLSTMCellSimple oraz tutaj jej logiki konwersji.

„Wykorzystaj własny TensorFlow RNN” w TensorFlow Lite

Jeśli interfejs RNN użytkownika różni się od interfejsu standardowego, masz 2 możliwości:

Opcja 1: wpisz kod adaptera w Pythonie TensorFlow, aby dostosować interfejs RNN do interfejsu Keras RNN. Oznacza to funkcję tf.z adnotacją tf_implements w funkcji wygenerowanego interfejsu RNN, która jest identyczna z funkcją wygenerowaną przez warstwę Keras LSTM. Po zakończeniu tego procesu będzie działać ten sam interfejs API konwersji używany w Keras LSTM.

Opcja 2: jeśli nie można zastosować tego rozwiązania (np. w interfejsie Keras LSTM brakuje funkcji, które są obecnie dostępne przez funkcję scalonego LSTM TensorFlow Lite, taką jak normalizacja warstw), rozszerz konwerter TensorFlow Lite, wpisując niestandardowy kod konwersji i wklejając go w metodzie create-composite-functions MLIR-pass tutaj. Interfejs funkcji powinien być traktowany jak umowa interfejsu API i zawierać argumenty potrzebne do konwersji na połączone operacje TensorFlow Lite LSTM, tj. dane wejściowe, odchylenia, wagi, projekcja, normalizację warstwy itp. W przypadku tensorów przekazywanych jako argumenty tej funkcji lepiej jest mieć znaną pozycję (np. RankedTensorType w MLI). Ułatwia to pisanie kodu konwersji, który może przyjmować te tensory jako rankingedTensorType, i przekształcanie ich w tensory o określonym rankingu odpowiadające operandom operatora TensorFlow Lite.

Pełnym przykładem takiego przepływu konwersji jest konwersja LSTMCellSimple na TensorFlow Lite firmy Lingvo.

Definicja LSTMCellSimple w Lingvo jest zdefiniowana tutaj. Modele wytrenowane z użyciem tej komórki LSTM można przekonwertować na TensorFlow Lite w ten sposób:

  1. Zawijaj wszystkie zastosowania funkcji LSTMCellSimple w funkcji tf.function z adnotacją tf_implements oznaczoną taką etykietą (np. lingvo.LSTMCellSimple będzie w tym przypadku dobrą nazwą adnotacji). Upewnij się, że wygenerowana funkcja tf.odpowiada interfejsowi funkcji oczekiwanej w kodzie konwersji. Jest to umowa zawarta między autorem modelu, który dodaje adnotację i kod konwersji.
  2. Rozszerz przekazywanie funkcji przygotowujących-kompozytowych, aby dodać niestandardową operację złożoną do konwersji operacji TensorFlow Lite scalonej LSTM. Zobacz kod konwersji LSTMCellSimple.

    Umowa konwersji:

  3. Transponowane są tensory ważności i projekcji.

  4. Wartości od {input, recurrent} do {cell, insert gate, talk gate, wyjściowych gate} są wyodrębniane przez odcięcie transponowanego tensora wagi.

  5. Wartości od {bias} do {cell, entry bramka, zapomnij bramkę, bramka wyjściowa} są wyodrębniane przez wycięcie tensora odchylenia.

  6. Odwzorowanie jest wyodrębniane przez wycinanie transponowanego tensora projekcji.

  7. Podobna konwersja jest zapisywana w funkcji LayerNormalizedLSTMCellSimple.

  8. Resztę infrastruktury konwersji TensorFlow Lite, w tym wszystkie zdefiniowane karty MLIR, oraz końcowy eksport do płaskiego bufora TensorFlow Lite można wykorzystać ponownie.

Znane problemy/ograniczenia

  1. Obecnie obsługiwana jest tylko konwersja bezstanowych Keras LSTM (działanie domyślne w Keras). Przyszła praca nad przekształcaniem Stateful Keras LSTM.
  2. Nadal można modelować stanową warstwę Keras LSTM za pomocą leżącej u jej podstaw bezstanowej warstwy Keras LSTM i zarządzać jej stanem bezpośrednio w programie użytkownika. Taki program w TensorFlow nadal można przekonwertować na TensorFlow Lite za pomocą opisywanej tu funkcji.
  3. Dwukierunkowa LSTM jest obecnie modelowana jako 2 operacje UnidirectionalSequenceLSTM w TensorFlow Lite. Zostanie ona zastąpiona pojedynczą opcją BidirectionalSequenceLSTM.