(Обновлено 12, 2, 2022)
Введение
Эта статья о машинном обучении и для таких новичков, как я. Я всегда не уверен, как я решаю количество слоев и единиц каждого слоя, когда я строю модель. В этой статье я буду исследовать их влияние на примере набора данных по жилью в Калифорнии.
Все приведенные ниже коды находятся в моем git-репозитории. Вы можете выполнить каждый следующий эксперимент, клонировав и запустив блокнот.
github repository: comparison_of_dnn
Обратите внимание, что это не «руководство», это памятка от новичка для новичков. Если у вас возникли какие-либо замечания, предложения, вопросы и т.д. во время чтения этой статьи, пожалуйста, дайте мне знать в комментариях ниже.
Калифорнийский набор данных по жилью
Набор данных California housing предназначен для регрессии. Он содержит восемь признаков и одно целевое значение. Мы можем получить набор данных с помощью функции sklearn.datasets.fetch_california_housing()
. Восемь характеристик выглядят следующим образом.
- MedInc: медианный доход в блочной группе
- HouseAge: средний возраст дома в блочной группе
- AveRooms: среднее количество комнат на домохозяйство
- AveBedrms: среднее количество спален на домохозяйство
- Население: численность населения в блок-группе
- AveOccup: среднее число членов домохозяйства
- Широта: широта группы блоков
- Долгота: долгота группы блоков
Одно целевое значение выглядит следующим образом:
- MedHouseVal: медианная стоимость дома для районов Калифорнии, выраженная в сотнях тысяч долларов.
Как я уже сказал, это для регрессии, поэтому я построю модель, входами которой будут эти характеристики, а выходом — целевое значение.
Я не буду тщательно анализировать этот набор данных, а сделаю лишь немного, используя методы класса pandas.DataFrame
.
Давайте посмотрим информацию, чтобы проверить, есть ли пропущенные значения.
Ввод:
import sys
sys.path.append("./src")
import src.utils
# Load dataset
callifornia_df = src.utils.load_california_housing()
callifornia_df.info()
Выход:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 MedInc 20640 non-null float64
1 HouseAge 20640 non-null float64
2 AveRooms 20640 non-null float64
3 AveBedrms 20640 non-null float64
4 Population 20640 non-null float64
5 AveOccup 20640 non-null float64
6 Latitude 20640 non-null float64
7 Longitude 20640 non-null float64
8 MedHouseVal 20640 non-null float64
dtypes: float64(9)
memory usage: 1.4 MB
Пропущенных значений нет. Затем посмотрим статистику.
Вход:
callifornia_df.describe().drop(["count"])
Выход:
MedInc HouseAge AveRooms AveBedrms Population
mean 3.870671 28.639486 5.429000 1.096675 1425.476744
std 1.899822 12.585558 2.474173 0.473911 1132.462122
min 0.499900 1.000000 0.846154 0.333333 3.000000
25% 2.563400 18.000000 4.440716 1.006079 787.000000
50% 3.534800 29.000000 5.229129 1.048780 1166.000000
75% 4.743250 37.000000 6.052381 1.099526 1725.000000
max 15.000100 52.000000 141.909091 34.066667 35682.000000
AveOccup Latitude Longitude MedHouseVal
mean 3.070655 35.631861 -119.569704 2.068558
std 10.386050 2.135952 2.003532 1.153956
min 0.692308 32.540000 -124.350000 0.149990
25% 2.429741 33.930000 -121.800000 1.196000
50% 2.818116 34.260000 -118.490000 1.797000
75% 3.282261 37.710000 -118.010000 2.647250
max 1243.333333 41.950000 -114.310000 5.000010
Сравнение
Для простоты предположим следующие условия.
- В модели фиксированы все условия, кроме количества слоев и количества единиц каждого слоя.
- Никакой предварительной обработки данных не производится.
- Посевной материал фиксирован.
Итак, дальнейшее обсуждение ведется при этих условиях, но если вы хотите изменить эти условия или убрать эти условия, это будет сделано в ближайшее время. Большинство из них, все, что вам нужно сделать, это изменить config_california.yaml
. В нем есть следующие утверждения.
mlflow:
experiment_name: california
run_name: default
dataset:
eval_size: 0.25
test_size: 0.25
train_size: 0.75
shuffle: True
dnn:
n_layers: 3
n_units_list:
- 8
- 4
- 1
activation_function_list:
- relu
- relu
- linear
seed: 57
dnn_train:
epochs: 30
batch_size: 4
patience: 5
Вам нужно только изменить 57
в блоке seed на other integer или None
, если вы проводите эксперимент при другом фиксированном seed или без фиксированного seed, соответственно.
результат
Сводка потерь выглядит следующим образом.
#слои | потери при обучении | потеря при оценке | потеря теста |
---|---|---|---|
3 (маленькие #единицы) | 0.616 | 0.565 | 0.596 |
четыре | 0.54 | 0.506 | 0.53 |
пять | 0.543 | 1.126 | 1.2 |
шесть | 0.515 | 0.49 | 0.512 |
семь | 1.31 | 1.335 | 1.377 |
три (много единиц) | 0.537 | 0.515 | 0.555 |
Лучшей моделью является та, которая имеет шесть слоев в смысле тестовых потерь (на самом деле, в смысле всех потерь). Тестовые потери пяти и семи слоев близки, но результаты обучения совсем не близки. При обучении седьмой возникает проблема исчезающего градиента. Вероятно, это происходит из-за большой глубины.
Я построю график предсказанных значений и истинных значений цели. Это говорит нам о том, что четвертая модель также является лучшей в смысле каждого предсказания.
Модели с первой по пятую имеют разное количество блоков. Последняя модель, три слоя и количество единиц которой аналогичны четвертой модели, была построена для сравнения влияния количества слоев и количества единиц. В результате, четвертая модель оказалась лучше других, и это означает, что глубина слоев важнее количества единиц, по крайней мере, для калифорнийского набора данных. Очевидно, что разница между максимальным значением истинной цели и средним значением больше, чем разница между минимальным значением и средним значением в наборе данных Калифорнии. Вероятно, глубина слоев эффективно влияет на устойчивость к выбросам.
Далее, при сравнении первой модели и последней модели, выявляется влияние количества узлов. Очевидно, что количество узлов способствует лучшей подгонке.
Более подробную информацию см. в следующих разделах.
крошечный трехслойный (два скрытых слоя плюс один выходной слой)
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_3 (Dense) (None, 8) 72
dense_4 (Dense) (None, 4) 36
dense_5 (Dense) (None, 1) 5
=================================================================
Total params: 113
Trainable params: 113
Non-trainable params: 0
_________________________________________________________________
Итоговые потери следующие.
- потери при обучении: 0.616
- потери при оценке: 0.565
- потеря при тестировании: 0.596
Результаты прогнозирования выглядят следующим образом.
Зеленая линия представляет собой предсказанные целевые значения, а красная — истинные целевые значения.
Невидимая линия нижней границы есть, и некоторые предсказанные значения больше, чем максимальное истинное значение. Это, вероятно, означает, что модель недооценивает данные.
четыре слоя (три скрытых слоя плюс один выходной слой)
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_10 (Dense) (None, 16) 144
dense_11 (Dense) (None, 8) 136
dense_12 (Dense) (None, 4) 36
dense_13 (Dense) (None, 1) 5
=================================================================
Total params: 321
Trainable params: 321
Non-trainable params: 0
_________________________________________________________________
Итоговые потери выглядят следующим образом.
- потери при обучении: 0.54
- потери при оценке: 0.506
- потеря при тестировании: 0.53
Результаты прогнозирования выглядят следующим образом.
Зеленая линия представляет предсказанные целевые значения, а красная — истинные целевые значения. Обратите внимание, что для наглядности утоплены первые 500 значений.
Невидимая линия все еще присутствует. Количество предсказанных значений, которые превышают максимальное истинное значение, меньше, чем предсказанные значения из трехслойной модели, но все еще есть некоторые предсказанные значения, которые превышают максимальное истинное значение.
пять слоев (четыре скрытых слоя плюс один выходной слой)
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_19 (Dense) (None, 32) 288
dense_20 (Dense) (None, 16) 528
dense_21 (Dense) (None, 8) 136
dense_22 (Dense) (None, 4) 36
dense_23 (Dense) (None, 1) 5
=================================================================
Total params: 993
Trainable params: 993
Non-trainable params: 0
_________________________________________________________________
Итоговые потери следующие.
- потери при обучении: 0.543
- потери при оценке: 1.126
- тестовый убыток: 1.2
Результаты прогнозирования выглядят следующим образом.
Зеленая линия представляет собой предсказанные целевые значения, а красная — истинные целевые значения.
Невидимая линия все еще присутствует. Количество высоких предсказанных значений меньше, чем раньше. В то же время, некоторые из предсказанных значений меньше, чем раньше. Это может быть чрезмерной подгонкой.
шесть слоев (пять скрытых слоев плюс один выходной слой)
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_30 (Dense) (None, 64) 576
dense_31 (Dense) (None, 32) 2080
dense_32 (Dense) (None, 16) 528
dense_33 (Dense) (None, 8) 136
dense_34 (Dense) (None, 4) 36
dense_35 (Dense) (None, 1) 5
=================================================================
Total params: 3,361
Trainable params: 3,361
Non-trainable params: 0
_________________________________________________________________
Итоговые потери следующие.
- потери при обучении: 0.515
- потери при оценке: 0.49
- тестовый убыток: 0.512
Результаты прогнозирования выглядят следующим образом.
Зеленая линия представляет собой предсказанные значения цели, а красная — истинные значения цели.
Невидимая горизонтальная линия немного уменьшилась. Линия все еще присутствует, но горизонтальность, конечно, меньше, чем раньше. Также количество высоких предсказанных значений меньше, чем раньше.
семь слоев (шесть скрытых слоев плюс один выходной слой)
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_43 (Dense) (None, 128) 1152
dense_44 (Dense) (None, 64) 8256
dense_45 (Dense) (None, 32) 2080
dense_46 (Dense) (None, 16) 528
dense_47 (Dense) (None, 8) 136
dense_48 (Dense) (None, 4) 36
dense_49 (Dense) (None, 1) 5
=================================================================
Total params: 12,193
Trainable params: 12,193
Non-trainable params: 0
_________________________________________________________________
Итоговые потери выглядят следующим образом.
- потери при обучении: 1.31
- оценочный проигрыш: 1.335
- тестовый убыток: 1.377
Результаты прогнозирования выглядят следующим образом.
Зеленая линия представляет собой предсказанные целевые значения, а красная — истинные целевые значения.
Модель выдала константу для всех входов. Вероятно, произошло исчезновение градиента. На самом деле, потери при обучении скоро сошлись:
три слоя с почти 3300 единицами (два скрытых слоя плюс один выходной слой).
Эта структура выглядит следующим образом.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_67 (Dense) (None, 72) 648
dense_68 (Dense) (None, 36) 2628
dense_69 (Dense) (None, 1) 37
=================================================================
Total params: 3,313
Trainable params: 3,313
Non-trainable params: 0
_________________________________________________________________
Итоговые потери выглядят следующим образом.
- потери при обучении: 0.537
- потери при оценке: 0.515
- тестовый убыток: 0.555
Результаты прогнозирования следующие.
Как и в шестислойной модели, горизонтальность невидимой линии меньше, чем у других. В то же время, количество высоких предсказанных значений явно больше, чем в шестислойной модели.
Заключение
Я исследовал влияние количества слоев и узлов на калифорнийском наборе данных. В результате я обнаружил, что большее количество слоев и большее количество узлов эффективно для лучшего соответствия, но огромное количество слоев вызывает проблему исчезающего градиента.
Это здорово — писать коды и проводить эксперименты самостоятельно, но, к сожалению, я все еще не уверен, как я определяю числа. Я буду снова исследовать эффект с другими наборами данных.
И снова, я буду очень признателен, если вы дадите мне комментарий, предложение, вопрос и т.д.