БытьАвтор: команда TensorFlow
TensorFlow 1.3 представляет две важные функции, которые вы должны попробовать:
Вот как они вписываются в архитектуру TensorFlow. Объединение этих оценщиков упрощает создание и передачу данных в модели TensorFlow:
Чтобы изучить эти возможности, мы построим модель и покажем вам соответствующие фрагменты кода. Полный код находится наздесь, который включает в себя инструкции по получению обучающих и тестовых файлов. Обратите внимание, что код написан для демонстрации работы набора данных и оценщика и не оптимизирован для максимальной производительности.
Обученная модель может быть основана на четырех ботанических признаках (чашелистикдлина, ширина чашелистика,лепестокдлина и ширина лепестков) для классификации ирисов. Таким образом, во время вывода вы можете указать значения для этих четырех признаков, и модель предскажет, к какому из трех красивых сортов принадлежит цветок:
Слева направо:Горный ирис(RadomilФотография, CC BY-SA 3.0),ирис разноцветный(DlangloisФотография, CC BY-SA 3.0) и размерЖеня ирис(Frank MayfieldФотография, CC BY-SA 2.0).
Мы будем обучать классификатор глубокой нейронной сети, используя приведенную ниже структуру. Все входные и выходные значения
Например, вывод для радужной оболочки может быть 0,05, 0,9 для ириса разноцветного и 0,05 для ириса виргинского, что указывает на 90% вероятность того, что цветок является ирисом разноцветным.
Хорошо! Теперь, когда мы определили модель, давайте посмотрим, как обучить модель и сделать прогнозы, используя набор данных и оценщик.
Наборы данных — это новый способ создания входных конвейеров для моделей TensorFlow. Использование этого API намного эффективнее, чем использование каналов feed_dict или очередей, а сам API чище и проще в использовании. Хотя набор данных все еще находится в tf.contrib.data в версии 1.3, мы планируем переместить этот API в ядро в версии 1.4, так что пришло время попробовать его.
На высоком уровне набор данных состоит из следующих классов:
в:
Во-первых, давайте посмотрим на набор данных, который будет использоваться для подачи модели. Мы будем читать данные из файла CSV, каждая строка этого файла будет содержать пять значений — четыре входных значения плюс метки:
Значения тегов описаны ниже:
Чтобы проиллюстрировать наш набор данных, давайте сначала создадим список функций:
При обучении модели нам нужна функция, которая может читать входной файл и возвращать данные функций и меток. Оценщик требует, чтобы вы создали функцию в следующем формате:
Возвращаемое значение должно быть двухэлементным кортежем, организованным следующим образом:
Поскольку мы возвращаем набор входных функций и обучающих меток, все списки в операторе return будут иметь одинаковую длину. Технически, когда мы говорим здесь «список», мы на самом деле имеем в виду одномерные тензоры TensorFlow.
Для удобства повторного использования
Вот как мы реализовали эту функцию с помощью Dataset API. Мы поместим это в «входную функцию», которая позже будет использоваться для предоставления данных для нашей модели оценки:
Обратите внимание на следующее:
Выше приведено краткое введение в набор данных! Ради интереса теперь мы можем распечатать первую партию, используя следующую функцию:
Это все, что нам нужно от Dataset API при реализации модели. Однако набор данных может предложить гораздо больше; см. наш список дополнительных ресурсов в конце этого сообщения в блоге.
Оценщики — это высокоуровневый API, который устраняет необходимость написания большого количества шаблонного кода при обучении модели TensorFlow. Оценщик также очень гибок, позволяя вам переопределить поведение по умолчанию, если у вас есть особые требования к модели.
С помощью оценщика вы можете построить модель двумя возможными способами:
Ниже представлена диаграмма классов оценщика:
Мы надеемся добавить больше готовых оценщиков в будущих выпусках.
Как видите, все оценщики используют
Следующий код создает экземпляр оценщика, который предсказывает тип радужной оболочки:
Теперь у нас есть оценщик, готовый начать обучение.
Выполните обучение с помощью одной строки кода TensorFlow:
Но подождите минутку... это"
Теперь у нас есть обученная модель. Как оценить его работу? К счастью, каждая оценка содержит
В нашем примере мы достигли точности около 93%. Конечно, точность можно повысить несколькими способами. Один из способов — запустить программу несколько раз. Поскольку состояние модели будет сохраняться (в приведенном выше
Готово! Теперь у нас есть обученная модель, и если мы удовлетворены результатами оценки, мы можем использовать эту модель для прогнозирования радужной оболочки на основе некоторых входных данных. Как и в случае с обучением и оценкой, мы делаем прогнозы с помощью одного вызова функции:
Ранее отображаемый код
Использование оценщика, такого как DNNClassifier, может предоставить множество значений. Помимо простоты использования, готовые оценщики предоставляют встроенные метрики оценки и создают сводки, которые вы можете увидеть в TensorBoard. Чтобы просмотреть этот отчет, запустите TensorBoard из командной строки следующим образом:
На следующих рисунках показаны некоторые данные, которые TensorBoard предоставит:
В этом сообщении блога мы исследуем наборы данных и оценки. Это важные API для определения потоков входных данных и создания моделей, поэтому стоит потратить некоторое время на их изучение!
Дополнительные сведения см. в приведенных ниже ресурсах.
Это еще не конец. Скоро мы опубликуем в блоге больше сообщений о том, как работают эти API, так что следите за обновлениями!
А пока получайте удовольствие от кодирования в TensorFlow!
TensorFlow 1.3 представляет две важные функции, которые вы должны попробовать:
- Наборы данных: совершенно новый способ создания входных конвейеров (то есть чтения данных в вашу программу).
- Оценщики: расширенный способ создания моделей TensorFlow. Оценщики включают в себя готовые модели для общих задач машинного обучения, но вы также можете использовать их для создания собственных пользовательских моделей.
Вот как они вписываются в архитектуру TensorFlow. Объединение этих оценщиков упрощает создание и передачу данных в модели TensorFlow:
Наша примерная модель
Чтобы изучить эти возможности, мы построим модель и покажем вам соответствующие фрагменты кода. Полный код находится наздесь, который включает в себя инструкции по получению обучающих и тестовых файлов. Обратите внимание, что код написан для демонстрации работы набора данных и оценщика и не оптимизирован для максимальной производительности.
Обученная модель может быть основана на четырех ботанических признаках (чашелистикдлина, ширина чашелистика,лепестокдлина и ширина лепестков) для классификации ирисов. Таким образом, во время вывода вы можете указать значения для этих четырех признаков, и модель предскажет, к какому из трех красивых сортов принадлежит цветок:
Слева направо:Горный ирис(RadomilФотография, CC BY-SA 3.0),ирис разноцветный(DlangloisФотография, CC BY-SA 3.0) и размерЖеня ирис(Frank MayfieldФотография, CC BY-SA 2.0).
Мы будем обучать классификатор глубокой нейронной сети, используя приведенную ниже структуру. Все входные и выходные значения
float32
, сумма выходных значений будет равна 1 (поскольку мы прогнозируем вероятность принадлежности к каждому типу радужной оболочки):Например, вывод для радужной оболочки может быть 0,05, 0,9 для ириса разноцветного и 0,05 для ириса виргинского, что указывает на 90% вероятность того, что цветок является ирисом разноцветным.
Хорошо! Теперь, когда мы определили модель, давайте посмотрим, как обучить модель и сделать прогнозы, используя набор данных и оценщик.
Введение в набор данных
Наборы данных — это новый способ создания входных конвейеров для моделей TensorFlow. Использование этого API намного эффективнее, чем использование каналов feed_dict или очередей, а сам API чище и проще в использовании. Хотя набор данных все еще находится в tf.contrib.data в версии 1.3, мы планируем переместить этот API в ядро в версии 1.4, так что пришло время попробовать его.
На высоком уровне набор данных состоит из следующих классов:
в:
- Наборы данных: базовый класс, содержащий функции для создания и преобразования наборов данных. Позволяет инициализировать набор данных из данных в памяти или из генератора Python.
- TextLineDataset: чтение строк из текстового файла.
- TFRecordDataset: Чтение записей из файла TFRecord.
- FixedLengthRecordDataset: считывает записи фиксированного размера из двоичного файла.
- Итераторы: Предоставляет способ получать элементы набора данных по одному.
наш набор данных
Во-первых, давайте посмотрим на набор данных, который будет использоваться для подачи модели. Мы будем читать данные из файла CSV, каждая строка этого файла будет содержать пять значений — четыре входных значения плюс метки:
Значения тегов описаны ниже:
- Горный ирис 0
- Цвет радужной оболочки меняется на 1
- Виргинский ирис 2.
представляет наш набор данных
Чтобы проиллюстрировать наш набор данных, давайте сначала создадим список функций:
feature_names = [
'SepalLength',
'SepalWidth',
'PetalLength',
'PetalWidth']
При обучении модели нам нужна функция, которая может читать входной файл и возвращать данные функций и меток. Оценщик требует, чтобы вы создали функцию в следующем формате:
def input_fn():
...<code>...
return ({ 'SepalLength':[values], ..<etc>.., 'PetalWidth':[values] },
[IrisFlowerType])
Возвращаемое значение должно быть двухэлементным кортежем, организованным следующим образом:
- Первым элементом должен быть словарь (где каждая входная функция является ключом), за которым следует список значений для обучающего пакета.
- Второй элемент — это список меток, которые будут использоваться для обучающего пакета.
Поскольку мы возвращаем набор входных функций и обучающих меток, все списки в операторе return будут иметь одинаковую длину. Технически, когда мы говорим здесь «список», мы на самом деле имеем в виду одномерные тензоры TensorFlow.
Для удобства повторного использования
input_fn
, мы добавим к нему некоторые параметры. Таким образом, мы можем построить функцию ввода с различными настройками. Параметры интуитивно понятны:-
file_path
: файл данных для чтения. -
perform_shuffle
: Должен ли быть рандомизирован порядок записей. -
repeat_count
: количество повторений записей в наборе данных. Например, если мы укажем 1, каждая запись будет прочитана один раз. Если мы не укажем, итерация будет продолжаться вечно.
Вот как мы реализовали эту функцию с помощью Dataset API. Мы поместим это в «входную функцию», которая позже будет использоваться для предоставления данных для нашей модели оценки:
def my_input_fn(file_path, perform_shuffle=False, repeat_count=1):
def decode_csv(line):
parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
label = parsed_line[-1:] # Last element is the label
del parsed_line[-1] # Delete last element
features = parsed_line # Everything (but last element) are the features
d = dict(zip(feature_names, features)), label
return d
dataset = (tf.contrib.data.TextLineDataset(file_path) # Read text file
.skip(1) # Skip header row
.map(decode_csv)) # Transform each elem by applying decode_csv fn
if perform_shuffle:
# Randomizes input using a window of 256 elements (read into memory)
dataset = dataset.shuffle(buffer_size=256)
dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
dataset = dataset.batch(32) # Batch size to use
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
Обратите внимание на следующее:
-
TextLineDataset
: он сделает за вас большую часть работы по управлению памятью, когда вы используете наборы данных Dataset API в виде файлов. Например, вы можете прочитать файл набора данных, который намного больше памяти, или прочитать несколько файлов, указав список в качестве параметра. -
shuffle
: чтение записей buffer_size, затем перемешивание (рандомизация) их порядка. -
map
:перечислитьdecode_csv
с каждым элементом в наборе данных в качестве параметра (поскольку мы используем TextLineDataset, каждый элемент будет строкой текста CSV). Затем мы применим к каждой строкеdecode_csv
. -
decode_csv
: Разделите каждую строку на поля, предоставляя значения по умолчанию по мере необходимости. Затем верните словарь, содержащий ключи и значения полей. Функция карты будет обновлять каждый элемент (строку) в наборе данных с помощью словаря.
Выше приведено краткое введение в набор данных! Ради интереса теперь мы можем распечатать первую партию, используя следующую функцию:
next_batch = my_input_fn(FILE, True) # Will return 32 random elements
# Now let's try it out, retrieving and printing one batch of data.
# Although this code looks strange, you don't need to understand
# the details.
with tf.Session() as sess:
first_batch = sess.run(next_batch)
print(first_batch)
# Output
({'SepalLength': array([ 5.4000001, ...<repeat to 32 elems>], dtype=float32),
'PetalWidth': array([ 0.40000001, ...<repeat to 32 elems>], dtype=float32),
...
},
[array([[2], ...<repeat to 32 elems>], dtype=int32) # Labels
)
Это все, что нам нужно от Dataset API при реализации модели. Однако набор данных может предложить гораздо больше; см. наш список дополнительных ресурсов в конце этого сообщения в блоге.
Введение в оценщик
Оценщики — это высокоуровневый API, который устраняет необходимость написания большого количества шаблонного кода при обучении модели TensorFlow. Оценщик также очень гибок, позволяя вам переопределить поведение по умолчанию, если у вас есть особые требования к модели.
С помощью оценщика вы можете построить модель двумя возможными способами:
- Готовые оценщики — это предварительно определенные оценщики, предназначенные для создания модели определенного типа. В этом сообщении блога мы будем использовать предварительно созданный оценщик DNNClassifier.
- Estimator (базовый класс) — позволяет вам полностью контролировать создание модели с помощью функции model_fn. Мы расскажем, как это сделать, в отдельной статье блога.
Ниже представлена диаграмма классов оценщика:
Мы надеемся добавить больше готовых оценщиков в будущих выпусках.
Как видите, все оценщики используют
input_fn
, который предоставляет входные данные для оценщика. В нашем примере мы будем повторно использоватьmy_input_fn
, функцию, которую мы определили специально для демонстрации.Следующий код создает экземпляр оценщика, который предсказывает тип радужной оболочки:
# Create the feature_columns, which specifies the input to our model.
# All our input features are numeric, so use numeric_column for each one.
feature_columns = [tf.feature_column.numeric_column(k) for k in feature_names]
# Create a deep neural network regression classifier.
# Use the DNNClassifier pre-made estimator
classifier = tf.estimator.DNNClassifier(
feature_columns=feature_columns, # The input features to our model
hidden_units=[10, 10], # Two layers, each with 10 neurons
n_classes=3,
model_dir=PATH) # Path to where checkpoints etc are stored
Теперь у нас есть оценщик, готовый начать обучение.
Обучите модель
Выполните обучение с помощью одной строки кода TensorFlow:
# Train our model, use the previously function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
classifier.train(
input_fn=lambda: my_input_fn(FILE_TRAIN, True, 8))
Но подождите минутку... это"
lambda:
my_input_fn(FILE_TRAIN, True, 8)
«Что? Здесь мы соединяем набор данных с оценщиком! Оценщику нужны данные для обучения, оценки и прогнозирования, он используетinput_fn
Извлечь данные. Оценщик требует безпараметрическогоinput_fn
, поэтому мы будем использоватьlambda
Создайте функцию без параметров, которая принимает требуемые параметрыfile_path, shuffle
setting,
иrepeat_count
Вызовите input_fn. В нашем примере мы используемmy_input_fn,
и передать его:-
FILE_TRAIN
, файл обучающих данных. -
True
, который указывает оценщику перетасовать данные. -
8
, который указывает оценщику повторить набор данных 8 раз.
Оцените нашу обученную модель
Теперь у нас есть обученная модель. Как оценить его работу? К счастью, каждая оценка содержит
evaluate
функция:# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
evaluate_result = estimator.evaluate(
input_fn=lambda: my_input_fn(FILE_TEST, False, 4)
print("Evaluation results")
for key in evaluate_result:
print(" {}, was: {}".format(key, evaluate_result[key]))
В нашем примере мы достигли точности около 93%. Конечно, точность можно повысить несколькими способами. Один из способов — запустить программу несколько раз. Поскольку состояние модели будет сохраняться (в приведенном выше
model_dir=PATH
), чем больше итераций вы на нем тренируете, тем больше модель улучшается, пока не даст результатов. Другой способ — настроить количество скрытых слоев или количество узлов в каждом скрытом слое. Вы можете вносить коррективы, однако обратите внимание, что при внесении изменений вам нужно будет удалитьmodel_dir=PATH
, потому что вы изменилиDNNClassifier
Структура.Мы используем модель для прогнозирования обученных
Готово! Теперь у нас есть обученная модель, и если мы удовлетворены результатами оценки, мы можем использовать эту модель для прогнозирования радужной оболочки на основе некоторых входных данных. Как и в случае с обучением и оценкой, мы делаем прогнозы с помощью одного вызова функции:
# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
input_fn=lambda: my_input_fn(FILE_TEST, False, 1))
print("Predictions on test file")
for prediction in predict_results:
# Will print the predicted class, i.e: 0, 1, or 2 if the prediction
# is Iris Sentosa, Vericolor, Virginica, respectively.
print prediction["class_ids"][0]
Делайте прогнозы на основе данных в памяти
Ранее отображаемый код
FILE_TEST
Указано для прогнозирования на основе данных, хранящихся в файле, но как насчет прогнозирования на основе данных из других источников, таких как память? Как вы могли догадаться, для этого предсказания не требуетсяpredict
Звоните, чтобы внести изменения. Однако нам нужно настроить API набора данных для использования такой структуры памяти:# Let create a memory dataset for prediction.
# We've taken the first 3 examples in FILE_TEST.
prediction_input = [[5.9, 3.0, 4.2, 1.5], # -> 1, Iris Versicolor
[6.9, 3.1, 5.4, 2.1], # -> 2, Iris Virginica
[5.1, 3.3, 1.7, 0.5]] # -> 0, Iris Sentosa
def new_input_fn():
def decode(x):
x = tf.split(x, 4) # Need to split into our 4 features
# When predicting, we don't need (or have) any labels
return dict(zip(feature_names, x)) # Then build a dict from them
# The from_tensor_slices function will use a memory structure as input
dataset = tf.contrib.data.Dataset.from_tensor_slices(prediction_input)
dataset = dataset.map(decode)
iterator = dataset.make_one_shot_iterator()
next_feature_batch = iterator.get_next()
return next_feature_batch, None # In prediction, we have no labels
# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)
# Print results
print("Predictions on memory data")
for idx, prediction in enumerate(predict_results):
type = prediction["class_ids"][0] # Get the predicted class (index)
if type == 0:
print("I think: {}, is Iris Sentosa".format(prediction_input[idx]))
elif type == 1:
print("I think: {}, is Iris Versicolor".format(prediction_input[idx]))
else:
print("I think: {}, is Iris Virginica".format(prediction_input[idx])
Dataset.from_tensor_slides()
Для небольших наборов данных, которые могут поместиться в памяти. Используйте так же, как для обучения и оценкиTextLineDataset
, вы можете обрабатывать произвольно большие файлы, если ваша память может управлять произвольными буферами и размерами пакетов.расширять
Использование оценщика, такого как DNNClassifier, может предоставить множество значений. Помимо простоты использования, готовые оценщики предоставляют встроенные метрики оценки и создают сводки, которые вы можете увидеть в TensorBoard. Чтобы просмотреть этот отчет, запустите TensorBoard из командной строки следующим образом:
# Replace PATH with the actual path passed as model_dir argument when the
# DNNRegressor estimator was created.
tensorboard --logdir=PATH
На следующих рисунках показаны некоторые данные, которые TensorBoard предоставит:
Суммировать
В этом сообщении блога мы исследуем наборы данных и оценки. Это важные API для определения потоков входных данных и создания моделей, поэтому стоит потратить некоторое время на их изучение!
Дополнительные сведения см. в приведенных ниже ресурсах.
- Полный исходный код, использованный в этом сообщении в блоге, находится по адресуздесь.
- Очень хорошие заметки Джоша Гордона о Jupyter по этому вопросу. С помощью этой заметки вы можете узнать, как запустить самый богатый пример с различными типами функций (входных данных). Как вы поняли, в нашей модели мы используем только числовые характеристики.
- Наборы данных см.Руководство программистаиСправочная документацияновая глава в .
- Оценщики см.Руководство программистаиСправочная документацияновая глава в .
Это еще не конец. Скоро мы опубликуем в блоге больше сообщений о том, как работают эти API, так что следите за обновлениями!
А пока получайте удовольствие от кодирования в TensorFlow!