Урок за линейна регресия с TensorFlow [Примери]

⚡ Умно обобщение

Линейната регресия в TensorFlow моделира връзката между числови характеристики и непрекъсната целева стойност. Това ръководство обучава инструмент за прогнозиране на цените на жилищата в Бостън по три отделни начина, използвайки Pandas, NumPy и входни канали на TensorFlow с оценителя LinearRegressor.

  • 🔘 Моделна форма: Линейна регресия се апроксимира с y = bias + weight × x, разширена с повече ковариации за многовариантни задачи.
  • ☑️ Тренировъчен цикъл: Градиентното спускане настройва теглата при всяка итерация, докато средноквадратичната грешка спре да намалява.
  • ✅ API за оценка: LinearRegressor се нуждае само от колони с функции, директория на модела и входна функция.
  • 🧪 Три тръбопровода: Pandas, NumPy и native TensorFlow наборите от данни захранват един и същ модел и връщат идентични прогнози.
  • 🛠️ Разработен пример: Девет характеристики на Бостън прогнозират средна стойност на къщата и достигат тестова загуба от 3215.
  • ⚠️ Реалност на версията: Оценителите бяха остарели в TensorFlow 2.12 и премахнати в 2.16, така че пренесете нова работа в Keras.

Линейна регресия с TensorFlow

Какво е линейна регресия?

линейна регресия е подход в статистиката за моделиране на връзки между две променливи. Това моделиране се извършва между скаларен отговор и една или повече обяснителни променливи. Връзката с една обяснителна променлива се нарича проста линейна регресия, а с повече от една обяснителна променлива - множествена линейна регресия.

TensorFlow предоставя инструменти за пълен контрол върху изчисленията. Това се прави с API от ниско ниво. Освен това TensorFlow е оборудван с широк набор от API за изпълнение на много машинно обучение алгоритми. Това е API от високо ниво, а TensorFlow ги нарича estimators (оценители).

  • API от ниско нивоИзградете архитектурата и оптимизацията на модела от нулата. Сложно е за начинаещ.
  • API от високо нивоДефинирайте алгоритъма. Той е лесен за ползване. TensorFlow предоставя набор от инструменти, наречен оценител да конструира, обучава, оценява и прави прогноза.

В този урок ще използвате само оценителиИзчисленията са по-бързи и по-лесни за изпълнение. Първата част обяснява как да използвате оптимизатора за градиентен спуск за обучение на линейна регресия в TensorFlow. Във втората част ще използвате набора от данни Boston, за да предскажете цената на къща, използвайки TensorFlow оценител.

Изтеглете Boston DataSet

Как да обучим модел на линейна регресия

Преди да започнем да обучаваме модела, нека разгледаме какво всъщност представлява линейната регресия.

Представете си, че имате две променливи, x и y, и вашата задача е да предскажете стойността на y, знаейки стойността на x. Ако начертаете данните, можете да видите положителна връзка между вашата независима променлива, x, и вашата зависима променлива, y, както е показано на точковата диаграма по-долу.

Точкова диаграма на x спрямо y, показваща положителна линейна зависимост

Може да забележите, че ако x=1, y ще бъде приблизително равно на 6, а ако x=2, y ще бъде около 8.5.

Това не е много точен метод и е склонен към грешки, особено при набор от данни, съдържащ стотици хиляди точки.

Линейната регресия се оценява с уравнение. Променливата y се обяснява с една или много ковариати. Във вашия пример има само една зависима променлива. Ако трябва да напишете това уравнение, то ще бъде:

Просто линейно регресионно уравнение с отклонение, тегло и член на грешката

С участието на:

  • Символ на коефициента на отклонение е отклонението. Тоест, ако x=0, y=Стойност на коефициента на отклонение, когато x е равно на нула
  • Символ за тегловен коефициент, свързан с x е теглото, свързано с x
  • Символ за остатъчна грешка е остатъкът или грешката на модела. Той включва това, което моделът не може да научи от данните

Представете си, че отговаряте на модела и намирате следното решение за:

  • Коефициент на отклонение, пригоден за измерване, равен на 3.8 = 3.8
  • Коефициент на пригодено тегло, равен на 2.78 = 2.78

Можете да замените тези числа в уравнението и то става:

y= 3.8 + 2.78x

Вече имате по-добър начин да намерите стойностите за y. Тоест, можете да замените x с всяка стойност, която искате, за да предскажете y. На изображението по-долу сме заменили x в уравнението с всички стойности от набора от данни и сме изобразили резултата.

Напасната регресионна линия, начертана в червено през нанесените точки от данни

Червената линия представлява апроксимираната стойност, т.е. стойностите на y за всяка стойност на x. Не е необходимо да виждате стойността на x, за да предскажете y; за всяко x има стойност, която принадлежи на червената линия. Можете също така да предскажете за стойности на x, по-големи от 2.

Ако искате да разширите линейната регресия до повече ковариации, можете да го направите, като добавите още променливи към модела. Разликата между традиционния анализ и линейната регресия е, че линейната регресия разглежда как y ще реагира за всяка променлива x, взета независимо.

Нека да разгледаме един пример. Представете си, че искате да предвидите продажбите на магазин за сладолед. Наборът от данни съдържа различна информация, като например времето (дъждовно, слънчево, облачно) и информация за клиентите (заплата, пол, семейно положение).

Традиционният анализ ще се опита да предскаже продажбата, например чрез изчисляване на средната стойност за всяка променлива и опит за оценка на продажбата за различни сценарии. Това ще доведе до лоши прогнози и ще ограничи анализа до избрания сценарий.

Ако използвате линейна регресия, можете да напишете това уравнение:

Уравнение за множествена линейна регресия, комбиниращо няколко претеглени ковариати

Алгоритъмът ще намери най-доброто решение за теглата; това означава, че ще се опита да минимизира цената, която е разликата между напасната линия и точките от данни.

Как работи алгоритъмът

Диаграмата по-долу обобщава цикъла, който алгоритъмът повтаря: избиране на тегла, прогнозиране на y, измерване на грешката и коригиране на теглата.

Блок-схема на обучителния цикъл на линейна регресия от случайни тегла до минимизирана грешка

Алгоритъмът ще избере произволно число за всеки Случайно инициализиран коефициент на отклонение намлява Случайно инициализиран коефициент на тегло и заменете стойността на x, за да получите предвидената стойност на y. Ако наборът от данни има 100 наблюдения, алгоритъмът изчислява 100 прогнозирани стойности.

Можем да изчислим грешката, отбелязано Термин за грешка на модела, използван при изчисляването на загубата, на модела, което е разликата между прогнозираната стойност и реалната стойност. Положителна грешка означава, че моделът подценява прогнозата на y, а отрицателна грешка означава, че моделът надценява прогнозата на y.

Цел за минимизиране на квадратната грешка, записана в математическа нотация

Вашата цел е да минимизирате квадрата на грешката. Алгоритъмът изчислява средната стойност на квадрата на грешката. Тази стъпка се нарича минимизиране на грешката. За линейна регресия това е Средна квадратна грешка, наричан още MSE. Математически това е:

Формула за средноквадратична грешка, записана в матрична нотация

Където:

  • Символ за вектор на теглото, използван във формулата за MSE са тежестите, така че Нотация на прогнозираната стойност, използвана във формулата MSE се отнася до прогнозираната стойност
  • y е реалните стойности
  • m е броят на наблюденията

Имайте предвид, че Нотация на транспонирана матрица на теглото означава, че използва транспонирането на матриците. The Нотация за сумиране и средна стойност, използвана във формулата MSE е математическата нотация на средната стойност.

Целта е да се намери най-доброто Символ за оптимално тегло, който минимизира MSE това минимизира MSE.

Ако средната грешка е голяма, това означава, че моделът работи лошо и теглата не са избрани правилно. За да коригирате теглата, трябва да използвате оптимизатор. Традиционният оптимизатор се нарича Градиентно спускане.

Градиентният спуск взема производната и намалява или увеличава теглото. Ако производната е положителна, теглото се намалява. Ако производната е отрицателна, теглото се увеличава. Моделът ще актуализира теглата и ще преизчисли грешката. Този процес се повтаря, докато грешката вече не се променя. Всеки проход се нарича повторениеОсвен това, градиентите се умножават по скорост на обучение, която показва скоростта на обучение.

Ако скоростта на обучение е твърде малка, ще отнеме много време, за да се сближи алгоритъмът, защото изисква много повече итерации. Ако скоростта на обучение е твърде висока, алгоритъмът може никога да не се сближи. Кривата на загубите по-долу изобразява грешката спрямо броя на итерациите за този набор от данни.

Крива на загубите, показваща спадане и стабилизиране на грешката след около двадесет итерации

От горната снимка можете да видите, че моделът повтаря процеса около 20 пъти, преди да намери стабилна стойност за теглата, като по този начин достига най-ниската грешка.

Обърнете внимание, че грешката не е равна на нула, а се стабилизира около 5. Това означава, че моделът прави типична грешка от 5. Ако искате да намалите грешката, трябва да добавите повече информация към модела, като например повече променливи, или да използвате различни оценки.

Спомняте си първото уравнение:

Окончателно напаснато уравнение на линейна регресия с решените тегла

Крайните тегла са 3.8 и 2.78. Видеото по-долу показва как градиентният спуск оптимизира функцията на загуба, за да намери тези тегла.

Как да тренирате линейна регресия с TensorFlow

Сега, когато разбирате по-добре какво се случва зад капака, вие сте готови да използвате API за оценка, предоставен от TensorFlow, за да обучите първата си линейна регресия с помощта на TensorFlow.

Бележка към версията: Показаният по-долу работен процес на оценката е написан за TensorFlow 1.x и ранните версии 2.x. TensorFlow маркира tf.estimator намлява tf.feature_column API-тата са напълно отхвърлени във версия 2.12 и са премахнати оценките във версия 2.16. В текущата инсталация, изпълнете този код в TensorFlow 1.15 или 2.x-с-tf.compat.v1 среда или да го пренесете в Keras, където tf.keras.layers.Dense(1) Плюс слоевете за предварителна обработка заместват линейния регресор и колоните с характеристики. Концепциите – характеристики, етикети, партиди, епохи, MSE и градиентен спуск – остават непроменени.

Ще използвате набора от данни от Бостън, който включва следните променливи.

Променлив Descriptйон
крим ниво на престъпност на глава от населението по градове
zn част от жилищна земя, зонирана за парцели над 25,000 XNUMX кв. фута.
индус съотношение на бизнес акра за нетърговски бизнес на град.
NOx концентрация на азотни оксиди
rm среден брой стаи на жилище
възраст дял на обитавани от собственици единици, построени преди 1940 г
DIS претеглени разстояния до пет центъра по заетостта в Бостън
данък данъчна ставка на пълната стойност на имуществото за 10,000 XNUMX долара
ptratio съотношение ученик/учител по градове
медв Средна стойност на жилищата, обитавани от собственици в хиляди долара

Ще създадете три различни набора от данни:

набор от данни цел оформянето
Обучение Обучете модела и вземете тежестите 400, 10
Оценка Оценете ефективността на модела върху невидяни данни 100, 10
Познайте Използвайте модела, за да прогнозирате стойността на къщата на нови данни 6, 10

Целта е да се използват характеристиките на набора от данни, за да се предскаже стойността на къщата.

Във втората част на урока ще научите как да използвате TensorFlow с три различни начина за импортиране на данни:

  • С панди
  • с numpy
  • Само TensorFlow

Обърнете внимание, че и трите опции дават едни и същи резултати.

Ще научите как да използвате високо ниво API за изграждане, обучение и оценка на линеен регресионен модел на TensorFlow. Ако използвахте ниско ниво API, ще трябва да дефинирате ръчно:

  • Функция на загуба
  • Оптимизатор: градиентен спускаем метод
  • Умножение на матрици
  • График и тензор

Това е досадно и по-сложно за начинаещ.

Решение на Пандите

Трябва да импортирате необходимите библиотеки, за да обучите модела.

import pandas as pd
from sklearn import datasets
import tensorflow as tf
import itertools

Стъпка 1) Импортирайте данните с Пандите.

Дефинирате имената на колоните и ги съхранявате в COLUMNS. Можете да използвате pd.read_csv(), за да импортирате данните.

COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",
           "dis", "tax", "ptratio", "medv"]

Насочете всяко обаждане към CSV файловете, които сте изтеглили по-рано.

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)

Можете да отпечатате формата на данните.

print(training_set.shape, test_set.shape, prediction_set.shape)

Продукция

(400, 10) (100, 10) (6, 10)

Обърнете внимание, че етикетът, т.е. вашето y, е включен в набора от данни. Така че трябва да дефинирате два други списъка: един, съдържащ само характеристиките, и един, съдържащ само името на етикета. Тези два списъка ще кажат на вашия инструмент за оценка какви са характеристиките в набора от данни и кое име на колона е етикетът.

Това се прави с кода по-долу.

FEATURES = ["crim", "zn", "indus", "nox", "rm",
                 "age", "dis", "tax", "ptratio"]
LABEL = "medv"

Стъпка 2) Преобразувайте данните

Трябва да конвертирате числовите променливи в правилния формат. TensorFlow предоставя метод за конвертиране на непрекъсната променлива: tf.feature_column.numeric_column().

В предишната стъпка дефинирахте списък с характеристики, които искате да включите в модела. Сега можете да използвате този списък, за да ги преобразувате в числови данни. Ако искате да изключите характеристики от вашия модел, можете да премахнете една или повече променливи от списъка FEATURES, преди да конструирате feature_cols.

Обърнете внимание, че ще използвате Python Разбиране на списъци със списъка FEATURES, за да създадете нов списък с име feature_cols. Това ви помага да избегнете писането на tf.feature_column.numeric_column() девет пъти. Разбирането на списъци е по-бърз и по-чист начин за създаване на нови списъци.

feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]

Стъпка 3) Дефинирайте оценителя

В тази стъпка трябва да дефинирате оценката. TensorFlow предоставя шест предварително изградени консервирани оценки, три за задачи за класификация и три за задачи за регресия на TensorFlow:

  • Регресор
    • DNNRegressor
    • Линеен регресор
    • DNNЛинеенКомбиниранРегресор
  • Класификатор
    • DNNClassifier
    • Линеен класификатор
    • DNNЛинеенКомбиниранКласификатор

В този урок ще използвате линейния регресор. За достъп до тази функция трябва да използвате tf.estimator.

Функцията се нуждае от два аргумента:

  • feature_columns: съдържа променливите, които да бъдат включени в модела
  • model_dir: път за съхранение на графиката, запазване на параметрите на модела и т.н.

TensorFlow автоматично ще създаде папка с име train във вашата работна директория. Трябва да използвате този път за достъп TensorBoard, както е показано в примера за регресия на TensorFlow по-долу.

estimator = tf.estimator.LinearRegressor(
        feature_columns=feature_cols,
        model_dir="train")

Продукция

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}

Трудната част с TensorFlow е начинът за захранване на модела. TensorFlow е проектиран да работи с паралелни изчисления и много големи набори от данни. Поради ограничението на машинните ресурси е невъзможно да се захранва моделът с всички данни наведнъж. За целта е необходимо да се захранва партида от данни всеки път. Обърнете внимание, че говорим за огромни набори от данни с милиони или повече записи. Ако не добавите партида, ще получите грешка в паметта.

Например, ако вашите данни съдържат 100 наблюдения и дефинирате размер на партидата от 10, това означава, че моделът ще вижда 10 наблюдения за всяка итерация (10*10).

Когато моделът е видял всички данни, той завършва една епоха. Епохата определя колко пъти искате моделът да види данните. По-добре е да зададете тази стъпка на „няма“ и да оставите модела да извърши определен брой итерации.

Втора информация, която трябва да добавите, е дали искате да разместите данните преди всяка итерация. По време на обучението е важно да разместите данните, така че моделът да не научи специфичен модел на набора от данни. Ако моделът научи подробностите за основния модел на данните, ще има затруднения с обобщаването на прогнозата за невидими данни. Това се нарича свръхнапасване. Моделът се представя добре с данните за обучение, но не може да предскаже правилно за невидими данни.

TensorFlow улеснява изпълнението на тези две стъпки. Когато данните отидат в конвейера, той знае колко наблюдения са му необходими (партида) и дали трябва да ги разбърка.

За да инструктирате TensorFlow как да захранва модела, можете да използвате pandas_input_fn. Този обект се нуждае от пет параметъра:

  • x: данни за характеристиките
  • y: данни на етикета
  • размер_на_партида: партида. По подразбиране 128
  • num_epoch: брой епохи, по подразбиране 1
  • разбъркване: разбърква данните или не. По подразбиране, Няма

Трябва да захранвате модела многократно, затова дефинирате функция, която да повтаря този процес. Наречете тази функция 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)

Обичайният метод за оценка на ефективността на даден модел е:

  • Обучете модела
  • Оценете модела на различен набор от данни
  • Направете прогноза

TensorFlow оценителът предоставя три различни функции за лесно изпълнение на тези три стъпки.

Стъпка 4) Обучете модела

Можете да използвате метода estimator train, за да напаснете модела. Train estimator се нуждае от input_fn и определен брой стъпки. Можете да използвате функцията, която създадохте по-горе, за да захраните модела. След това инструктирате модела да итерира 1000 пъти. Обърнете внимание, че не задавате броя на епохите; оставяте модела да итерира 1000 пъти. Ако зададете броя на епохите на 1, тогава моделът ще итерира четири пъти, защото в обучаващия набор има 400 записа, а размерът на партидата е 128:

  1. 128 реда
  2. 128 реда
  3. 128 реда
  4. 16 реда

Следователно е по-лесно да се зададе броят на епохите на „няма“ и да се дефинира броят на итерациите, както е показано в примера за класификация на TensorFlow по-долу.

estimator.train(input_fn=get_input_fn(training_set,
                                           num_epochs=None,
                                           n_batch = 128,
                                           shuffle=False),
                                           steps=1000)

Продукция

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.

Можете да проверите TensorBoard със следната команда:

activate hello-tf
# For MacOS
tensorboard --logdir=./train
# For Windows
tensorboard --logdir=train

Стъпка 5) Оценете вашия модел

Можете да оцените съответствието на вашия модел с тестовия комплект с кода по-долу:

ev = estimator.evaluate(
          input_fn=get_input_fn(test_set,
          num_epochs=1,
          n_batch = 128,
          shuffle=False))

Продукция

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

Можете да отпечатате загубата с кода по-долу:

loss_score = ev["loss"]
print("Loss: {0:f}".format(loss_score))

Продукция

Loss: 3215.895996

Моделът има загуба от 3215. Можете да проверите обобщената статистика, за да добиете представа колко голяма е грешката.

training_set['medv'].describe()

Продукция

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

От обобщената статистика по-горе знаете, че средната цена на къща е 22 хиляди, с минимална цена от 5 хиляди и максимална от 50 хиляди. Тъй като отчетената загуба е средноквадратичната грешка, типичната грешка в оригиналните единици е приблизително корен квадратен от 32.16, което е около 5.7 хиляди долара.

Стъпка 6) Направете прогнозата

Накрая, можете да използвате метода за прогнозиране TensorFlow, за да оцените стойността на шест къщи в Бостън.

y = estimator.predict(
         input_fn=get_input_fn(prediction_set,
         num_epochs=1,
         n_batch = 128,
         shuffle=False))

За да отпечатате приблизителните стойности, можете да използвате този код:

predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))

Продукция

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)]

Моделът прогнозира следните стойности:

Къщи предсказване
1 32.29
2 18.96
3 27.27
4 29.29
5 16.43
6 21.46

Обърнете внимание, че не знаем истинската стойност на тези шест къщи. В урока за дълбоко обучение ще се опитате да преодолеете линейния модел.

Решение на NumPy

Този раздел обяснява как да се обучи моделът, използвайки NumPy оценител за подаване на данни. Методът е същият, с изключение на това, че ще използвате numpy_input_fn оценител.

Прочетете същите три CSV файла, но запазете само суровите NumPy масиви с .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

Стъпка 1) Импортирайте данните

Първо, трябва да разграничите променливите на характеристиките от етикета. Трябва да направите това за данните за обучение и данните за оценка. По-бързо е да дефинирате функция за разделяне на данните.

def prepare_data(df):
        X_train = df[:, :-3]
        y_train = df[:,-3]
        return X_train, y_train

Можете да използвате функцията, за да разделите етикета от характеристиките на влака и да оцените наборите от данни.

X_train, y_train = prepare_data(training_set_n)
X_test, y_test = prepare_data(test_set_n)

Трябва да изключите последната колона от набора от данни за прогнозиране, защото тя съдържа само NaN.

x_predict = prediction_set_n[:, :-2]

Потвърдете формата на масива. Обърнете внимание, че етикетът не трябва да има второ измерение, което означава (400,).

print(X_train.shape, y_train.shape, x_predict.shape)

Продукция

(400, 9) (400,) (6, 9)

Можете да конструирате колоните с характеристики, както следва:

feature_columns = [      tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]

Оценката се дефинира както преди: вие задавате колоните с характеристики и къде да се запази графиката.

estimator = tf.estimator.LinearRegressor(
         feature_columns=feature_columns,
         model_dir="train1")

Продукция

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}

Можете да използвате NumPy естиматора, за да подадете данните към модела и след това да го обучите. Обърнете внимание, че предварително дефинираме функцията input_fn, за да улесним четливостта.

# 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)

Продукция

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>

Вие повтаряте същата стъпка с различна входна функция, за да оцените вашия модел.

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)

Продукция

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}

Накрая можете да изчислите прогнозата. Тя трябва да е подобна на резултата от 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)))

Продукция

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

Последният раздел е посветен на чистото TensorFlow решение. Този метод е малко по-сложен от другите два.

Обърнете внимание, че ако използвате Jupyter тетрадка, трябва да рестартирате и изчистите ядрото, за да стартирате тази сесия.

TensorFlow е създал чудесен инструмент за предаване на данни в конвейера. В този раздел ще изградите сами функцията input_fn.

Стъпка 1) Определете пътя и формата на данните

Първо, декларирате две променливи с пътя до CSV файловете. Обърнете внимание, че имате два файла, един за обучителния набор и един за тестовия набор.

import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"

След това трябва да дефинирате колоните, които искате да използвате от CSV файла. Ще използваме всички тях. След това трябва да декларирате типа на всяка променлива.

Променливите с плаваща запетая са дефинирани от [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]]

Стъпка 2) Дефинирайте функцията input_fn

Функцията може да бъде разделена на три части:

  1. Импортирайте данните
  2. Създайте итератора
  3. Консумирайте данните

По-долу е показан общият код за дефиниране на функцията. Кодът ще бъде обяснен по-късно.

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

Импортирайте данните

За CSV файл, методът за набор от данни чете ред по ред. За да изградите набора от данни, трябва да използвате обекта TextLineНабор от данни. Вашият набор от данни има заглавка, така че трябва да използвате skip(1), за да пропуснете първия ред. В този момент само четете данните и изключвате заглавката от конвейера. За да захраните модела, трябва да отделите характеристиките от етикета. Методът, използван за прилагане на всяка трансформация към данните, е map.

Този метод извиква функция, която ще създадете, за да инструктира как да се трансформират данните. Накратко, трябва да предадете данните в TextLineОбект от набор от данни, изключете заглавката и приложете трансформация, която е инструктирана от функция.

Code обяснение

  • tf.data.TextLineНабор от данни(файл_данни): този ред чете CSV файла
  • .skip(1): пропуска заглавката
  • .map(parse_csv)): анализира записите в тензори

Трябва да дефинирате функция, която да инструктира обекта карта. Можете да извикате тази функция parse_csv.

Тази функция анализира CSV файла с метода tf.decode_csv и декларира характеристиките и етикета. Характеристиките могат да бъдат декларирани като речник или кортеж. Използвате метода dictionary, защото е по-удобен.

Code обяснение

  • tf.decode_csv(стойност, record_defaults= RECORDS_ALL): методът decode_csv използва изхода на TextLineНабор от данни за четене на CSV файла. record_defaults инструктира TensorFlow за типовете колони. В TensorFlow 2.x този символ се намира в tf.io.decode_csv.
  • dict(zip(КОЛОНИ, колони)): попълва речника с всички колони extracпо време на тази обработка на данни
  • features.pop('medv'): изключва целевата променлива от променливите на feature и създава променлива с етикет

Наборът от данни се нуждае от допълнителни елементи за итеративно захранване на тензорите. Всъщност, трябва да добавите метода repeat, за да позволите на набора от данни да продължи неопределено време, за да захранва модела. Ако не добавите метода, моделът ще итерира само веднъж и след това ще генерира грешка, защото в конвейера не се подават повече данни.

След това можете да контролирате размера на партидата с метода batch. Това означава, че казвате на набора от данни колко данни искате да предадете в конвейера за всяка итерация. Ако зададете голям размер на партидата, моделът ще бъде бавен.

Стъпка 3) Създайте итератора

Сега сте готови за втората стъпка: създайте итератор, за да върнете елементите в набора от данни.

Най-простият начин за създаване на оператор е с метода make_one_shot_iterator.

След това можете да създадете характеристиките и етикетите от итератора.

Стъпка 4) Консумирайте данните

Можете да проверите какво се случва с функцията input_fn. Трябва да извикате функцията в сесия, за да консумирате данните. Опитвате с размер на партидата, равен на 1.

Обърнете внимание, че отпечатва характеристиките в речник и етикета като масив.

Ще се покаже първият ред от CSV файла. Можете да опитате да изпълните този код многократно с различни размери на партидите.

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)

Продукция

({'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))

Стъпка 5) Дефинирайте колоната с характеристики

Трябва да дефинирате числовите колони, както следва:

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')

Обърнете внимание, че трябва да комбинирате всички променливи в една кофа.

base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]

Стъпка 6) Изградете модела

Можете да обучите модела с оценителя LinearRegressor.

model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')

Продукция

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}

Трябва да използвате a ламбда функция за да можете да запишете аргументите за функцията input_fn. Ако не използвате ламбда функция, не можете да обучите модела.

# Train the estimator
model.train(steps =1000,
          input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))

Продукция

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>

Можете да оцените съответствието на вашия модел с тестовия комплект с кода по-долу:

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]))

Продукция

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

Последната стъпка е прогнозиране на стойността на целта въз основа на стойността на матрицата на характеристиките. Можете да напишете речник със стойностите, които искате да предскажете. Вашият модел има девет характеристики, така че трябва да предоставите стойност за всяка от тях. Моделът ще предостави прогноза за всяка от тях.

В кода по-долу записвате стойностите на всяка функция, която се съдържа в CSV файла df_predict.

Трябва да напишете нова функция input_fn, защото в набора от данни няма етикет. Можете да използвате API-то from_tensors от обекта 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)

Накрая отпечатвате прогнозите.

for pred in enumerate(pred_results):
print(pred)

Продукция

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)})

И трите конвейера връщат едни и същи шест прогнози, което потвърждава, че изборът между Pandas, NumPy и нативен набор от данни на TensorFlow е въпрос на удобство, а не на точност.

Въпроси и Отговори

Не. TensorFlow маркира Estimators и feature columns като напълно остарели във версия 2.12 и ги премахна във версия 2.16. Закачете TensorFlow 1.15 или 2.15, за да изпълнявате този код непроменен, или пренапишете модела със слоеве Keras, което екипът на TensorFlow сега препоръчва.

Заредете CSV файловете с Пандите, мащабирайте деветте характеристики с нормализационен слой, след което подредете една Dense(1) единица. Компилирайте с оптимизатор и mean_squared_error loss, след което извикайте fit. Една Dense единица без активиране е линейна регресия.

Започнете от около 0.01 и коригирайте с коефициенти от десет. Твърде малка скорост се нуждае от много повече итерации, за да се сближи, докато твърде голяма скорост кара загубата да осцилира. Начертайте кривата на загубите и запазете най-голямата скорост, която все още пада плавно.

scikit-learn премахна load_boston във версия 1.2 поради етични съображения относно проектирана расова променлива. Този урок чете обикновени CSV файлове, така че връзката за изтегляне все още работи, но новите проекти трябва да използват наборите от данни за жилищно настаняване в Калифорния или Еймс.

Средноквадратичната грешка (Root Mean Square Error) възстановява оригиналните единици, средната абсолютна грешка (Mean Absolute Error) предотвратява отклоненията, а R-квадратът (R-квадрат) отчита обяснения дял на дисперсията. Отчитайте и метрика за абсолютна грешка заедно с R-квадрат, тъй като високият R-квадрат все още може да скрие големи индивидуални грешки при прогнозиране.

Линейната регресия предсказва непрекъснато число, като например цената на жилището. линеен класификатор предсказва етикет на дискретен клас. И двете отговарят на претеглена сума от характеристиките, но класификаторът прекарва тази сума през праг на решение.

Автоматизираните конвейери оценяват характеристиките с ласо регуларизация, взаимна информация или важност на пермутациите, след което премахват най-слабите. Инструментите на AutoML търсят едновременно предварителна обработка и опции за моделиране, така че губите по-малко време в ръчен избор на колони, които принадлежат във feature_cols.

Copilot бързо изготвя шаблонни проекти, включително входни функции, списъци с колони с функции и цикли за оценка. Третирайте всяко предложение като чернова, тъй като то често генерира остарели извиквания на Estimator. Проверявайте всеки генериран символ спрямо текущия TensorFlow API, преди да го стартирате.

Обобщете тази публикация с: