Оригинал: keras: Deep Learning in R
В этом руководстве по глубокому обучению в R с пакетом keras RStudio вы узнаете, как создать многослойный персептрон (MLP).
Как вы уже знаете, машинное обучение - это отдельная область компьютерных наук. Таким образом, глубокое обучение - это подраздел машинного обучения, представляющий собой набор алгоритмов, основанных на структуре и функциях мозга и обычно называемых искусственными нейронными сетями (ИНС). Глубокое обучение - одна из самых популярных тенденций в машинном обучении на данный момент, и есть много проблем, в которых глубокое обучение хорошо себя проявляет, таких как робототехника, распознавание изображений и искусственный интеллект (AI).
Сегодняшнее руководство предоставит вам краткое введение в глубокое обучение в R с пакетом keras:
Вы начнете с краткого обзора пакетов глубокого обучения в R и узнаете больше о различиях между пакетами Keras, kerasR и keras и о том, что это означает, когда пакет является интерфейсом для другого пакета;
Затем вы по-настоящему начнете работу с пакетом keras RStudio: вы узнаете, как сначала подготовить рабочее пространство и загрузить встроенные наборы данных, фиктивные данные и данные из файлов CSV;
Затем вы увидите, как можно исследовать и предварительно обрабатывать данные, загруженные из файла CSV: вы нормализуете и разделите данные на наборы для обучения и тестирования.
После этого вы будете готовы построить свою модель глубокого обучения; в этом случае вы создадите многослойный персептрон (MLP) для мультиклассовой классификации.
Вы узнаете, как скомпилировать и подогнать модель под свои данные, как визуализировать историю обучения и
прогнозировать целевые значения на основе тестовых данных;
Наконец, вы оцените свою модель, интерпретируете результаты и точно настроите свою модель, чтобы она работала лучше: вы узнаете, как добавлять слои и скрытые слои, и увидите, как вы можете настроить параметры оптимизации для достижения лучших результатов.
Кроме того, вы можете сохранить свою (оптимизированную) модель или загрузить ее в другой раз. Вы увидите, как это делается, в последнем разделе этого руководства.
Совет: здесь вы найдете шпаргалку по Keras.
Глубокое обучение в R: краткий обзор пакетов
С ростом популярности глубокого обучения в CRAN появилось больше пакетов глубокого обучения R. Ниже вы можете увидеть обзор этих пакетов, взятый из пMachine Learning and Statistical Learning CRAN task view. В столбце «Процентиль» указывается процентиль, найденный в документации RDocumentation:
Совет: для сравнения пакетов глубокого обучения в R прочтите это сообщение в блоге. Для получения дополнительной информации о рейтинге и оценке в RDocumentation ознакомьтесь с этим сообщением в блоге.
Deepr и MXNetR не были найдены на RDocumentation.org, поэтому процентиль для этих двух пакетов неизвестен.
Keras, keras и kerasR
Недавно в сообщество R попали два новых пакета: пакет kerasR, созданный Тейлором Арнольдом, и пакет keras RStudio.
Оба пакета предоставляют интерфейс R для пакета глубокого обучения Python Keras, о котором вы, возможно, уже слышали, или, может быть, вы даже работали с ним! Для тех из вас, кто не знает, что пакет Keras может предложить пользователям Python, это «высокоуровневый API нейронных сетей, написанный на Python и способный работать поверх TensorFlow, Microsoft Cognitive Toolkit (CNTK) или Theano».
Интерфейсы?
Видите ли, работа с Keras - один из самых простых способов познакомиться с глубоким обучением в Python, и это также объясняет, почему пакеты kerasR и keras предоставляют интерфейс для этого фантастического пакета для пользователей R.
В этом случае вам будет полезно понять, что именно означает, когда пакет, такой как R keras, является «интерфейсом» для другого пакета, Python Keras. Проще говоря, это означает, что пакет keras R с интерфейсом позволяет вам пользоваться преимуществами программирования на R, имея при этом доступ к возможностям пакета Python Keras.
Обратите внимание, что это не редкость: например, пакет h2o также предоставляет интерфейс, но в этом случае - и, как уже следует из названия, к H2O, математическому механизму с открытым исходным кодом для больших данных, который вы можете использовать для параллельных распределенных алгоритмов машинного обучения. Другие пакеты, которые, возможно, предоставляют интерфейсы, это RWeka (интерфейс R для Weka), tensorflow (интерфейс R для TensorFlow), openml-r (интерфейс R для OpenML),… Вы можете продолжать и продолжать!
В чем разница между Keras, keras и kerasR?
Теперь, когда вы все это знаете, вы можете сначала задать себе следующий вопрос: как бы вы сравнивали исходный пакет Python с пакетами R?
По сути, вы не найдете слишком много различий между пакетами R и исходным пакетом Python, в основном потому, что имена функций почти все одинаковы. Единственные различия, которые вы замечаете, в основном связаны с самими языками программирования (назначение переменных, загрузка библиотеки и т. д.). Но самое важное, что следует заметить, заключается в том, какая часть исходных функций была включена в пакет R.
Обратите внимание, что это замечание справедливо не только для библиотеки keras, но и для tenorflow, openml-r,… и других пакетов, упомянутых выше!
Во-вторых, вы также можете задаться вопросом, в чем же тогда разница между этими двумя пакетами R. Что ж, если вы хотите оценить, чем они отличаются, вы можете рассмотреть следующие моменты:
Пакет keras использует оператор конвейера (%>%) для соединения функций или операций, в то время как вы не найдете его в kerasR: например, чтобы создать свою модель с kerasR, вам нужно использовать оператор $. Использование оператора конвейера обычно улучшает читаемость вашего кода, и вы наверняка уже видели этот оператор, если раньше работали с пакетами Tidyverse.
Вы увидите, что kerasR содержит функции, названные так же, но не совсем так, как в исходном пакете Keras. Например, изначальная (Python) функция compile() называется keras_compile(); то же самое относится и к другим функциям, таким как, например, fit(), которая становится keras_fit(), или predict(), которая становится keras_predict, когда вы используете пакет kerasR. Это все нестандартные обертки.
Вы можете возразить, что установка пакета keras RStudio проще, чем установка пакета kerasR. Чтобы установить последний, вам необходимо сначала убедиться, что вы настроили, какую версию Python использовать, и это может быть сложно, если вы работаете на компьютере, на котором установлено несколько сред или версий Python. Но я предоставлю вам решать это :)
Теперь, когда вы собрали некоторую предысторию, пришло время по-настоящему начать работу с Keras в R. Как вы уже прочитали во введении к этому руководству, сначала вы рассмотрите настройку своего рабочего пространства. Затем вы загрузите некоторые данные, и после короткого исследования данных и предварительной обработки вы сможете приступить к построению вашего MLP!
Установка пакета keras
Как всегда, первым шагом к началу работы с любым пакетом является настройка рабочего пространства: установка и загрузка библиотеки в RStudio или в любую другую среду, в которой вы работаете.
Во-первых, убедитесь, что вы установили keras: вы можете легко сделать это, запустив devtools::install_github("rstudio/keras") в вашей консоли. Затем вы можете загрузить пакет и установить TensorFlow:
# Load in the keras package
library(keras)
# Install TensorFlow
install_tensorflow()
Когда вы это сделаете, все готово! Это быстро, правда?
Совет: для получения дополнительной информации о процессе установки посетите веб-сайт пакета.
Загрузка данных
Теперь, когда процесс установки прозрачен и ваше рабочее пространство готово, вы можете начать загрузку данных! На этом этапе у вас есть три больших варианта, когда дело доходит до ваших данных: вы можете выбрать использование одного из встроенных наборов данных, поставляемых с пакетом keras, вы можете загрузить свой собственный набор данных, например, из файлов CSV или вы можете создать фиктивные данные.
В какой бы ситуации вы ни оказались, вы увидите, что сможете быстро приступить к работе с пакетом. В этом разделе будут быстро рассмотрены три варианта и объяснено, как вы можете загрузить (или создать) данные, которые вам нужны для начала работы!
Встроенные наборы данных
Если у вас есть предыдущий опыт работы с пакетом Keras в Python, вы, вероятно, уже имели доступ к встроенным наборам данных Keras с такими функциями, как mnist.load_data(), cifar10.load_data() или imdb.load_data().
Вот несколько примеров загрузки данных MNIST, CIFAR10 и IMDB с помощью пакета keras:
# Read in MNIST data
mnist <- dataset_mnist()
# Read in CIFAR10 data
cifar10 <- dataset_cifar10()
# Read in IMDB data
imdb <- dataset_imdb()
Обратите внимание, что все функции для загрузки встроенных наборов данных с помощью keras следуют одному шаблону. Для данных MNIST вы будете использовать функцию dataset_mnist() для загрузки ваших данных.
Фиктивные данные
В качестве альтернативы вы также можете быстро создать фиктивные данные, чтобы начать работу. Для этого вы можете использовать функцию matrix():
# Make your dummy data
data <- matrix(rexp(1000*784), nrow = 1000, ncol = 784)
# Make dummy target values for your dummy data
labels <- matrix(round(runif(1000*10, min = 0, max = 9)),
nrow = 1000, ncol = 10)
Обратите внимание, что рекомендуется проверить структуру ваших данных. Крайне важно заранее знать, с какими данными вы работаете, потому что они понадобятся вам для последующих шагов. Вы узнаете об этом больше позже в этом руководстве!
Чтение данных из файлов
Помимо встроенных наборов данных, вы также можете загружать данные из файлов. В этом руководстве вы сосредоточитесь на загрузке данных из файлов CSV, но если вы хотите узнать больше об импорте файлов в R, рассмотрите руководство DataCamp R Data Import Tutorial.
Давайте воспользуемся функцией read.csv () из пакета read.table для загрузки набора данных из репозитория машинного обучения UCI:
# Read in `iris` data
iris <- read.csv(url("http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"), header = FALSE)
# Return the first part of `iris`
head(iris)
# Inspect the structure
str(iris)
# Obtain the dimensions
dim(iris)
Всегда полезно проверить, был ли импорт данных успешным. Обычно для этого используются такие функции, как head(), str() и dim(), как в приведенном выше фрагменте DataCamp Light, чтобы быстро сделать это.
Результаты работы этих трех функций не сразу указывают на что-то необычное. Глядя на вывод функции str(), вы видите, что строки столбца Species читаются как факторы. Это не проблема, но определенно полезно знать это на следующих этапах, где вы собираетесь исследовать и предварительно обрабатывать данные.
Исследование данных
В этом руководстве вы продолжаете работу со знаменитым набором данных iris, который вы импортировали с помощью функции read.csv().
Для тех из вас, кто не обладает знаниями биологии, необходимыми для работы с этими данными, вот некоторая справочная информация: все цветы содержат чашелистик и лепесток. Чашелистик, охватывающий лепестки, обычно зеленый и листообразный, тогда как лепестки обычно представляют собой цветные листья. Что касается цветов ириса, они немного отличаются, как вы можете видеть на следующем рисунке:
Вы, возможно, уже видели в предыдущем разделе, что во фрейме данных iris не было имен столбцов после импорта. Теперь, что касается оставшейся части руководства, это не слишком важно: хотя функция read.csv() возвращает вам данные в data.frame, данные, которые вам нужно передать функции fit(), нуждаются в том, чтобы быть матрицей или массивом.
Некоторые вещи, о которых следует помнить об этих двух структурах данных, которые были только что упомянуты: матрицы и массивы не имеют имен столбцов. Матрицы - это двухмерные объекты одного типа данных. Массивы - это многомерные объекты одного типа данных.
Совет: посмотрите это видео, если вы хотите получить обзор структур данных в R!
Обратите внимание, что фрейм данных, с другой стороны, представляет собой особый вид именованного списка, в котором все элементы имеют одинаковую длину. Это многомерный объект, который может содержать несколько типов данных. Вы уже видели, что это правда, когда проверяли структуру фрейма данных iris в предыдущем разделе. Зная это и принимая во внимание, что вам нужно будет работать над двумерным или многомерным объектом с одним типом данных, вы уже должны подготовиться к предварительной обработке, прежде чем приступить к построению нейронной сети!
На данный момент имена столбцов могут быть удобны для целей исследования, и они определенно облегчат ваше понимание данных, поэтому давайте добавим имена столбцов с помощью функции names(). Затем вы можете сразу же использовать переменную iris в исследовании данных! Посмотрите, например, как коррелируют длина лепестка и ширина лепестка, с помощью функции plot ().
names(iris) <- c("Sepal.Length", "Sepal.Width", "Petal
.Length", "Petal.Width", "Species")
plot(iris$Petal.Length,
iris$Petal.Width,
pch=21, bg=c("red","green3","blue")[unclass
(iris$Species)],
xlab="Petal Length",
ylab="Petal Width")
Обратите внимание, что вы используете функцию unclass() для преобразования названий видов, то есть «setosa, versicolor» и «virginica», в числовые 1, 2 и 3.
Теперь внимательно посмотрим на результат работы функции построения графика:
График показывает положительную корреляцию между Petal.Length и Petal.Width для разных видов цветов ириса. Однако это то, что вы, вероятно, захотите протестировать с помощью функции cor(), которая даст вам общую корреляцию между всеми атрибутами, включенными в набор данных:
# Overall correlation between `Petal.Length` and `Petal.Width`
cor(iris$Petal.Length, iris$Petal.Width)
Кроме того, вы можете использовать пакет corrplot в сочетании с функцией cor() для построения корреляций между атрибутами ваших данных. В этом случае вы вычисляете общую корреляцию для всех атрибутов фрейма данных iris. Вы сохраняете результат этого вычисления в переменной M и передаете его функции corrplot().
Кроме того, не забудьте указать аргумент method, чтобы указать, как вы хотите отображать данные!
Вы можете продолжить эксперименты с методом визуализации в фрагменте DataCamp Light ниже:
# Store the overall correlation in `M`
M <- cor(iris[,1:4])
# Plot the correlation plot with `M`
corrplot(M, method="circle")
Используйте консоль R для дальнейшего изучения ваших данных.
Предварительная обработка данных
Прежде чем вы сможете построить свою модель, вам также необходимо убедиться, что ваши данные очищены, нормализованы (если это применимо) и разделены на обучающий и тестовый наборы. Поскольку набор данных поступает из репозитория машинного обучения UCI, вы можете ожидать, что он уже достаточно чист, но давайте все равно дважды проверим качество ваших данных.
На первый взгляд, когда вы просматривали данные с помощью head(), вы действительно не увидели ничего необычного, верно? Давайте воспользуемся функциями summary() и str(), чтобы кратко резюмировать то, что вы узнали, когда проверили, был ли импорт ваших данных успешным:
# Pull up a summary of `iris`
summary(iris)
# Inspect the structure of `iris`
str(iris)
Теперь, когда вы уверены, что данные достаточно чистые, вы можете начать с проверки необходимости нормализации для каких-либо данных, с которыми вы работаете в этом руководстве.
Нормализация данных с помощью функции, определяемой пользователем (UDF)
Из результата функции summary() в приведенном выше фрагменте DataCamp Light видно, что набор данных Iris не нужно нормализовать: атрибут Sepal.Length имеет значения от 4,3 до 7,9, а Sepal.Width содержит значения от 2 до 4,4, в то время как значения Petal.Length варьируются от 1 до 6,9, а Petal.Width - от 0,1 до 2,5. Другими словами, все значения всех атрибутов набора данных Iris содержатся в диапазоне от 0,1 до 7,9, что можно считать приемлемым.
Тем не менее, может быть хорошей идеей изучить влияние нормализации на ваши данные. Вы можете даже пойти дальше, передав нормализованные данные в вашу модель, чтобы увидеть, есть ли какой-либо эффект. Это выходит за рамки данного руководства, но вы можете попробовать это самостоятельно! Код находится здесь, в этом руководстве :)
Вы можете создать свою собственную функцию для нормализации данных iris. В данном случае это функция нормализации min-max, которая линейно преобразует ваши данные с помощью функции (x-min)/(max-min). В R это довольно просто: вы создаете функцию, в которую передаете x или некоторые данные. Затем вы вычисляете результат первого вычитания x-min и сохраняете результат в num. Затем вы также рассчитываете max-min и сохраняете результат в denom. Результат вашей функции normalize() должен возвращать результат деления num на denom.
Чтобы применить эту определяемую пользователем функцию к данным iris (за исключением целевых значений), вам необходимо не только использовать normalize, но и функцию lapply() для нормализации данных, как показано ниже:
# Build your own `normalize()` function
normalize <- function(x) {
num <- x - min(x)
denom <- max(x) - min(x)
return (num/denom)
}
# Normalize the `iris` data
iris_norm <- as.data.frame(lapply(iris[1:4], normalize))
# Return the first part of `iris`
head(iris)
Совет: используйте функцию hist() в консоли R, чтобы изучить распределение данных Iris до (iris) и после нормализации (iris_norm).
Нормализация данных с помощью keras
Чтобы использовать функцию normalize() из пакета keras, вам сначала нужно убедиться, что вы работаете с матрицей. Как вы, наверное, помните из ранее, особенность матриц состоит в том, что элементы данных матрицы имеют один и тот же базовый тип. В данном случае у вас целевые значения типа фактор, а все остальные данные числовые.
Это нужно изменить.
Вы можете использовать функцию as.numeric() для преобразования данных в числа:
iris[,5] <- as.numeric(iris[,5]) -1
# Turn `iris` into a matrix
iris <- as.matrix(iris)
# Set iris `dimnames` to `NULL`
dimnames(iris) <- NULL
Числовой data frame - это нормально, но вам нужно будет преобразовать данные в массив или матрицу, если вы хотите использовать пакет keras. Вы можете легко сделать это с помощью функции as.matrix(). Не забудьте здесь установить для dimnames значение NULL.
Как вы могли прочитать в разделе выше, нормализация данных Iris не требуется. Тем не менее, по-прежнему рекомендуется изучить нормализацию и ее эффект, а также увидеть, как это можно сделать не только с помощью UDF, но и с помощью встроенной функции normalize() из keras.
После преобразования ваших данных в матрицу вы действительно можете использовать пакет keras для изучения влияния возможной нормализации на ваши данные:
# Normalize the `iris` data
iris <- normalize(iris[,1:4])
# Return the summary of `iris`
summary(iris)
Обратите внимание, что здесь вы используете dimnames(), чтобы установить dimnames iris в NULL. Это гарантирует, что в ваших данных нет имен столбцов.
Обучающие и тестовые наборы
Теперь, когда вы проверили качество своих данных и знаете, что нормализовать данные не обязательно, вы можете продолжить работу с исходными данными и разделить их на обучающие и тестовые наборы, чтобы наконец начать создавать свои модель. Поступая таким образом, вы гарантируете, что впоследствии сможете честно оценить эффективность вашей прогнозной модели.
Прежде чем разделить данные на обучающий и тестовый наборы, лучше всего сначала установить начальное число. Вы можете легко сделать это с помощью set.seed(): используйте эту функцию и просто передайте ей случайное целое число. Начальное число - это номер генератора случайных чисел R. Основное преимущество установки начального числа состоит в том, что вы можете получить одну и ту же последовательность случайных чисел всякий раз, когда вы вводите одно и то же начальное число в генератор случайных чисел.
Это отлично подходит для воспроизводимости вашего кода!
Вы используете функцию sample(), чтобы взять образец с размером, установленным как количество строк набора данных Iris, или 150. Выборка с заменой: вы выбираете из вектора из 2 элементов и назначаете 1 или 2 к 150 строкам набора данных Iris. Присвоение элементов зависит от весов вероятности 0,67 и 0,33.
# Determine sample size
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.67, 0.33))
# Split the `iris` data
iris.training <- iris[ind==1, 1:4]
iris.test <- iris[ind==2, 1:4]
# Split the class attribute
iris.trainingtarget <- iris[ind==1, 5]
iris.testtarget <- iris[ind==2, 5]
Аргумент replace функции sample() установлен в TRUE, что означает, что вы присваиваете 1 или 2 определенной строке, а затем сбрасываете вектор 2 в исходное состояние.
Другими словами, для следующих строк в наборе данных вы можете назначать 1 или 2 каждый раз заново. Вероятность выбора 1 или 2 не должна быть пропорциональна весам среди оставшихся элементов, поэтому вы указываете веса вероятности.
Примечание: если вы, например, использовали бы встроенный набор данных с определенной функцией dataset_imdb(), ваши данные можно было легко разделить с помощью оператора $:
x_train <- imdb$train$x
y_train <- imdb$train$y
x_test <- imdb$test$x
y_test <- imdb$test$y
One-Hot Encoding
Вы успешно разделили данные, но есть еще один шаг, который вам нужно сделать, чтобы начать построение модели. Вы можете угадать, какой именно?
Если вы хотите смоделировать проблемы классификации нескольких классов с помощью нейронных сетей, обычно рекомендуется убедиться, что вы преобразовываете целевой атрибут из вектора, который содержит значения для каждого значения класса, в матрицу с логическим значением для каждого значения класса и имеет ли данный экземпляр это значение класса или нет.
Это вкратце объяснение термина One Hot Encoding (OHE). Звучит довольно сложно, не правда ли?
К счастью, в пакете keras есть функция to_categorical(), которая сделает все это за вас; Передайте iris.trainingtarget и iris.testtarget этой функции и сохраните результат в iris.trainLabels и iris.testLabels:
# One hot encode training target values
iris.trainLabels <- to_categorical(iris.trainingtarget)
# One hot encode test target values
iris.testLabels <- to_categorical(iris.testtarget)
# Print out the iris.testLabels to double check the result
print(iris.testLabels)
Теперь вы официально подошли к концу этапов исследования и предварительной обработки в этом руководстве. Далее вы можете перейти к созданию нейронной сети с помощью keras!
Построение модели
Чтобы начать построение модели, вы должны сначала инициализировать последовательную модель с помощью функции keras_model_sequential(). После этого вы готовы приступить к моделированию.
Однако перед тем как начать, неплохо было бы вернуться к исходному вопросу об этом наборе данных: можете ли вы предсказать вид определенного цветка ириса? С числовыми данными работать легче, вы предварительно обработали данные и быстро закодировали значения целевой переменной: цветок имеет тип versicolor, setosa или virginica, и это отражается в двоичных значениях 1 и 0.
Тип сети, который хорошо справляется с такой задачей, - это многослойный перцептрон. Нейронные сети этого типа часто полностью соединены. Это означает, что вы хотите построить относительно простой стек полностью связанных слоев для решения этой проблемы. Что касается функций активации, которые вы будете использовать, здесь лучше всего использовать одну из наиболее распространенных, для ознакомления с Keras и нейронными сетями, а именно функцию активации relu. Эта функция активации используется в скрытом слое, что, вообще говоря, является хорошей практикой.
Кроме того, вы также видите, что в выходном слое используется функция активации softmax. Вы делаете это, потому что хотите убедиться, что выходные значения находятся в диапазоне от 0 до 1 и могут использоваться в качестве прогнозируемых вероятностей:
# Initialize a sequential model
model <- keras_model_sequential()
# Add layers to the model
model %>%
layer_dense(units = 8, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 3, activation = 'softmax')
Обратите внимание, как выходной слой создает 3 выходных значения, по одному для каждого класса Iris (versicolor, virginica или setosa). Первый слой, который содержит 8 скрытых элементов, с другой стороны, имеет input_shape равный 4. Это связано с тем, что ваши тренировочные данные iris.training имеют 4 столбца.
Вы можете дополнительно проверить свою модель с помощью следующих функций:
- Вы можете использовать функцию summary() для вывода сводного представления вашей модели;
- get_config() вернет список, содержащий конфигурацию модели;
- get_layer() вернет конфигурацию слоя.
- Атрибут Layers можно использовать для получения сводного списка слоев модели.
- Чтобы вывести входные тензоры, вы можете использовать атрибут input; и, наконец, чтобы получить выходные тензоры, вы можете использовать атрибут outputs.
# Print a summary of a model
summary(model)
# Get model configuration
get_config(model)
# Get layer configuration
get_layer(model, index = 1)
# List the model's layers
model$layers
# List the input tensors
model$inputs
# List the output tensors
model$outputs
Компиляция и подгонка модели
Теперь, когда вы настроили архитектуру своей модели, пришло время скомпилировать и подогнать модель к данным. Чтобы скомпилировать вашу модель, вы конфигурируете модель с оптимизатором adam и функцией потери category_crossentropy. Кроме того, вы также отслеживаете точность во время обучения, передавая «accuracy» аргументу metrics.
# Compile the model
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy'
)
optimizer и loss - два аргумента, которые необходимы, если вы хотите скомпилировать модель.
Некоторые из наиболее популярных используемых алгоритмов оптимизации - это стохастический градиентный спуск (SGD), ADAM и RMSprop. В зависимости от того, какой алгоритм вы выберете, вам потребуется настроить определенные параметры, такие как скорость обучения или momentum. Выбор функции потерь зависит от стоящей перед вами задачи: например, для задачи регрессии вы обычно используют среднеквадратичную ошибку (MSE).
Как вы видите в этом примере, вы использовали функцию потерь categoryorical_crossentropy для задачи классификации нескольких классов, чтобы определить, принадлежит ли ирис к типу versicolor, virginica или setosa. Однако обратите внимание, что если бы у вас возникла проблема классификации двоичного класса, вам следовало бы использовать функцию потерь binary_crossentropy.
Затем вы также можете подогнать модель под свои данные. В этом случае вы обучаете модель для 200 эпох или итераций по всем образцам в iris.training и iris.trainLabels, пакетами по 5 образцов.
# Fit the model
model %>% fit(
iris.training,
iris.trainLabels,
epochs = 200,
batch_size = 5,
validation_split = 0.2
)
Подсказка, если хотите, вы также можете указать аргумент verbose в функции fit(). Устанавливая для этого аргумента значение 1, вы указываете, что хотите видеть индикатор выполнения.
С приведенным выше кодом вы обучаете модели для указанного количества эпох или воздействий на набор обучающих данных. Эпоха - это один проход через весь обучающий набор с последующим тестированием проверочного набора. Размер пакета, который вы указываете в приведенном выше коде, определяет количество выборок, которые будут распространяться по сети. Кроме того, таким образом вы оптимизируете эффективность, так как убедитесь, что вы не загружаете слишком много шаблонов ввода в память одновременно.
Визуализация истории обучения модели
Кроме того, полезно знать, что вы также можете визуализировать подгонку, если присвоите строки кода в блоке DataCamp Light выше переменной. Затем вы можете передать переменную функции plot(), как вы видите в этом конкретном фрагменте кода!
# Store the fitting history in `history`
history <- model %>% fit(
iris.training,
iris.trainLabels,
epochs = 200,
batch_size = 5,
validation_split = 0.2
)
# Plot the history
plot(history)
Обязательно изучите график более подробно.
На первый взгляд неудивительно, что все это выглядит немного беспорядочно. Возможно, вы не совсем понимаете, на что смотрите, верно?
Следует знать, что loss и acc указывают на ошибки и точность модели для обучающих данных, в то время как val_loss и val_acc - это те же показатели, ошибки и точность для проверочных данных.
Но, даже если вы это знаете, эти два графика непросто интерпретировать. Давайте попробуем разбить их на части, которые вам будет легче понять! Вы разделите эти два графика и сделаете два отдельных: один для ошибок модели, а другой - для точности модели. К счастью, вы можете легко использовать оператор $, чтобы получить доступ к данным и построить график пошагово.
Посмотрите на код ниже, чтобы узнать, как это сделать:
# Plot the model loss of the training data
plot(history$metrics$loss, main="Model Loss", xlab = "epoch", ylab="loss", col="blue", type="l")
# Plot the model loss of the test data
lines(history$metrics$val_loss, col="green")
# Add legend
legend("topright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
На этом первом графике вы нанесли ошибки модели на обучающие и тестовые данные. Пришло время сделать то же самое, но для точности модели:
# Plot the accuracy of the training data
plot(history$metrics$acc, main="Model Accuracy", xlab = "epoch", ylab="accuracy", col="blue", type="l")
# Plot the accuracy of the validation data
lines(history$metrics$val_acc, col="green")
# Add Legend
legend("bottomright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
Здесь следует помнить о следующем:
Если точность на ваших обучающих данных продолжает улучшаться, в то время как точность на проверочных данных ухудшается, вы, вероятно, переобучаетесь: ваша модель начинает просто запоминать данные, а не учиться на них.
Если тенденция к точности для обоих наборов данных все еще растет в последние несколько эпох, вы можете ясно видеть, что модель еще не усвоила обучающий набор данных.
Предсказание значений для новых данных
Теперь, когда ваша модель создана, скомпилирована и подогнана к данным, пришло время фактически использовать вашу модель для прогнозирования значений для вашего тестового набора iris.test. Как и следовало ожидать, для этого вы можете использовать функцию Forex(). После этого вы можете вывести матрицу ошибок, чтобы проверить прогнозы и реальные значения данных iris.test с помощью функции table().
# Predict the classes for the test data
classes <- model %>% predict_classes(iris.test, batch_size = 128)
# Confusion matrix
table(iris.testtarget, classes)
Что вы думаете о результатах? На первый взгляд, делает ли созданная вами модель верные прогнозы?
Оценка вашей модели
Даже если вы уже имеете некоторое представление о том, как работает ваша модель, глядя на предсказанные значения для iris.test, все же важно, чтобы вы нашли время для оценки своей модели. Для этого используйте функцию eval(): передайте тестовые данные iris.test, тестовые значения iris.testLabels и определите размер пакета. Сохраните результат в переменной Score, как в примере кода ниже:
# Evaluate on test data and labels
score <- model %>% evaluate(iris.test, iris.testLabels, batch_size = 128)
# Print the score
print(score)
Распечатав score, вы вернете значение ошибок и значение метрики (в данном случае «accuracy»).
Точная настройка вашей модели
Вероятно, вам придется много заниматься точной настройкой модели, особенно вначале, потому что не все задачи классификации и регрессии так просты, как та, которую вы видели в первой части этого руководства. Как вы читали выше, уже есть два ключевых решения, которые вы, вероятно, захотите изменить: сколько слоев вы собираетесь использовать и сколько «скрытых единиц» вы выберете для каждого слоя.
Вначале это действительно будет настоящее путешествие.
Помимо игры с количеством эпох или размером пакета, есть другие способы, которыми вы можете настроить свою модель в надежде, что она будет работать лучше: добавляя слои, увеличивая количество скрытых единиц и передав свои собственные параметры оптимизации в функцию compile(). В этом разделе мы рассмотрим эти три варианта.
Добавление слоев
Что произойдет, если вы добавите в модель еще один слой? Что, если бы она выглядела так?
# Initialize the sequential model
model <- keras_model_sequential()
# Add layers to model
model %>%
layer_dense(units = 8, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 5, activation = 'relu') %>%
layer_dense(units = 3, activation = 'softmax')
# Compile the model
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy'
)
# Fit the model to the data
model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Evaluate the model
score <- model %>% evaluate(iris.test, iris.testLabels, batch_size = 128)
# Print the score
print(score)
Обратите внимание, что вы также можете визуализировать показатели ошибок и точности этой новой модели! Попробуйте это в приведенном ниже фрагменте DataCamp Light:
# Initialize a sequential model
model <- keras_model_sequential()
# Add layers to the model
model %>%
layer_dense(units = 8, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 5, activation = 'relu') %>%
layer_dense(units = 3, activation = 'softmax')
# Compile the model
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy'
)
# Save the training history in history
history <- model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Plot the model loss
plot(history$metrics$loss, main="Model Loss", xlab = "epoch", ylab="loss", col="blue", type="l")
lines(history$metrics$val_loss, col="green")
legend("topright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
# Plot the model accuracy
plot(history$metrics$acc, main="Model Accuracy", xlab = "epoch", ylab="accuracy", col="blue", type="l")
lines(history$metrics$val_acc, col="green")
legend("bottomright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
Скрытые единицы
Также попробуйте эффект добавления дополнительных скрытых единиц в архитектуру вашей модели и изучите влияние на эффективность, как показано ниже:
# Initialize a sequential model
model <- keras_model_sequential()
# Add layers to the model
model %>%
layer_dense(units = 28, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 3, activation = 'softmax')
# Compile the model
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy'
)
# Fit the model to the data
model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Evaluate the model
score <- model %>% evaluate(iris.test, iris.testLabels, batch_size = 128)
# Print the score
print(score)
Обратите внимание, что в целом это не всегда лучшая оптимизация, потому что, если у вас нет большого количества данных, может быть переобучение, и будет еще хуже. Вот почему вам следует попробовать использовать небольшую сеть с такими небольшими наборами данных, как этот.
Почему бы вам не попробовать визуализировать эффект добавления скрытых узлов в вашу модель? Попробуйте это:
# Initialize the sequential model
model <- keras_model_sequential()
# Add layers to the model
model %>%
layer_dense(units = 28, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 3, activation = 'softmax')
# Compile the model
model %>% compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy'
)
# Save the training history in the history variable
history <- model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Plot the model loss
plot(history$metrics$loss, main="Model Loss", xlab = "epoch", ylab="loss", col="blue", type="l")
lines(history$metrics$val_loss, col="green")
legend("topright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
# Plot the model accuracy
plot(history$metrics$acc, main="Model Accuracy", xlab = "epoch", ylab="accuracy", col="blue", type="l")
lines(history$metrics$val_acc, col="green")
legend("bottomright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
Параметры оптимизации
Помимо добавления слоев и игры со скрытыми модулями, вы также можете попытаться настроить (некоторые) параметры алгоритма оптимизации, который вы передаете функции compile(). До сих пор вы всегда передавали в аргумент оптимизатора вектор со строкой adam.
Но так может быть не всегда!
Кроме того, попробуйте поэкспериментировать с другими алгоритмами оптимизации, такими как стохастический градиентный спуск (SGD). Попробуйте, например, использовать функцию optimizer_sgd() для настройки скорости обучения lr. Вы заметили эффект?
# Initialize a sequential model
model <- keras_model_sequential()
# Build up your model by adding layers to it
model %>%
layer_dense(units = 8, activation = 'relu', input_shape = c(4)) %>%
layer_dense(units = 3, activation = 'softmax')
# Define an optimizer
sgd <- optimizer_sgd(lr = 0.01)
# Use the optimizer to compile the model
model %>% compile(optimizer=sgd,
loss='categorical_crossentropy',
metrics='accuracy')
# Fit the model to the training data
model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Evaluate the model
score <- model %>% evaluate(iris.test, iris.testLabels, batch_size = 128)
# Print the loss and accuracy metrics
print(score)
Помимо использования другого оптимизатора, вы также можете попробовать использовать меньшую скорость обучения для обучения вашей сети. Это один из самых распространенных методов точной настройки. Обычная практика - сделать начальную скорость обучения в 10 раз меньше, чем та, которую вы использовали для обучения модели ранее.
Давайте еще раз визуализируем историю обучения, чтобы увидеть эффект этой небольшой корректировки:
# Define an optimizer
sgd <- optimizer_sgd(lr = 0.01)
# Compile the model
model %>% compile(optimizer=sgd,
loss='categorical_crossentropy',
metrics='accuracy')
# Fit the model to the training data
history <- model %>% fit(
iris.training, iris.trainLabels,
epochs = 200, batch_size = 5,
validation_split = 0.2
)
# Plot the model loss
plot(history$metrics$loss, main="Model Loss", xlab = "epoch", ylab="loss", col="blue", type="l")
lines(history$metrics$val_loss, col="green")
legend("topright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
# Plot the model accuracy
plot(history$metrics$acc, main="Model Accuracy", xlab = "epoch", ylab="accuracy", col="blue", type="l")
lines(history$metrics$val_acc, col="green")
legend("bottomright", c("train","test"), col=c("blue", "green"), lty=c(1,1))
Сохранение, загрузка или экспорт вашей модели
Последнее, что осталось в вашем путешествии с пакетом keras, это сохранение или экспорт вашей модели, чтобы вы могли загрузить ее обратно в любой момент.
Во-первых, вы можете легко использовать функции save_model_hdf5() и load_model_hdf5() для сохранения и загрузки вашей модели в рабочее пространство:
save_model_hdf5(model, "my_model.h5")
model <- load_model_hdf5("my_model.h5")
Кроме того, вы также можете сохранять и загружать веса модели с помощью функций save_model_weights_hdf5() и load_model_weights_hdf5():
save_model_weights_hdf5("my_model_weights.h5")
model %>% load_model_weights_hdf5("my_model_weights.h5")
Наконец, важно знать, что вы также можете экспортировать конфигурацию модели в JSON или YAML. Здесь вам помогут функции model_to_json() и model_to_yaml(). Чтобы загрузить конфигурации обратно в рабочее пространство, вы можете просто использовать функции model_from_json() и model_from yaml():
json_string <- model_to_json(model)
model <- model_from_json(json_string)
yaml_string <- model_to_yaml(model)
model <- model_from_yaml(yaml_string)
Комментариев нет:
Отправить комментарий