Handledning för linjär regression med TensorFlow [Exempel]
⚡ Smart sammanfattning
Linjär regression i TensorFlow modellerar förhållandet mellan numeriska funktioner och ett kontinuerligt målvärde. Denna genomgång tränar en prediktor för bostadspriser i Boston på tre separata sätt, med hjälp av Pandas, NumPy och nativa TensorFlow-inmatningspipelines med LinearRegressor-estimatorn.
Vad är linjär regression?
linjär regression är en metod inom statistik för att modellera samband mellan två variabler. Denna modellering görs mellan ett skalärt svar och en eller flera förklarande variabler. Sambandet med en förklarande variabel kallas enkel linjär regression, och med mer än en förklarande variabel kallas det multipel linjär regression.
TensorFlow tillhandahåller verktyg för att ha full kontroll över beräkningarna. Detta görs med lågnivå API. Utöver det är TensorFlow utrustad med ett stort utbud av API:er för att utföra många maskininlärning algoritmer. Detta är högnivå-API:et, och TensorFlow kallar dem estimatorer.
- API på låg nivåBygg arkitekturen och optimeringen av modellen från grunden. Det är komplicerat för en nybörjare.
- API på hög nivåDefiniera algoritmen. Den är användarvänlig. TensorFlow tillhandahåller en verktygslåda som heter uppskattare att konstruera, träna, utvärdera och göra en förutsägelse.
I den här handledningen kommer du att använda endast estimerareBeräkningarna är snabbare och enklare att implementera. Den första delen förklarar hur man använder gradient descent-optimeraren för att träna en linjär regression i TensorFlow. I en andra del kommer du att använda Boston-datasetet för att förutsäga priset på ett hus med hjälp av en TensorFlow-estimator.
Hur man tränar en linjär regressionsmodell
Innan vi börjar träna modellen, låt oss titta på vad en linjär regression egentligen är.
Tänk dig att du har två variabler, x och y, och din uppgift är att förutsäga värdet på y med värdet på x. Om du plottar data kan du se ett positivt samband mellan din oberoende variabel, x, och din beroende variabel, y, som spridningsdiagrammet nedan visar.
Du kan observera att om x=1, kommer y ungefär att vara lika med 6, och om x=2, kommer y att vara runt 8.5.
Detta är inte en särskilt noggrann metod och är felbenägen, särskilt med en datamängd som innehåller hundratusentals punkter.
En linjär regression utvärderas med en ekvation. Variabeln y förklaras av en eller flera kovariater. I ditt exempel finns det bara en beroende variabel. Om du måste skriva den här ekvationen blir det:
Med:
är biasen. Det vill säga, om x=0, y=
är vikten associerad med x
är residualen, eller modellens fel. Den inkluderar vad modellen inte kan lära sig av data
Föreställ dig att du passar modellen och du hittar följande lösning för:
= 3.8
= 2.78
Du kan ersätta dessa siffror i ekvationen och det blir:
y= 3.8 + 2.78x
Nu har du ett bättre sätt att hitta värdena för y. Det vill säga, du kan ersätta x med vilket värde du vill för att förutsäga y. I bilden nedan har vi ersatt x i ekvationen med alla värden i datamängden och ritat resultatet.
Den röda linjen representerar det anpassade värdet, det vill säga värdena på y för varje värde på x. Du behöver inte se värdet på x för att förutsäga y; för varje x finns det ett värde som hör till den röda linjen. Du kan också förutsäga för värden på x högre än 2.
Om du vill utöka den linjära regressionen till fler kovariater kan du göra det genom att lägga till fler variabler i modellen. Skillnaden mellan traditionell analys och linjär regression är att linjär regression tittar på hur y kommer att reagera för varje variabel x tagen oberoende av varandra.
Låt oss se ett exempel. Tänk dig att du vill förutsäga försäljningen i en glassbutik. Datasetet innehåller olika uppgifter såsom väder (regnigt, soligt, molnigt) och kundinformation (lön, kön, civilstånd).
Traditionell analys försöker förutsäga försäljningen genom att, låt oss säga, beräkna medelvärdet för varje variabel och försöka uppskatta försäljningen för olika scenarier. Det kommer att leda till dåliga förutsägelser och begränsa analysen till det valda scenariot.
Om du använder linjär regression kan du skriva denna ekvation:
Algoritmen kommer att hitta den bästa lösningen för vikterna; det betyder att den kommer att försöka minimera kostnaden, vilket är skillnaden mellan den anpassade linjen och datapunkterna.
Hur algoritmen fungerar
Diagrammet nedan sammanfattar loopen som algoritmen upprepar: välj vikter, förutsäg y-värdet, mät felet och korrigera vikterna.
Algoritmen kommer att välja ett slumpmässigt tal för varje och
och ersätt värdet på x för att få det förutsagda värdet på y. Om datasetet har 100 observationer, beräknar algoritmen 100 förutsagda värden.
Vi kan beräkna felet, noterade , för modellen, vilket är skillnaden mellan det förutspådda värdet och det verkliga värdet. Ett positivt fel innebär att modellen underskattar förutsägelsen av y, och ett negativt fel innebär att modellen överskattar förutsägelsen av y.
Ditt mål är att minimera kvadraten av felet. Algoritmen beräknar medelvärdet av kvadratfelet. Detta steg kallas minimering av felet. För linjär regression är detta Mean Square Error, även kallad MSE. Matematiskt är det:
Var:
är vikterna, så
hänvisar till det förutsagda värdet
- y är de verkliga värdena
- m är antalet observationer
Observera att betyder att den använder transponeringen av matriserna. De
är den matematiska notationen av medelvärdet.
Målet är att hitta det bästa som minimerar MSE.
Om medelfelet är stort betyder det att modellen presterar dåligt och att vikterna inte är rätt valda. För att korrigera vikterna måste du använda en optimerare. Den traditionella optimeraren kallas Gradient härkomst.
Gradientnedgången tar derivatan och minskar eller ökar vikten. Om derivatan är positiv minskas vikten. Om derivatan är negativ ökar vikten. Modellen uppdaterar vikterna och beräknar om felet. Denna process upprepas tills felet inte längre ändras. Varje pass kallas en iterationDessutom multipliceras gradienterna med en inlärningshastighet, vilket indikerar inlärningshastigheten.
Om inlärningshastigheten är för liten tar det mycket lång tid för algoritmen att konvergera, eftersom det kräver många fler iterationer. Om inlärningshastigheten är för hög kanske algoritmen aldrig konvergerar. Förlustkurvan nedan visar felet mot iterationsantalet för denna datamängd.
Du kan se från bilden ovan att modellen upprepar processen ungefär 20 gånger innan den hittar ett stabilt värde för vikterna och därmed når det lägsta felet.
Observera att felet inte är lika med noll utan stabiliseras runt 5. Det betyder att modellen gör ett typiskt fel på 5. Om du vill minska felet behöver du lägga till mer information i modellen, till exempel fler variabler, eller använda andra estimatorer.
Du minns den första ekvationen:
De slutliga vikterna är 3.8 och 2.78. Videon nedan visar hur gradientdestinationen optimerar förlustfunktionen för att hitta dessa vikter.
Hur man tränar en linjär regression med TensorFlow
Nu när du har en bättre förståelse för vad som händer bakom huven, är du redo att använda estimator-API:et från TensorFlow för att träna din första linjära regression med TensorFlow.
Versionsnotering: Estimatorarbetsflödet som visas nedan skrevs mot TensorFlow 1.x och de tidiga 2.x-versionerna. TensorFlow markerade tf.estimator och tf.feature_column API:er är helt föråldrade i version 2.12 och Estimators togs bort i version 2.16. Kör den här koden i en TensorFlow 1.15 eller 2.x-with- på en aktuell installation.tf.compat.v1 miljö, eller portera den till Keras, där tf.keras.layers.Dense(1) plus att förbehandlingslager ersätter LinearRegressor och funktionskolumnerna. Begreppen – funktioner, etiketter, batchar, epoker, MSE och gradientnedgång – bibehålls oförändrade.
Du kommer att använda Boston-datasetet, som innehåller följande variabler.
| Variabel | BESKRIVNING |
| krim | brottslighet per capita per stad |
| zn | andel av bostadsmark som är planlagd för tomter över 25,000 XNUMX kvm. |
| indus | andel icke-detaljhandelsföretag per stad. |
| nox | kväveoxidkoncentration |
| rm | genomsnittligt antal rum per bostad |
| ålder | andel ägarbostäder byggda före 1940 |
| DIS | vägda avstånd till fem arbetsförmedlingar i Boston |
| skatt | fastighetsskattesats för fullt värde per dollar 10,000 XNUMX |
| ptratio | elev-lärare per stad |
| medv | Medianvärdet av ägda bostäder i tusen dollar |
Du kommer att skapa tre olika datamängder:
| dataset | mål | forma |
| Utbildning | Träna modellen och skaffa vikterna | 400, 10 |
| Utvärdering | Utvärdera modellens prestanda på osynliga data | 100, 10 |
| förutsäga | Använd modellen för att förutsäga husvärde på ny data | 6, 10 |
Målet är att använda datamängdens funktioner för att förutsäga husets värde.
Under den andra delen av handledningen lär du dig hur du använder TensorFlow med tre olika sätt att importera data:
- Med pandor
- Med numpy
- Endast TensorFlow
Observera att alla tre alternativen ger samma resultat.
Du kommer att lära dig hur du använder högnivå-API:et för att bygga, träna och utvärdera en TensorFlow-linjär regressionsmodell. Om du använde lågnivå-API:et skulle du behöva definiera följande manuellt:
- Förlustfunktion
- Optimerare: gradientnedgång
- Matrix multiplikation
- Graf och tensor
Detta är tråkigt och mer komplicerat för en nybörjare.
Pandas lösning
Du måste importera de nödvändiga biblioteken för att träna modellen.
import pandas as pd from sklearn import datasets import tensorflow as tf import itertools
Steg 1) Importera data med pandas.
Du definierar kolumnnamnen och lagrar dem i KOLUMNER. Du kan använda pd.read_csv() för att importera data.
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio", "medv"]
Peka varje samtal mot de CSV-filer du laddade ner tidigare.
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)
Du kan skriva ut formen på data.
print(training_set.shape, test_set.shape, prediction_set.shape)
Produktion
(400, 10) (100, 10) (6, 10)
Observera att etiketten, det vill säga ditt y, ingår i datamängden. Så du behöver definiera två andra listor: en som endast innehåller objekten och en som endast innehåller etikettens namn. Dessa två listor kommer att berätta för din estimator vilka objekten i datamängden är och vilket kolumnnamn som är etiketten.
Det görs med koden nedan.
FEATURES = ["crim", "zn", "indus", "nox", "rm", "age", "dis", "tax", "ptratio"] LABEL = "medv"
Steg 2) Konvertera data
Du måste konvertera de numeriska variablerna till rätt format. TensorFlow tillhandahåller en metod för att konvertera en kontinuerlig variabel: tf.feature_column.numeric_column().
I föregående steg definierade du en lista med funktioner som du vill inkludera i modellen. Nu kan du använda den här listan för att konvertera dem till numeriska data. Om du vill exkludera funktioner från din modell kan du gärna ta bort en eller flera variabler från listan FEATURES innan du konstruerar feature_cols.
Observera att du kommer att använda en Python listförståelse med listfunktionerna FEATURES för att skapa en ny lista med namnet feature_cols. Det hjälper dig att undvika att skriva tf.feature_column.numeric_column() nio gånger. Listförståelse är ett snabbare och renare sätt att skapa nya listor.
feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]
Steg 3) Definiera estimatorn
I det här steget behöver du definiera estimatorn. TensorFlow tillhandahåller sex förbyggda standardiserade estimatorer, tre för klassificeringsuppgifter och tre för TensorFlow-regressionsuppgifter:
- Regressor
- DNNRegressor
- LinjärRegressor
- DNNLinjär Kombinerad Regressor
- klassificera
- DNNklassificerare
- LinearClassifier
- DNNLinearCombinedClassifier
I den här handledningen kommer du att använda den linjära regressorn. För att komma åt denna funktion måste du använda tf.estimator.
Funktionen behöver två argument:
- feature_columns: innehåller variablerna som ska inkluderas i modellen
- model_dir: sökväg för att lagra grafen, spara modellparametrarna och så vidare
TensorFlow skapar automatiskt en mapp med namnet train i din arbetskatalog. Du måste använda den här sökvägen för att komma åt TensorBoard, som visas i TensorFlow-regressionsexemplet nedan.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_cols,
model_dir="train")
Produktion
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}
Det knepiga med TensorFlow är sättet att mata modellen. TensorFlow är utformat för att fungera med parallell beräkning och mycket stora datamängder. På grund av begränsade maskinresurser är det omöjligt att mata modellen med all data på en gång. För det måste du mata en batch data varje gång. Observera att vi talar om enorma datamängder med miljontals eller fler poster. Om du inte lägger till en batch kommer du att få ett minnesfel.
Till exempel, om din data innehåller 100 observationer och du definierar en batchstorlek på 10, betyder det att modellen kommer att se 10 observationer för varje iteration (10*10).
När modellen har sett all data avslutar den en epok. En epok definierar hur många gånger du vill att modellen ska se data. Det är bättre att ställa in det här steget till ingen och låta modellen utföra ett visst antal iterationer.
En andra information att lägga till är om du vill blanda data före varje iteration. Under träningen är det viktigt att blanda data så att modellen inte lär sig ett specifikt mönster i datamängden. Om modellen lär sig detaljerna i det underliggande datamönstret kommer den att ha svårt att generalisera förutsägelsen för osedda data. Detta kallas överanpassning. Modellen presterar bra på träningsdata men kan inte förutsäga korrekt för osedda data.
TensorFlow gör dessa två steg enkla att utföra. När data skickas till pipelinen vet den hur många observationer den behöver (batch) och om den behöver blanda data.
För att instruera TensorFlow hur modellen ska matas kan du använda pandas_input_fn. Detta objekt behöver fem parametrar:
- x: funktionsdata
- y: etikettdata
- batch_size: batch. Som standard 128
- num_epoch: antal epoker, som standard 1
- blanda: blanda informationen eller inte. Som standard är ingen
Du behöver mata modellen många gånger, så du definierar en funktion för att upprepa processen. Anropa funktionen 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)
Den vanliga metoden för att utvärdera en modells prestanda är att:
- Träna modellen
- Utvärdera modellen på en annan datamängd
- Gör en förutsägelse
TensorFlow-estimatorn tillhandahåller tre olika funktioner för att enkelt utföra dessa tre steg.
Steg 4) Träna modellen
Du kan använda estimatorns train-metoden för att anpassa modellen. Tågestimatorn behöver en input_fn och ett antal steg. Du kan använda funktionen du skapade ovan för att mata modellen. Sedan instruerar du modellen att iterera 1000 gånger. Observera att du inte anger antalet epoker; du låter modellen iterera 1000 gånger. Om du ställer in antalet epoker till 1 kommer modellen att iterera fyra gånger, eftersom det finns 400 poster i träningsuppsättningen och batchstorleken är 128:
- 128 rader
- 128 rader
- 128 rader
- 16 rader
Därför är det enklare att ställa in antalet epoker till inga och definiera antalet iterationer, som visas i TensorFlow-klassificeringsexemplet nedan.
estimator.train(input_fn=get_input_fn(training_set,
num_epochs=None,
n_batch = 128,
shuffle=False),
steps=1000)
Produktion
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.
Du kan kontrollera TensorBoard med följande kommando:
activate hello-tf # For MacOS tensorboard --logdir=./train # For Windows tensorboard --logdir=train
Steg 5) Utvärdera din modell
Du kan utvärdera passformen för din modell på testsetet med koden nedan:
ev = estimator.evaluate(
input_fn=get_input_fn(test_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
Produktion
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
Du kan skriva ut förlusten med koden nedan:
loss_score = ev["loss"] print("Loss: {0:f}".format(loss_score))
Produktion
Loss: 3215.895996
Modellen har en förlust på 3215. Du kan kontrollera den sammanfattande statistiken för att få en uppfattning om hur stort felet är.
training_set['medv'].describe()
Produktion
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
Från den sammanfattande statistiken ovan vet du att genomsnittspriset för ett hus är 22 tusen, med ett lägsta pris på 5 tusen och ett högsta pris på 50 tusen. Eftersom den rapporterade förlusten är medelkvadratfelet, är det typiska felet i de ursprungliga enheterna ungefär kvadratroten ur 32.16, vilket är cirka 5.7 tusen dollar.
Steg 6) Gör förutsägelsen
Slutligen kan du använda estimatorn TensorFlows predikteringsmetod för att uppskatta värdet av sex hus i Boston.
y = estimator.predict(
input_fn=get_input_fn(prediction_set,
num_epochs=1,
n_batch = 128,
shuffle=False))
För att skriva ut de uppskattade värdena kan du använda den här koden:
predictions = list(p["predictions"] for p in itertools.islice(y, 6)) print("Predictions: {}".format(str(predictions)))
Produktion
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)]
Modellen prognostiserar följande värden:
| Huset | Förutsägelse |
| 1 | 32.29 |
| 2 | 18.96 |
| 3 | 27.27 |
| 4 | 29.29 |
| 5 | 16.43 |
| 6 | 21.46 |
Observera att vi inte vet det verkliga värdet av dessa sex hus. I handledningen för djupinlärning kommer du att försöka besegra den linjära modellen.
NumPy-lösning
Det här avsnittet förklarar hur man tränar modellen med hjälp av en NumPy-estimator för att mata in data. Metoden är densamma, förutom att du använder numpy_input_fn-estimatorn.
Läs samma tre CSV-filer, men behåll bara de råa NumPy-arrayererna med .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
Steg 1) Importera data
Först och främst måste du skilja funktionsvariablerna från etiketten. Du behöver göra detta för träningsdata och utvärderingsdata. Det är snabbare att definiera en funktion för att dela upp data.
def prepare_data(df): X_train = df[:, :-3] y_train = df[:,-3] return X_train, y_train
Du kan använda funktionen för att dela upp etiketten från tågets funktioner och utvärdera datauppsättningar.
X_train, y_train = prepare_data(training_set_n) X_test, y_test = prepare_data(test_set_n)
Du måste exkludera den sista kolumnen i prediktionsdatauppsättningen eftersom den bara innehåller NaN.
x_predict = prediction_set_n[:, :-2]
Bekräfta arrayens form. Observera att etiketten inte ska ha en andra dimension, vilket betyder (400,).
print(X_train.shape, y_train.shape, x_predict.shape)
Produktion
(400, 9) (400,) (6, 9)
Du kan konstruera funktionskolumnerna enligt följande:
feature_columns = [ tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]
Estimatorn definieras som tidigare: du anger funktionskolumnerna och var grafen ska sparas.
estimator = tf.estimator.LinearRegressor(
feature_columns=feature_columns,
model_dir="train1")
Produktion
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}
Du kan använda NumPy-estimatorn för att mata in data till modellen och sedan träna modellen. Observera att vi definierar funktionen input_fn i förväg för att underlätta läsbarheten.
# 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)
Produktion
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>
Du replikerar samma steg med en annan inmatningsfunktion för att utvärdera din modell.
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)
Produktion
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}
Slutligen kan du beräkna förutsägelsen. Den bör likna Pandas resultat.
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)))
Produktion
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)]
TensorFlow-lösning
Det sista avsnittet är tillägnat en ren TensorFlow lösning. Den här metoden är något mer komplicerad än de andra två.
Observera att om du använder en Jupyter anteckningsbok, måste du starta om och rensa kärnan för att köra den här sessionen.
TensorFlow har byggt ett utmärkt verktyg för att skicka data till pipelinen. I det här avsnittet ska du bygga input_fn-funktionen själv.
Steg 1) Definiera sökvägen och formatet för data
Först och främst deklarerar du två variabler med sökvägen till CSV-filerna. Observera att du har två filer, en för träningsmängden och en för testmängden.
import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"
Sedan behöver du definiera de kolumner du vill använda från CSV-filen. Vi kommer att använda alla. Efter det behöver du deklarera typen för varje variabel.
Flytvariabler definieras av [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]]
Steg 2) Definiera funktionen input_fn
Funktionen kan delas in i tre delar:
- Importera data
- Skapa iteratorn
- Konsumera data
Nedan följer den övergripande koden för att definiera funktionen. Koden kommer att förklaras senare.
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
Importera data
För en CSV-fil läser dataset-metoden en rad i taget. För att bygga datasetet måste du använda objektet TextLineDataset. Din dataset har en rubrik, så du behöver använda skip(1) för att hoppa över den första raden. I det här skedet läser du bara data och exkluderar rubriken i pipelinen. För att mata modellen måste du separera funktionerna från etiketten. Metoden som används för att tillämpa transformationer på data är map.
Den här metoden anropar en funktion som du skapar för att instruera hur data ska transformeras. Kortfattat behöver du skicka data till TextLineDataset-objekt, exkludera rubriken och tillämpa en transformation som instrueras av en funktion.
Code förklaring
- tf.data.TextLineDataset(data_file): den här raden läser CSV-filen
- .skip(1): hoppar över rubriken
- .map(parse_csv)): analyserar posterna till tensorerna
Du måste definiera en funktion för att instruera kartobjektet. Du kan anropa den här funktionen parse_csv.
Den här funktionen analyserar CSV-filen med metoden tf.decode_csv och deklarerar funktionerna och etiketten. Funktionerna kan deklareras som en ordbok eller en tupel. Du använder ordboksmetoden eftersom den är mer praktisk.
Code förklaring
- tf.decode_csv(värde, record_defaults= RECORDS_ALL): metoden decode_csv använder utdata från TextLineDataset för att läsa CSV-filen. record_defaults instruerar TensorFlow om kolumntyperna. I TensorFlow 2.x finns den här symbolen på tf.io.decode_csv.
- dict(zip(COLUMNS, columns)): fyller ordboken med alla kolumner t.ex.tracted under denna databehandling
- features.pop('medv'): exkluderar målvariabeln från funktionsvariablerna och skapar en etikettvariabel
Datasetet behöver ytterligare element för att iterativt mata tensorerna. Du måste lägga till metoden "repeat" för att tillåta att datasetet fortsätter att mata modellen i all oändlighet. Om du inte lägger till metoden kommer modellen bara att iterera en gång och sedan ge ett fel eftersom ingen mer data matas in i pipelinen.
Efter det kan du styra batchstorleken med batchmetoden. Det innebär att du anger för datamängden hur mycket data du vill skicka in i pipelinen för varje iteration. Om du anger en stor batchstorlek kommer modellen att vara långsam.
Steg 3) Skapa iteratorn
Nu är du redo för det andra steget: skapa en iterator för att returnera elementen i datamängden.
Det enklaste sättet att skapa en operator är med metoden make_one_shot_iterator.
Efter det kan du skapa funktionerna och etiketterna från iteratorn.
Steg 4) Konsumera data
Du kan kontrollera vad som händer med funktionen input_fn. Du måste anropa funktionen i en session för att förbruka data. Du försöker med en batchstorlek lika med 1.
Observera att den skriver ut funktionerna i en ordbok och etiketten som en array.
Den första raden i CSV-filen visas. Du kan försöka köra den här koden många gånger med olika batchstorlekar.
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)
Produktion
({'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))
Steg 5) Definiera funktionskolumnen
Du måste definiera de numeriska kolumnerna enligt följande:
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')
Observera att du måste kombinera alla variabler i en hink.
base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]
Steg 6) Bygg modellen
Du kan träna modellen med estimatorn LinearRegressor.
model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')
Produktion
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}
Du måste använda en lambda-funktion för att låta dig skriva argumenten för funktionen input_fn. Om du inte använder en lambdafunktion kan du inte träna modellen.
# Train the estimator model.train(steps =1000, input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))
Produktion
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>
Du kan utvärdera passformen för din modell på testsetet med koden nedan:
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]))
Produktion
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
Det sista steget är att förutsäga målets värde baserat på värdet på funktionsmatrisen. Du kan skriva en ordbok med de värden du vill förutsäga. Din modell har nio funktioner, så du måste ange ett värde för varje. Modellen kommer att ge en förutsägelse för var och en av dem.
I koden nedan skriver du värdena för varje funktion som finns i df_predict CSV-filen.
Du behöver skriva en ny input_fn-funktion eftersom det inte finns någon etikett i datamängden. Du kan använda from_tensors API från Dataset-objektet.
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)
Slutligen skriver du ut förutsägelserna.
for pred in enumerate(pred_results): print(pred)
Produktion
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)})
Alla tre pipelines returnerar samma sex förutsägelser, vilket bekräftar att valet mellan Pandas, NumPy och en inbyggd TensorFlow-datauppsättning är en fråga om bekvämlighet, inte om noggrannhet.





