В этом примере показано, как создать, обучайтесь и сравните три нейронных сети для глубокого обучения для предсказания вероятности значения по умолчанию кредита.
Набор данных панели потребительских кредитов позволяет вам идентифицировать и предсказать шаблоны уровня по умолчанию. Можно обучить нейронную сеть с помощью данных о панели, чтобы предсказать уровень по умолчанию с года на уровне риска и книгах.
Этот пример требует Deep Learning Toolbox™ и Risk Management Toolbox™.
В этом примере вы создаете и обучаете три модели предсказанию значения по умолчанию кредита:
Сеть логистической регрессии (также известный как одноуровневый perceptron)
Многоуровневый perceptron (MLP)
Остаточная сеть (ResNet)
Можно описать каждую из этих моделей как нейронная сеть различной сложности и глубины.
Загрузите розничный набор данных панели кредита. Эти данные включают следующие переменные:
ID
— Идентификатор ссуды.
ScoreGroup
— Кредитный рейтинг в начале ссуды, дискретизированной в три группы: High Risk
, Medium Risk
, и Low Risk
.
YOB
— Годы на книгах.
Default
— Индикатор по умолчанию. Значение 1
для Default
средние значения, что ссуда приняла значение по умолчанию в соответствующий календарный год.
Year
— Календарный год.
filename = fullfile(toolboxdir('risk'),'riskdata','RetailCreditPanelData.mat'); tbl = load(filename).data;
Чтобы обучить нейронную сеть для глубокого обучения, необходимо сначала закодировать категориальный ScoreGroup
переменная к одногорячим закодированным векторам.
Просмотрите порядок ScoreGroup
категории.
categories(tbl.ScoreGroup)'
ans = 1×3 cell
{'High Risk'} {'Medium Risk'} {'Low Risk'}
Преобразуйте категориальный ScoreGroup
переменная к одногорячим закодированным векторам с помощью onehotencode
функция.
riskGroup = onehotencode(tbl.ScoreGroup,2);
Добавьте одногорячие векторы в таблицу.
tbl.HighRisk = riskGroup(:,1); tbl.MediumRisk = riskGroup(:,2); tbl.LowRisk = riskGroup(:,3);
Удалите исходный ScoreGroup
переменная из таблицы с помощью removevars
.
tbl = removevars(tbl,{'ScoreGroup'});
Поскольку вы хотите предсказать Default
переменный ответ, перемещение Default
переменная в конец таблицы.
tbl = movevars(tbl,'Default','After','LowRisk');
Просмотрите первые несколько строк таблицы. Заметьте, что ScoreGroup
переменная была разделена в несколько столбцов с категориальными значениями как имена переменных.
head(tbl)
ans=8×7 table
ID YOB Year HighRisk MediumRisk LowRisk Default
__ ___ ____ ________ __________ _______ _______
1 1 1997 0 0 1 0
1 2 1998 0 0 1 0
1 3 1999 0 0 1 0
1 4 2000 0 0 1 0
1 5 2001 0 0 1 0
1 6 2002 0 0 1 0
1 7 2003 0 0 1 0
1 8 2004 0 0 1 0
Разделите набор данных в обучение, валидацию, и протестируйте разделы с помощью уникальных идентификационных номеров ссуды. Отложите 60% данных для обучения, 20% для валидации и 20% для тестирования.
Найдите уникальные идентификаторы ссуды.
idx = unique(tbl.ID); numObservations = length(idx);
Определите количество наблюдений для каждого раздела.
numObservationsTrain = floor(0.6*numObservations); numObservationsValidation = floor(0.2*numObservations); numObservationsTest = numObservations - numObservationsTrain - numObservationsValidation;
Создайте массив случайных индексов, соответствующих наблюдениям, и разделите его с помощью размеров раздела.
rng('default')
idxShuffle = idx(randperm(numObservations));
idxTrain = idxShuffle(1:numObservationsTrain);
idxValidation = idxShuffle(numObservationsTrain+1:numObservationsTrain+numObservationsValidation);
idxTest = idxShuffle(numObservationsTrain+numObservationsValidation+1:end);
Найдите записи таблицы, соответствующие разделам набора данных.
idxTrainTbl = ismember(tbl.ID,idxTrain); idxValidationTbl = ismember(tbl.ID,idxValidation); idxTestTbl = ismember(tbl.ID,idxTest);
Сохраните представляющие интерес переменные для задачи (YOB
, HighRisk
, MediumRisk
, LowRisk
, и Default
) и удалите все другие переменные из таблицы.
tbl = removevars(tbl,{'ID','Year'}); head(tbl)
ans=8×5 table
YOB HighRisk MediumRisk LowRisk Default
___ ________ __________ _______ _______
1 0 0 1 0
2 0 0 1 0
3 0 0 1 0
4 0 0 1 0
5 0 0 1 0
6 0 0 1 0
7 0 0 1 0
8 0 0 1 0
Разделите таблицу данных в обучение, валидацию и разделы тестирования с помощью индексов.
tblTrain = tbl(idxTrainTbl,:); tblValidation = tbl(idxValidationTbl,:); tblTest = tbl(idxTestTbl,:);
Можно использовать различные архитектуры глубокого обучения для задачи предсказания вероятностей значения по умолчанию кредита. Меньшие сети быстры, чтобы обучаться, но более глубокие сети могут узнать больше абстрактные функции. Выбор архитектуры нейронной сети требует балансирующегося времени вычисления против точности. В этом примере вы задаете три сетевых архитектуры с различными уровнями сложности.
Первая сеть является простой нейронной сетью, содержащей четыре слоя.
Начните с входного слоя функции, который передает табличные данные (данные о панели кредита) к сети. В этом примере существует четыре входных функции: YOB
, HighRisk
, MediumRisk
, и LowRisk
. Сконфигурируйте входной слой, чтобы нормировать данные с помощью нормализации z-счета. Нормализация данных важна для задач, где шкала и область значений входных переменных очень отличаются.
Затем используйте полносвязный слой с одним выходом, сопровождаемым сигмоидальным слоем. Для последнего слоя используйте пользовательский бинарный слой потери перекрестной энтропии. Этот слой присоединен к этому примеру как к вспомогательному файлу.
logisticLayers = [ featureInputLayer(4,'Normalization','zscore') fullyConnectedLayer(1) sigmoidLayer BinaryCrossEntropyLossLayer('output')];
Эта сеть называется одноуровневым perceptron. Можно визуализировать сеть с помощью Deep Network Designer или analyzeNetwork
функция.
deepNetworkDesigner(logisticLayers)
Можно легко показать, что одноуровневая perceptron нейронная сеть эквивалентна логистической регрессии. Пусть будьте вектором 1 на 4, содержащим функции наблюдения . С входом , выход полносвязного слоя
.
Выход полносвязного слоя обеспечивает вход для сигмоидального слоя. Сигмоидальный слой затем выходные параметры
.
Выход сигмоидального слоя эквивалентен модели логистической регрессии. Последний слой нейронной сети является бинарным слоем потери перекрестной энтропии. Минимизация бинарной потери перекрестной энтропии эквивалентна максимизации вероятности в модели логистической регрессии.
Следующая сеть имеет подобную архитектуру к модели логистической регрессии, но имеет дополнительный полносвязный слой с выходным размером 100, сопровождаемый ReLU нелинейная функция активации. Этот тип сети называется многоуровневым perceptron должным к сложению другого скрытого слоя и нелинейной функции активации. Принимая во внимание, что одноуровневый perceptron может изучить только линейные функции, многоуровневый perceptron может изучить комплексные, нелинейные отношения между входными и выходными данными.
mlpLayers = [ featureInputLayer(4,'Normalization','zscore') fullyConnectedLayer(100) reluLayer fullyConnectedLayer(1) sigmoidLayer BinaryCrossEntropyLossLayer('output')]; deepNetworkDesigner(mlpLayers)
Для итоговой сети создайте остаточную сеть (ResNet) [1] от нескольких стеков активаций ReLU и полносвязных слоев. Первоначально разработанный для классификации изображений, ResNets оказались успешными через многие области. Поскольку ResNet имеет намного больше параметров, чем многоуровневый perceptrons или логистические сети, они занимают больше времени, чтобы обучаться.
residualLayers = [ featureInputLayer(4,'Normalization','zscore','Name','input') fullyConnectedLayer(16,'Name','fc1') batchNormalizationLayer('Name','bn1') reluLayer('Name','relu1') fullyConnectedLayer(32,'Name','resblock1-fc1') batchNormalizationLayer('Name','resblock1-bn1') reluLayer('Name','resblock1-relu1') fullyConnectedLayer(32,'Name','resblock1-fc2') additionLayer(2,'Name','resblock1-add') batchNormalizationLayer('Name','resblock1-bn2') reluLayer('Name','resblock1-relu2') fullyConnectedLayer(64,'Name','resblock2-fc1') batchNormalizationLayer('Name','resblock2-bn1') reluLayer('Name','resblock2-relu1') fullyConnectedLayer(64,'Name','resblock2-fc2') additionLayer(2,'Name','resblock2-add') batchNormalizationLayer('Name','resblock2-bn2') reluLayer('Name','resblock2-relu2') fullyConnectedLayer(1,'Name','fc2') sigmoidLayer('Name','sigmoid') BinaryCrossEntropyLossLayer('output')]; residualLayers = layerGraph(residualLayers); residualLayers = addLayers(residualLayers,fullyConnectedLayer(32,'Name','resblock1-fc-shortcut')); residualLayers = addLayers(residualLayers,fullyConnectedLayer(64,'Name','resblock2-fc-shortcut')); residualLayers = connectLayers(residualLayers,'relu1','resblock1-fc-shortcut'); residualLayers = connectLayers(residualLayers,'resblock1-fc-shortcut','resblock1-add/in2'); residualLayers = connectLayers(residualLayers,'resblock1-relu2','resblock2-fc-shortcut'); residualLayers = connectLayers(residualLayers,'resblock2-fc-shortcut','resblock2-add/in2'); deepNetworkDesigner(residualLayers)
Глубина сети является важной концепцией в глубоком обучении и задана как наибольшее число сверточных последовательных или полносвязные слоя (представленный желтыми блоками в следующей схеме) на пути от входного слоя до выходного слоя. Чем глубже сеть, тем более комплексные функции она может изучить. В этом примере логистическая сеть имеет глубину 1, многоуровневый perceptron имеет глубину 2, и остаточная сеть имеет глубину 6.
Задайте опции обучения.
Обучите использование оптимизатора Адама.
Установите начальную скорость обучения на 0,001.
Установите мини-пакетный размер на 512.
Включите график процесса обучения и выключите командное окно выход.
Переставьте данные в начале каждой эпохи.
Контролируйте сетевую точность во время обучения путем определения данных о валидации и использования его, чтобы проверить сеть каждые 1 000 итераций.
options = trainingOptions('adam', ... 'InitialLearnRate',0.001, ... 'MiniBatchSize',512, ... 'Plots','training-progress', ... 'Verbose',false, ... 'Shuffle','every-epoch', ... 'ValidationData',tblValidation, ... 'ValidationFrequency',1000);
Среда потерь сети логистической регрессии выпукла, поэтому, это не должно обучаться для как много эпох. Для логистической регрессии и многоуровневых perceptron моделей, обучайтесь в течение 15 эпох. Для более комплексной остаточной сети обучайтесь в течение 50 эпох.
logisticOptions = options; logisticOptions.MaxEpochs = 15; mlpOptions = options; mlpOptions.MaxEpochs = 15; residualOptions = options; residualOptions.MaxEpochs = 50;
Эти три сети имеют различные архитектуры, таким образом, они требуют, чтобы различные наборы опций обучения достигли оптимальной эффективности. Можно выполнить оптимизацию программно или в интерактивном режиме использование Experiment Manager. Для примера, показывающего, как выполнить развертку гиперпараметра опций обучения, смотрите, Создают Эксперимент Глубокого обучения для Классификации.
Обучите сети с помощью заданных архитектур, обучающие данные и опции обучения. По умолчанию, trainNetwork
использует графический процессор, если вы доступны; в противном случае это использует центральный процессор. Обучение на графическом процессоре требует Parallel Computing Toolbox™ и поддерживаемого устройства графического процессора. Для получения информации о поддерживаемых устройствах смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Можно также задать среду выполнения при помощи ExecutionEnvironment
аргумент значения имени trainingOptions
.
Чтобы постараться не ожидать обучения, загрузите предварительно обученные сети путем установки doTrain
отметьте к false
. Обучать сети с помощью trainNetwork
, установите doTrain
отметьте к true
.
Учебные времена с помощью NVIDIA® GeForce® RTX 2080 Ti:
Логистическая сеть — Приблизительно 4 минуты
Многоуровневый perceptron — Приблизительно 5 минут
Остаточная сеть — Приблизительно 35 минут
doTrain = false; if doTrain logisticNet = trainNetwork(tblTrain,'Default',logisticLayers,logisticOptions); mlpNet = trainNetwork(tblTrain,'Default',mlpLayers,mlpOptions); residualNet = trainNetwork(tblTrain,'Default',residualLayers,residualOptions); else load logisticTrainedNetwork load mlpTrainedNetwork load residualTrainedNetwork end
Предскажите вероятность по умолчанию тестовых данных с помощью обучившего нейронные сети.
tblTest.logisticPred = predict(logisticNet,tblTest(:,1:end-1)); tblTest.mlpPred = predict(mlpNet,tblTest(:,1:end-1)); tblTest.residualPred = predict(residualNet,tblTest(:,1:end-1));
Чтобы оценить эффективность сети, используйте groupsummary
функционируйте, чтобы сгруппировать истинные уровни по умолчанию и соответствующие предсказания к годам на книгах (представленный YOB
переменная), и вычисляют среднее значение.
summaryYOB = groupsummary(tblTest,'YOB','mean',{'Default','logisticPred','mlpPred','residualPred'}); head(summaryYOB)
ans=8×6 table
YOB GroupCount mean_Default mean_logisticPred mean_mlpPred mean_residualPred
___ __________ ____________ _________________ ____________ _________________
1 19364 0.017352 0.017471 0.018056 0.017663
2 18917 0.012158 0.014209 0.015486 0.014192
3 18526 0.011875 0.011538 0.013154 0.011409
4 18232 0.011683 0.0093902 0.011151 0.010311
5 17925 0.0082008 0.007626 0.0089826 0.0093438
6 17727 0.0066565 0.0062047 0.0062967 0.0073401
7 12294 0.0030909 0.0050643 0.0042998 0.0047071
8 6361 0.0017293 0.0041463 0.0029052 0.0025272
Постройте истинный средний уровень по умолчанию против средних предсказаний к годам на книгах.
networks = ["Logistic Regression Network","Multilayer Percerptron Network","Residual Network"]; figure tiledlayout('flow','TileSpacing','compact') for i = 1:3 nexttile scatter(summaryYOB.YOB,summaryYOB.mean_Default*100,'*'); hold on plot(summaryYOB.YOB,summaryYOB{:,i+3}*100); hold off title(networks(i)) xlabel('Years on Books') ylabel('Default Rate (%)') legend('Observed','Predicted') end
Все три сети показывают ясную тенденцию к понижению с уровнями по умолчанию, понижающимися как номер лет на книжных увеличениях. Годы три и четыре являются исключением к тенденции к понижению. В целом, эти три модели предсказывают уровни по умолчанию хорошо, и даже более простая модель логистической регрессии предсказывает общую тенденцию. Остаточная сеть получает более комплексное, нелинейное отношение по сравнению с логистической моделью, которая может соответствовать только линейному соотношению.
Используйте группу кредитного рейтинга в качестве сгруппированной переменной, чтобы вычислить наблюдаемый, и предсказал уровень по умолчанию для каждой группы счета.
Декодируйте ScoreGroup
назад в категориальные группы счета.
ScoreGroup = onehotdecode(tblTest{:,2:4},{'HighRisk','MediumRisk','LowRisk'},2); tblTest.ScoreGroup = ScoreGroup; tblTest = removevars(tblTest,{'HighRisk','MediumRisk','LowRisk'}); riskGroups = categories(tblTest.ScoreGroup);
Используйте groupsummary
функционируйте, чтобы сгруппировать истинный уровень по умолчанию и предсказания YOB
и ScoreGroup
, и возвратите среднее значение для каждой группы.
numYOB = height(summaryYOB); numRiskGroups = height(riskGroups); summaryYOBScore = groupsummary(tblTest,{'ScoreGroup','YOB'},'mean',{'Default','logisticPred','mlpPred','residualPred'}); head(summaryYOBScore)
ans=8×7 table
ScoreGroup YOB GroupCount mean_Default mean_logisticPred mean_mlpPred mean_residualPred
__________ ___ __________ ____________ _________________ ____________ _________________
HighRisk 1 6424 0.029577 0.028404 0.031563 0.02973
HighRisk 2 6180 0.020065 0.02325 0.026649 0.023655
HighRisk 3 5949 0.019163 0.019013 0.022484 0.018724
HighRisk 4 5806 0.020668 0.015535 0.018957 0.017207
HighRisk 5 5634 0.01349 0.012686 0.01577 0.015374
HighRisk 6 5531 0.013379 0.010354 0.010799 0.01215
HighRisk 7 3862 0.0051787 0.0084466 0.0071398 0.0083738
HighRisk 8 2027 0.0034534 0.0068881 0.0047145 0.0040559
Постройте истинный средний уровень по умолчанию против предсказанного уровня к годам на книгах и рискните группой.
figure t = tiledlayout('flow','TileSpacing','compact'); color = lines(3); YOB = summaryYOBScore.YOB; default = summaryYOBScore.mean_Default*100; group = summaryYOBScore.ScoreGroup; for i = 1:3 pred = summaryYOBScore{:,i+4}*100; meanScore = reshape(pred,numYOB,numRiskGroups); nexttile hs = gscatter(YOB,default,group,color,'*',6,false); hold on colororder(color) plot(meanScore) hold off title(networks(i)) xlabel('Years on Books') ylabel('Default Rate (%)') grid on end labels = ["True: " + riskGroups; "Pred: " + riskGroups]; lgd = legend(labels); lgd.Layout.Tile = 4;
График показывает, что все группы счета ведут себя так же, в то время как время прогрессирует с общей тенденцией к понижению. Через группу высокого риска год четыре не следует за тенденцией к понижению. В средней группе риска годы три и четыре кажутся плоскими. Наконец, в группе с низким риском, год три показывает увеличение. Эти неправильные тренды затрудняют, чтобы различить с более простой моделью логистической регрессии.
Для примера, показывающего, как использовать локально поддающиеся толкованию объяснения модели агностические (LIME) и значения Шепли interpretability методы, чтобы изучить предсказания остаточной сети для предсказания значения по умолчанию кредита, смотрите, Интерпретируют и Нейронные сети для глубокого обучения Стресс-теста для Вероятности Значения по умолчанию (Risk Management Toolbox).
[1] Он, Kaiming, Сянюй Чжан, Шаоцин Жэнь и Цзянь Сунь. "Глубокая невязка, учащаяся для распознавания изображений". В Продолжениях конференции по IEEE по компьютерному зрению и распознаванию образов, стр 770-778. 2016.
trainNetwork
| trainingOptions
| fullyConnectedLayer
| Deep Network Designer | featureInputLayer