содержание
Как Keras принимает несколько входных данных?
Получить набор данных о ценах на жилье
Загрузить числовые и категориальные данные
Загрузить набор данных изображения
Определение многослойных персептронов (MLP) и сверточных нейронных сетей (CNN)
Использование нескольких входов с Keras
Множественные входы и смешанные результаты данных
Перевод из: Керас: несколько входных данных и смешанные данные, Адриан Роузброк.
Резюме
Нажмите здесь, чтобы загрузить исходный код:jbox.sjtu.edu.cn/l/NHfFZu
Используйте регрессионный прогноз цен на жилье в качестве фона. Набор данных о ценах на жилье включает не толькоЧисленная величинаикатегорияданные, в том числеизображениеданные, известные как различные типысмешанные данные. Модель должна иметь возможность принимать несколько типов смешанных входных данных и вычислять выходное значение проблемы регрессии.
В оставшейся части этого руководства вы узнаете, как:
- Определите модель Keras, которая может одновременно принимать несколько типов входных данных, включая числовые, категориальные и типы изображений.
- Обучите сквозную модель Keras на смешанных входных данных.
- Оцените нашу модель, используя несколько входных данных.
текст
В первой части этого урока мы кратко рассмотримсмешанные данныеконцепция иКак Keras принимает несколько типов входных данных.
Что такое смешанные данные?
Рис. 1. Используя гибкую структуру глубокого обучения Keras, можно определить модель с несколькими входами, которая включает ветви CNN и MLP для раздельной обработки смешанных данных.
Смешанные данные относятся к одновременному использованию входных данных разных типов данных.
Например, предположим, что мы инженеры по машинному обучению, работающие в больнице, разрабатывающие систему, которая может классифицировать состояние здоровья пациентов.
У нас есть несколько типов входных данных для пациента, в том числе:
- Числовой/непрерывный, такие как возраст, частота сердечных сокращений, артериальное давление
- Значение категории, включая пол и расу
- данные изображениянапример, МРТ, рентген и т. д.
Наши модели машинного обучения должны иметь возможность принимать эти «смешанные данные» и делать (точные) прогнозы о здоровье пациента.
Разработка систем машинного обучения, способных обрабатывать смешанные данные, является сложной задачей, поскольку для каждого типа данных могут потребоваться отдельные этапы предварительной обработки, включая масштабирование, нормализацию и проектирование признаков.
Обработка смешанных данных по-прежнему является очень открытой областью исследований и часто сильно зависит от конкретных задач/целей.
Как Keras принимает несколько входных данных?
Keras может обрабатывать несколько входов (и даже несколько выходов) через свой функциональный API.
Вы должны были использовать последовательный API через класс Sequential раньше.Функциональный API, напротив, может использоваться для определения гораздо более сложных моделей, которые не являются последовательными, в том числе:
- Модель с несколькими входами
- Несколько выходных моделей
- Модель включает несколько входов и несколько выходов
- Направленный ациклический граф
- Модель с общими слоями
Например, мы можем определить простую последовательную нейронную сеть как:
model = Sequential()
model.add(Dense(8, input_shape=(10,), activation="relu"))
model.add(Dense(4, activation="relu"))
model.add(Dense(1, activation="linear"))
Сеть представляет собой простую нейронную сеть с прямой связью с 10 входами, первый скрытый слой имеет 8 узлов, второй скрытый слой имеет 4 узла, а последний выходной слой используется для регрессии.
Мы можем определить пример нейронной сети, используя функциональный API:
inputs = Input(shape=(10,))
x = Dense(8, activation="relu")(inputs)
x = Dense(4, activation="relu")(x)
x = Dense(1, activation="linear")(x)
model = Model(inputs, x)
# define two sets of inputs
inputA = Input(shape=(32,))
inputB = Input(shape=(128,))
# the first branch operates on the first input
x = Dense(8, activation="relu")(inputA)
x = Dense(4, activation="relu")(x)
x = Model(inputs=inputA, outputs=x)
# the second branch opreates on the second input
y = Dense(64, activation="relu")(inputB)
y = Dense(32, activation="relu")(y)
y = Dense(4, activation="relu")(y)
y = Model(inputs=inputB, outputs=y)
# combine the output of the two branches
combined = concatenate([x.output, y.output])
# apply a FC layer and then a regression prediction on the
# combined outputs
z = Dense(2, activation="relu")(combined)
z = Dense(1, activation="linear")(z)
# our model will accept the inputs of the two branches and
# then output a single value
model = Model(inputs=[x.input, y.input], outputs=z)
Вы можете видеть, что мы определили два входа в нейронную сеть Keras:
- inputA: 32 измерения
- inputB: 128 размеров
Архитектура визуальной модели:
Рисунок 2: Эта модель имеет две входные ветви, которые в конечном итоге сливаются и дают один выход. Функциональный API Keras позволяет использовать этот тип архитектуры, и вы можете построить любую другую архитектуру, которую только можете себе представить.
Обратите внимание, что наша модель имеет две отдельные ветви.
Первая ветвь принимает 128-мерный ввод, а вторая ветвь принимает 32-мерный ввод. Ветви выполняются независимо друг от друга до объединения и после этого выводят значение.
В оставшейся части этого руководства вы узнаете, как создать сеть с несколькими входами с помощью Keras.
набор данных о ценах на жилье
Рисунок 4. Набор данных о ценах на жилье включает числовые данные, категориальные данные и данные изображения. Используя Keras, мы построим модель, которая поддерживает несколько входных и смешанных типов данных, и используем эту модель регрессии для прогнозирования стоимости дома.
В этой серии статей мы используем статью Ахмеда и Мустафы 2016 года «Оценка цен на жилье по визуальным и текстовым признакам» (House price estimate from visual and text features) в наборе данных о ценах на жилье.
Этот набор данных включает числовые данные, категориальные данные и данные изображений для 535 типовых домов.
Числовые и категориальные свойства включают в себя:
- количество спален
- количество ванных комнат
- площадь (площадь)
- почтовый индекс
Всего для каждого дома предусмотрено четыре изображения:
- спальная комната
- ванная комната
- кухня
- фасад дома
В первой статье этой серии вы узнали, как обучить регрессионную сеть Кераса на числовых и категориальных данных.
Во второй статье этой серии вы узнали, как использовать Keras CNN для регрессии.
Сегодня мы будем использовать Keras для обработки нескольких входных и смешанных данных.
Мы возьмем числовые данные, категориальные данные и данные изображения, обработаем каждый тип данных, определив две ветви сети, и, наконец, объединим эти ветви, чтобы получить окончательный прогноз цены дома. Таким образом, мы сможем использовать Keras для обработки нескольких входных и смешанных данных.
Получить набор данных о ценах на жилье
Нажмите здесь, чтобы загрузить исходный код:jbox.sjtu.edu.cn/l/NHfFZu
Набор данных о ценах на жилье должен находиться в каталоге keras-multi-input, который мы используем в этом проекте.
Структура проекта
$ tree --dirsfirst --filelimit 10
.
├── Houses-dataset
│ ├── Houses\ Dataset [2141 entries]
│ └── README.md
├── pyimagesearch
│ ├── __init__.py
│ ├── datasets.py
│ └── models.py
└── mixed_training.py
3 directories, 5 files
Папка Houses-dataset содержит набор данных о ценах на жилье, который мы использовали в этой серии. Когда мы будем готовы запустить сценарийmixed_training.py, вам просто нужно указать путь к набору данных в качестве аргумента командной строки (я подробно расскажу, как это сделать, в разделе «Результаты»).
Сегодня мы рассмотрим три скрипта Python:
- pyimagesearch/datasets.py: загружает и предварительно обрабатывает наши числовые данные, категориальные данные и данные изображения.
- pyimagesearch/models.py: содержит многослойные перцептроны (MLP) и сверточные нейронные сети (CNN). Эти компоненты являются входными ветвями нашей модели смешанных данных с несколькими входами.
- mixed_training.py: Сначала наш тренировочный скрипт будет использовать
pyimagesearch
модуль для загрузки и разделения набора обучающих данных, добавления заголовка данных и подключения двух ветвей к нашей сети. Затем модель обучается и оценивается.
Загрузить числовые и категориальные данные
# import the necessary packages
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import numpy as np
import glob
import cv2
import os
def load_house_attributes(inputPath):
# initialize the list of column names in the CSV file and then
# load it using Pandas
cols = ["bedrooms", "bathrooms", "area", "zipcode", "price"]
df = pd.read_csv(inputPath, sep=" ", header=None, names=cols)
# determine (1) the unique zip codes and (2) the number of data
# points with each zip code
zipcodes = df["zipcode"].value_counts().keys().tolist()
counts = df["zipcode"].value_counts().tolist()
# loop over each of the unique zip codes and their corresponding
# count
for (zipcode, count) in zip(zipcodes, counts):
# the zip code counts for our housing dataset is *extremely*
# unbalanced (some only having 1 or 2 houses per zip code)
# so let's sanitize our data by removing any houses with less
# than 25 houses per zip code
if count < 25:
idxs = df[df["zipcode"] == zipcode].index
df.drop(idxs, inplace=True)
# return the data frame
return df
load_house_attributes
функция. Эта функция проходитpanda
изpd
Считайте числовые и категориальные данные из набора данных о ценах на жилье в виде файла CSV.
Необработанные данные необходимо отфильтровать, чтобы учесть неравномерность распределения выборки. Поскольку некоторые почтовые индексы представлены только 1 или 2 домами, мы хотим удалить (строки 23-30) все записи из домов с менее чем 25 почтовыми индексами. Таким образом можно решить проблему неравномерного распределения выборок почтовых индексов, и в результате получается более точная модель.
определениеprocess_house_attributes
функция:
def process_house_attributes(df, train, test):
# initialize the column names of the continuous data
continuous = ["bedrooms", "bathrooms", "area"]
# performin min-max scaling each continuous feature column to
# the range [0, 1]
cs = MinMaxScaler()
trainContinuous = cs.fit_transform(train[continuous])
testContinuous = cs.transform(test[continuous])
# one-hot encode the zip code categorical data (by definition of
# one-hot encoding, all output features are now in the range [0, 1])
zipBinarizer = LabelBinarizer().fit(df["zipcode"])
trainCategorical = zipBinarizer.transform(train["zipcode"])
testCategorical = zipBinarizer.transform(test["zipcode"])
# construct our training and testing data points by concatenating
# the categorical features with the continuous features
trainX = np.hstack([trainCategorical, trainContinuous])
testX = np.hstack([testCategorical, testContinuous])
# return the concatenated training and testing data
return (trainX, testX)
Эта функция проходитscikit-learn
изMinMaxScaler
(Строки 41-43) Примените масштабирование минимум-максимум к непрерывным функциям.
Затем, поscikit-learn
изLabelBinarizer
(Строки 47-49) Вычислите однократное кодирование категориальных признаков.
Затем объедините непрерывные и категориальные функции и верните
Загрузить набор данных изображения
Рисунок 6: Ветвь нашей модели принимает изображение — сшитое изображение из четырех изображений дома. Используя сглаженные изображения для объединения числовых, категориальных данных, введенных в другую ветвь, наша модель затем использует структуру Keras для регрессии и прогнозирования стоимости жилья.
Следующим шагом является определениеhelper
функция для загрузки входного изображения. Так же открытьdata .py
файл и вставьте следующий код:
def load_house_images(df, inputPath):
# initialize our images array (i.e., the house images themselves)
images = []
# loop over the indexes of the houses
for i in df.index.values:
# find the four images for the house and sort the file paths,
# ensuring the four are always in the *same order*
basePath = os.path.sep.join([inputPath, "{}_*".format(i + 1)])
housePaths = sorted(list(glob.glob(basePath)))
load_house_images
Функция имеет три функции:
- Загрузите все фотографии из набора данных о ценах на жилье. Напомним, что у нас есть четыре изображения каждого дома (рис. 6).
- Создайте одно плоское изображение из четырех фотографий. Сведенные изображения всегда расположены в том порядке, в котором вы видите их на картинке.
- Добавьте все эти мастер-маски в список/массив и вернитесь к вызывающей функции.
Продолжать:
- Инициализирует список изображений (строка 61) и заполняет этот список всеми созданными нами плоскими изображениями.
- Переберите дома во фрейме данных (строка 64), чтобы получить путь к четырем фотографиям текущего дома.
Внутри цикла:
# initialize our list of input images along with the output image
# after *combining* the four input images
inputImages = []
outputImage = np.zeros((64, 64, 3), dtype="uint8")
# loop over the input house paths
for housePath in housePaths:
# load the input image, resize it to be 32 32, and then
# update the list of input images
image = cv2.imread(housePath)
image = cv2.resize(image, (32, 32))
inputImages.append(image)
# tile the four input images in the output image such the first
# image goes in the top-right corner, the second image in the
# top-left corner, the third image in the bottom-right corner,
# and the final image in the bottom-left corner
outputImage[0:32, 0:32] = inputImages[0]
outputImage[0:32, 32:64] = inputImages[1]
outputImage[32:64, 32:64] = inputImages[2]
outputImage[32:64, 0:32] = inputImages[3]
# add the tiled image to our set of images the network will be
# trained on
images.append(outputImage)
# return our set of images
return np.array(images)
До сих пор код завершил первый гол, обсуждаемый выше (четыре изображения каждого дома).
-
В цикле мы:
-
Выполните инициализацию (строки 72 и 73). наш
inputImages
Четыре фотографии для каждой записи будут включены в список. нашinputImages
будет сшитое изображение фотографии (как показано на рисунке 6). -
Цикл 4 фотографии (строка 76):
- Загрузите, измените размер и прикрепите каждую фотографию к
inputImages
Средний (строки 79-81).
- Загрузите, измените размер и прикрепите каждую фотографию к
-
Создайте плитки (склеенные изображения) для изображений четырех домов (строки 87-90):
- Изображение ванной комнаты вверху слева.
- Фото спальни в правом верхнем углу.
- Вид спереди внизу справа.
- Кухня находится в левом нижнем углу.
-
Добавить строчку
outputImage
прибытьimages
(Линия 94).
-
-
Выходя из цикла, мы возвращаем все изображения в виде массива NumPy (строка 97).
Определение многослойных персептронов (MLP) и сверточных нейронных сетей (CNN)
Рисунок 7: Модель Keras с несколькими входами (смешанные данные) имеет одну ветвь, которая принимает числовые/категориальные данные (слева), и другую, которая принимает данные изображения в виде сшивания 4 фотографий (справа).
До сих пор мы тщательно обрабатывали данные, используя несколько библиотек:panda、scikit-learn、OpenCV和NumPy
.
мы прошлиdatasets.py
Два режима набора данных организованы и предварительно обработаны.
- Числовые и категориальные данные
- данные изображения
Чтобы достичь этого, навыки, которые мы используем, развиваются на основе опыта и практики с небольшой отладкой. Пожалуйста, не игнорируйте методы манипулирования данными, которые мы обсуждали и использовали до сих пор, поскольку они являются ключом к успеху нашего проекта.
Давайте сменим тему и обсудим, как мы будем строить сети с несколькими входами и смешанными данными, используя функциональный API Keras.
Для построения нашей многовходовой сети нам понадобятся две ветви:
- Первая ветвь представляет собой простой многослойный персептрон (MLP) для обработки числовых входных данных.
- Вторая ветвь — сверточная нейронная сеть, работающая с данными изображений.
- Затем эти ветви соединяются вместе, чтобы сформировать окончательную модель Keras с несколькими входами.
Мы займемся построением окончательной конкатенированной модели с несколькими входами в следующем разделе, и наша текущая задача — определить эти две ветви.
Открытымmodels.py
файл, вставьте следующий код:
# import the necessary packages
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras.layers import Flatten
from keras.layers import Input
from keras.models import Model
def create_mlp(dim, regress=False):
# define our MLP network
model = Sequential()
model.add(Dense(8, input_dim=dim, activation="relu"))
model.add(Dense(4, activation="relu"))
# check to see if the regression node should be added
if regress:
model.add(Dense(1, activation="linear"))
# return our model
return model
Наши категориальные/числовые данные будут обрабатываться простым многослойным персептроном (MLP).
МЛП поcreate_mlp
определение.
Наш MLP прост:
- Полностью связанный (плотный) входной слой с активациями ReLU
- Полностью подключенный скрытый слой, также с активациями ReLU
- Наконец, необязательный вывод регрессии с линейной активацией
Хотя мы использовали регрессионный вывод MLP в первой статье, он не будет использоваться в этой сети со смешанными данными с несколькими входами. Как вы вскоре увидите, мы явно установим regress=False, хотя это тоже значение по умолчанию.Регрессия будет выполнена позже для головы всей многовходовой сети смешанных данных..
Согласно рисунку 7 мы построили верхнюю левую ветвь сети.
Теперь давайте определим верхнюю правую ветвь нашей сети, CNN:
def create_cnn(width, height, depth, filters=(16, 32, 64), regress=False):
# initialize the input shape and channel dimension, assuming
# TensorFlow/channels-last ordering
inputShape = (height, width, depth)
chanDim = -1
# define the model input
inputs = Input(shape=inputShape)
# loop over the number of filters
for (i, f) in enumerate(filters):
# if this is the first CONV layer then set the input
# appropriately
if i == 0:
x = inputs
# CONV => RELU => BN => POOL
x = Conv2D(f, (3, 3), padding="same")(x)
x = Activation("relu")(x)
x = BatchNormalization(axis=chanDim)(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
create_cnn
Функция обрабатывает данные изображения и принимает пять аргументов:
- ширина: ширина входного изображения в пикселях.
- Высота: высота входного изображения в пикселях.
- Глубина: количество каналов во входном изображении. Для цветных изображений RGB это 3.
- Фильтры: прогрессивно увеличивающийся набор фильтров, которые позволяют нашей сети изучать более различительные функции.
- регрессия: логическое значение, указывающее, следует ли добавлять полностью связанный линейный слой активации в CNN для регрессии.
Отсюда мы начинаем пересекать фильтр и создать набор COVE => RELU> BN => Pool Play. Каждая итерация контура накапливающих слоев.
Достроим ветку сети CNN:
# flatten the volume, then FC => RELU => BN => DROPOUT
x = Flatten()(x)
x = Dense(16)(x)
x = Activation("relu")(x)
x = BatchNormalization(axis=chanDim)(x)
x = Dropout(0.5)(x)
# apply another FC layer, this one to match the number of nodes
# coming out of the MLP
x = Dense(4)(x)
x = Activation("relu")(x)
# check to see if the regression node should be added
if regress:
x = Dense(1, activation="linear")(x)
# construct the CNN
model = Model(inputs, x)
# return the CNN
return model
Мы сглаживаем следующий слой, то есть объединяем все извлеченные признаки в одномерный вектор признаков, затем добавляем полносвязный слой с пакетной нормализацией и отбрасыванием.
Другой полносвязный слой используется для сопоставления четырех узлов многослойного персептрона. Количество совпадающих узлов не требуется, но помогает сбалансировать ветви.
Проверьте, добавлен ли узел регрессии, и при необходимости добавьте его соответствующим образом. На самом деле, мы не будем делать регрессию в конце этой ветки. Регрессия будет выполняться в начале сети смешанных данных с несколькими входами (нижняя часть рисунка 7).
Наконец, модель состоит из нашего ввода и всех слоев, собранных вместе. Мы можем вернуть ветвь CNN вызывающей функции (строка 68).
Теперь, когда мы определили две ветви модели Keras с несколькими входами, давайте научимся их комбинировать!
Использование нескольких входов с Keras
Теперь мы готовы построить окончательную модель Keras, способную обрабатывать несколько входных данных и смешанные данные. Именно здесь сходятся ветви — и происходит «волшебство».
Обучение также будет проходить по этому сценарию.
Создатьmixed_training.py
, откройте его и вставьте следующий код:
# import the necessary packages
from pyimagesearch import datasets
from pyimagesearch import models
from sklearn.model_selection import train_test_split
from keras.layers.core import Dense
from keras.models import Model
from keras.optimizers import Adam
from keras.layers import concatenate
import numpy as np
import argparse
import locale
import os
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", type=str, required=True,
help="path to input dataset of house images")
args = vars(ap.parse_args())
Для начала давайте импортируем необходимые модули и разберем аргументы командной строки.
-
datasets
: наши три удобные функции для загрузки/обработки данных CSV из наборов данных домов и загрузки/предварительной обработки фотографий домов. -
models
: Наши входные ветви MLP и CNN, которые будут служить в качестве наших смешанных данных с несколькими входами. -
train_test_split
: Одинscikit-learn
Функция для построения нашего разделения данных поезда/теста. -
concatenate
: специальная функция Keras, которая принимает несколько входных данных. -
argparse
: обрабатывает аргументы командной строки синтаксического анализа.
В строках 15-18 у нас есть аргумент командной строки для разбора, а именноdataset
, то есть путь, по которому вы скачали набор данных о ценах на жилье.
Далее давайте загрузим наши числовые/категориальные данные и данные изображения:
# construct the path to the input .txt file that contains information
# on each house in the dataset and then load the dataset
print("[INFO] loading house attributes...")
inputPath = os.path.sep.join([args["dataset"], "HousesInfo.txt"])
df = datasets.load_house_attributes(inputPath)
# load the house images and then scale the pixel intensities to the
# range [0, 1]
print("[INFO] loading house images...")
images = datasets.load_house_images(df, args["dataset"])
images = images / 255.0
Здесь мы загружаем набор данных о ценах на жилье какpanda dataframe
(строки 23 и 24). Затем мы загружаем изображение и масштабируем его до [0,1] (строки 29-30).
Если вам нужно напоминание о базовой функциональности этих функций, обязательно ознакомьтесь с приведенным вышеload_house_attributes
иload_house_images
функция.
Теперь, когда наши данные загружены, мы построим разделение поезд/тест, скорректируем цены и обработаем атрибуты дома:
# partition the data into training and testing splits using 75% of
# the data for training and the remaining 25% for testing
print("[INFO] processing data...")
split = train_test_split(df, images, test_size=0.25, random_state=42)
(trainAttrX, testAttrX, trainImagesX, testImagesX) = split
# find the largest house price in the training set and use it to
# scale our house prices to the range [0, 1] (will lead to better
# training and convergence)
maxPrice = trainAttrX["price"].max()
trainY = trainAttrX["price"] / maxPrice
testY = testAttrX["price"] / maxPrice
# process the house attributes data by performing min-max scaling
# on continuous features, one-hot encoding on categorical features,
# and then finally concatenating them together
(trainAttrX, testAttrX) = datasets.process_house_attributes(df,
trainAttrX, testAttrX)
Наше обучение и тестирование проводятся на линиях 35 и 36. Мы выделили 75% данных для обучения и 25% для тестирования.
Исходя из этого, находим из обучающей выборки (строка 41)maxPrice
и соответствующим образом скорректируйте обучающие и тестовые данные (строки 42 и 43). Настройка данных значения в диапазоне [0,1] позволяет улучшить обучение и сходимость.
Наконец, мы продолжаем обрабатывать атрибуты нашего дома, выполняя минимальное-максимальное масштабирование для непрерывных функций и однократное кодирование для категориальных функций.
process_house_attributes
Функция обрабатывает эти операции и объединяет непрерывные и категориальные признаки вместе, возвращая результат (строки 48 и 49).
Готовы ли вы использовать магию?
Ну, я солгал. На самом деле нет никакой «магии» в следующем блоке кода! Но мы проведем наши сетевые филиалы, чтобы завершить нашу многопользовательскую сеть KERAS:
# create the MLP and CNN models
mlp = models.create_mlp(trainAttrX.shape[1], regress=False)
cnn = models.create_cnn(64, 64, 3, regress=False)
# create the input to our final set of layers as the *output* of both
# the MLP and CNN
combinedInput = concatenate([mlp.output, cnn.output])
# our final FC layer head will have two dense layers, the final one
# being our regression head
x = Dense(4, activation="relu")(combinedInput)
x = Dense(1, activation="linear")(x)
# our final model will accept categorical/numerical data on the MLP
# input and images on the CNN input, outputting a single value (the
# predicted price of the house)
model = Model(inputs=[mlp.input, cnn.input], outputs=x)
Обработка нескольких входных данных с помощью Keras очень проста, если у вас есть организованный код и модели.
В строках 52 и 53 мы создаем модели mlp и cnn. Обратите внимание, что regression=False — наш заголовок регрессии появляется после строки 62.
Затем мы объединим вывод mlp и вывод cnn, как показано в строке 57. я называю это нашимcombinedInput
, так как это вход для остальной части сети (как видно из рисунка 3, этоconcatenate_1
, две ветви вместе).
Комбинированный ввод для последнего уровня в сети является выходом уровня 8-4-1 FC на основе ветвей MLP и CNN (поскольку обе ветви выводят 4-мерный уровень FC, который затем мы объединяем для создания 8-мерного уровня FC). размерный вектор).
Фиксируем полносвязный слой из четырех нейронов вcombinedInput
(строка 61). Затем мы добавляем "liner
"activation
Головка регрессии (строка 62), результатом которой является прогнозируемая цена.
Перейдем к компиляции, обучению и оценке нашей вновь сформированной модели:
# compile the model using mean absolute percentage error as our loss,
# implying that we seek to minimize the absolute percentage difference
# between our price *predictions* and the *actual prices*
opt = Adam(lr=1e-3, decay=1e-3 / 200)
model.compile(loss="mean_absolute_percentage_error", optimizer=opt)
# train the model
print("[INFO] training model...")
model.fit(
[trainAttrX, trainImagesX], trainY,
validation_data=([testAttrX, testImagesX], testY),
epochs=200, batch_size=8)
# make predictions on the testing data
print("[INFO] predicting house prices...")
preds = model.predict([testAttrX, testImagesX])
В нашей модели используется "mean_absolute_percentage_error
«Потеря иAdam
Компилируется оптимизатором, скорость обучения которого снижается (строки 72 и 73).
Обучение начинается на строках 77-80. Это называется подгонкой модели (то есть, когда все веса настраиваются с помощью процесса, называемого обратным распространением).
вызвав тестовый набор данныхmodel.predict
(Строка 84) Предсказываемые моделью значения дома можно получить для оценки нашей модели.
Теперь оценим:
# compute the difference between the *predicted* house prices and the
# *actual* house prices, then compute the percentage difference and
# the absolute percentage difference
diff = preds.flatten() - testY
percentDiff = (diff / testY) * 100
absPercentDiff = np.abs(percentDiff)
# compute the mean and standard deviation of the absolute percentage
# difference
mean = np.mean(absPercentDiff)
std = np.std(absPercentDiff)
# finally, show some statistics on our model
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
print("[INFO] avg. house price: {}, std house price: {}".format(
locale.currency(df["price"].mean(), grouping=True),
locale.currency(df["price"].std(), grouping=True)))
print("[INFO] mean: {:.2f}%, std: {:.2f}%".format(mean, std))
Чтобы оценить нашу модель, мы рассчитали абсолютный процент (строки 89-91) и использовали его для получения окончательной метрики (строки 95 и 96).
Эти показатели (средняя цена, стандартное отклонение цены и абсолютный процент, а также стандартное отклонение) будут выведены на терминал в соответствующем формате (строки 100-103).
Множественные входы и смешанные результаты данных
Рис. 8. Прогнозирование цен на недвижимость — сложная задача, но наши регрессионные модели Keras с несколькими и смешанными входными данными дают относительно хорошие результаты на нашем ограниченном наборе данных о ценах на жилье.
Наконец, мы обучаем нашу сеть с несколькими входами на смешанных данных!
Убедитесь, что у вас есть:
- Настройте среду разработки в соответствии с первым руководством в этой серии.
- Используйте исходный код для этого руководства.
- Загрузите набор данных о ценах на жилье, следуя инструкциям в разделе «Получение набора данных о ценах на жилье» выше.
Исходя из этого, откройте терминал и выполните следующую команду, чтобы начать обучение сети:
$ python mixed_training.py --dataset Houses-dataset/Houses\ Dataset/
Наша средняя абсолютная процентная ошибка вначале очень высока, но продолжает уменьшаться на протяжении всей тренировки.
В конце обучения мы получили абсолютную ошибку тестового набора 22,41%, что означает, что прогноз нашей сети цен на жилье упал в среднем примерно на 22%.
Сравним этот результат с двумя предыдущими статьями этой серии:
- Использование MLP только для числовых/категориальных данных: 26,01%
- Данные изображения только с CNN: 56,91%
- Используя смешанные данные: 22,41%
Как видите, метод обработки смешанных данных выглядит следующим образом:
- Объединение наших данных числовой/l категории и данных изображения
- Обучите модель с несколькими входами на смешанных данных.
- Предлагаем более эффективную модель!
Суммировать
В этом руководстве вы узнали, как определить сеть Keras, которая может принимать несколько входных данных.
Вы также узнали, как работать со смешанными данными с помощью Keras.
Для достижения этих целей мы определяем нейронную сеть с несколькими входами, которая может принимать:
- Числовые данные
- Категориальные данные
- данные изображения
Перед тренировкой мин-макс числовых данных масштабируется до диапазона [0,1]. Данные нашей категорииone-hot
Закодировано (убедитесь, что результирующий целочисленный вектор находится в диапазоне [0,1]).
Затем числовые и категориальные данные объединяются в вектор признаков, который формирует первый вход в сеть Keras.
Данные нашего изображения также масштабируются до диапазона [0,1] — эти данные служат вторым входом в сеть Keras.
Одна ветвь модели содержит строго полносвязные слои (для связанных числовых и категориальных данных), а вторая ветвь многовходовой модели представляет собой, по сути, небольшую сверточную нейронную сеть.
Объедините выходные данные двух ветвей, чтобы определить выходной результат (предсказание регрессии).
Таким образом, мы можем тренировать нашу сеть с несколькими входами от начала до конца, что приводит к большей точности, чем использование только одного из входов.