Этот пример сначала показывает, как выполнить распознавание активности с помощью предварительно обученного 2D потока Расширенного 3-D (I3D) основанный на сверточной нейронной сети видео классификатор и затем показывает, как использовать передачу обучения, чтобы обучить такой видео классификатор с помощью RGB и данных об оптическом потоке из видео [1].
Основанное на видении распознавание активности включает предсказание действия объекта, такого как обход, плавание или нахождение, с помощью набора видеокадров. Распознавание активности от видео имеет много приложений, таких как человеко-машинное взаимодействие, изучение робота, обнаружение аномалии, наблюдение и обнаружение объектов. Например, онлайновое предсказание нескольких действий для входящих видео от нескольких камер может быть важно для изучения робота. Сравненный с классификацией изображений, распознавание действия с помощью видео сложно к модели из-за неточных достоверных данных для наборов видеоданных, множества жестов, которые агенты в видео могут выполнить, в большой степени класс неустойчивые наборы данных и большой объем данных, требуемый обучать устойчивый классификатор с нуля. Методы глубокого обучения, такие как 2D поток I3D сверточные сети [1], R (2+1) D [4] и SlowFast [5] показали улучшенную производительность на меньших наборах данных с помощью передачи обучения с сетями, предварительно обученными на больших видео наборах данных распознавания активности, таких как кинетика 400 [6].
Примечание: Этот пример требует Модели Computer Vision Toolbox™ для расширенной 3D Видео Классификации. Можно установить Модель Computer Vision Toolbox для расширенной 3D Видео Классификации из Add-On Explorer. Для получения дополнительной информации об установке дополнений, смотрите, Получают и Управляют Дополнениями.
Загрузите предварительно обученный расширенный 3D видео классификатор наряду с видеофайлом, на котором можно выполнить распознавание активности. Размер загруженного zip-файла составляет приблизительно 89 Мбайт.
downloadFolder = fullfile(tempdir,"hmdb51","pretrained","I3D"); if ~isfolder(downloadFolder) mkdir(downloadFolder); end filename = "activityRecognition-I3D-HMDB51-21b.zip"; zipFile = fullfile(downloadFolder,filename); if ~isfile(zipFile) disp('Downloading the pretrained network...'); downloadURL = "https://ssd.mathworks.com/supportfiles/vision/data/" + filename; websave(zipFile,downloadURL); unzip(zipFile,downloadFolder); end
Загрузите предварительно обученный расширенный 3D видео классификатор.
pretrainedDataFile = fullfile(downloadFolder,"inflated3d-FiveClasses-hmdb51.mat");
pretrained = load(pretrainedDataFile);
inflated3dPretrained = pretrained.data.inflated3d;
Отобразите имена метки класса предварительно обученного видео классификатора.
classes = inflated3dPretrained.Classes
classes = 5×1 categorical
kiss
laugh
pick
pour
pushup
Считайте и отобразите видео pour.avi
использование VideoReader
и vision.VideoPlayer
.
videoFilename = fullfile(downloadFolder, "pour.avi"); videoReader = VideoReader(videoFilename); videoPlayer = vision.VideoPlayer; videoPlayer.Name = "pour"; while hasFrame(videoReader) frame = readFrame(videoReader); % Resize the frame for display. frame = imresize(frame, 1.5); step(videoPlayer,frame); end release(videoPlayer);
Выберите 10 случайным образом выбранных видео последовательностей, чтобы классифицировать видео, однородно покрыть полноту файла, чтобы найти класс действия, который преобладает в видео.
numSequences = 10;
Классифицируйте видеофайл с помощью classifyVideoFile
функция.
[actionLabel,score] = classifyVideoFile(inflated3dPretrained, videoFilename, "NumSequences", numSequences)
actionLabel = categorical
pour
score = single
0.4482
Этот раздел примера показывает, как видео классификатор, показанный выше, обучен с помощью передачи обучения. Установите doTraining
переменная к false
использовать предварительно обученный видео классификатор, не имея необходимость ожидать обучения завершиться. В качестве альтернативы, если вы хотите обучить видео классификатор, установите doTraining
переменная к true
.
doTraining = false;
Этот пример обучает расширенный 3D Видео Классификатор (I3D) с помощью набора данных HMDB51. Используйте downloadHMDB51
поддерживание функции, перечисленной в конце этого примера, чтобы загрузить набор данных HMDB51 на папку под названием hmdb51
.
downloadFolder = fullfile(tempdir,"hmdb51");
downloadHMDB51(downloadFolder);
После того, как загрузка завершена, извлеките файл RAR hmdb51_org.rar
к hmdb51
папка. Затем используйте checkForHMDB51Folder
поддерживание функции, перечисленной в конце этого примера, чтобы подтвердить, что загруженные и извлеченные файлы существуют.
allClasses = checkForHMDB51Folder(downloadFolder);
Набор данных содержит приблизительно 2 Гбайт видеоданных для 7 000 клипов более чем 51 класс, такие как напиток, запуск, и обменяться рукопожатием. Каждый видеокадр имеет высоту 240 пикселей и минимальную ширину 176 пикселей. Количество кадров лежит в диапазоне от 18 до приблизительно 1 000.
Чтобы уменьшать учебное время, этот пример обучает сеть распознавания активности, чтобы классифицировать 5 классов действия вместо всего 51 класса в наборе данных. Установите useAllData
к true
обучаться со всем 51 классом.
useAllData = false; if useAllData classes = allClasses; end dataFolder = fullfile(downloadFolder, "hmdb51_org");
Разделите набор данных в набор обучающих данных для обучения классификатор и набор тестов для оценки классификатора. Используйте 80% данных для набора обучающих данных и остальных для набора тестов. Используйте folders2labels
и splitlabels
создать информацию о метке из папок и разделить данные на основе каждой метки в обучение и тестовые данные устанавливают путем случайного выбора пропорции файлов от каждой метки.
[labels,files] = folders2labels(fullfile(dataFolder,string(classes)),... "IncludeSubfolders",true,... "FileExtensions",'.avi'); indices = splitlabels(labels,0.8,'randomized'); trainFilenames = files(indices{1}); testFilenames = files(indices{2});
Чтобы нормировать входные данные для сети, минимальные и максимальные значения для набора данных введены в файле MAT inputStatistics.mat
, присоединенный к этому примеру. Чтобы найти минимальные и максимальные значения для различного набора данных, используйте inputStatistics
поддерживание функции, перечисленной в конце этого примера.
inputStatsFilename = 'inputStatistics.mat'; if ~exist(inputStatsFilename, 'file') disp("Reading all the training data for input statistics...") inputStats = inputStatistics(dataFolder); else d = load(inputStatsFilename); inputStats = d.inputStats; end
Этот пример использует datastore, чтобы считать сцены видео, соответствующие данные об оптическом потоке и соответствующие метки из видеофайлов.
Задайте количество видеокадров, которые datastore должен быть сконфигурирован, чтобы вывести в течение каждого раза, когда данные считаны из datastore.
numFrames = 64;
Значение 64 используется здесь, чтобы сбалансировать время классификации и использование памяти. Общие значения, чтобы рассмотреть равняются 16, 32, 64, или 128. Используя большее количество систем координат помогает получить дополнительную временную информацию, но требует большей памяти. Вы можете должны быть понизить это значение в зависимости от своих системных ресурсов. Эмпирический анализ требуется, чтобы определять оптимальное количество кадров.
Затем задайте высоту и ширину систем координат, которые datastore должен быть сконфигурирован, чтобы вывести. Datastore автоматически изменяет размер необработанных видеокадров к заданному размеру, чтобы включить пакетную обработку данных нескольких видео последовательностей.
frameSize = [112,112];
Значение [112 112] используется, чтобы получить дольше временные отношения в видеоизображении, какая справка классифицируют действия с долговременной длительностью. Общие значения для размера [112 112], [224 224], или [256 256]. Меньшие размеры включают использование большего количества видеокадров за счет использования памяти, время вычислений и пространственное разрешение. Минимальная высота и ширина видеокадров в наборе данных HMDB51 240 и 176, соответственно. Если вы хотите задать формат кадра для datastore, чтобы считать, что больше, чем минимальные значения, такой, когда [256, 256], сначала измените размер систем координат с помощью imresize
. Как с количеством кадров, эмпирический анализ требуется, чтобы определять оптимальные значения.
Задайте количество каналов как 3
для подсети видео RGB и 2
для подсети оптического потока видео классификатора I3D. Два канала для данных об оптическом потоке и компоненты скорости, и , соответственно.
rgbChannels = 3; flowChannels = 2;
Используйте функцию помощника, createFileDatastore
, сконфигурировать два FileDatastore
объекты для загрузки данных, один для обучения и другого для валидации. Функция помощника перечислена в конце этого примера. Каждый datastore читает видеофайл, чтобы обеспечить данные о RGB и соответствующую информацию о метке.
isDataForTraining = true; dsTrain = createFileDatastore(trainFilenames,numFrames,rgbChannels,classes,isDataForTraining); isDataForTraining = false; dsVal = createFileDatastore(testFilenames,numFrames,rgbChannels,classes,isDataForTraining);
Используя 3-D CNN естественный подход к извлечению пространственно-временных функций от видео. Можно создать сеть I3D из предварительно обученной 2D сети классификации изображений, такой как Начало v1 или ResNet-50 путем расширения 2D фильтров и объединения ядер в 3-D. Эта процедура снова использует веса, усвоенные из задачи классификации изображений загрузить видео задачу распознавания.
Следующая фигура является выборкой, показывающей, как раздуть 2D слой свертки к 3-D слою свертки. Инфляция включает расширение размера фильтра, весов и смещения путем добавления третьей размерности (временная размерность).
Видеоданные, как может рассматриваться, имеют две части: пространственный компонент и временный компонент.
Пространственный компонент включает информацию о форме, структуре и цвете объектов в видео. Данные о RGB содержат эту информацию.
Временный компонент включает информацию о движении объектов через системы координат и изображает важные перемещения между камерой и объектами в сцене. Вычисление оптического потока является общим методом для извлечения временной информации от видео.
2D потоковый CNN включает пространственную подсеть и временную подсеть [2]. Сверточная нейронная сеть, обученная на плотном оптическом потоке и потоке видеоданных, может достигнуть лучшей эффективности с ограниченными обучающими данными, чем со сложенными системами координат RGB сырых данных. Следующий рисунок показывает типичную 2D потоковую сеть I3D.
В этом примере вы создаете видео классификатор I3D на основе архитектуры GoogLeNet, 3D Классификатор Видео Нейронной сети Свертки, предварительно обученный на кинетике 400 наборов данных.
Задайте GoogLeNet как магистральную архитектуру нейронной сети свертки для видео классификатора I3D, который содержит две подсети, один для видеоданных и другого для данных об оптическом потоке.
baseNetwork = "googlenet-video-flow";
Задайте входной размер для расширенного 3D Видео Классификатора.
inputSize = [frameSize, rgbChannels, numFrames];
Получите минимальные и максимальные значения для RGB и данных об оптическом потоке из inputStats
структура загружена от inputStatistics.mat
файл. Эти значения необходимы, чтобы нормировать входные данные.
oflowMin = squeeze(inputStats.oflowMin)'; oflowMax = squeeze(inputStats.oflowMax)'; rgbMin = squeeze(inputStats.rgbMin)'; rgbMax = squeeze(inputStats.rgbMax)'; stats.Video.Min = rgbMin; stats.Video.Max = rgbMax; stats.Video.Mean = []; stats.Video.StandardDeviation = []; stats.OpticalFlow.Min = oflowMin(1:flowChannels); stats.OpticalFlow.Max = oflowMax(1:flowChannels); stats.OpticalFlow.Mean = []; stats.OpticalFlow.StandardDeviation = [];
Создайте Видео Классификатор I3D при помощи inflated3dVideoClassifier
функция.
i3d = inflated3dVideoClassifier(baseNetwork,string(classes),... "InputSize",inputSize,... "InputNormalizationStatistics",stats);
Задайте имя модели для видео классификатора.
i3d.ModelName = "Inflated-3D Activity Recognizer Using Video and Optical Flow";
Увеличение данных обеспечивает способ использовать наборы ограниченных данных для обучения. Увеличение на видеоданных должно быть тем же самым для набора систем координат, т.е. видео последовательностью, на основе сетевого входного размера. Незначительные изменения, такие как перевод, обрезка, или преобразование изображения, обеспечивают, новые, отличные, и уникальные изображения, которые можно использовать, чтобы обучить устойчивый видео классификатор. Хранилища данных являются удобным способом считать и увеличить наборы данных. Увеличьте учебные видеоданные при помощи augmentVideo
поддерживание функции, заданной в конце этого примера.
dsTrain = transform(dsTrain, @augmentVideo);
Предварительно обработайте учебные видеоданные, чтобы изменить размер к размеру входа Inflated-3D Video Classifier, при помощи preprocessVideoClips
, заданный в конце этого примера. Задайте InputNormalizationStatistics
свойство видео классификатора и входного размера к предварительной обработке функционирует как значения полей в struct, preprocessInfo
. InputNormalizationStatistics
свойство используется, чтобы перемасштабировать видеокадры и данные об оптическом потоке между-1 и 1. Входной размер используется, чтобы изменить размер видеокадров с помощью imresize
на основе SizingOption
значение в info
struct (). В качестве альтернативы вы могли использовать "randomcrop"
или "centercrop"
к случайной обрезке или центру обрезают входные данные к входному размеру видео классификатора. Обратите внимание на то, что увеличение данных не применяется к данным о валидации и тесту. Идеально, тест и данные о валидации должны быть представительными для исходных данных и оставлены немодифицированными для несмещенной оценки.
preprocessInfo.Statistics = i3d.InputNormalizationStatistics;
preprocessInfo.InputSize = inputSize;
preprocessInfo.SizingOption = "resize";
dsTrain = transform(dsTrain, @(data)preprocessVideoClips(data, preprocessInfo));
dsVal = transform(dsVal, @(data)preprocessVideoClips(data, preprocessInfo));
Создайте функцию поддержки modelGradients
, перечисленный в конце этого примера. modelGradients
функционируйте берет в качестве входа видео классификатор I3D i3d
, мини-пакет входных данных dlRGB
и dlFlow
, и мини-пакет основной истины помечает данные dlY
. Функция возвращает учебное значение потерь, градиенты потери относительно настраиваемых параметров классификатора и мини-пакетной точности классификатора.
Потеря вычисляется путем вычисления среднего значения перекрестных энтропийных потерь предсказаний от каждой из подсетей. Выходные предсказания сети являются вероятностями между 0 и 1 для каждого из классов.
Точность каждого классификатора вычисляется путем взятия среднего значения RGB и предсказаний оптического потока, и сравнения его с меткой основной истины входных параметров.
Обучайтесь с мини-пакетным размером 20 для 600 итераций. Задайте итерацию, после которой можно сохранить видео классификатор с лучшей точностью валидации при помощи SaveBestAfterIteration
параметр.
Задайте отжигающие косинус параметры расписания [3] скорости обучения:
Минимальная скорость обучения 1e-4.
Максимальная скорость обучения 1e-3.
Количество косинуса итераций 100, 200, и 300, после которого цикл расписания скорости обучения перезапускает. Опция CosineNumIterations
задает ширину каждого цикла косинуса.
Задайте параметры для оптимизации SGDM. Инициализируйте параметры оптимизации SGDM в начале обучения:
Импульс 0,9.
Начальный скоростной параметр, инициализированный как []
.
Фактор регуляризации L2 0,0005.
Задайте, чтобы диспетчеризировать данные в фоновом режиме с помощью параллельного пула. Если DispatchInBackground
установлен в истинный, откройте параллельный пул с конкретным количеством параллельных рабочих и создайте DispatchInBackgroundDatastore
, если как часть этого примера, который диспетчеризирует данные в фоновом режиме, чтобы ускорить обучение с помощью асинхронной загрузки данных и предварительной обработки. По умолчанию этот пример использует графический процессор, если вы доступны. В противном случае это использует центральный процессор. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA® графический процессор. Для получения информации о поддерживаемом вычислите возможности, смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).
params.Classes = classes; params.MiniBatchSize = 20; params.NumIterations = 600; params.SaveBestAfterIteration = 400; params.CosineNumIterations = [100, 200, 300]; params.MinLearningRate = 1e-4; params.MaxLearningRate = 1e-3; params.Momentum = 0.9; params.VelocityRGB = []; params.VelocityFlow = []; params.L2Regularization = 0.0005; params.ProgressPlot = true; params.Verbose = true; params.ValidationData = dsVal; params.DispatchInBackground = false; params.NumWorkers = 4;
Обучите видео классификатор I3D с помощью видеоданных RGB и данных об оптическом потоке.
В течение каждой эпохи:
Переставьте данные перед цикличным выполнением по мини-пакетам данных.
Используйте minibatchqueue
циклично выполняться по мини-пакетам. Функция поддержки createMiniBatchQueue
, перечисленный в конце этого примера, использует данный учебный datastore, чтобы создать minibatchqueue
.
Используйте данные о валидации dsVal
проверять сети.
Отобразите результаты потери и точности за каждую эпоху с помощью функции поддержки displayVerboseOutputEveryEpoch
, перечисленный в конце этого примера.
Для каждого мини-пакета:
Преобразуйте видеоданные или данные об оптическом потоке и метки к dlarray
объекты с базовым одним типом.
Чтобы позволить обработать измерение времени, видеоданные с помощью Видео Классификатора I3D задают временную размерность последовательности, "T"
. Укажите, что размерность маркирует "SSCTB"
(пространственный, пространственный, канал, временный, пакет) для видеоданных и "CB"
для данных о метке.
minibatchqueue
возразите использует функцию поддержки batchVideoAndFlow
, перечисленный в конце этого примера, чтобы обработать в пакетном режиме видео RGB и данные об оптическом потоке.
params.ModelFilename = "inflated3d-FiveClasses-hmdb51.mat"; if doTraining epoch = 1; bestLoss = realmax; accTrain = []; accTrainRGB = []; accTrainFlow = []; lossTrain = []; iteration = 1; start = tic; trainTime = start; shuffled = shuffleTrainDs(dsTrain); % Number of outputs is three: One for RGB frames, one for optical flow % data, and one for ground truth labels. numOutputs = 3; mbq = createMiniBatchQueue(shuffled, numOutputs, params); % Use the initializeTrainingProgressPlot and initializeVerboseOutput % supporting functions, listed at the end of the example, to initialize % the training progress plot and verbose output to display the training % loss, training accuracy, and validation accuracy. plotters = initializeTrainingProgressPlot(params); initializeVerboseOutput(params); while iteration <= params.NumIterations % Iterate through the data set. [dlVideo,dlFlow,dlY] = next(mbq); % Evaluate the model gradients and loss using dlfeval. [gradRGB,gradFlow,loss,acc,accRGB,accFlow,stateRGB,stateFlow] = ... dlfeval(@modelGradients,i3d,dlVideo,dlFlow,dlY); % Accumulate the loss and accuracies. lossTrain = [lossTrain, loss]; accTrain = [accTrain, acc]; accTrainRGB = [accTrainRGB, accRGB]; accTrainFlow = [accTrainFlow, accFlow]; % Update the network state. i3d.VideoState = stateRGB; i3d.OpticalFlowState = stateFlow; % Update the gradients and parameters for the RGB and optical flow % subnetworks using the SGDM optimizer. [i3d.VideoLearnables,params.VelocityRGB] = ... updateLearnables(i3d.VideoLearnables,gradRGB,params,params.VelocityRGB,iteration); [i3d.OpticalFlowLearnables,params.VelocityFlow,learnRate] = ... updateLearnables(i3d.OpticalFlowLearnables,gradFlow,params,params.VelocityFlow,iteration); if ~hasdata(mbq) || iteration == params.NumIterations % Current epoch is complete. Do validation and update progress. trainTime = toc(trainTime); [validationTime,cmat,lossValidation,accValidation,accValidationRGB,accValidationFlow] = ... doValidation(params, i3d); accTrain = mean(accTrain); accTrainRGB = mean(accTrainRGB); accTrainFlow = mean(accTrainFlow); lossTrain = mean(lossTrain); % Update the training progress. displayVerboseOutputEveryEpoch(params,start,learnRate,epoch,iteration,... accTrain,accTrainRGB,accTrainFlow,... accValidation,accValidationRGB,accValidationFlow,... lossTrain,lossValidation,trainTime,validationTime); updateProgressPlot(params,plotters,epoch,iteration,start,lossTrain,accTrain,accValidation); % Save the trained video classifier and the parameters, that gave % the best validation loss so far. Use the saveData supporting function, % listed at the end of this example. bestLoss = saveData(i3d,bestLoss,iteration,cmat,lossTrain,lossValidation,... accTrain,accValidation,params); end if ~hasdata(mbq) && iteration < params.NumIterations % Current epoch is complete. Initialize the training loss, accuracy % values, and minibatchqueue for the next epoch. accTrain = []; accTrainRGB = []; accTrainFlow = []; lossTrain = []; trainTime = tic; epoch = epoch + 1; shuffled = shuffleTrainDs(dsTrain); numOutputs = 3; mbq = createMiniBatchQueue(shuffled, numOutputs, params); end iteration = iteration + 1; end % Display a message when training is complete. endVerboseOutput(params); disp("Model saved to: " + params.ModelFilename); end
Используйте набор тестовых данных, чтобы оценить точность обученного видео классификатора.
Загрузите лучшую модель, сохраненную во время обучения, или используйте предварительно обученную модель.
if doTraining transferLearned = load(params.ModelFilename); inflated3dPretrained = transferLearned.data.inflated3d; end
Создайте minibatchqueue
возразите, чтобы загрузить пакеты тестовых данных.
numOutputs = 3; mbq = createMiniBatchQueue(params.ValidationData, numOutputs, params);
Для каждого пакета тестовых данных сделайте предсказания с помощью RGB и сетей оптического потока, возьмите среднее значение предсказаний и вычислите точность предсказания с помощью матрицы беспорядка.
numClasses = numel(classes); cmat = sparse(numClasses,numClasses); while hasdata(mbq) [dlRGB, dlFlow, dlY] = next(mbq); % Pass the video input as RGB and optical flow data through the % two-stream I3D Video Classifier to get the separate predictions. [dlYPredRGB,dlYPredFlow] = predict(inflated3dPretrained,dlRGB,dlFlow); % Fuse the predictions by calculating the average of the predictions. dlYPred = (dlYPredRGB + dlYPredFlow)/2; % Calculate the accuracy of the predictions. [~,YTest] = max(dlY,[],1); [~,YPred] = max(dlYPred,[],1); cmat = aggregateConfusionMetric(cmat,YTest,YPred); end
Вычислите среднюю точность классификации для обучившего нейронные сети.
accuracyEval = sum(diag(cmat))./sum(cmat,"all")
accuracyEval = 0.8850
Отобразите матрицу неточностей.
figure chart = confusionchart(cmat,classes);
Расширенный 3D видео классификатор, который предварительно обучен на кинетике 400 наборов данных, обеспечивает лучшую эффективность для распознавания деятельности человека на передаче обучения. Вышеупомянутое обучение было запущено на Титане-X 24GB графический процессор в течение приблизительно 100 минут. Когда обучение с нуля на маленьком наборе данных видео распознавания активности, учебное время и сходимость берет намного дольше, чем предварительно обученный видео классификатор. Transer, изучающий использование кинетики 400, предварительно обучался, расширенный 3D видео классификатор также старается не сверхсоответствовать классификатору, когда запустился для большего числа эпох. Однако Классификатор Видео SlowFast и R (2+1) Видео Классификатор D, которые предварительно обучены на кинетике 400 наборов данных, обеспечивают лучшую эффективность и более быструю сходимость во время обучения по сравнению с расширенным 3D Видео Классификатором. Чтобы узнать больше о видео распознавании с помощью глубокого обучения, смотрите Начало работы с Видео Классификацией Используя Глубокое обучение.
inputStatistics
inputStatistics
функционируйте берет в качестве входа имя папки, содержащей данные HMDB51, и вычисляет минимальные и максимальные значения для данных о RGB и данных об оптическом потоке. Минимальные и максимальные значения используются в качестве входных параметров нормализации к входному слою сетей. Эта функция также получает количество кадров в каждом из видеофайлов, чтобы использовать позже во время обучения и тестирования сети. Для того, чтобы найти минимальные и максимальные значения для различного набора данных, используйте эту функцию с именем папки, содержащим набор данных.
function inputStats = inputStatistics(dataFolder) ds = createDatastore(dataFolder); ds.ReadFcn = @getMinMax; tic; tt = tall(ds); varnames = {'rgbMax','rgbMin','oflowMax','oflowMin'}; stats = gather(groupsummary(tt,[],{'max','min'}, varnames)); inputStats.Filename = gather(tt.Filename); inputStats.NumFrames = gather(tt.NumFrames); inputStats.rgbMax = stats.max_rgbMax; inputStats.rgbMin = stats.min_rgbMin; inputStats.oflowMax = stats.max_oflowMax; inputStats.oflowMin = stats.min_oflowMin; save('inputStatistics.mat','inputStats'); toc; end function data = getMinMax(filename) reader = VideoReader(filename); opticFlow = opticalFlowFarneback; data = []; while hasFrame(reader) frame = readFrame(reader); [rgb,oflow] = findMinMax(frame,opticFlow); data = assignMinMax(data, rgb, oflow); end totalFrames = floor(reader.Duration * reader.FrameRate); totalFrames = min(totalFrames, reader.NumFrames); [labelName, filename] = getLabelFilename(filename); data.Filename = fullfile(labelName, filename); data.NumFrames = totalFrames; data = struct2table(data,'AsArray',true); end function data = assignMinMax(data, rgb, oflow) if isempty(data) data.rgbMax = rgb.Max; data.rgbMin = rgb.Min; data.oflowMax = oflow.Max; data.oflowMin = oflow.Min; return; end data.rgbMax = max(data.rgbMax, rgb.Max); data.rgbMin = min(data.rgbMin, rgb.Min); data.oflowMax = max(data.oflowMax, oflow.Max); data.oflowMin = min(data.oflowMin, oflow.Min); end function [rgbMinMax,oflowMinMax] = findMinMax(rgb, opticFlow) rgbMinMax.Max = max(rgb,[],[1,2]); rgbMinMax.Min = min(rgb,[],[1,2]); gray = rgb2gray(rgb); flow = estimateFlow(opticFlow,gray); oflow = cat(3,flow.Vx,flow.Vy,flow.Magnitude); oflowMinMax.Max = max(oflow,[],[1,2]); oflowMinMax.Min = min(oflow,[],[1,2]); end function ds = createDatastore(folder) ds = fileDatastore(folder,... 'IncludeSubfolders', true,... 'FileExtensions', '.avi',... 'UniformRead', true,... 'ReadFcn', @getMinMax); disp("NumFiles: " + numel(ds.Files)); end
createFileDatastore
createFileDatastore
функция создает FileDatastore
объект с помощью данных имен файлов. FileDatastore
объект считывает данные в 'partialfile'
режим, таким образом, каждое чтение может возвратить частично системы координат чтения в видео. Эта функция помогает с чтением больших видеофайлов, если все системы координат не умещаются в памяти.
function datastore = createFileDatastore(trainingFolder,numFrames,numChannels,classes,isDataForTraining) readFcn = @(f,u)readVideo(f,u,numFrames,numChannels,classes,isDataForTraining); datastore = fileDatastore(trainingFolder,... 'IncludeSubfolders',true,... 'FileExtensions','.avi',... 'ReadFcn',readFcn,... 'ReadMode','partialfile'); end
shuffleTrainDs
shuffleTrainDs
функционируйте переставляет файлы, существующие в учебном datastore dsTrain
.
function shuffled = shuffleTrainDs(dsTrain) shuffled = copy(dsTrain); transformed = isa(shuffled, 'matlab.io.datastore.TransformedDatastore'); if transformed files = shuffled.UnderlyingDatastores{1}.Files; else files = shuffled.Files; end n = numel(files); shuffledIndices = randperm(n); if transformed shuffled.UnderlyingDatastores{1}.Files = files(shuffledIndices); else shuffled.Files = files(shuffledIndices); end reset(shuffled); end
readVideo
readVideo
функционируйте читает видеокадры и соответствующие значения метки для данного видеофайла. Во время обучения функция чтения читает определенное количество кадров согласно сетевому входному размеру со случайным образом выбранной стартовой системой координат. Во время тестирования последовательно читаются все системы координат. Видеокадры изменены к необходимому входному размеру сети классификатора для обучения, и для тестирования и валидации.
function [data,userdata,done] = readVideo(filename,userdata,numFrames,numChannels,classes,isDataForTraining) if isempty(userdata) userdata.reader = VideoReader(filename); userdata.batchesRead = 0; userdata.label = getLabel(filename,classes); totalFrames = floor(userdata.reader.Duration * userdata.reader.FrameRate); totalFrames = min(totalFrames, userdata.reader.NumFrames); userdata.totalFrames = totalFrames; userdata.datatype = class(read(userdata.reader,1)); end reader = userdata.reader; totalFrames = userdata.totalFrames; label = userdata.label; batchesRead = userdata.batchesRead; if isDataForTraining video = readForTraining(reader, numFrames, totalFrames); else video = readForValidation(reader, userdata.datatype, numChannels, numFrames, totalFrames); end data = {video, label}; batchesRead = batchesRead + 1; userdata.batchesRead = batchesRead; if numFrames > totalFrames numBatches = 1; else numBatches = floor(totalFrames/numFrames); end % Set the done flag to true, if the reader has read all the frames or % if it is training. done = batchesRead == numBatches || isDataForTraining; end
readForTraining
readForTraining
функционируйте читает видеокадры для обучения видео классификатор. Функция читает определенное количество кадров согласно сетевому входному размеру со случайным образом выбранной стартовой системой координат. Если существует недостаточно перенесенных систем координат, видео последовательность повторяется, чтобы заполнить необходимое количество кадров.
function video = readForTraining(reader, numFrames, totalFrames) if numFrames >= totalFrames startIdx = 1; endIdx = totalFrames; else startIdx = randperm(totalFrames - numFrames + 1); startIdx = startIdx(1); endIdx = startIdx + numFrames - 1; end video = read(reader,[startIdx,endIdx]); if numFrames > totalFrames % Add more frames to fill in the network input size. additional = ceil(numFrames/totalFrames); video = repmat(video,1,1,1,additional); video = video(:,:,:,1:numFrames); end end
readForValidation
readForValidation
функционируйте читает видеокадры для оценки обученного видео классификатора. Функция читает определенное количество кадров последовательно согласно сетевому входному размеру. Если существует недостаточно перенесенных систем координат, видео последовательность повторяется, чтобы заполнить необходимое количество кадров.
function video = readForValidation(reader, datatype, numChannels, numFrames, totalFrames) H = reader.Height; W = reader.Width; toRead = min([numFrames,totalFrames]); video = zeros([H,W,numChannels,toRead], datatype); frameIndex = 0; while hasFrame(reader) && frameIndex < numFrames frame = readFrame(reader); frameIndex = frameIndex + 1; video(:,:,:,frameIndex) = frame; end if frameIndex < numFrames video = video(:,:,:,1:frameIndex); additional = ceil(numFrames/frameIndex); video = repmat(video,1,1,1,additional); video = video(:,:,:,1:numFrames); end end
getLabel
getLabel
функция получает имя метки из полного пути имени файла. Метка для файла является папкой, в которой она существует. Например, для пути к файлу, такого как "/path/to/dataset/clapping/video_0001.avi"
, именем метки является "clapping"
.
function label = getLabel(filename,classes) folder = fileparts(string(filename)); [~,label] = fileparts(folder); label = categorical(string(label), string(classes)); end
augmentVideo
augmentVideo
функционируйте использует приращение, преобразовывают функцию, обеспеченную augmentTransform
поддерживание функции, чтобы применить то же увеличение через видео последовательность.
function data = augmentVideo(data) numSequences = size(data,1); for ii = 1:numSequences video = data{ii,1}; % HxWxC sz = size(video,[1,2,3]); % One augmentation per sequence augmentFcn = augmentTransform(sz); data{ii,1} = augmentFcn(video); end end
augmentTransform
augmentTransform
функция создает метод увеличения со случайным зеркальным отражением лево-права и масштабными коэффициентами.
function augmentFcn = augmentTransform(sz) % Randomly flip and scale the image. tform = randomAffine2d('XReflection',true,'Scale',[1 1.1]); rout = affineOutputView(sz,tform,'BoundsStyle','CenterOutput'); augmentFcn = @(data)augmentData(data,tform,rout); function data = augmentData(data,tform,rout) data = imwarp(data,tform,'OutputView',rout); end end
preprocessVideoClips
preprocessVideoClips
функция предварительно обрабатывает учебные видеоданные, чтобы изменить размер к размеру входа Inflated-3D Video Classifier. Это берет InputNormalizationStatistics
и InputSize
свойства видео классификатора в struct, info
. InputNormalizationStatistics
свойство используется, чтобы перемасштабировать видеокадры и данные об оптическом потоке между-1 и 1. Входной размер используется, чтобы изменить размер видеокадров с помощью imresize
на основе SizingOption
значение в info
struct (). В качестве альтернативы вы могли использовать "randomcrop"
или "centercrop"
как значения для SizingOption
к случайной обрезке или центру обрезают входные данные к входному размеру видео классификатора.
function preprocessed = preprocessVideoClips(data, info) inputSize = info.InputSize(1:2); sizingOption = info.SizingOption; switch sizingOption case "resize" sizingFcn = @(x)imresize(x,inputSize); case "randomcrop" sizingFcn = @(x)cropVideo(x,@randomCropWindow2d,inputSize); case "centercrop" sizingFcn = @(x)cropVideo(x,@centerCropWindow2d,inputSize); end numClips = size(data,1); rgbMin = info.Statistics.Video.Min; rgbMax = info.Statistics.Video.Max; oflowMin = info.Statistics.OpticalFlow.Min; oflowMax = info.Statistics.OpticalFlow.Max; numChannels = length(rgbMin); rgbMin = reshape(rgbMin, 1, 1, numChannels); rgbMax = reshape(rgbMax, 1, 1, numChannels); numChannels = length(oflowMin); oflowMin = reshape(oflowMin, 1, 1, numChannels); oflowMax = reshape(oflowMax, 1, 1, numChannels); preprocessed = cell(numClips, 3); for ii = 1:numClips video = data{ii,1}; resized = sizingFcn(video); oflow = computeFlow(resized,inputSize); % Cast the input to single. resized = single(resized); oflow = single(oflow); % Rescale the input between -1 and 1. resized = rescale(resized,-1,1,"InputMin",rgbMin,"InputMax",rgbMax); oflow = rescale(oflow,-1,1,"InputMin",oflowMin,"InputMax",oflowMax); preprocessed{ii,1} = resized; preprocessed{ii,2} = oflow; preprocessed{ii,3} = data{ii,2}; end end function outData = cropVideo(data, cropFcn, inputSize) imsz = size(data,[1,2]); cropWindow = cropFcn(imsz, inputSize); numFrames = size(data,4); sz = [inputSize, size(data,3), numFrames]; outData = zeros(sz, 'like', data); for f = 1:numFrames outData(:,:,:,f) = imcrop(data(:,:,:,f), cropWindow); end end
computeFlow
computeFlow
функционируйте берет в качестве входа видео последовательность, videoFrames
, и вычисляет соответствующие данные об оптическом потоке opticalFlowData
использование opticalFlowFarneback
. Данные об оптическом потоке содержат два канала, которые соответствуют - и - компоненты скорости.
function opticalFlowData = computeFlow(videoFrames, inputSize) opticalFlow = opticalFlowFarneback; numFrames = size(videoFrames,4); sz = [inputSize, 2, numFrames]; opticalFlowData = zeros(sz, 'like', videoFrames); for f = 1:numFrames gray = rgb2gray(videoFrames(:,:,:,f)); flow = estimateFlow(opticalFlow,gray); opticalFlowData(:,:,:,f) = cat(3,flow.Vx,flow.Vy); end end
createMiniBatchQueue
createMiniBatchQueue
функция создает minibatchqueue
объект, который обеспечивает miniBatchSize
объем данных от данного datastore. Это также создает DispatchInBackgroundDatastore
если параллельный пул открыт.
function mbq = createMiniBatchQueue(datastore, numOutputs, params) if params.DispatchInBackground && isempty(gcp('nocreate')) % Start a parallel pool, if DispatchInBackground is true, to dispatch % data in the background using the parallel pool. c = parcluster('local'); c.NumWorkers = params.NumWorkers; parpool('local',params.NumWorkers); end p = gcp('nocreate'); if ~isempty(p) datastore = DispatchInBackgroundDatastore(datastore, p.NumWorkers); end inputFormat(1:numOutputs-1) = "SSCTB"; outputFormat = "CB"; mbq = minibatchqueue(datastore, numOutputs, ... "MiniBatchSize", params.MiniBatchSize, ... "MiniBatchFcn", @batchVideoAndFlow, ... "MiniBatchFormat", [inputFormat,outputFormat]); end
batchVideoAndFlow
batchVideoAndFlow
функционируйте обрабатывает в пакетном режиме видео, оптический поток и данные о метке из массивов ячеек. Это использует onehotencode
функция, чтобы закодировать основную истину категориальные метки в одногорячие массивы. Одногорячий закодированный массив содержит 1
в положении, соответствующем классу метки и 0
в любом положении.
function [video,flow,labels] = batchVideoAndFlow(video, flow, labels) % Batch dimension: 5 video = cat(5,video{:}); flow = cat(5,flow{:}); % Batch dimension: 2 labels = cat(2,labels{:}); % Feature dimension: 1 labels = onehotencode(labels,1); end
modelGradients
modelGradients
функционируйте берет в качестве входа мини-пакет данных о RGB dlRGB
, соответствующие данные об оптическом потоке dlFlow
, и соответствующий целевой dlY
, и возвращает соответствующую потерю, градиенты потери относительно настраиваемых параметров и учебную точность. Чтобы вычислить градиенты, оцените modelGradients
функция с помощью dlfeval
функция в учебном цикле.
function [gradientsRGB,gradientsFlow,loss,acc,accRGB,accFlow,stateRGB,stateFlow] = modelGradients(i3d,dlRGB,dlFlow,Y) % Pass video input as RGB and optical flow data through the two-stream % network. [dlYPredRGB,dlYPredFlow,stateRGB,stateFlow] = forward(i3d,dlRGB,dlFlow); % Calculate fused loss, gradients, and accuracy for the two-stream % predictions. rgbLoss = crossentropy(dlYPredRGB,Y); flowLoss = crossentropy(dlYPredFlow,Y); % Fuse the losses. loss = mean([rgbLoss,flowLoss]); gradientsRGB = dlgradient(rgbLoss,i3d.VideoLearnables); gradientsFlow = dlgradient(flowLoss,i3d.OpticalFlowLearnables); % Fuse the predictions by calculating the average of the predictions. dlYPred = (dlYPredRGB + dlYPredFlow)/2; % Calculate the accuracy of the predictions. [~,YTest] = max(Y,[],1); [~,YPred] = max(dlYPred,[],1); acc = gather(extractdata(sum(YTest == YPred)./numel(YTest))); % Calculate the accuracy of the RGB and flow predictions. [~,YTest] = max(Y,[],1); [~,YPredRGB] = max(dlYPredRGB,[],1); [~,YPredFlow] = max(dlYPredFlow,[],1); accRGB = gather(extractdata(sum(YTest == YPredRGB)./numel(YTest))); accFlow = gather(extractdata(sum(YTest == YPredFlow)./numel(YTest))); end
updateLearnables
updateLearnables
функционируйте обновляет обеспеченный learnables
с градиентами и другими параметрами с помощью оптимизационной функции SGDM sgdmupdate
.
function [learnables,velocity,learnRate] = updateLearnables(learnables,gradients,params,velocity,iteration) % Determine the learning rate using the cosine-annealing learning rate schedule. learnRate = cosineAnnealingLearnRate(iteration, params); % Apply L2 regularization to the weights. idx = learnables.Parameter == "Weights"; gradients(idx,:) = dlupdate(@(g,w) g + params.L2Regularization*w, gradients(idx,:), learnables(idx,:)); % Update the network parameters using the SGDM optimizer. [learnables, velocity] = sgdmupdate(learnables, gradients, velocity, learnRate, params.Momentum); end
cosineAnnealingLearnRate
cosineAnnealingLearnRate
функция вычисляет скорость обучения на основе текущего номера итерации, минимальную скорость обучения, максимальную скорость обучения и количество итераций для отжига [3].
function lr = cosineAnnealingLearnRate(iteration, params) if iteration == params.NumIterations lr = params.MinLearningRate; return; end cosineNumIter = [0, params.CosineNumIterations]; csum = cumsum(cosineNumIter); block = find(csum >= iteration, 1,'first'); cosineIter = iteration - csum(block - 1); annealingIteration = mod(cosineIter, cosineNumIter(block)); cosineIteration = cosineNumIter(block); minR = params.MinLearningRate; maxR = params.MaxLearningRate; cosMult = 1 + cos(pi * annealingIteration / cosineIteration); lr = minR + ((maxR - minR) * cosMult / 2); end
aggregateConfusionMetric
aggregateConfusionMetric
функционируйте инкрементно заполняет матрицу беспорядка на основе предсказанных результатов YPred
и ожидаемые результаты YTest
.
function cmat = aggregateConfusionMetric(cmat,YTest,YPred) YTest = gather(extractdata(YTest)); YPred = gather(extractdata(YPred)); [m,n] = size(cmat); cmat = cmat + full(sparse(YTest,YPred,1,m,n)); end
doValidation
doValidation
функция подтверждает видео классификатор с помощью данных о валидации.
function [validationTime, cmat, lossValidation, accValidation, accValidationRGB, accValidationFlow] = doValidation(params, i3d) validationTime = tic; numOutputs = 3; mbq = createMiniBatchQueue(params.ValidationData, numOutputs, params); lossValidation = []; numClasses = numel(params.Classes); cmat = sparse(numClasses,numClasses); cmatRGB = sparse(numClasses,numClasses); cmatFlow = sparse(numClasses,numClasses); while hasdata(mbq) [dlX1,dlX2,dlY] = next(mbq); [loss,YTest,YPred,YPredRGB,YPredFlow] = predictValidation(i3d,dlX1,dlX2,dlY); lossValidation = [lossValidation,loss]; cmat = aggregateConfusionMetric(cmat,YTest,YPred); cmatRGB = aggregateConfusionMetric(cmatRGB,YTest,YPredRGB); cmatFlow = aggregateConfusionMetric(cmatFlow,YTest,YPredFlow); end lossValidation = mean(lossValidation); accValidation = sum(diag(cmat))./sum(cmat,"all"); accValidationRGB = sum(diag(cmatRGB))./sum(cmatRGB,"all"); accValidationFlow = sum(diag(cmatFlow))./sum(cmatFlow,"all"); validationTime = toc(validationTime); end
predictValidation
predictValidation
функция вычисляет потерю и значения предсказания с помощью обеспеченного видео классификатора для данных об оптическом потоке и RGB.
function [loss,YTest,YPred,YPredRGB,YPredFlow] = predictValidation(i3d,dlRGB,dlFlow,Y) % Pass the video input through the two-stream Inflated-3D video classifier. [dlYPredRGB,dlYPredFlow] = predict(i3d,dlRGB,dlFlow); % Calculate the cross-entropy separately for the two-stream outputs. rgbLoss = crossentropy(dlYPredRGB,Y); flowLoss = crossentropy(dlYPredFlow,Y); % Fuse the losses. loss = mean([rgbLoss,flowLoss]); % Fuse the predictions by calculating the average of the predictions. dlYPred = (dlYPredRGB + dlYPredFlow)/2; % Calculate the accuracy of the predictions. [~,YTest] = max(Y,[],1); [~,YPred] = max(dlYPred,[],1); [~,YPredRGB] = max(dlYPredRGB,[],1); [~,YPredFlow] = max(dlYPredFlow,[],1); end
saveData
saveData
функция сохраняет данный Расширенный 3-й Видео Классификатор, точность, потерю и другие параметры обучения к MAT-файлу.
function bestLoss = saveData(inflated3d,bestLoss,iteration,cmat,lossTrain,lossValidation,... accTrain,accValidation,params) if iteration >= params.SaveBestAfterIteration lossValidtion = extractdata(gather(lossValidation)); if lossValidtion < bestLoss params = rmfield(params, 'VelocityRGB'); params = rmfield(params, 'VelocityFlow'); bestLoss = lossValidtion; inflated3d = gatherFromGPUToSave(inflated3d); data.BestLoss = bestLoss; data.TrainingLoss = extractdata(gather(lossTrain)); data.TrainingAccuracy = accTrain; data.ValidationAccuracy = accValidation; data.ValidationConfmat= cmat; data.inflated3d = inflated3d; data.Params = params; save(params.ModelFilename, 'data'); end end end
gatherFromGPUToSave
gatherFromGPUToSave
функция собирает данные из графического процессора для того, чтобы сохранить видео классификатор на диск.
function classifier = gatherFromGPUToSave(classifier) if ~canUseGPU return; end p = string(properties(classifier)); p = p(endsWith(p, ["Learnables","State"])); for jj = 1:numel(p) prop = p(jj); classifier.(prop) = gatherValues(classifier.(prop)); end function tbl = gatherValues(tbl) for ii = 1:height(tbl) tbl.Value{ii} = gather(tbl.Value{ii}); end end end
checkForHMDB51Folder
checkForHMDB51Folder
функционируйте проверки на загруженные данные в папке загрузки.
function classes = checkForHMDB51Folder(dataLoc) hmdbFolder = fullfile(dataLoc, "hmdb51_org"); if ~isfolder(hmdbFolder) error("Download 'hmdb51_org.rar' file using the supporting function 'downloadHMDB51' before running the example and extract the RAR file."); end classes = ["brush_hair","cartwheel","catch","chew","clap","climb","climb_stairs",... "dive","draw_sword","dribble","drink","eat","fall_floor","fencing",... "flic_flac","golf","handstand","hit","hug","jump","kick","kick_ball",... "kiss","laugh","pick","pour","pullup","punch","push","pushup","ride_bike",... "ride_horse","run","shake_hands","shoot_ball","shoot_bow","shoot_gun",... "sit","situp","smile","smoke","somersault","stand","swing_baseball","sword",... "sword_exercise","talk","throw","turn","walk","wave"]; expectFolders = fullfile(hmdbFolder, classes); if ~all(arrayfun(@(x)exist(x,'dir'),expectFolders)) error("Download hmdb51_org.rar using the supporting function 'downloadHMDB51' before running the example and extract the RAR file."); end end
downloadHMDB51
downloadHMDB51
функционируйте загружает набор данных и сохраняет его в директорию.
function downloadHMDB51(dataLoc) if nargin == 0 dataLoc = pwd; end dataLoc = string(dataLoc); if ~isfolder(dataLoc) mkdir(dataLoc); end dataUrl = "http://serre-lab.clps.brown.edu/wp-content/uploads/2013/10/hmdb51_org.rar"; options = weboptions('Timeout', Inf); rarFileName = fullfile(dataLoc, 'hmdb51_org.rar'); % Download the RAR file and save it to the download folder. if ~isfile(rarFileName) disp("Downloading hmdb51_org.rar (2 GB) to the folder:") disp(dataLoc) disp("This download can take a few minutes...") websave(rarFileName, dataUrl, options); disp("Download complete.") disp("Extract the hmdb51_org.rar file contents to the folder: ") disp(dataLoc) end end
initializeTrainingProgressPlot
initializeTrainingProgressPlot
функция конфигурирует два графика для отображения учебной потери, учебной точности и точности валидации.
function plotters = initializeTrainingProgressPlot(params) if params.ProgressPlot % Plot the loss, training accuracy, and validation accuracy. figure % Loss plot subplot(2,1,1) plotters.LossPlotter = animatedline; xlabel("Iteration") ylabel("Loss") % Accuracy plot subplot(2,1,2) plotters.TrainAccPlotter = animatedline('Color','b'); plotters.ValAccPlotter = animatedline('Color','g'); legend('Training Accuracy','Validation Accuracy','Location','northwest'); xlabel("Iteration") ylabel("Accuracy") else plotters = []; end end
updateProgressPlot
updateProgressPlot
функционируйте обновляет график прогресса с информацией о потере и точности во время обучения.
function updateProgressPlot(params,plotters,epoch,iteration,start,lossTrain,accuracyTrain,accuracyValidation) if params.ProgressPlot % Update the training progress. D = duration(0,0,toc(start),"Format","hh:mm:ss"); title(plotters.LossPlotter.Parent,"Epoch: " + epoch + ", Elapsed: " + string(D)); addpoints(plotters.LossPlotter,iteration,double(gather(extractdata(lossTrain)))); addpoints(plotters.TrainAccPlotter,iteration,accuracyTrain); addpoints(plotters.ValAccPlotter,iteration,accuracyValidation); drawnow end end
initializeVerboseOutput
initializeVerboseOutput
функционируйте отображает заголовки столбцов для таблицы учебных значений, которая показывает эпоху, мини-пакетную точность и другие учебные значения.
function initializeVerboseOutput(params) if params.Verbose disp(" ") if canUseGPU disp("Training on GPU.") else disp("Training on CPU.") end p = gcp('nocreate'); if ~isempty(p) disp("Training on parallel cluster '" + p.Cluster.Profile + "'. ") end disp("NumIterations:" + string(params.NumIterations)); disp("MiniBatchSize:" + string(params.MiniBatchSize)); disp("Classes:" + join(string(params.Classes), ",")); disp("|=======================================================================================================================================================================|") disp("| Epoch | Iteration | Time Elapsed | Mini-Batch Accuracy | Validation Accuracy | Mini-Batch | Validation | Base Learning | Train Time | Validation Time |") disp("| | | (hh:mm:ss) | (Avg:RGB:Flow) | (Avg:RGB:Flow) | Loss | Loss | Rate | (hh:mm:ss) | (hh:mm:ss) |") disp("|=======================================================================================================================================================================|") end end
displayVerboseOutputEveryEpoch
displayVerboseOutputEveryEpoch
функция отображает многословный вывод учебных значений, таких как эпоха, мини-пакетная точность, точность валидации и мини-пакетная потеря.
function displayVerboseOutputEveryEpoch(params,start,learnRate,epoch,iteration,... accTrain,accTrainRGB,accTrainFlow,accValidation,accValidationRGB,accValidationFlow,lossTrain,lossValidation,trainTime,validationTime) if params.Verbose D = duration(0,0,toc(start),'Format','hh:mm:ss'); trainTime = duration(0,0,trainTime,'Format','hh:mm:ss'); validationTime = duration(0,0,validationTime,'Format','hh:mm:ss'); lossValidation = gather(extractdata(lossValidation)); lossValidation = compose('%.4f',lossValidation); accValidation = composePadAccuracy(accValidation); accValidationRGB = composePadAccuracy(accValidationRGB); accValidationFlow = composePadAccuracy(accValidationFlow); accVal = join([accValidation,accValidationRGB,accValidationFlow], " : "); lossTrain = gather(extractdata(lossTrain)); lossTrain = compose('%.4f',lossTrain); accTrain = composePadAccuracy(accTrain); accTrainRGB = composePadAccuracy(accTrainRGB); accTrainFlow = composePadAccuracy(accTrainFlow); accTrain = join([accTrain,accTrainRGB,accTrainFlow], " : "); learnRate = compose('%.13f',learnRate); disp("| " + ... pad(string(epoch),5,'both') + " | " + ... pad(string(iteration),9,'both') + " | " + ... pad(string(D),12,'both') + " | " + ... pad(string(accTrain),26,'both') + " | " + ... pad(string(accVal),26,'both') + " | " + ... pad(string(lossTrain),10,'both') + " | " + ... pad(string(lossValidation),10,'both') + " | " + ... pad(string(learnRate),13,'both') + " | " + ... pad(string(trainTime),10,'both') + " | " + ... pad(string(validationTime),15,'both') + " |") end function acc = composePadAccuracy(acc) acc = compose('%.2f',acc*100) + "%"; acc = pad(string(acc),6,'left'); end end
endVerboseOutput
endVerboseOutput
функционируйте отображает конец многословного выхода во время обучения.
function endVerboseOutput(params) if params.Verbose disp("|=======================================================================================================================================================================|") end end
[1] Carreira, Жоао и Эндрю Зиссермен. "Quo Vadis, распознавание действия? Новая модель и набор данных кинетики". Продолжения конференции по IEEE по компьютерному зрению и распознаванию образов (CVPR): 6299?? 6308. Гонолулу, HI: IEEE, 2017.
[2] Симонян, Карен и Эндрю Зиссермен. "2D поток сверточные сети для распознавания действия в видео". Усовершенствования в нейронных системах обработки информации 27, Лонг-Бич, CA: ЗАЖИМЫ, 2017.
[3] Лощилов, Илья и Франк Хуттер. "SGDR: стохастический градиентный спуск с горячими перезапусками". Международный Conferencee на изучении представлений 2017. Тулон, Франция: ICLR, 2017.
[4] Дю Тран, Хэн Ван, Лоренсо Торресани, Джейми Рэй, Yann LeCun, Manohar Paluri. "Более внимательное рассмотрение в Пространственно-временных Свертках для Распознавания Действия". Продолжения Конференции по IEEE по Компьютерному зрению и Распознаванию образов (CVPR), 2018, стр 6450-6459.
[5] Кристоф Файхтенхофер, Хэоки Фэн, Джитендра Малик и Кэйминг он. "Сети SlowFast для видео распознавания". Продолжения конференции по IEEE по компьютерному зрению и распознаванию образов (CVPR), 2019.
[6] Уилл Кей, Жоао Карреира, Карен Симонян, Брайн Чжан, Хлоя Хиллир, Sudheendra Vijayanarasimhan, Фабио Виола, Тим Грин, Тревор Бэк, Пол Нацев, Мустафа Сулейман, Эндрю Зиссермен. "Набор данных Видео Человеческой деятельности кинетики". arXiv предварительно распечатывают arXiv:1705.06950, 2017.