dlnetwork

Нейронная сеть для глубокого обучения для пользовательских учебных циклов

Описание

dlnetwork объект включает поддержку пользовательских учебных циклов с помощью автоматического дифференцирования.

Совет

Для большинства задач глубокого обучения можно использовать предварительно обученную сеть и адаптировать ее к собственным данным. Для примера, показывающего, как использовать передачу обучения, чтобы переобучить сверточную нейронную сеть, чтобы классифицировать новый набор изображений, смотрите, Обучают Нейронную сеть для глубокого обучения Классифицировать Новые Изображения. В качестве альтернативы можно создать и обучить нейронные сети с нуля с помощью layerGraph объекты с trainNetwork и trainingOptions функции.

Если trainingOptions функция не обеспечивает опции обучения, в которых вы нуждаетесь для своей задачи, затем можно создать пользовательский учебный цикл с помощью автоматического дифференцирования. Чтобы узнать больше, смотрите, Задают Нейронную сеть для глубокого обучения для Пользовательских Учебных Циклов.

Создание

Описание

пример

dlnet = dlnetwork(layers) преобразует слоя сети, заданные в layers к инициализированному dlnetwork объект, представляющий глубокую нейронную сеть для использования с пользовательскими учебными циклами. layers может быть LayerGraph возразите или Layer массив. layers должен содержать входной слой.

Инициализированный dlnetwork объект готов к обучению. Настраиваемые параметры и значения состояния dlnet инициализируются для обучения с начальными значениями на основе входного размера, заданного сетевым входным слоем.

пример

dlnet = dlnetwork(layers,dlX1,...,dlXn) создает инициализированный dlnetwork объект с помощью примера вводит dlX1,...,dlXn. Настраиваемые параметры и значения состояния dlnet инициализируются начальными значениями на основе входного размера и формата, заданного входными параметрами в качестве примера. Используйте этот синтаксис, чтобы создать инициализированный dlnetwork с входными параметрами, которые не соединяются с входным слоем.

пример

dlnet = dlnetwork(layers,'Initialize',tf) задает, возвратить ли инициализированный или деинициализировал dlnetwork. Используйте этот синтаксис, чтобы создать неинициализированную сеть.

Неинициализированная сеть сбросила, пустые значения для настраиваемых параметров и параметров состояния и не готова к обучению. Необходимо инициализировать неинициализированный dlnetwork прежде чем можно будет использовать его. Создайте неинициализированную сеть, когда это необходимо, чтобы задержать инициализацию к более поздней точке. Можно использовать неинициализированный dlnetwork объекты создать комплексные сети с помощью промежуточных базовых блоков, которые вы затем соединяете вместе, например, с помощью рабочих процессов Состава Нейронной сети для глубокого обучения. Можно инициализировать неинициализированный dlnetwork использование initialize функция.

Входные параметры

развернуть все

Слоя сети в виде LayerGraph возразите или как Layer массив.

Если layers Layer массив, затем dlnetwork функционируйте соединяет слои последовательно.

Слоя сети не должны содержать выходные слои. При обучении сети вычислите потерю отдельно.

Для списка слоев, поддержанных dlnetwork, смотрите Поддерживаемые Слои.

Сеть Example вводит в виде отформатированного dlarray объекты. Программное обеспечение распространяет входные параметры в качестве примера через сеть, чтобы определить соответствующие размеры и форматы настраиваемых параметров и параметры состояния dlnetwork.

Входными параметрами в качестве примера должен быть отформатированный dlarray объекты. Когда layers Layer массив, обеспечьте входные параметры в качестве примера в том же порядке, что слои, которые требуют входных параметров, появляются в Layer массив. Когда layers LayerGraph возразите, обеспечьте входные параметры в качестве примера в том же порядке как слои, которые требуют, чтобы входные параметры появились в Layers свойство LayerGraph.

Входные параметры в качестве примера не поддерживаются когда tf является ложным.

Отметьте, чтобы возвратить инициализированный dlnetworkВ виде числового или логического 1 TRUE) или 0 ложь).

Если tf true или 1, настраиваемые параметры и параметры состояния dlnet инициализируются начальными значениями для обучения, согласно сетевому входному слою или обеспеченным входным параметрам в качестве примера.

Если tf является ложным, learnable и параметры состояния не инициализируются. Прежде чем вы будете использовать неинициализированную сеть, необходимо сначала инициализировать ее с помощью initialize функция. Входные параметры в качестве примера не поддерживаются когда tf является ложным.

Свойства

развернуть все

Слоя сети в виде Layer массив.

Связи слоя в виде таблицы с двумя столбцами.

Каждая строка таблицы представляет связь в графике слоев. Первый столбец, Source, задает источник каждой связи. Второй столбец, Destination, задает место назначения каждой связи. Источники связи и места назначения являются или именами слоя или имеют форму 'layerName/IOName', где 'IOName' имя ввода или вывода слоя.

Типы данных: table

Сетевые настраиваемые параметры в виде таблицы с тремя столбцами:

  • Layer – Имя слоя в виде строкового скаляра.

  • Parameter – Название параметра в виде строкового скаляра.

  • Value – Значение параметра в виде dlarray объект.

Сетевые настраиваемые параметры содержат функции, изученные сетью. Например, веса свертки и полносвязных слоев.

Типы данных: table

Сетевое состояние в виде таблицы.

Сетевое состояние является таблицей с тремя столбцами:

  • Layer – Имя слоя в виде строкового скаляра.

  • Parameter – Название параметра в виде строкового скаляра.

  • Value – Значение параметра в виде dlarray объект.

Сетевое состояние содержит информацию, которую помнит сеть между итерациями. Например, состояние LSTM и слоев нормализации партии.

Во время обучения или вывода, можно обновить сетевое состояние с помощью выхода forward и predict функции.

Типы данных: table

Сетевой входной слой называет в виде массива ячеек из символьных векторов.

Типы данных: cell

Сетевой выходной слой называет в виде массива ячеек из символьных векторов. Это свойство включает все слои с разъединенными выходными параметрами. Если слой имеет несколько выходных параметров, то разъединенные выходные параметры заданы как 'layerName/outputName'.

Типы данных: cell

Это свойство доступно только для чтения.

Отметьте для инициализированной сети в виде 0 или 1.

Если Initialized 0, сеть не инициализируется. Необходимо инициализировать сеть, прежде чем можно будет использовать ее. Инициализируйте сеть с помощью initialize функция.

Если Initialized 1, сеть инициализируется и может использоваться для обучения и вывода. Если вы изменяете значения настраиваемых параметров — например, во время обучения — значение Initialized остается 1.

Типы данных: логический

Функции объекта

forwardВычислите нейронную сеть для глубокого обучения выход для обучения
predictВычислите нейронную сеть для глубокого обучения выход для вывода
initializeИнициализируйте настраиваемые параметры и параметры состояния dlnetwork
layerGraphГрафик слоев сети для глубокого обучения
setL2FactorУстановитесь коэффициент регуляризации L2 настраиваемого параметра слоя
setLearnRateFactorУстановите изучают фактор уровня настраиваемого параметра слоя
getLearnRateFactorДоберитесь изучают фактор уровня настраиваемого параметра слоя
getL2FactorПолучите фактор регуляризации L2 настраиваемого параметра слоя

Примеры

свернуть все

Чтобы реализовать пользовательский учебный цикл для вашей сети, сначала преобразуйте его в dlnetwork объект. Не включайте выходные слои в dlnetwork объект. Вместо этого необходимо задать функцию потерь в пользовательском учебном цикле.

Загрузите предварительно обученную модель GoogLeNet с помощью googlenet функция. Эта функция требует Модели Deep Learning Toolbox™ для пакета Сетевой поддержки GoogLeNet. Если этот пакет поддержки не установлен, то функция обеспечивает ссылку на загрузку.

net = googlenet;

Преобразуйте сеть в график слоев и удалите слои, используемые для классификации с помощью removeLayers.

lgraph = layerGraph(net);
lgraph = removeLayers(lgraph,["prob" "output"]);

Преобразуйте сеть в dlnetwork объект.

dlnet = dlnetwork(lgraph)
dlnet = 
  dlnetwork with properties:

         Layers: [142x1 nnet.cnn.layer.Layer]
    Connections: [168x2 table]
     Learnables: [116x3 table]
          State: [0x3 table]
     InputNames: {'data'}
    OutputNames: {'loss3-classifier'}
    Initialized: 1

Используйте входные параметры в качестве примера, чтобы создать мультивход dlnetwork это готово к обучению. Программное обеспечение распространяет входные параметры в качестве примера через сеть, чтобы определить соответствующие размеры и форматы настраиваемых параметров и параметры состояния dlnetwork.

Определить сетевую архитектуру. Создайте сеть с двумя ветвями. Сеть берет два входных параметров с одним входом на ветвь. Соедините ветви с помощью слоя сложения.

numFilters = 24;

layersBranch1 = [
    convolution2dLayer(3,6*numFilters,'Padding','same','Stride',2,'Name','conv1Branch1')
    groupNormalizationLayer('all-channels','Name','gn1Branch1')
    reluLayer('Name','relu1Branch1')
    convolution2dLayer(3,numFilters,'Padding','same','Name','conv2Branch1')
    groupNormalizationLayer('channel-wise','Name','gn2Branch1')
    additionLayer(2,'Name','add')
    reluLayer('Name','reluCombined')
    fullyConnectedLayer(10,'Name','fc')
    softmaxLayer('Name','sm')];

layersBranch2 = [
    convolution2dLayer(1,numFilters,'Name','convBranch2')
    groupNormalizationLayer('all-channels','Name','gnBranch2')];

lgraph = layerGraph(layersBranch1);
lgraph = addLayers(lgraph,layersBranch2);
lgraph = connectLayers(lgraph,'gnBranch2','add/in2');  

Создайте формат входных параметров сети примера одного размера как типичные сетевые входные параметры. Для обоих входных параметров используйте пакетный размер 32. Используйте вход размера 64 64 с тремя каналами для входа к слою convBranch1. Используйте вход размера 64 64 с 18 каналами для входа для входа к слою convBranch2.

dlX1 = dlarray(rand([64 64 3 32]),"SSCB");
dlX2 = dlarray(rand([32 32 18 32]),"SSCB");

Создайте dlnetwork. Обеспечьте входные параметры в том же порядке, что несвязанные слои появляются в Layers свойство lgraph.

dlnet = dlnetwork(lgraph,dlX1,dlX2);

Проверяйте, что сеть инициализируется и готова к обучению.

dlnet.Initialized
ans = 
   1

В этом примере показано, как обучить сеть, которая классифицирует рукописные цифры с пользовательским расписанием скорости обучения.

Если trainingOptions не предоставляет возможности, в которых вы нуждаетесь (например, пользовательское расписание скорости обучения), затем можно задать собственный учебный цикл с помощью автоматического дифференцирования.

Этот пример обучает сеть, чтобы классифицировать рукописные цифры с основанным на времени расписанием скорости обучения затухания: для каждой итерации решатель использует скорость обучения, данную ρt=ρ01+kt, где t является номером итерации, ρ0 начальная скорость обучения, и k является затуханием.

Загрузите обучающие данные

Загрузите данные о цифрах как datastore изображений с помощью imageDatastore функционируйте и задайте папку, содержащую данные изображения.

dataFolder = fullfile(toolboxdir('nnet'),'nndemos','nndatasets','DigitDataset');
imds = imageDatastore(dataFolder, ...
    'IncludeSubfolders',true, ....
    'LabelSource','foldernames');

Разделите данные в наборы обучения и валидации. Отложите 10% данных для валидации с помощью splitEachLabel функция.

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9,'randomize');

Сеть, используемая в этом примере, требует входных изображений размера 28 28 1. Чтобы автоматически изменить размер учебных изображений, используйте увеличенный datastore изображений. Задайте дополнительные операции увеличения, чтобы выполнить на учебных изображениях: случайным образом переведите изображения до 5 пикселей в горизонтальных и вертикальных осях. Увеличение данных помогает препятствовать тому, чтобы сеть сверхсоответствовала и запомнила точные детали учебных изображений.

inputSize = [28 28 1];
pixelRange = [-5 5];
imageAugmenter = imageDataAugmenter( ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,'DataAugmentation',imageAugmenter);

Чтобы автоматически изменить размер изображений валидации, не выполняя дальнейшее увеличение данных, используйте увеличенный datastore изображений, не задавая дополнительных операций предварительной обработки.

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

Определите количество классов в обучающих данных.

classes = categories(imdsTrain.Labels);
numClasses = numel(classes);

Сеть Define

Задайте сеть для классификации изображений.

layers = [
    imageInputLayer(inputSize,'Normalization','none','Name','input')
    convolution2dLayer(5,20,'Name','conv1')
    batchNormalizationLayer('Name','bn1')
    reluLayer('Name','relu1')
    convolution2dLayer(3,20,'Padding','same','Name','conv2')
    batchNormalizationLayer('Name','bn2')
    reluLayer('Name','relu2')
    convolution2dLayer(3,20,'Padding','same','Name','conv3')
    batchNormalizationLayer('Name','bn3')
    reluLayer('Name','relu3')
    fullyConnectedLayer(numClasses,'Name','fc')
    softmaxLayer('Name','softmax')];
lgraph = layerGraph(layers);

Создайте dlnetwork объект от графика слоев.

dlnet = dlnetwork(lgraph)
dlnet = 
  dlnetwork with properties:

         Layers: [12×1 nnet.cnn.layer.Layer]
    Connections: [11×2 table]
     Learnables: [14×3 table]
          State: [6×3 table]
     InputNames: {'input'}
    OutputNames: {'softmax'}

Функция градиентов модели Define

Создайте функциональный modelGradients, перечисленный в конце примера, который берет dlnetwork объект, мини-пакет входных данных с соответствующими метками и возвращают градиенты потери относительно настраиваемых параметров в сети и соответствующей потери.

Задайте опции обучения

Обучайтесь в течение десяти эпох с мини-пакетным размером 128.

numEpochs = 10;
miniBatchSize = 128;

Задайте опции для оптимизации SGDM. Укажите, что начальная буква изучает уровень 0,01 с затуханием 0,01, и импульс 0.9.

initialLearnRate = 0.01;
decay = 0.01;
momentum = 0.9;

Обучите модель

Создайте minibatchqueue возразите, что процессы и управляют мини-пакетами изображений во время обучения. Для каждого мини-пакета:

  • Используйте пользовательский мини-пакет, предварительно обрабатывающий функциональный preprocessMiniBatch (заданный в конце этого примера), чтобы преобразовать метки в одногорячие закодированные переменные.

  • Формат данные изображения с размерностью маркирует 'SSCB' (пространственный, пространственный, канал, пакет). По умолчанию, minibatchqueue объект преобразует данные в dlarray объекты с базовым типом single. Не добавляйте формат в метки класса.

  • Обучайтесь на графическом процессоре, если вы доступны. По умолчанию, minibatchqueue объект преобразует каждый выход в gpuArray если графический процессор доступен. Используя графический процессор требует Parallel Computing Toolbox™ и поддерживаемого устройства графического процессора. Для получения информации о поддерживаемых устройствах смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).

mbq = minibatchqueue(augimdsTrain,...
    'MiniBatchSize',miniBatchSize,...
    'MiniBatchFcn',@preprocessMiniBatch,...
    'MiniBatchFormat',{'SSCB',''});

Инициализируйте график процесса обучения.

figure
lineLossTrain = animatedline('Color',[0.85 0.325 0.098]);
ylim([0 inf])
xlabel("Iteration")
ylabel("Loss")
grid on

Инициализируйте скоростной параметр для решателя SGDM.

velocity = [];

Обучите сеть с помощью пользовательского учебного цикла. В течение каждой эпохи переставьте данные и цикл по мини-пакетам данных. Для каждого мини-пакета:

  • Оцените градиенты модели, состояние и потерю с помощью dlfeval и modelGradients функции и обновление сетевое состояние.

  • Определите скорость обучения для основанного на времени расписания скорости обучения затухания.

  • Обновите сетевые параметры с помощью sgdmupdate функция.

  • Отобразите прогресс обучения.

iteration = 0;
start = tic;

% Loop over epochs.
for epoch = 1:numEpochs
    % Shuffle data.
    shuffle(mbq);
    
    % Loop over mini-batches.
    while hasdata(mbq)
        iteration = iteration + 1;
        
        % Read mini-batch of data.
        [dlX, dlY] = next(mbq);
        
        % Evaluate the model gradients, state, and loss using dlfeval and the
        % modelGradients function and update the network state.
        [gradients,state,loss] = dlfeval(@modelGradients,dlnet,dlX,dlY);
        dlnet.State = state;
        
        % Determine learning rate for time-based decay learning rate schedule.
        learnRate = initialLearnRate/(1 + decay*iteration);
        
        % Update the network parameters using the SGDM optimizer.
        [dlnet,velocity] = sgdmupdate(dlnet,gradients,velocity,learnRate,momentum);
        
        % Display the training progress.
        D = duration(0,0,toc(start),'Format','hh:mm:ss');
        addpoints(lineLossTrain,iteration,loss)
        title("Epoch: " + epoch + ", Elapsed: " + string(D))
        drawnow
    end
end

Тестовая модель

Протестируйте точность классификации модели путем сравнения предсказаний на наборе валидации с истинными метками.

После обучения создание предсказаний на новых данных не требует меток. Создайте minibatchqueue объект, содержащий только предикторы тестовых данных:

  • Чтобы проигнорировать метки для тестирования, определите номер выходных параметров мини-пакетной очереди к 1.

  • Задайте тот же мини-пакетный размер, используемый для обучения.

  • Предварительно обработайте предикторы с помощью preprocessMiniBatchPredictors функция, перечисленная в конце примера.

  • Для одного выхода datastore задайте мини-пакетный формат 'SSCB' (пространственный, пространственный, канал, пакет).

numOutputs = 1;
mbqTest = minibatchqueue(augimdsValidation,numOutputs, ...
    'MiniBatchSize',miniBatchSize, ...
    'MiniBatchFcn',@preprocessMiniBatchPredictors, ...
    'MiniBatchFormat','SSCB');

Цикл по мини-пакетам и классифицирует изображения с помощью modelPredictions функция, перечисленная в конце примера.

predictions = modelPredictions(dlnet,mbqTest,classes);

Оцените точность классификации.

YTest = imdsValidation.Labels;
accuracy = mean(predictions == YTest)
accuracy = 0.9530

Функция градиентов модели

modelGradients функционируйте берет dlnetwork объект dlnet, мини-пакет входных данных dlX с соответствием маркирует Y и возвращает градиенты потери относительно настраиваемых параметров в dlnet, сетевое состояние и потеря. Чтобы вычислить градиенты автоматически, используйте dlgradient функция.

function [gradients,state,loss] = modelGradients(dlnet,dlX,Y)

[dlYPred,state] = forward(dlnet,dlX);

loss = crossentropy(dlYPred,Y);
gradients = dlgradient(loss,dlnet.Learnables);

loss = double(gather(extractdata(loss)));

end

Функция предсказаний модели

modelPredictions функционируйте берет dlnetwork объект dlnet, minibatchqueue из входных данных mbq, и сетевые классы, и вычисляют предсказания модели путем итерации по всем данным в minibatchqueue объект. Функция использует onehotdecode функционируйте, чтобы найти предсказанный класс с самым высоким счетом.

function predictions = modelPredictions(dlnet,mbq,classes)

predictions = [];

while hasdata(mbq)
    
    dlXTest = next(mbq);
    dlYPred = predict(dlnet,dlXTest);
    
    YPred = onehotdecode(dlYPred,classes,1)';
    
    predictions = [predictions; YPred];
end

end

Мини-функция предварительной обработки пакета

preprocessMiniBatch функция предварительно обрабатывает мини-пакет предикторов и меток с помощью следующих шагов:

  1. Предварительно обработайте изображения с помощью preprocessMiniBatchPredictors функция.

  2. Извлеките данные о метке из массива входящей ячейки и конкатенируйте в категориальный массив вдоль второго измерения.

  3. Одногорячий кодируют категориальные метки в числовые массивы. Кодирование в первую размерность производит закодированный массив, который совпадает с формой сетевого выхода.

function [X,Y] = preprocessMiniBatch(XCell,YCell)

% Preprocess predictors.
X = preprocessMiniBatchPredictors(XCell);

% Extract label data from cell and concatenate.
Y = cat(2,YCell{1:end});

% One-hot encode labels.
Y = onehotencode(Y,1);

end

Мини-пакетные предикторы, предварительно обрабатывающие функцию

preprocessMiniBatchPredictors функция предварительно обрабатывает мини-пакет предикторов путем извлечения данных изображения из входного массива ячеек, и конкатенируйте в числовой массив. Для полутонового входа, конкатенирующего по четвертой размерности, добавляет третью размерность в каждое изображение, чтобы использовать в качестве одноэлементной размерности канала.

function X = preprocessMiniBatchPredictors(XCell)

% Concatenate.
X = cat(4,XCell{1:end});

end

Загрузите предварительно обученную сеть.

net = squeezenet;

Преобразуйте сеть в график слоев, удалите выходной слой и преобразуйте его в dlnetwork объект.

lgraph = layerGraph(net);
lgraph = removeLayers(lgraph,'ClassificationLayer_predictions');
dlnet = dlnetwork(lgraph);

Learnables свойство dlnetwork объект является таблицей, которая содержит настраиваемые параметры сети. Таблица включает параметры вложенных слоев в отдельных строках. Просмотрите первые несколько строк learnables таблицы.

learnables = dlnet.Learnables;
head(learnables)
ans=8×3 table
          Layer           Parameter           Value       
    __________________    _________    ___________________

    "conv1"               "Weights"    {3x3x3x64  dlarray}
    "conv1"               "Bias"       {1x1x64    dlarray}
    "fire2-squeeze1x1"    "Weights"    {1x1x64x16 dlarray}
    "fire2-squeeze1x1"    "Bias"       {1x1x16    dlarray}
    "fire2-expand1x1"     "Weights"    {1x1x16x64 dlarray}
    "fire2-expand1x1"     "Bias"       {1x1x64    dlarray}
    "fire2-expand3x3"     "Weights"    {3x3x16x64 dlarray}
    "fire2-expand3x3"     "Bias"       {1x1x64    dlarray}

Заморозить настраиваемые параметры сети, цикла по настраиваемым параметрам и установить изучить уровень на 0 использований setLearnRateFactor функция.

factor = 0;

numLearnables = size(learnables,1);
for i = 1:numLearnables
    layerName = learnables.Layer(i);
    parameterName = learnables.Parameter(i);
    
    dlnet = setLearnRateFactor(dlnet,layerName,parameterName,factor);
end

Чтобы использовать обновленный изучают факторы уровня, когда обучение, необходимо передать объект dlnetwork функции обновления в пользовательском учебном цикле. Например, используйте команду

[dlnet,velocity] = sgdmupdate(dlnet,gradients,velocity);

Создайте неинициализированный dlnetwork объект без входного слоя. Создание неинициализированного dlnetwork полезно, когда вы еще не знаете размера и формата сетевых входных параметров, например, когда dlnetwork вкладывается в пользовательском слое.

Задайте слоя сети. Эта сеть имеет один вход, который не соединяется с входным слоем.

layers = [convolution2dLayer(5,20,'Name','conv')
    batchNormalizationLayer('Name','bn')
    reluLayer('Name','relu')
    fullyConnectedLayer(10,'Name','fc')
    softmaxLayer('Name','sm')];

Создайте неинициализированный dlnetwork. Установите Initialize опция значения имени ко лжи.

dlnet = dlnetwork(layers,'Initialize',false);

Проверяйте, что сеть не инициализируется.

dlnet.Initialized
ans = 
   0

Настраиваемые параметры и параметры состояния этой сети не инициализируются для обучения. Чтобы инициализировать сеть, используйте initialize функция.

Если вы хотите использовать dlnet непосредственно в пользовательском учебном цикле, затем можно инициализировать его при помощи initialize функционируйте и обеспечение входа в качестве примера.

Если вы хотите использовать dlnet в пользовательском слое затем можно использовать в своих интересах автоматическую инициализацию. Если вы используете пользовательский слой в dlnetwork, dlnet инициализируется когда родительский dlnetwork создается (или когда родительская сеть инициализируется, если она создается как неинициализированный dlnetwork). Если вы используете пользовательский слой в сети, которая обучена с помощью trainNetwork функция, затем dlnet автоматически инициализируется в учебное время. Для получения дополнительной информации смотрите Состав Нейронной сети для глубокого обучения.

Больше о

развернуть все

Вопросы совместимости

развернуть все

Расширенные возможности

Введенный в R2019b