Samouczek dotyczący regresji liniowej z TensorFlow [Przykłady]
⚡ Inteligentne podsumowanie
Regresja liniowa w TensorFlow modeluje relację między cechami numerycznymi a ciągłą wartością docelową. W tym przewodniku przedstawiono trzy niezależne metody trenowania predyktora cen nieruchomości w Bostonie, wykorzystując Pandas, NumPy oraz natywne potoki danych wejściowych TensorFlow z estymatorem LinearRegressor.
Co to jest regresja liniowa?
regresji liniowej to podejście statystyczne do modelowania relacji między dwiema zmiennymi. Modelowanie to odbywa się między odpowiedzią skalarną a jedną lub kilkoma zmiennymi objaśniającymi. Relacja z jedną zmienną objaśniającą nazywana jest prostą regresją liniową, a z wieloma zmiennymi objaśniającymi – wielokrotną regresją liniową.
TensorFlow zapewnia narzędzia umożliwiające pełną kontrolę nad obliczeniami. Odbywa się to za pomocą niskopoziomowego interfejsu API. Co więcej, TensorFlow jest wyposażony w szeroką gamę interfejsów API umożliwiających wykonywanie wielu operacji uczenie maszynowe algorytmy. To jest API wysokiego poziomu, a TensorFlow nazywa je estymatorami.
- API niskiego poziomu:Zbuduj architekturę i zoptymalizuj model od podstaw. To skomplikowane dla początkującego.
- Interfejs API wysokiego poziomu: Zdefiniuj algorytm. Jest on przyjazny dla użytkownika. TensorFlow udostępnia zestaw narzędzi o nazwie taksator konstruować, szkolić, oceniać i przewidywać.
W tym samouczku użyjesz tylko estymatoryObliczenia są szybsze i łatwiejsze do wdrożenia. Pierwsza część wyjaśnia, jak użyć optymalizatora gradientu zstępującego do trenowania regresji liniowej w TensorFlow. W drugiej części wykorzystasz zbiór danych z Bostonu do prognozowania ceny domu za pomocą estymatora TensorFlow.
Jak wytrenować model regresji liniowej
Zanim zaczniemy trenować model, przyjrzyjmy się, czym właściwie jest regresja liniowa.
Wyobraź sobie, że masz dwie zmienne, x i y, a Twoim zadaniem jest przewidzenie wartości y, znając wartość x. Jeśli naniesiesz dane na wykres, możesz zauważyć dodatnią zależność między zmienną niezależną x a zmienną zależną y, jak pokazano na poniższym wykresie punktowym.
Można zauważyć, że jeśli x=1, y będzie w przybliżeniu równe 6, a jeśli x=2, y będzie wynosić około 8.5.
Nie jest to zbyt dokładna metoda i jest podatna na błędy, zwłaszcza w przypadku zbiorów danych zawierających setki tysięcy punktów.
Regresję liniową ocenia się za pomocą równania. Zmienna y jest wyjaśniona przez jedną lub wiele współzmiennych. W twoim przykładzie istnieje tylko jedna zmienna zależna. Jeśli musisz napisać to równanie, będzie to:
Z:
jest odchyleniem. Oznacza to, że jeśli x=0, y=
jest wagą powiązaną z x
jest resztką, czyli błędem modelu. Obejmuje to to, czego model nie może dowiedzieć się z danych.
Wyobraź sobie, że dopasowujesz model i znajdujesz następujące rozwiązanie:
= 3.8
= 2.78
Możesz podstawić te liczby do równania i otrzymasz:
y= 3.8 + 2.78x
Teraz masz lepszy sposób znajdowania wartości y. Oznacza to, że możesz zastąpić x dowolną wartością, aby przewidzieć y. Na poniższym obrazku zastąpiliśmy x w równaniu wszystkimi wartościami w zestawie danych i przedstawiliśmy wynik na wykresie.
Czerwona linia przedstawia wartość dopasowaną, czyli wartości y dla każdej wartości x. Nie musisz znać wartości x, aby przewidzieć y; dla każdego x istnieje wartość należąca do czerwonej linii. Możesz również prognozować wartości x większe niż 2.
Jeśli chcesz rozszerzyć regresję liniową na więcej zmiennych współzależnych, możesz to zrobić, dodając do modelu więcej zmiennych. Różnica między analizą tradycyjną a regresją liniową polega na tym, że regresja liniowa bada, jak y zareaguje na każdą zmienną x rozpatrywaną niezależnie.
Spójrzmy na przykład. Wyobraź sobie, że chcesz przewidzieć sprzedaż w lodziarni. Zbiór danych zawiera różne informacje, takie jak pogoda (deszczowo, słonecznie, pochmurno) oraz informacje o klientach (wynagrodzenie, płeć, stan cywilny).
Tradycyjna analiza będzie próbowała przewidzieć sprzedaż, na przykład poprzez obliczenie średniej dla każdej zmiennej i oszacowanie sprzedaży dla różnych scenariuszy. Doprowadzi to do błędnych prognoz i ograniczy analizę do wybranego scenariusza.
Jeśli użyjesz regresji liniowej, możesz zapisać to równanie:
Algorytm znajdzie najlepsze rozwiązanie dla danych wagowych, co oznacza, że postara się zminimalizować koszt, który jest różnicą między dopasowaną linią a punktami danych.
Jak działa algorytm
Poniższy diagram podsumowuje pętlę, którą powtarza algorytm: wybieranie wag, przewidywanie y, mierzenie błędu i korygowanie wag.
Algorytm wybierze dla każdego losową liczbę oraz
i zamień wartość x, aby uzyskać przewidywaną wartość y. Jeśli zbiór danych zawiera 100 obserwacji, algorytm oblicza 100 przewidywanych wartości.
Zauważyliśmy, że możemy obliczyć błąd modelu, czyli różnicy między wartością przewidywaną a wartością rzeczywistą. Błąd dodatni oznacza, że model niedoszacowuje przewidywaną wartość y, a błąd ujemny oznacza, że model przeszacowuje przewidywaną wartość y.
Twoim celem jest minimalizacja kwadratu błędu. Algorytm oblicza średnią kwadratu błędu. Ten krok nazywa się minimalizacją błędu. W przypadku regresji liniowej jest to… Średni błąd kwadratowy, zwany także MSE. Matematycznie jest to:
Gdzie:
to są wagi, więc
odnosi się do przewidywanej wartości
- y to wartości rzeczywiste
- m to liczba obserwacji
Należy pamiętać, że oznacza, że wykorzystuje transpozycję macierzy. The
jest matematycznym zapisem średniej.
Celem jest znalezienie najlepszych co minimalizuje MSE.
Jeśli średni błąd jest duży, oznacza to, że model działa słabo, a wagi są niewłaściwie dobrane. Aby skorygować wagi, należy użyć optymalizatora. Tradycyjny optymalizator nazywa się Gradientowe zejście.
Metoda gradientu prostego pobiera pochodną i zmniejsza lub zwiększa wagę. Jeśli pochodna jest dodatnia, waga jest zmniejszana. Jeśli pochodna jest ujemna, waga wzrasta. Model zaktualizuje wagi i ponownie obliczy błąd. Ten proces jest powtarzany, aż błąd przestanie się zmieniać. Każde przejście nazywa się… iteracjaPonadto gradienty mnożone są przez współczynnik uczenia się, który wskazuje szybkość uczenia się.
Jeśli tempo uczenia się jest zbyt niskie, algorytm będzie potrzebował bardzo dużo czasu na osiągnięcie zbieżności, ponieważ wymaga to wielu iteracji. Jeśli tempo uczenia się jest zbyt wysokie, algorytm może nigdy nie osiągnąć zbieżności. Poniższa krzywa strat przedstawia zależność błędu od liczby iteracji dla tego zbioru danych.
Na powyższym wykresie widać, że model powtarza proces około 20 razy, zanim znajdzie stabilną wartość wagi, osiągając w ten sposób najniższy błąd.
Należy pamiętać, że błąd nie jest równy zeru, ale stabilizuje się wokół 5. Oznacza to, że model generuje typowy błąd wynoszący 5. Aby zmniejszyć błąd, należy dodać do modelu więcej informacji, na przykład więcej zmiennych lub użyć innych estymatorów.
Pamiętasz pierwsze równanie:
Ostateczne wagi to 3.8 i 2.78. Poniższy film pokazuje, jak metoda gradientu prostego optymalizuje funkcję straty, aby znaleźć te wagi.
Jak wytrenować regresję liniową za pomocą TensorFlow
Teraz, gdy lepiej rozumiesz, co dzieje się za maską, możesz skorzystać z interfejsu API estymatora dostarczonego przez TensorFlow, aby wytrenować pierwszą regresję liniową za pomocą TensorFlow.
Uwaga dotycząca wersji: Przepływ pracy estymatora pokazany poniżej został napisany dla TensorFlow 1.x i wczesnych wersji 2.x. TensorFlow był tf.estimator oraz tf.feature_column Interfejsy API zostały całkowicie wycofane w wersji 2.12, a Estimatory zostały usunięte w wersji 2.16. W bieżącej instalacji uruchom ten kod w środowisku TensorFlow 1.15 lub 2.x z…tf.compat.v1 środowisko lub przenieść je do Keras, gdzie tf.keras.layers.Dense(1) Dodatkowo warstwy wstępnego przetwarzania zastępują regresor liniowy i kolumny cech. Koncepcje – cechy, etykiety, partie, epoki, MSE i gradient spadkowy – są przenoszone bez zmian.
Będziesz korzystać ze zbioru danych Boston Dataset, który zawiera następujące zmienne.
| Zmienna | OPIS |
| kryminalny | wskaźnik przestępczości na mieszkańca według miasta |
| zn | część gruntów mieszkalnych przeznaczonych na działki o powierzchni powyżej 25,000 XNUMX stóp kwadratowych. |
| indus | odsetek powierzchni użytków niehandlowych przypadających na miasto. |
| nox | stężenie tlenków azotu |
| rm | średnia liczba pokoi w mieszkaniu |
| wiek | odsetek mieszkań własnościowych wybudowanych przed 1940 rokiem |
| dis | odległości ważone do pięciu bostońskich centrów zatrudnienia |
| podatek | pełnowartościowa stawka podatku od nieruchomości na 10,000 XNUMX dolarów |
| ptratio | stosunek liczby uczniów do nauczycieli według miasta |
| med | Średnia wartość domów zamieszkałych przez właścicieli w tysiącach dolarów |
Utworzysz trzy różne zbiory danych:
| zestaw danych | cel | kształt |
| Szkolenia | Wytrenuj model i uzyskaj ciężary | 400, 10 |
| Ocena | Oceń wydajność modelu na niewidocznych danych | 100, 10 |
| Przewiduj | Użyj modelu, aby przewidzieć wartość domu na podstawie nowych danych | 6, 10 |
Celem jest wykorzystanie cech zbioru danych do przewidzenia wartości domu.
W drugiej części samouczka dowiesz się, jak używać TensorFlow, importując dane na trzy różne sposoby:
- Z Pandami
- Z numpy
- Tylko TensorFlow
Należy pamiętać, że wszystkie trzy opcje dają takie same rezultaty.
Dowiesz się, jak korzystać z API wysokiego poziomu do budowania, trenowania i ewaluacji modelu regresji liniowej TensorFlow. Korzystając z API niskiego poziomu, musiałbyś ręcznie zdefiniować:
- Funkcja utraty
- Optymalizator: gradient zstępujący
- Mnożenie macierzy
- Wykres i tensor
Dla początkującego jest to żmudne i skomplikowane.
Rozwiązanie Pandas
Aby wytrenować model, należy zaimportować niezbędne biblioteki.
import pandas as pd from sklearn import datasets import tensorflow as tf import itertools
Krok 1) Zaimportuj dane za pomocą Pandy.
Definiujesz nazwy kolumn i zapisujesz je w COLUMNS. Możesz użyć pd.read_csv(), aby zaimportować dane.
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"]
W każdym przypadku kieruj rozmowę na pliki CSV, które wcześniej pobrałeś.
training_set = pd.read_csv("E:/boston_train.csv", skipinitialspace=True,skiprows=1, names=COLUMNS) test_set = pd.read_csv("E:/boston_test.csv", skipinitialspace=True,skiprows=1, names=COLUMNS) prediction_set = pd.read_csv("E:/boston_predict.csv", skipinitialspace=True,skiprows=1, names=COLUMNS)
Można wydrukować kształt danych.
print(training_set.shape, test_set.shape, prediction_set.shape)
Wydajność
(400, 10) (100, 10) (6, 10)
Zwróć uwagę, że etykieta, czyli Twoje y, jest zawarta w zbiorze danych. Musisz więc zdefiniować dwie inne listy: jedną zawierającą tylko cechy, a drugą tylko nazwę etykiety. Te dwie listy wskażą Twojemu estymatorowi, jakie cechy znajdują się w zbiorze danych i która nazwa kolumny jest etykietą.
Robi się to za pomocą poniższego kodu.
FEATURES = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio"] LABEL = "medv"
Krok 2) Konwertuj dane
Musisz przekonwertować zmienne numeryczne do odpowiedniego formatu. TensorFlow udostępnia metodę konwersji zmiennej ciągłej: tf.feature_column.numeric_column().
W poprzednim kroku zdefiniowałeś listę cech, które chcesz uwzględnić w modelu. Teraz możesz użyć tej listy, aby przekonwertować je na dane liczbowe. Jeśli chcesz wykluczyć cechy z modelu, możesz usunąć jedną lub więcej zmiennych z listy FEATURES przed utworzeniem kolumny feature_cols.
Należy pamiętać, że użyjesz Python Złożenie listy z listą FEATURES pozwala utworzyć nową listę o nazwie feature_cols. Pozwala to uniknąć konieczności pisania tf.feature_column.numeric_column() dziewięć razy. Złożenie listy to szybszy i bardziej przejrzysty sposób tworzenia nowych list.
feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]
Krok 3) Zdefiniuj estymator
W tym kroku należy zdefiniować estymator. TensorFlow udostępnia sześć gotowych estymatorów: trzy dla zadań klasyfikacyjnych i trzy dla zadań regresyjnych TensorFlow:
- Regresor
- DNNRegresor
- Regresor liniowy
- DNNLinearCombinedRegressor
- klasyfikować
- Klasyfikator DNN
- Klasyfikator liniowy
- DNNLinearCombinedKlasyfikator
W tym samouczku użyjesz regresora liniowego. Aby uzyskać dostęp do tej funkcji, musisz użyć tf.estimator.
Funkcja potrzebuje dwóch argumentów:
- feature_columns: zawiera zmienne, które mają zostać uwzględnione w modelu
- model_dir: ścieżka do przechowywania wykresu, zapisywania parametrów modelu itd.
TensorFlow automatycznie utworzy folder o nazwie „train” w Twoim katalogu roboczym. Aby uzyskać do niego dostęp, musisz skorzystać z tej ścieżki. Tensorboard, jak pokazano w poniższym przykładzie regresji TensorFlow.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_cols,
model_dir="train")
Wydajność
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a215dc550>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Problem z TensorFlow polega na sposobie zasilania modelu. TensorFlow został zaprojektowany do pracy z obliczeniami równoległymi i bardzo dużymi zbiorami danych. Ze względu na ograniczone zasoby maszynowe, nie jest możliwe zasilanie modelu wszystkimi danymi naraz. W tym celu konieczne jest za każdym razem zasilanie partii danych. Należy pamiętać, że mówimy o ogromnych zbiorach danych z milionami lub więcej rekordów. Jeśli nie dodasz partii, wystąpi błąd pamięci.
Na przykład, jeśli dane zawierają 100 obserwacji i zdefiniujesz wielkość partii 10, oznacza to, że model będzie widział 10 obserwacji w każdej iteracji (10*10).
Gdy model zobaczy wszystkie dane, kończy jedną epokę. Epoka definiuje, ile razy model ma zobaczyć dane. Lepiej ustawić ten krok na „brak” i pozwolić modelowi wykonać określoną liczbę iteracji.
Drugą informacją, którą należy dodać, jest to, czy dane mają być przetasowane przed każdą iteracją. Podczas treningu ważne jest, aby przetasować dane, aby model nie nauczył się określonego wzorca zbioru danych. Jeśli model nauczy się szczegółów wzorca danych, będzie miał trudności z generalizowaniem prognozy dla danych niewidocznych. Nazywa się to przeuczeniem (overfitting). Model działa dobrze na danych treningowych, ale nie potrafi poprawnie prognozować dla danych niewidocznych.
TensorFlow ułatwia wykonanie tych dwóch kroków. Kiedy dane trafiają do potoku, wie, ile obserwacji jest potrzebnych (w partiach) i czy konieczne jest przetasowanie danych.
Aby poinstruować TensorFlow, jak zasilić model, możesz użyć pandas_input_fn. Ten obiekt wymaga pięciu parametrów:
- x: dane funkcji
- y: dane etykiety
- rozmiar_partia: partia. Domyślnie 128
- num_epoch: liczba epok, domyślnie 1
- shuffle: tasować dane lub nie. Domyślnie: brak
Musisz wielokrotnie podawać dane do modelu, więc definiujesz funkcję, która powtarza ten proces. Nazywasz ją get_input_fn.
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True): return tf.estimator.inputs.pandas_input_fn( x=pd.DataFrame({k: data_set[k].values for k in FEATURES}), y = pd.Series(data_set[LABEL].values), batch_size=n_batch, num_epochs=num_epochs, shuffle=shuffle)
Typową metodą oceny wydajności modelu jest:
- Trenuj model
- Oceń model na innym zestawie danych
- Zrób prognozę
Estymator TensorFlow udostępnia trzy różne funkcje pozwalające na łatwą realizację tych trzech kroków.
Krok 4) Trenuj model
Możesz użyć metody trenowania estymatora, aby dopasować model. Estymator trenujący potrzebuje input_fn i liczby kroków. Możesz użyć funkcji utworzonej powyżej, aby zasilić model. Następnie instruujesz model, aby wykonał 1000 iteracji. Zwróć uwagę, że nie określasz liczby epok; pozwalasz modelowi wykonać 1000 iteracji. Jeśli ustawisz liczbę epok na 1, model wykona cztery iteracje, ponieważ w zestawie treningowym znajduje się 400 rekordów, a rozmiar partii wynosi 128:
- Wiersze 128
- Wiersze 128
- Wiersze 128
- Wiersze 16
Dlatego łatwiej jest ustawić liczbę epok na zero i zdefiniować liczbę iteracji, jak pokazano w poniższym przykładzie klasyfikacji TensorFlow.
estimator.train(input_fn=get_input_fn(training_set,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 238.616 INFO:tensorflow:loss = 13909.657, step = 101 (0.420 sec) INFO:tensorflow:global_step/sec: 314.293 INFO:tensorflow:loss = 12881.449, step = 201 (0.320 sec) INFO:tensorflow:global_step/sec: 303.863 INFO:tensorflow:loss = 12391.541, step = 301 (0.327 sec) INFO:tensorflow:global_step/sec: 308.782 INFO:tensorflow:loss = 12050.5625, step = 401 (0.326 sec) INFO:tensorflow:global_step/sec: 244.969 INFO:tensorflow:loss = 11766.134, step = 501 (0.407 sec) INFO:tensorflow:global_step/sec: 155.966 INFO:tensorflow:loss = 11509.922, step = 601 (0.641 sec) INFO:tensorflow:global_step/sec: 263.256 INFO:tensorflow:loss = 11272.889, step = 701 (0.379 sec) INFO:tensorflow:global_step/sec: 254.112 INFO:tensorflow:loss = 11051.9795, step = 801 (0.396 sec) INFO:tensorflow:global_step/sec: 292.405 INFO:tensorflow:loss = 10845.855, step = 901 (0.341 sec) INFO:tensorflow:Saving checkpoints for 1000 into train/model.ckpt. INFO:tensorflow:Loss for final step: 5925.9873.
Możesz sprawdzić TensorBoard za pomocą następującego polecenia:
activate hello-tf # For MacOS tensorboard --logdir=./train # For Windows tensorboard --logdir=train
Krok 5) Oceń swój model
Możesz ocenić dopasowanie swojego modelu na zestawie testowym, korzystając z poniższego kodu:
ev = estimator.evaluate(
input_fn=get_input_fn(test_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-01:43:13 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-01:43:13 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896
Stratę możesz wydrukować za pomocą poniższego kodu:
loss_score = ev["loss"] print("Loss: {0:f}".format(loss_score))
Wydajność
Loss: 3215.895996
Model wykazuje stratę wynoszącą 3215. Aby zorientować się, jak duży jest błąd, sprawdź statystyki podsumowujące.
training_set['medv'].describe()
Wydajność
count 400.000000 mean 22.625500 std 9.572593 min 5.000000 25% 16.600000 50% 21.400000 75% 25.025000 max 50.000000 Name: medv, dtype: float64
Z powyższego podsumowania wynika, że średnia cena domu wynosi 22 tysiące dolarów, przy cenie minimalnej 5 tysięcy dolarów i maksymalnej 50 tysięcy dolarów. Ponieważ podana strata jest średnim błędem kwadratowym, typowy błąd w oryginalnych jednostkach wynosi w przybliżeniu pierwiastek kwadratowy z 32.16, czyli około 5.7 tysiąca dolarów.
Krok 6) Dokonaj prognozy
Na koniec możesz użyć metody estymatora TensorFlow predict, aby oszacować wartość sześciu domów w Bostonie.
y = estimator.predict(
input_fn=get_input_fn(prediction_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
Aby wydrukować szacowane wartości, możesz użyć tego kodu:
predictions = list(p["predictions"] for p in itertools.islice(y, 6)) print("Predictions: {}".format(str(predictions)))
Wydajność
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.96125], dtype=float32), array([27.270979], dtype=float32), array([29.299236], dtype=float32), array([16.436684], dtype=float32), array([21.460876], dtype=float32)]
Model prognozuje następujące wartości:
| dom | Przepowiednia |
| 1 | 32.29 |
| 2 | 18.96 |
| 3 | 27.27 |
| 4 | 29.29 |
| 5 | 16.43 |
| 6 | 21.46 |
Zwróć uwagę, że nie znamy rzeczywistej wartości tych sześciu domów. W samouczku dotyczącym głębokiego uczenia się spróbujesz pokonać model liniowy.
Rozwiązanie NumPy
W tej sekcji wyjaśnimy, jak trenować model za pomocą estymatora NumPy do wprowadzania danych. Metoda jest taka sama, z tą różnicą, że użyjemy estymatora numpy_input_fn.
Odczytaj te same trzy pliki CSV, ale zachowaj tylko surowe tablice NumPy z opcjami .values.
training_set_n = pd.read_csv("E:/boston_train.csv").values test_set_n = pd.read_csv("E:/boston_test.csv").values prediction_set_n = pd.read_csv("E:/boston_predict.csv").values
Krok 1) Importuj dane
Przede wszystkim należy odróżnić zmienne cech od etykiety. Należy to zrobić zarówno dla danych treningowych, jak i danych ewaluacyjnych. Szybciej jest zdefiniować funkcję dzielącą dane.
def prepare_data(df): X_train = df[:, :-3] y_train = df[:,-3] return X_train, y_train
Za pomocą tej funkcji można oddzielić etykietę od cech pociągu i ocenić zestawy danych.
X_train, y_train = prepare_data(training_set_n) X_test, y_test = prepare_data(test_set_n)
Należy wykluczyć ostatnią kolumnę zestawu danych prognozowania, ponieważ zawiera ona tylko NaN.
x_predict = prediction_set_n[:, :-2]
Potwierdź kształt tablicy. Zwróć uwagę, że etykieta nie powinna mieć drugiego wymiaru, czyli (400).
print(X_train.shape, y_train.shape, x_predict.shape)
Wydajność
(400, 9) (400,) (6, 9)
Kolumny funkcji można utworzyć w następujący sposób:
feature_columns = [ tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]
Estymator jest definiowany jak poprzednio: określasz kolumny cech i miejsce zapisania wykresu.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_columns,
model_dir="train1")
Wydajność
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a218d8f28>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Możesz użyć estymatora NumPy do wprowadzenia danych do modelu, a następnie wytrenowania modelu. Pamiętaj, że wcześniej zdefiniowaliśmy funkcję input_fn, aby ułatwić odczyt.
# Train the estimator train_input = tf.estimator.inputs.numpy_input_fn( x={"x": X_train}, y=y_train, batch_size=128, shuffle=False, num_epochs=None) estimator.train(input_fn = train_input,steps=5000)
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train1/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 490.057 INFO:tensorflow:loss = 13909.656, step = 101 (0.206 sec) INFO:tensorflow:global_step/sec: 788.986 INFO:tensorflow:loss = 12881.45, step = 201 (0.126 sec) INFO:tensorflow:global_step/sec: 736.339 INFO:tensorflow:loss = 12391.541, step = 301 (0.136 sec) INFO:tensorflow:global_step/sec: 383.305 INFO:tensorflow:loss = 12050.561, step = 401 (0.260 sec) INFO:tensorflow:global_step/sec: 859.832 INFO:tensorflow:loss = 11766.133, step = 501 (0.117 sec) INFO:tensorflow:global_step/sec: 804.394 INFO:tensorflow:loss = 11509.918, step = 601 (0.125 sec) INFO:tensorflow:global_step/sec: 753.059 INFO:tensorflow:loss = 11272.891, step = 701 (0.134 sec) INFO:tensorflow:global_step/sec: 402.165 INFO:tensorflow:loss = 11051.979, step = 801 (0.248 sec) INFO:tensorflow:global_step/sec: 344.022 INFO:tensorflow:loss = 10845.854, step = 901 (0.288 sec) INFO:tensorflow:Saving checkpoints for 1000 into train1/model.ckpt. INFO:tensorflow:Loss for final step: 5925.985. Out[23]: <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1b6ea860>
Powtarzasz ten sam krok, ale z inną funkcją wejściową, aby ocenić swój model.
eval_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_test},
y=y_test,
shuffle=False,
batch_size=128,
num_epochs=1)
estimator.evaluate(eval_input,steps=None)
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-01:44:00 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-01:44:00 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.158947, global_step = 1000, loss = 3215.8945 Out[24]: {'average_loss': 32.158947, 'global_step': 1000, 'loss': 3215.8945}
Na koniec możesz obliczyć prognozę. Powinna być podobna do wyniku Pandas.
test_input = tf.estimator.inputs.numpy_input_fn(
x={"x": x_predict},
batch_size=128,
num_epochs=1,
shuffle=False)
y = estimator.predict(test_input)
predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))
Wydajność
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.961248], dtype=float32), array([27.270979], dtype=float32), array([29.299242], dtype=float32), array([16.43668], dtype=float32), array([21.460878], dtype=float32)]
Rozwiązanie TensorFlow
Ostatnia część poświęcona jest czystemu TensorFlow Rozwiązanie. Ta metoda jest nieco bardziej skomplikowana niż dwie pozostałe.
Należy pamiętać, że jeśli używasz Jupyter notatnik, aby uruchomić tę sesję, należy ponownie uruchomić komputer i wyczyścić jądro.
TensorFlow stworzył świetne narzędzie do przesyłania danych do potoku. W tej sekcji samodzielnie utworzysz funkcję input_fn.
Krok 1) Zdefiniuj ścieżkę i format danych
Najpierw deklarujesz dwie zmienne ze ścieżką do plików CSV. Zauważ, że masz dwa pliki: jeden dla zestawu treningowego i jeden dla zestawu testowego.
import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"
Następnie musisz zdefiniować kolumny, których chcesz użyć w pliku CSV. Wykorzystamy je wszystkie. Następnie musisz zadeklarować typ każdej zmiennej.
Zmienne typu float są definiowane przez [0.]
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"] RECORDS_ALL = [[0.0], [0.0], [0.0], [0.0],[0.0],[0.0],[0.0],[0.0],[0.0],[0.0]]
Krok 2) Zdefiniuj funkcję input_fn
Funkcję tę można podzielić na trzy części:
- Importuj dane
- Utwórz iterator
- Korzystaj z danych
Poniżej znajduje się ogólny kod definiujący funkcję. Kod zostanie wyjaśniony później.
def input_fn(data_file, batch_size, num_epoch = None): # Step 1 def parse_csv(value): columns = tf.decode_csv(value, record_defaults= RECORDS_ALL) features = dict(zip(COLUMNS, columns)) #labels = features.pop('median_house_value') labels = features.pop('medv') return features, labels # Extract lines from input files using the Dataset API. dataset = (tf.data.TextLineDataset(data_file) # Read text file .skip(1) # Skip header row .map(parse_csv)) dataset = dataset.repeat(num_epoch) dataset = dataset.batch(batch_size) # Step 3 iterator = dataset.make_one_shot_iterator() features, labels = iterator.get_next() return features, labels
Importuj dane
W przypadku pliku CSV metoda dataset odczytuje po jednym wierszu na raz. Aby zbudować zbiór danych, należy użyć obiektu TextLineZbiór danych. Twój zbiór danych ma nagłówek, więc musisz użyć funkcji skip(1), aby pominąć pierwszy wiersz. Na tym etapie odczytujesz tylko dane i pomijasz nagłówek w potoku. Aby zasilić model, musisz oddzielić cechy od etykiety. Metodą używaną do zastosowania dowolnej transformacji danych jest mapa.
Ta metoda wywołuje funkcję, którą utworzysz, aby poinstruować Cię, jak przekształcić dane. W skrócie, musisz przekazać dane do TextLineObiekt zbioru danych, wyklucz nagłówek i zastosuj transformację zleconą przez funkcję.
Code wyjaśnienie
- dane tf.TextLineDataset(data_file): ta linia odczytuje plik CSV
- .skip(1): pomija nagłówek
- .map(parse_csv)): analizuje rekordy w tensory
Musisz zdefiniować funkcję, która będzie instruować obiekt mapy. Możesz nazwać tę funkcję parse_csv.
Ta funkcja analizuje plik CSV metodą tf.decode_csv i deklaruje cechy oraz etykietę. Cechy można zadeklarować jako słownik lub krotkę. Używa się metody słownikowej, ponieważ jest wygodniejsza.
Code wyjaśnienie
- tf.decode_csv(value, record_defaults= RECORDS_ALL): metoda decode_csv wykorzystuje dane wyjściowe TextLineZestaw danych do odczytu pliku CSV. record_defaults informuje TensorFlow o typach kolumn. W TensorFlow 2.x ten symbol znajduje się w tf.io.decode_csv.
- dict(zip(COLUMNS, columns)): wypełnia słownik wszystkimi kolumnami, np.tracpodczas przetwarzania tych danych
- features.pop('medv'): wyklucza zmienną docelową ze zmiennych funkcji i tworzy zmienną etykiety
Zbiór danych potrzebuje dodatkowych elementów, aby iteracyjnie zasilać tensory. W rzeczywistości należy dodać metodę „repeat”, aby zbiór danych mógł w nieskończoność kontynuować przetwarzanie modelu. Jeśli metoda nie zostanie dodana, model wykona iterację tylko raz, a następnie zgłosi błąd, ponieważ do potoku nie zostaną przesłane żadne dalsze dane.
Następnie możesz kontrolować rozmiar partii za pomocą metody wsadowej. Oznacza to, że informujesz zestaw danych, ile danych chcesz przekazać do potoku dla każdej iteracji. Jeśli ustawisz duży rozmiar partii, model będzie działał wolno.
Krok 3) Utwórz iterator
Teraz jesteś gotowy na drugi krok: utwórz iterator, który zwróci elementy zbioru danych.
Najprostszym sposobem utworzenia operatora jest użycie metody make_one_shot_iterator.
Następnie możesz utworzyć funkcje i etykiety z poziomu iteratora.
Krok 4) Korzystaj z danych
Możesz sprawdzić, co dzieje się z funkcją input_fn. Aby pobrać dane, musisz wywołać tę funkcję w sesji. Spróbuj użyć rozmiaru wsadu równego 1.
Należy pamiętać, że drukuje funkcje w słowniku, a etykieta jest wyświetlana jako tablica.
Wyświetli się pierwszy wiersz pliku CSV. Możesz spróbować uruchomić ten kod wielokrotnie, używając różnych rozmiarów partii.
next_batch = input_fn(df_train, batch_size = 1, num_epoch = None) with tf.Session() as sess: first_batch = sess.run(next_batch) print(first_batch)
Wydajność
({'crim': array([2.3004], dtype=float32), 'zn': array([0.], dtype=float32), 'indus': array([19.58], dtype=float32), 'nox': array([0.605], dtype=float32), 'rm': array([6.319], dtype=float32), 'age': array([96.1], dtype=float32), 'dis': array([2.1], dtype=float32), 'tax': array([403.], dtype=float32), 'ptratio': array([14.7], dtype=float32)}, array([23.8], dtype=float32))
Krok 5) Zdefiniuj kolumnę funkcji
Należy zdefiniować kolumny numeryczne w następujący sposób:
X1= tf.feature_column.numeric_column('crim') X2= tf.feature_column.numeric_column('zn') X3= tf.feature_column.numeric_column('indus') X4= tf.feature_column.numeric_column('nox') X5= tf.feature_column.numeric_column('rm') X6= tf.feature_column.numeric_column('age') X7= tf.feature_column.numeric_column('dis') X8= tf.feature_column.numeric_column('tax') X9= tf.feature_column.numeric_column('ptratio')
Należy pamiętać o połączeniu wszystkich zmiennych w jednym zbiorze.
base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]
Krok 6) Zbuduj model
Model można trenować za pomocą estymatora LinearRegressor.
model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')
Wydajność
INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1820a010f0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Musisz użyć funkcja lambda aby umożliwić Ci zapisanie argumentów dla funkcji input_fn. Bez użycia funkcji lambda nie możesz trenować modelu.
# Train the estimator model.train(steps =1000, input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Saving checkpoints for 1 into train3/model.ckpt. INFO:tensorflow:loss = 83729.64, step = 1 INFO:tensorflow:global_step/sec: 72.5646 INFO:tensorflow:loss = 13909.657, step = 101 (1.380 sec) INFO:tensorflow:global_step/sec: 101.355 INFO:tensorflow:loss = 12881.449, step = 201 (0.986 sec) INFO:tensorflow:global_step/sec: 109.293 INFO:tensorflow:loss = 12391.541, step = 301 (0.915 sec) INFO:tensorflow:global_step/sec: 102.235 INFO:tensorflow:loss = 12050.5625, step = 401 (0.978 sec) INFO:tensorflow:global_step/sec: 104.656 INFO:tensorflow:loss = 11766.134, step = 501 (0.956 sec) INFO:tensorflow:global_step/sec: 106.697 INFO:tensorflow:loss = 11509.922, step = 601 (0.938 sec) INFO:tensorflow:global_step/sec: 118.454 INFO:tensorflow:loss = 11272.889, step = 701 (0.844 sec) INFO:tensorflow:global_step/sec: 114.947 INFO:tensorflow:loss = 11051.9795, step = 801 (0.870 sec) INFO:tensorflow:global_step/sec: 111.484 INFO:tensorflow:loss = 10845.855, step = 901 (0.897 sec) INFO:tensorflow:Saving checkpoints for 1000 into train3/model.ckpt. INFO:tensorflow:Loss for final step: 5925.9873. Out[8]: <tensorflow.python.estimator.canned.linear.LinearRegressor at 0x18225eb8d0>
Możesz ocenić dopasowanie swojego modelu na zestawie testowym, korzystając z poniższego kodu:
results = model.evaluate(steps =None,input_fn=lambda: input_fn(df_eval, batch_size =128, num_epoch = 1)) for key in results: print(" {}, was: {}".format(key, results[key]))
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-05-13-02:06:02 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-05-13-02:06:02 INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896 average_loss, was: 32.158958435058594 loss, was: 3215.89599609375 global_step, was: 1000
Ostatnim krokiem jest prognozowanie wartości celu na podstawie wartości macierzy cech. Możesz napisać słownik z wartościami, które chcesz prognozować. Twój model ma dziewięć cech, więc musisz podać wartość dla każdej z nich. Model zapewni prognozę dla każdej z nich.
W poniższym kodzie należy wpisać wartości każdej funkcji zawartej w pliku CSV df_predict.
Musisz napisać nową funkcję input_fn, ponieważ w zbiorze danych nie ma etykiety. Możesz skorzystać z API from_tensors z obiektu Dataset.
prediction_input = {
'crim': [0.03359,5.09017,0.12650,0.05515,8.15174,0.24522],
'zn': [75.0,0.0,25.0,33.0,0.0,0.0],
'indus': [2.95,18.10,5.13,2.18,18.10,9.90],
'nox': [0.428,0.713,0.453,0.472,0.700,0.544],
'rm': [7.024,6.297,6.762,7.236,5.390,5.782],
'age': [15.8,91.8,43.4,41.1,98.9,71.7],
'dis': [5.4011,2.3682,7.9809,4.0220,1.7281,4.0317],
'tax': [252,666,284,222,666,304],
'ptratio': [18.3,20.2,19.7,18.4,20.2,18.4]
}
def test_input_fn():
dataset = tf.data.Dataset.from_tensors(prediction_input)
return dataset
# Predict all our prediction_input
pred_results = model.predict(input_fn=test_input_fn)
Na koniec wydrukuj prognozy.
for pred in enumerate(pred_results): print(pred)
Wydajność
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([32.297546], dtype=float32)}) (1, {'predictions': array([18.96125], dtype=float32)}) (2, {'predictions': array([27.270979], dtype=float32)}) (3, {'predictions': array([29.299236], dtype=float32)}) (4, {'predictions': array([16.436684], dtype=float32)}) (5, {'predictions': array([21.460876], dtype=float32)}) INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-5000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([35.60663], dtype=float32)}) (1, {'predictions': array([22.298521], dtype=float32)}) (2, {'predictions': array([25.74533], dtype=float32)}) (3, {'predictions': array([35.126694], dtype=float32)}) (4, {'predictions': array([17.94416], dtype=float32)}) (5, {'predictions': array([22.606628], dtype=float32)})
Wszystkie trzy potoki zwracają te same sześć prognoz, co potwierdza, że wybór między Pandas, NumPy i natywnym zestawem danych TensorFlow jest kwestią wygody, a nie dokładności.





