Migracja z sieci neuronowych

Lasy decyzyjne TensorFlow ( TF-DF ) to zbiór algorytmów lasów decyzyjnych ( DF ) dostępnych w TensorFlow. Lasy decyzyjne działają inaczej niż sieci neuronowe ( NN ): DF na ogół nie trenują z propagacją wsteczną ani w minipartiach. Dlatego potoki TF-DF mają kilka różnic od innych potoków TensorFlow.

Ten dokument zawiera listę tych różnic oraz przewodnik dotyczący aktualizacji potoków TF w celu korzystania z TF-DF

W tym dokumencie założono znajomość współpracy dla początkujących .

Zbiór danych i funkcje

Zbiór danych walidacyjnych

W przeciwieństwie do standardowego paradygmatu uczenia sieci neuronowej, modele TF-DF nie potrzebują zestawu danych walidacyjnych do monitorowania nadmiernego dopasowania lub wcześniejszego przerwania uczenia. Jeśli masz już podział na pociąg/walidację/test i używasz walidacji z jednego z tych powodów, bezpieczne jest trenowanie TF-DF w trybie pociąg + walidacja (chyba że podział walidacji jest również używany do czegoś innego, np. strojenie hiperparametrów).

- model.fit(train_ds, validation_data=val_ds)
+ model.fit(train_ds.concatenate(val_ds))

# Or just don't create a validation dataset

Uzasadnienie: Struktura TF-DF składa się z wielu algorytmów. Niektóre z nich nie korzystają ze zbioru danych walidacyjnych (np. Random Forest), podczas gdy inne to robią (np. Gradient Boosted Trees). Algorytmy, które to robią, mogą czerpać korzyści z różnych typów i rozmiarów zestawów danych walidacyjnych. Dlatego jeśli potrzebny jest zbiór danych do walidacji, zostanie on automatycznie wyodrębniony ze zbioru danych szkoleniowych.

We/wy zestawu danych

Trenuj dokładnie przez 1 epokę

# Number of epochs in Keras
- model.fit(train_ds, num_epochs=5)

# Number of epochs in the dataset
- train_ds = train_ds.repeat(5)
- model.fit(train_ds)
+ model.fit(train_ds)

Uzasadnienie: Użytkownicy sieci neuronowych często trenują model dla N kroków (co może obejmować zapętlenie zbioru danych > 1 raz) ze względu na naturę SGD . TF-DF trenuje, czytając cały zbiór danych, a następnie przeprowadzając szkolenie na końcu. Do odczytania pełnego zestawu danych potrzebna jest 1 epoka, a wszelkie dodatkowe kroki spowodują niepotrzebne operacje we/wy danych, a także wolniejsze uczenie.

Nie mieszaj zbioru danych

Zbiory danych nie muszą być tasowane (chyba że input_fn odczytuje tylko próbkę zbioru danych).

- train_ds = train_ds.shuffle(5)
- model.fit(train_ds)
+ model.fit(train_ds)

Uzasadnienie: TF-DF tasuje wewnętrznie dostęp do danych po wczytaniu pełnego zestawu danych do pamięci. Algorytmy TF-DF są deterministyczne (jeśli użytkownik nie zmienia losowego materiału siewnego). Włączenie tasowania spowoduje jedynie, że algorytm będzie niedeterministyczny. Tasowanie ma sens, jeśli wejściowy zbiór danych jest uporządkowany, a input_fn będzie czytać tylko jego próbkę (próbka powinna być losowa). Jednakże spowoduje to, że procedura uczenia będzie niedeterministyczna.

Nie dostosowuj wielkości partii

Wielkość partii nie ma wpływu na jakość modelu

- train_ds = train_ds.batch(hyper_parameter_batch_size())
- model.fit(train_ds)
# The batch size does not matter.
+ train_ds = train_ds.batch(64)
+ model.fit(train_ds)

Uzasadnienie: Ponieważ TF-DF jest zawsze szkolony na pełnym zestawie danych po jego odczytaniu, jakość modelu nie będzie się różnić w zależności od wielkości partii (w przeciwieństwie do algorytmów uczenia mini-wsadowego, takich jak SGD, gdzie parametry takie jak szybkość uczenia się muszą być dostrajane wspólnie). Dlatego należy go usunąć z przemiatania hiperparametrów. Rozmiar partii będzie miał wpływ jedynie na szybkość operacji we/wy zestawu danych.

Duże zbiory danych

W przeciwieństwie do sieci neuronowych, które mogą w nieskończoność przełączać minipartie dużego zbioru danych, lasy decyzyjne wymagają skończonego zbioru danych mieszczącego się w pamięci na potrzeby procedur szkoleniowych. Rozmiar zbioru danych ma wpływ na wydajność i pamięć.

Korzyści ze zwiększania rozmiaru zbioru danych maleją, a algorytmy DF prawdopodobnie potrzebują mniej przykładów zbieżności niż duże modele NN. Zamiast skalować liczbę kroków szkoleniowych (jak w sieci NN), możesz spróbować skalować ilość danych, aby zobaczyć, gdzie kompromis w obliczeniach ma sens. Dlatego dobrym pomysłem jest najpierw spróbować trenowania na (małym) podzbiorze zbioru danych.

Alternatywnym rozwiązaniem jest wykorzystanie szkoleń rozproszonych . Uczenie rozproszone to świetny sposób na zwiększenie rozmiaru zestawu danych, jeśli dostępnych jest wiele maszyn. Chociaż wszystkie rozproszone algorytmy są dostępne do dystrybucji obliczeń, nie wszystkie z nich są w stanie dystrybuować użycie pamięci RAM. Sprawdź dokumentację , aby uzyskać więcej szczegółów.

Ile przykładów użyć

Powinien zmieścić się w pamięci maszyny, na której model trenuje :

  • Należy pamiętać, że nie jest to to samo, co rozmiar przykładów na dysku.

  • Z reguły jedna wartość liczbowa lub kategoryczna zajmuje 4 bajty pamięci. Zatem zbiór danych zawierający 100 funkcji i 25 milionów przykładów zajmie ~10 GB (= 100 * 25 *10^6 * 4 bajty) pamięci.

  • Funkcje z zestawem kategorii (np. tekst tokenizowany) zajmują więcej pamięci (4 bajty na token + 12 bajtów na funkcję).

Rozważ swój budżet czasu na szkolenie

  • Chociaż ogólnie są szybsze niż NN w przypadku mniejszych zbiorów danych (np. <100 tys. przykładów), algorytmy uczące DF nie skalują się liniowo wraz z rozmiarem zbioru danych; raczej ~O(cechy x liczba_przykładów x log(liczba_przykładów)) w większości przypadków.

  • Czas uczenia zależy od hiperparametrów. Najbardziej wpływowe parametry to: (1) liczba drzew ( num_trees ), (2) przykładowa częstotliwość próbkowania ( subsample dla GBT) i (3) częstotliwość próbkowania atrybutu ( num_candidate_attributes_ratio )

  • Funkcje z zestawem kategorycznym są droższe niż inne funkcje. Koszt jest kontrolowany przez parametr categorical_set_split_greedy_sampling .

  • Funkcje rzadkiego ukośnego (domyślnie wyłączone) dają dobre wyniki, ale są kosztowne w obliczeniach.

Praktyczne zasady skalowania danych

Sugerujemy rozpoczęcie od małego wycinka danych (<10 tys. przykładów), co powinno pozwolić na wytrenowanie modelu TF-DF w ciągu kilku sekund lub w większości przypadków kilku minut. Następnie możesz zwiększać ilość danych ze stałą szybkością (np. o 40% więcej za każdym razem), zatrzymując się, gdy wydajność zestawu walidacyjnego nie ulegnie poprawie lub zbiór danych nie będzie już mieścił się w pamięci.

Normalizacja funkcji/przetwarzanie wstępne

Nie przekształcaj danych za pomocą kolumn funkcji

Modele TF-DF nie wymagają jawnego podawania semantyki i transformacji funkcji. Domyślnie wszystkie funkcje w zestawie danych (inne niż etykieta) zostaną wykryte i wykorzystane przez model. Semantyka funkcji zostanie wykryta automatycznie i w razie potrzeby można ją zastąpić ręcznie.

# Estimator code
- feature_columns = [
-   tf.feature_column.numeric_column(feature_1),
-   tf.feature_column.categorical_column_with_vocabulary_list(feature_2, ['First', 'Second', 'Third'])
-   ]
- model = tf.estimator.LinearClassifier(feature_columns=feature_columnes)
# Use all the available features. Detect the type automatically.
+ model = tfdf.keras.GradientBoostedTreesModel()

Można także określić podzbiór cech wejściowych:

+ features = [
+   tfdf.keras.FeatureUsage(name="feature_1"),
+   tfdf.keras.FeatureUsage(name="feature_2")
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features, exclude_non_specified_features=True)

Jeśli to konieczne, możesz wymusić semantykę funkcji.

+ forced_features = [
+   tfdf.keras.FeatureUsage(name="feature_1", semantic=tfdf.keras.FeatureSemantic.CATEGORICAL),
+   ]
+ model = tfdf.keras.GradientBoostedTreesModel(features=features)

Uzasadnienie: Podczas gdy niektóre modele (takie jak sieci neuronowe) wymagają ustandaryzowanej warstwy wejściowej (np. mapowania z różnych typów obiektów → osadzania), modele TF-DF mogą natywnie wykorzystywać cechy kategoryczne i numeryczne, a także automatycznie wykrywać typy semantyczne obiektów w oparciu o dane.

Nie przetwarzaj wstępnie funkcji

Algorytmy drzewa decyzyjnego nie korzystają z niektórych klasycznych metod wstępnego przetwarzania cech stosowanych w sieciach neuronowych. Poniżej wyraźnie wymieniono niektóre z bardziej powszechnych strategii przetwarzania funkcji, ale bezpiecznym punktem wyjścia jest usunięcie całego przetwarzania wstępnego, które miało pomóc w uczeniu sieci neuronowej.

Nie normalizuj cech numerycznych

- def zscore(value):
-   return (value-mean) / sd

- feature_columns = [tf.feature_column.numeric_column("feature_1",normalizer_fn=zscore)]

Racjonalne: Algorytmy lasu decyzyjnego natywnie obsługują nieznormalizowane cechy numeryczne, ponieważ algorytmy podziału nie dokonują żadnej transformacji numerycznej danych wejściowych. Niektóre rodzaje normalizacji (np. normalizacja zscore) nie pomogą w zapewnieniu stabilności numerycznej procedury szkoleniowej, a niektóre (np. obcinanie wartości odstających) mogą zaszkodzić wyrazistości ostatecznego modelu.

Nie koduj cech kategorycznych (np. mieszania, one-hot lub osadzania)

- integerized_column = tf.feature_column.categorical_column_with_hash_bucket("feature_1",hash_bucket_size=100)
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]
- integerized_column = tf.feature_column.categorical_column_with_vocabulary_list('feature_1', ['bob', 'george', 'wanda'])
- feature_columns = [tf.feature_column.indicator_column(integerized_column)]

Uzasadnienie: TF-DF ma natywną obsługę cech kategorycznych i będzie traktował „przekształcony” element słownictwa jako kolejny element w swoim wewnętrznym słownictwie (który można skonfigurować za pomocą hiperparametrów modelu). Niektóre transformacje (takie jak haszowanie) mogą być stratne. Osadzanie nie jest obsługiwane, chyba że zostało wstępnie przeszkolone, ponieważ modeli lasu decyzyjnego nie można różnicować (zobacz współpracę dla pośredników ). Należy pamiętać, że strategie słownictwa specyficzne dla domeny (np. usuwanie słów pomijanych, normalizacja tekstu) mogą być nadal pomocne.

Jak obsługiwać funkcje tekstowe

TF-DF obsługuje natywnie funkcje z zestawem kategorii . Dlatego worki tokenizowanych n-gramów można spożywać natywnie.

Alternatywnie tekst można również wykorzystać poprzez wstępnie wytrenowane osadzanie .

Zbiory kategoryczne są efektywne w przypadku małych zbiorów danych, ale ich uczenie na dużych zbiorach danych jest kosztowne. Łączenie zestawów kategorii i wstępnie wyszkolonego osadzania może często dać lepsze wyniki niż w przypadku użycia jednego z nich osobno.

Nie zastępuj brakujących funkcji magicznymi wartościami

Uzasadnienie: TF-DF ma natywną obsługę brakujących wartości. W przeciwieństwie do sieci neuronowych, które mogą propagować NaN do gradientów, jeśli na wejściu znajdują się NaN, TF-DF będzie trenował optymalnie, jeśli algorytm wykryje różnicę między wartością brakującą a wartością wskaźnikową.

- feature_columns = [
- tf.feature_column.numeric_column("feature_1", default_value=0),
- tf.feature_column.numeric_column("feature_1_is_missing"),
- ]

Obsługa obrazów i szeregów czasowych

Nie ma standardowego algorytmu korzystania z funkcji obrazów lub szeregów czasowych w lasach decyzyjnych, więc ich użycie wymaga dodatkowej pracy.

Uzasadnienie: Splot, LSTM, uwaga i inne algorytmy przetwarzania sekwencji to architektury specyficzne dla sieci neuronowej.

Można obsłużyć te funkcje, stosując następujące strategie:

  • Inżynieria funkcji

    • Obrazy: Używanie obrazów z Random Forest było w pewnym momencie popularne (np

      Microsoft Kinect , ale dziś sieci neuronowe są najnowocześniejsze.

    • Szeregi czasowe: [ Ruchome statystyki ] mogą zaskakująco dobrze działać w przypadku danych szeregów czasowych, które mają stosunkowo niewiele przykładów (np. parametry życiowe w dziedzinie medycyny).

    • Moduły osadzające: Moduły osadzające sieci neuronowe mogą zapewniać bogate funkcje algorytmu lasu decyzyjnego. Współpraca dla pośrednich pokazuje, jak połączyć osadzanie w formacie tf-hub i model TF-DF.

Rurociąg szkoleniowy

Nie używaj akceleratorów sprzętowych np. GPU, TPU

Szkolenie TF-DF nie obsługuje (jeszcze) akceleratorów sprzętowych. Całe szkolenie i wnioskowanie odbywa się na procesorze (czasami przy użyciu SIMD).

Należy zauważyć, że wnioskowanie TF-DF na temat procesora (zwłaszcza gdy jest obsługiwane przy użyciu bibliotek Yggdrasil C++) może być zaskakująco szybkie (submikrosekunda na przykład na rdzeń procesora).

Nie używaj punktów kontrolnych ani haków w połowie treningu

TF-DF nie obsługuje (obecnie) punktów kontrolnych modelu, co oznacza, że ​​haki oczekujące, że model będzie użyteczny przed zakończeniem uczenia, są w dużej mierze nieobsługiwane. Model będzie dostępny dopiero po przeszkoleniu żądanej liczby drzew (lub zatrzymaniu się wcześniej).

Nie sprawdzą się również haki Keras polegające na kroku treningowym – ze względu na charakter treningu TF-DF model trenuje pod koniec pierwszej epoki i po tej epoce będzie stały. Krok odpowiada tylko we/wy zestawu danych.

Determinizm modelowy

Algorytm szkoleniowy TF-DF jest deterministyczny, tj. dwukrotne szkolenie na tym samym zbiorze danych da dokładnie ten sam model. Różni się to od sieci neuronowych trenowanych za pomocą TensorFlow. Aby zachować ten determinizm, użytkownicy powinni upewnić się, że odczyty zbioru danych również są deterministyczne.

Konfiguracja treningu

Określ zadanie (np. klasyfikacja, ranking) zamiast straty (np. binarna entropia krzyżowa)

- model = tf_keras.Sequential()
- model.add(Dense(64, activation=relu))
- model.add(Dense(1)) # One output for binary classification

- model.compile(loss=tf_keras.losses.BinaryCrossentropy(from_logits=True),
-               optimizer='adam',
-               metrics=['accuracy'])
# The loss is automatically determined from the task.
+ model = tfdf.keras.GradientBoostedTreesModel(task=tf_keras.Task.CLASSIFICATION)

# Optional if you want to report the accuracy.
+ model.compile(metrics=['accuracy'])

Uzasadnienie: Nie wszystkie algorytmy uczenia się TF-DF wykorzystują stratę. W przypadku tych, którzy to zrobią, strata zostanie automatycznie wykryta na podstawie zadania i wydrukowana w podsumowaniu modelu. Można go również zastąpić hiperparametrem straty.

Hiperparametry są semantycznie stabilne

Wszystkie hiperparametry mają wartości domyślne. Te wartości są rozsądnymi kandydatami do wypróbowania w pierwszej kolejności. Gwarantujemy, że domyślne wartości hiperparametrów nigdy się nie zmienią. Z tego powodu nowe hiperparametry lub ulepszenia algorytmów są domyślnie wyłączone.

Użytkownicy, którzy chcą korzystać z najnowszych algorytmów, ale nie chcą samodzielnie optymalizować hiperparametrów, mogą skorzystać z „szablonów hiperparametrów” dostarczonych przez TF-DF. Nowe szablony hiperparametrów zostaną wydane wraz z aktualizacjami pakietu.

# Model with default hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel()

# List the hyper-parameters (with default value) and hyper-parameters templates of the GBT learning algorithm (in colab)
?tfdf.keras.GradientBoostedTreesModel

# Use a hyper-parameter template.
model = tfdf.keras.GradientBoostedTreesModel(hp_template="winner_1")

# Change one of the hyper-parameters.
model = tfdf.keras.GradientBoostedTreesModel(num_trees=500)

# List all the learning algorithms available
tfdf.keras.get_all_models()

Debugowanie modelu

W tej sekcji przedstawiono kilka sposobów przeglądania/debugowania/interpretowania modelu. Współpraca dla początkujących zawiera kompleksowy przykład.

Proste podsumowanie modelu

# Text description of the model, training logs, feature importances, etc.
model.summary()

Dzienniki szkoleniowe i Tensorboard

# List of metrics
logs = model.make_inspector().training_logs()
print(logs)

Lub używając TensorBoard:

% load_ext
tensorboard
model.make_inspector().export_to_tensorboard("/tmp/tensorboard_logs")
% tensorboard - -logdir
"/tmp/tensorboard_logs"

Znaczenie funkcji

model.make_inspector().variable_importances()

Wykreślanie drzew

tfdf.model_plotter.plot_model_in_colab(model, tree_idx=0)

Uzyskaj dostęp do struktury drzewa

tree = model.make_inspector().extract_tree(tree_idx=0)
print(tree)

(Zobacz zaawansowaną współpracę )

Nie używaj strategii dystrybucji TensorFlow

TF-DF nie obsługuje jeszcze strategii dystrybucji TF. Konfiguracje obejmujące wielu pracowników zostaną zignorowane, a szkolenie odbędzie się tylko w przypadku menedżera.

- with tf.distribute.MirroredStrategy():
-    model = ...
+ model = ....

Układanie modeli

Modele TF-DF nie propagują wstecznie gradientów. W rezultacie nie można ich składać z modeli NN, chyba że sieci NN zostały już przeszkolone.

Migracja z tf.estimator.BoostedTrees {Classifier/Regressor/Estimator}

Pomimo tego, że brzmi podobnie, drzewa wzmocnione TF-DF i Estimator to różne algorytmy. TF-DF implementuje klasyczne papiery Random Forest i Gradient Boosted Machine (przy użyciu drzew) . Tf.estimator.BoostedTreesEstimator to przybliżony algorytm Gradient Boosted Trees z procedurą uczenia w trybie mini-batch opisaną w tym artykule

Niektóre hiperparametry mają podobną semantykę (np. num_trees), ale mają różne implikacje jakościowe. Jeśli dostroiłeś hiperparametry w tf.estimator.BoostedTreesEstimator, będziesz musiał ponownie dostroić hiperparametry w TF-DF, aby uzyskać optymalne wyniki.

Dla użytkowników Yggdrasil

Yggdrasil Decision Forest jest podstawową biblioteką uczącą i wnioskowującą używaną przez TF-DF. Konfiguracja i modele szkoleniowe są wzajemnie kompatybilne (tj. modele trenowane za pomocą TF-DF mogą być używane z wnioskowaniem Yggdrasil).

Jednakże niektóre algorytmy Yggdrasil nie są (jeszcze) dostępne w TF-DF.

  • Drzewo wzmocnione gradientem z próbkowaniem fragmentowanym.