Zapisane modele wielokrotnego użytku

Wstęp

TensorFlow Hub obsługuje między innymi SavedModels dla TensorFlow 2. Można je ponownie załadować do programu w języku Python za pomocą obj = hub.load(url) [ dowiedz się więcej ]. Zwrócony obj jest wynikiem tf.saved_model.load() (patrz przewodnik TensorFlow SavedModel ). Obiekt ten może mieć dowolne atrybuty, którymi są funkcje tf, zmienne tf (inicjowane na podstawie ich wstępnie wyszkolonych wartości), inne zasoby i, rekurencyjnie, więcej takich obiektów.

Na tej stronie opisano interfejs, który ma zostać zaimplementowany przez załadowany obj w celu jego ponownego użycia w programie TensorFlow w języku Python. SavedModels zgodne z tym interfejsem nazywane są SavedModels wielokrotnego użytku .

Ponowne użycie oznacza zbudowanie większego modelu wokół obj , łącznie z możliwością jego dostrojenia. Dostrajanie oznacza dalsze uczenie ciężarów w załadowanym obj jako części otaczającego modelu. Funkcja straty i optymalizator są określone przez otaczający model; obj definiuje jedynie mapowanie aktywacji wejścia na wyjście („przejście w przód”), prawdopodobnie obejmując techniki takie jak odrzucanie lub normalizacja wsadowa.

Zespół TensorFlow Hub zaleca wdrożenie interfejsu SavedModel wielokrotnego użytku we wszystkich SavedModelach, które mają być ponownie użyte w powyższym sensie. Wiele narzędzi z biblioteki tensorflow_hub , w szczególności hub.KerasLayer , wymaga do ich implementacji SavedModels.

Związek z SignatureDefs

Ten interfejs pod względem funkcji tf. i innych funkcji TF2 jest odrębny od sygnatur SavedModel, które są dostępne od TF1 i nadal są używane w TF2 do wnioskowania (takie jak wdrażanie SavedModels do TF Serving lub TF Lite). Podpisy do wnioskowania nie są wystarczająco wyraziste, aby umożliwić dostrajanie, a tf.function zapewnia bardziej naturalny i wyrazisty interfejs API języka Python dla ponownie wykorzystywanego modelu.

Związek z bibliotekami do budowania modeli

SavedModel wielokrotnego użytku używa tylko prymitywów TensorFlow 2, niezależnie od konkretnej biblioteki do budowania modeli, takiej jak Keras lub Sonnet. Ułatwia to ponowne wykorzystanie bibliotek do budowania modeli, bez zależności od oryginalnego kodu do budowania modeli.

Konieczna będzie pewna adaptacja, załaduj zapisane modele wielokrotnego użytku do lub zapisz je z dowolnej biblioteki do budowania modeli. W przypadku Keras ładowanie zapewnia hub.KerasLayer , a wbudowane zapisywanie Keras w formacie SavedModel zostało przeprojektowane dla TF2 w celu zapewnienia nadzbioru tego interfejsu (patrz dokument RFC z maja 2019 r.).

Związek z konkretnymi zadaniami „Wspólnymi interfejsami API SavedModel”

Definicja interfejsu na tej stronie pozwala na dowolną liczbę i typ wejść i wyjść. Wspólne interfejsy API SavedModel dla TF Hub udoskonalają ten ogólny interfejs za pomocą konwencji użycia dla określonych zadań, aby ułatwić wymianę modeli.

Definicja interfejsu

Atrybuty

SavedModel wielokrotnego użytku to SavedModel TensorFlow 2 taki, że obj = tf.saved_model.load(...) zwraca obiekt, który ma następujące atrybuty

  • __call__ . Wymagany. Funkcja tf implementująca obliczenia modelu („przejście w przód”) z zastrzeżeniem poniższej specyfikacji.

  • variables : Lista obiektów tf.Variable, zawierająca wszystkie zmienne używane przy każdym możliwym wywołaniu __call__ , w tym zarówno te, które można trenować, jak i których nie można trenować.

    Listę tę można pominąć, jeśli jest pusta.

  • trainable_variables : Lista obiektów tf.Variable takich, że v.trainable ma wartość true dla wszystkich elementów. Zmienne te muszą stanowić podzbiór variables . Są to zmienne, które należy trenować podczas dostrajania obiektu. Twórca SavedModel może pominąć tutaj niektóre zmienne, które pierwotnie można było wytrenować, aby wskazać, że nie należy ich modyfikować podczas dostrajania.

    Tę listę można pominąć, jeśli jest pusta, w szczególności jeśli SavedModel nie obsługuje dostrajania.

  • regularization_losses : Lista funkcji tf, z których każda pobiera zero danych wejściowych i zwraca pojedynczy skalarny tensor zmiennoprzecinkowy. W celu dostrojenia użytkownikowi SavedModel zaleca się uwzględnienie ich jako dodatkowych warunków regularyzacji w stracie (w najprostszym przypadku bez dalszego skalowania). Zazwyczaj są one używane do reprezentowania regulatorów wagi. (Z powodu braku danych wejściowych te funkcje tf nie mogą wyrażać regulatorów aktywności.)

    Tę listę można pominąć, jeśli jest pusta, w szczególności jeśli SavedModel nie obsługuje dostrajania lub nie chce zalecić regularyzacji wagi.

Funkcja __call__

obj Restored SavedModel ma atrybut obj.__call__ , który jest przywróconą funkcją tf. i umożliwia wywoływanie obj w następujący sposób.

Streszczenie (pseudokod):

outputs = obj(inputs, trainable=..., **kwargs)

Argumenty

Argumenty są następujące.

  • Istnieje jeden pozycyjny, wymagany argument z partią aktywacji wejściowych SavedModel. Jego typ jest jednym z

    • pojedynczy Tensor dla jednego wejścia,
    • lista tensorów dla uporządkowanej sekwencji nienazwanych danych wejściowych,
    • dykt tensorów kluczowany przez określony zestaw nazw wejściowych.

    (Przyszłe wersje tego interfejsu mogą pozwolić na bardziej ogólne zagnieżdżenia.) Kreator SavedModel wybiera jeden z nich oraz kształty i typy tensora. W stosownych przypadkach niektóre wymiary kształtu powinny być niezdefiniowane (zwłaszcza wielkość partii).

  • Może istnieć opcjonalne training argumentów słów kluczowych, które akceptuje wartość logiczną Pythona, True lub False . Wartość domyślna to False . Jeśli model obsługuje dostrajanie i jeśli jego obliczenia różnią się między nimi (np. jak w przypadku normalizacji porzucania i normalizacji wsadowej), to rozróżnienie jest realizowane za pomocą tego argumentu. W przeciwnym razie argument ten może nie istnieć.

    Nie jest wymagane, aby __call__ akceptował argument training o wartościach Tensora. Jeśli to konieczne, do komunikacji między nimi należy użycie tf.cond() .

  • Twórca SavedModel może zaakceptować więcej opcjonalnych kwargs o określonych nazwach.

    • W przypadku argumentów o wartościach Tensora kreator SavedModel definiuje ich dopuszczalne typy i kształty. tf.function przyjmuje domyślną wartość języka Python jako argument śledzony za pomocą danych wejściowych tf.TensorSpec. Takich argumentów można użyć, aby umożliwić dostosowanie hiperparametrów numerycznych związanych z __call__ (np. współczynnik rezygnacji).

    • W przypadku argumentów o wartościach Pythona kreator SavedModel definiuje ich dopuszczalne wartości. Takich argumentów można używać jako flag do dokonywania dyskretnych wyborów w śledzonej funkcji (pamiętaj jednak o kombinatorycznej eksplozji śladów).

Przywrócona funkcja __call__ musi udostępniać ślady dla wszystkich dopuszczalnych kombinacji argumentów. Zamiana training między True a False nie może zmieniać dopuszczalności argumentów.

Wynik

outputs wywołania obj mogą być

  • pojedynczy Tensor dla jednego wyjścia,
  • lista tensorów dla uporządkowanej sekwencji nienazwanych wyników,
  • dykt tensorów kluczowany przez określony zestaw nazw wyjściowych.

(Przyszłe wersje tego interfejsu mogą umożliwiać bardziej ogólne zagnieżdżenia.) Typ zwracany może się różnić w zależności od kwargs cenionych w Pythonie. Pozwala to na flagi generujące dodatkowe wyjścia. Kreator SavedModel definiuje wyjściowe typy i kształty oraz ich zależność od danych wejściowych.

Nazwane elementy wywoływalne

SavedModel wielokrotnego użytku może zapewnić wiele elementów modelu w sposób opisany powyżej, umieszczając je w nazwanych podobiektach, na przykład obj.foo , obj.bar i tak dalej. Każdy podobiekt udostępnia metodę __call__ i atrybuty pomocnicze dotyczące zmiennych itp. specyficznych dla tego elementu modelu. W powyższym przykładzie byłyby obj.foo.__call__ , obj.foo.variables i tak dalej.

Należy zauważyć, że ten interfejs nie obejmuje podejścia polegającego na dodawaniu samej funkcji tf.function bezpośrednio jako tf.foo .

Oczekuje się, że użytkownicy SavedModels wielokrotnego użytku będą obsługiwać tylko jeden poziom zagnieżdżenia ( obj.bar , ale nie obj.bar.baz ). (Przyszłe wersje tego interfejsu mogą pozwolić na głębsze zagnieżdżanie i mogą odstąpić od wymogu, aby obiekt najwyższego poziomu mógł sam być wywoływany.)

Uwagi końcowe

Związek z interfejsami API w procesie

Ten dokument opisuje interfejs klasy Pythona, który składa się z prymitywów, takich jak tf.function i tf.Variable, które przetrwają cykl w obie strony poprzez serializację za pomocą tf.saved_model.save() i tf.saved_model.load() . Jednakże interfejs był już obecny w oryginalnym obiekcie, który został przekazany do tf.saved_model.save() . Dostosowanie do tego interfejsu umożliwia wymianę elementów modelu pomiędzy interfejsami API do budowania modeli w ramach jednego programu TensorFlow.