Format koncentratora TF1

W momencie premiery w 2018 roku TensorFlow Hub oferował jeden rodzaj aktywów: format TF1 Hub do importu do programów TensorFlow 1.

Na tej stronie wyjaśniono, jak używać formatu TF1 Hub w TF1 (lub trybie zgodności TF1 w TF2) z klasą hub.Module i powiązanymi interfejsami API. (Typowym zastosowaniem jest zbudowanie tf.Graph , prawdopodobnie wewnątrz TF1 Estimator , poprzez połączenie jednego lub więcej modeli w formacie TF1 Hub z tf.compat.layers lub tf.layers ).

Użytkownicy TensorFlow 2 (poza trybem zgodności TF1) muszą używać nowego interfejsu API z hub.load() lub hub.KerasLayer . Nowy interfejs API ładuje nowy typ zasobu TF2 SavedModel, ale ma również ograniczoną obsługę ładowania formatu TF1 Hub do TF2 .

Korzystanie z modelu w formacie TF1 Hub

Tworzenie instancji modelu w formacie TF1 Hub

Model w formacie TF1 Hub jest importowany do programu TensorFlow poprzez utworzenie obiektu hub.Module z ciągu znaków z jego adresem URL lub ścieżką systemu plików, na przykład:

m = hub.Module("path/to/a/module_dir")

Spowoduje to dodanie zmiennych modułu do bieżącego wykresu TensorFlow. Uruchomienie ich inicjatorów spowoduje odczytanie ich wstępnie wytrenowanych wartości z dysku. Podobnie tabele i inne stany są dodawane do wykresu.

Moduły buforowania

Podczas tworzenia modułu z adresu URL zawartość modułu jest pobierana i buforowana w katalogu tymczasowym systemu lokalnego. Lokalizacja, w której moduły są buforowane, można nadpisać za pomocą zmiennej środowiskowej TFHUB_CACHE_DIR . Aby uzyskać szczegółowe informacje, zobacz Buforowanie .

Stosowanie modułu

Po utworzeniu instancji moduł m może być wywoływany zero lub więcej razy, tak jak funkcja Pythona, od wejść tensorowych do wyjść tensorowych:

y = m(x)

Każde takie wywołanie dodaje operacje do bieżącego wykresu TensorFlow, aby obliczyć y z x . Jeśli dotyczy to zmiennych z wyuczonymi wagami, są one współdzielone przez wszystkie aplikacje.

Moduły mogą definiować wiele nazwanych podpisów , aby umożliwić ich zastosowanie na więcej niż jeden sposób (podobnie jak obiekty Pythona mają metody ). Dokumentacja modułu powinna opisywać dostępne podpisy. Powyższe wywołanie stosuje podpis o nazwie "default" . Dowolny podpis można wybrać, przekazując jego nazwę do opcjonalnego argumentu signature= .

Jeśli podpis ma wiele danych wejściowych, należy je przekazać jako dykt z kluczami zdefiniowanymi przez podpis. Podobnie, jeśli sygnatura ma wiele wyjść, można je pobrać jako dict, przekazując as_dict=True , pod kluczami zdefiniowanymi przez sygnaturę (klucz "default" jest dla pojedynczego wyjścia zwróconego, jeśli as_dict=False ). Zatem najogólniejsza forma zastosowania modułu wygląda tak:

outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]

Wywołujący musi dostarczyć wszystkie wejścia zdefiniowane przez sygnaturę, ale nie ma wymogu używania wszystkich wyjść modułu. TensorFlow uruchomi tylko te części modułu, które kończą się jako zależności celu w tf.Session.run() . Rzeczywiście, wydawcy modułów mogą zdecydować się na dostarczanie różnych wyników dla zaawansowanych zastosowań (takich jak aktywacje warstw pośrednich) wraz z głównymi wynikami. Odbiorcy modułów powinni z wdziękiem obsługiwać dodatkowe wyjścia.

Wypróbowanie alternatywnych modułów

Ilekroć istnieje wiele modułów do tego samego zadania, TensorFlow Hub zachęca do wyposażenia ich w kompatybilne sygnatury (interfejsy), tak aby wypróbowanie różnych z nich było tak proste, jak zmienianie uchwytu modułu jako hiperparametru o wartościach łańcuchowych.

W tym celu utrzymujemy zbiór zalecanych wspólnych podpisów dla popularnych zadań.

Tworzenie nowego modułu

Uwaga dotycząca kompatybilności

Format TF1 Hub jest nastawiony na TensorFlow 1. Jest tylko częściowo obsługiwany przez TF Hub w TensorFlow 2. Zamiast tego rozważ publikację w nowym formacie TF2 SavedModel .

Format TF1 Hub jest podobny do formatu SavedModel TensorFlow 1 na poziomie składniowym (te same nazwy plików i komunikaty protokołu), ale różni się semantycznie, aby umożliwić ponowne użycie modułu, skład i ponowne szkolenie (np. inne przechowywanie inicjatorów zasobów, różne tagowanie konwencje dotyczące metagrafów). Najłatwiejszym sposobem odróżnienia ich na dysku jest obecność lub brak pliku tfhub_module.pb .

Ogólne podejście

Aby zdefiniować nowy moduł, wydawca wywołuje hub.create_module_spec() z funkcją module_fn . Ta funkcja tworzy wykres reprezentujący wewnętrzną strukturę modułu, używając tf.placeholder() dla danych wejściowych dostarczanych przez obiekt wywołujący. Następnie definiuje podpisy, wywołując hub.add_signature(name, inputs, outputs) raz lub więcej razy.

Na przykład:

def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)

Wynik hub.create_module_spec() może być użyty zamiast ścieżki, aby utworzyć wystąpienie obiektu modułu w określonym wykresie TensorFlow. W takim przypadku nie ma punktu kontrolnego, a instancja modułu użyje zamiast tego inicjatorów zmiennych.

Dowolna instancja modułu może być serializowana na dysk za pomocą metody export(path, session) . Wyeksportowanie modułu powoduje serializację jego definicji wraz z bieżącym stanem jego zmiennych w session do przekazanej ścieżki. Można to wykorzystać przy eksporcie modułu po raz pierwszy, a także przy eksporcie modułu dostrojonego.

Aby zapewnić zgodność z modułami szacowania TensorFlow, hub.LatestModuleExporter eksportuje moduły z najnowszego punktu kontrolnego, podobnie jak tf.estimator.LatestExporter eksportuje cały model z najnowszego punktu kontrolnego.

Wydawcy modułów powinni w miarę możliwości wdrażać wspólny podpis , aby konsumenci mogli łatwo wymieniać moduły i znaleźć najlepszy dla ich problemu.

Prawdziwy przykład

Spójrz na nasz eksporter modułów osadzania tekstu, aby zobaczyć rzeczywisty przykład tworzenia modułu ze wspólnego formatu osadzania tekstu.

Strojenie

Uczenie zmiennych importowanego modułu wraz ze zmiennymi modelu wokół niego nazywa się dostrajaniem . Dostrajanie może skutkować lepszą jakością, ale dodaje nowe komplikacje. Radzimy konsumentom, aby zajęli się dostrajaniem dopiero po zapoznaniu się z prostszymi poprawkami jakości i tylko wtedy, gdy wydawca modułu to zaleci.

Dla Konsumentów

Aby umożliwić dostrajanie, utwórz wystąpienie modułu za pomocą hub.Module(..., trainable=True) , aby umożliwić trenowanie jego zmiennych i zaimportować REGULARIZATION_LOSSES REGULARIZATION_LOSSES . Jeśli moduł ma wiele wariantów wykresu, wybierz ten, który jest odpowiedni do szkolenia. Zwykle jest to ten z tagami {"train"} .

Wybierz reżim treningowy, który nie rujnuje wcześniej wytrenowanych ciężarów, na przykład niższy wskaźnik uczenia się niż w przypadku treningu od podstaw.

Dla wydawców

Aby ułatwić konsumentom dostrajanie, pamiętaj o następujących kwestiach:

  • Dostrajanie wymaga uregulowania. Twój moduł jest eksportowany z kolekcją REGULARIZATION_LOSSES , która umieszcza Twój wybór tf.layers.dense(..., kernel_regularizer=...) itp. w tym, co klient otrzymuje z tf.losses.get_regularization_losses() . Preferuj ten sposób definiowania strat regularyzacji L1/L2.

  • W modelu wydawcy unikaj definiowania regularyzacji L1/L2 za pomocą parametrów l1_ i l2_regularization_strength tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer i innych proksymalnych optymalizatorów. Nie są one eksportowane wraz z modułem, a globalne ustalanie mocnych stron w zakresie regularyzacji może nie być odpowiednie dla konsumenta. Z wyjątkiem regularyzacji L1 w modelach szerokich (tj. rzadkich liniowych) lub szerokich i głębokich, powinno być możliwe zastosowanie indywidualnych strat regularyzacji.

  • Jeśli używasz przerywania, normalizacji partii lub podobnych technik szkoleniowych, ustaw ich hiperparametry na wartości, które mają sens w wielu oczekiwanych zastosowaniach. Może zaistnieć potrzeba dostosowania wskaźnika porzucania do skłonności problemu docelowego do nadmiernego dopasowania. W normalizacji wsadowej pęd (inaczej współczynnik zaniku) powinien być wystarczająco mały, aby umożliwić dostrojenie małych zestawów danych i/lub dużych partii. W przypadku zaawansowanych konsumentów rozważ dodanie podpisu, który ujawnia kontrolę nad krytycznymi hiperparametrami.