W chwili premiery w 2018 r. TensorFlow Hub oferował jeden typ zasobów: format TF1 Hub do importowania do programów TensorFlow 1.
Na tej stronie wyjaśniono, jak używać formatu TF1 Hub w TF1 (lub trybu zgodności TF1 w TF2) z klasą hub.Module
i powiązanymi interfejsami API. (Typowym zastosowaniem jest zbudowanie tf.Graph
, ewentualnie wewnątrz Estimator
TF1, 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 z TF1) muszą używać nowego API z hub.load()
lub hub.KerasLayer
. Nowe 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 zawierającego jego adres URL lub ścieżkę do systemu plików, na przykład:
m = hub.Module("path/to/a/module_dir")
Uwaga: więcej informacji na temat innych prawidłowych typów uchwytów znajdziesz tutaj .
Spowoduje to dodanie zmiennych modułu do bieżącego wykresu TensorFlow. Uruchomienie ich inicjatorów spowoduje odczytanie wstępnie wyszkolonych wartości z dysku. Podobnie do wykresu dodawane są tabele i inne stany.
Moduły buforujące
Podczas tworzenia modułu z adresu URL zawartość modułu jest pobierana i buforowana w katalogu tymczasowym systemu lokalnego. Lokalizację, w której moduły są buforowane, można zastąpić za pomocą zmiennej środowiskowej TFHUB_CACHE_DIR
. Aby uzyskać szczegółowe informacje, zobacz Buforowanie .
Stosowanie modułu
Po utworzeniu modułu m
można wywołać zero lub więcej razy, podobnie jak funkcję Pythona, przechodząc z 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 przeszkolonymi wagami, są one współdzielone pomiędzy wszystkimi aplikacjami.
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 sygnatury. Powyższe wywołanie stosuje podpis o nazwie "default"
. Można wybrać dowolny podpis, przekazując jego nazwę do opcjonalnego argumentu signature=
.
Jeśli podpis ma wiele danych wejściowych, należy je przekazać jako dyktando, z kluczami zdefiniowanymi w podpisie. Podobnie, jeśli podpis ma wiele wyników, można je pobrać jako dyktando, przekazując as_dict=True
pod kluczami zdefiniowanymi przez podpis (klucz "default"
dotyczy pojedynczego wyniku zwróconego, jeśli as_dict=False
). Zatem najbardziej ogólna forma zastosowania modułu wygląda następująco:
outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]
Osoba wywołująca musi dostarczyć wszystkie wejścia zdefiniowane przez sygnaturę, ale nie ma wymogu wykorzystania wszystkich wyjść modułu. TensorFlow uruchomi tylko te części modułu, które staną się zależnościami celu w tf.Session.run()
. Rzeczywiście, wydawcy modułów mogą zdecydować się na udostępnienie różnych wyników do zastosowań zaawansowanych (takich jak aktywacja warstw pośrednich) wraz z głównymi wynikami. Konsumenci modułów powinni sprawnie obsługiwać dodatkowe wyjścia.
Wypróbowywanie 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 było tak proste, jak zmiana obsługi modułu jako hiperparametru o wartości łańcuchowej.
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 dostosowany do 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 syntaktycznym (te same nazwy plików i komunikaty protokołu), ale różni się semantycznie, aby umożliwić ponowne użycie modułu, kompozycję i ponowne szkolenie (np. inne przechowywanie inicjatorów zasobów, inne tagowanie konwencje metagrafów). Najłatwiejszym sposobem rozróż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 przedstawiający wewnętrzną strukturę modułu, używając tf.placeholder()
do wprowadzania danych wejściowych przez obiekt wywołujący. Następnie definiuje podpisy, wywołując funkcję 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)
Wyniku hub.create_module_spec()
można użyć zamiast ścieżki do utworzenia instancji obiektu modułu w obrębie określonego wykresu TensorFlow. W takim przypadku nie ma punktu kontrolnego i instancja modułu zamiast tego użyje inicjatorów zmiennych.
Dowolną instancję modułu można serializować na dysk za pomocą metody export(path, session)
. Eksportowanie modułu serializuje jego definicję wraz z bieżącym stanem jego zmiennych w session
do przekazanej ścieżki. Można tego użyć podczas eksportowania modułu po raz pierwszy, a także podczas eksportowania modułu dostrojonego.
Aby zapewnić zgodność z estymatorami 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, jeśli to możliwe, wdrożyć wspólny podpis , aby konsumenci mogli łatwo wymieniać moduły i znaleźć ten, który najlepiej rozwiąże ich problem.
Prawdziwy przykład
Zapoznaj się z naszym eksporterem modułów do osadzania tekstu, aby poznać rzeczywisty przykład tworzenia modułu na podstawie popularnego formatu osadzania tekstu.
Dostrajanie
Uczenie zmiennych zaimportowanego modułu wraz ze zmienną otaczającego go modelu nazywa się dostrajaniem . Dostrajanie może skutkować lepszą jakością, ale powoduje nowe komplikacje. Radzimy konsumentom, aby zastanowili się nad dostrojeniem dopiero po zapoznaniu się z prostszymi poprawkami jakości i tylko wtedy, gdy wydawca modułu to zaleca.
Dla Konsumentów
Aby umożliwić dostrajanie, utwórz instancję modułu za pomocą hub.Module(..., trainable=True)
aby umożliwić trenowanie jego zmiennych i zaimportuj REGULARIZATION_LOSSES
TensorFlow. Jeśli moduł posiada wiele wariantów wykresów, pamiętaj o wybraniu tego odpowiedniego do szkolenia. Zwykle jest to ten ze znacznikami {"train"}
.
Wybierz taki reżim treningowy, który nie zrujnuje wcześniej wytrenowanych ciężarów, np. mniejsze tempo uczenia się niż przy treningu od zera.
Dla wydawców
Aby ułatwić konsumentom dostrojenie, należy pamiętać o następujących kwestiach:
Dostrojenie wymaga regularyzacji. Twój moduł jest eksportowany z kolekcją
REGULARIZATION_LOSSES
, co powoduje umieszczenie wybranego przez Ciebietf.layers.dense(..., kernel_regularizer=...)
itd. w tym, co konsument otrzymuje ztf.losses.get_regularization_losses()
. Preferuję ten sposób definiowania strat regularyzacyjnych L1/L2.W modelu wydawcy należy unikać definiowania regularyzacji L1/L2 za pomocą parametrów
l1_
il2_regularization_strength
tf.train.FtrlOptimizer
,tf.train.ProximalGradientDescentOptimizer
i innych optymalizatorów proksymalnych. Nie są one eksportowane wraz z modułem, a globalne ustawienie mocy regularyzacji może nie być odpowiednie dla konsumenta. Z wyjątkiem regularyzacji L1 w modelach szerokich (tzn. rzadkich liniowych) lub szerokich i głębokich, zamiast tego powinno być możliwe wykorzystanie indywidualnych strat regularyzacyjnych.Jeśli używasz porzucania, normalizacji wsadowej lub podobnych technik szkoleniowych, ustaw ich hiperparametry na wartości, które mają sens w wielu oczekiwanych zastosowaniach. Może zaistnieć konieczność dostosowania współczynnika rezygnacji do skłonności docelowego problemu do nadmiernego dopasowania. W normalizacji wsadowej pęd (inaczej współczynnik zaniku) powinien być wystarczająco mały, aby umożliwić precyzyjne dostrojenie w przypadku małych zbiorów danych i/lub dużych partii. W przypadku zaawansowanych konsumentów rozważ dodanie podpisu, który udostępnia kontrolę nad krytycznymi hiperparametrami.