В этом примере показано, как классифицировать гиперспектральные изображения с помощью пользовательской спектральной нейронной сети свертки (CSCNN) для классификации.
Гиперспектральные меры обработки изображений пространственные и спектральные функции объекта в различных длинах волн в пределах от ультрафиолетового излучения через длинное инфракрасное излучение, включая видимый спектр. В отличие от цветной обработки изображений, которая использует только три типа датчиков, чувствительных к красным, зеленым, и синим фрагментам видимого спектра, гиперспектральные изображения могут включать десятки или сотни каналов. Поэтому гиперспектральные изображения могут включить дифференцирование объектов, которые кажутся идентичными в изображении RGB.
Этот пример использует CSCNN, который учится классифицировать 16 типов растительности и ландшафта на основе уникальных спектральных подписей каждого материала. Пример показывает, как обучить CSCNN и также обеспечивает предварительно обученную сеть, которую можно использовать, чтобы выполнить классификацию.
Этот пример использует индийский Сосновый набор данных, включенный с Image Processing Toolbox™ Гиперспектральная Библиотека Обработки изображений. Набор данных состоит из одного гиперспектрального изображения размера 145 145 пиксели с 220 цветовыми каналами. Набор данных также содержит изображение метки основной истины с 16 классами, такими как Люцерна, Зерно, пастбище Травы, Травяные деревья и Каменные Стальные Башни.
Считайте гиперспектральное изображение с помощью hypercube
функция.
hcube = hypercube('indian_pines.dat');
Визуализируйте версию фиктивного цвета изображения с помощью colorize
функция.
rgbImg = colorize(hcube,'method','rgb'); imshow(rgbImg)
Загрузите метки основной истины и задайте количество классов.
gtLabel = load('indian_pines_gt.mat');
gtLabel = gtLabel.indian_pines_gt;
numClasses = 16;
Сократите количество диапазонов к 30 использованиям hyperpca
функция. Эта функция выполняет анализ главных компонентов (PCA) и выбирает диапазоны с самыми уникальными подписями.
dimReduction = 30; imageData = hyperpca(hcube,dimReduction);
Нормируйте данные изображения.
sd = std(imageData,[],3); imageData = imageData./sd;
Разделите гиперспектральное изображение в закрашенные фигуры размера 25 25 пиксели с 30 каналами с помощью createImagePatchesFromHypercube
функция помощника. Эта функция присоединена к примеру как к вспомогательному файлу. Функция также возвращает одну метку для каждой закрашенной фигуры, которая является меткой центрального пикселя.
windowSize = 25; inputSize = [windowSize windowSize dimReduction]; [allPatches,allLabels] = createImagePatchesFromHypercube(imageData,gtLabel,windowSize); indianPineDataTransposed = permute(allPatches,[2 3 4 1]); dsAllPatches = augmentedImageDatastore(inputSize,indianPineDataTransposed,allLabels);
Не все кубы в этом наборе данных имеют метки. Однако обучение сети требует маркированных данных. Выберите только помеченные кубы для обучения. Рассчитайте, сколько помеченных закрашенных фигур доступно.
patchesLabeled = allPatches(allLabels>0,:,:,:); patchLabels = allLabels(allLabels>0); numCubes = size(patchesLabeled,1);
Преобразуйте числовые метки в категориальный.
patchLabels = categorical(patchLabels);
Случайным образом разделите закрашенные фигуры на наборы тестовых данных и обучение.
[trainingIndex,validationIndex,testInd] = dividerand(numCubes,0.3,0.7,0); dataInputTrain = patchesLabeled(trainingIndex,:,:,:); dataLabelTrain = patchLabels(trainingIndex,1);
Транспонируйте входные данные.
dataInputTransposeTrain = permute(dataInputTrain,[2 3 4 1]); dataInputVal = patchesLabeled(validationIndex,:,:,:); dataLabelVal = patchLabels(validationIndex,1); dataInputTransposeVal = permute(dataInputVal,[2 3 4 1]);
Создайте хранилища данных, которые читают пакеты обучения и тестовых данных.
imdsTrain = augmentedImageDatastore(inputSize,dataInputTransposeTrain,dataLabelTrain); imdsTest = augmentedImageDatastore(inputSize,dataInputTransposeVal,dataLabelVal);
Задайте архитектуру CSCNN.
layers = [ image3dInputLayer(inputSize,'Name','Input','Normalization','None') convolution3dLayer([3 3 7],8,'Name','conv3d_1') reluLayer('Name','Relu_1') convolution3dLayer([3 3 5],16,'Name','conv3d_2') reluLayer('Name','Relu_2') convolution3dLayer([3 3 3],32,'Name','conv3d_3') reluLayer('Name','Relu_3') convolution3dLayer([3 3 1],8,'Name','conv3d_4') reluLayer('Name','Relu_4') fullyConnectedLayer(256,'Name','fc1') reluLayer('Name','Relu_5') dropoutLayer(0.4,'Name','drop_1') fullyConnectedLayer(128,'Name','fc2') dropoutLayer(0.4,'Name','drop_2') fullyConnectedLayer(numClasses,'Name','fc3') softmaxLayer('Name','softmax') classificationLayer('Name','output')]; lgraph = layerGraph(layers);
Визуализируйте сеть с помощью Deep Network Designer.
deepNetworkDesigner(lgraph)
Задайте необходимые сетевые параметры. В данном примере обучите сеть в течение 100 эпох с начальной скоростью обучения 0,001, пакетным размером 256, и оптимизация Адама.
numEpochs = 100; miniBatchSize = 256; initLearningRate = 0.001; momentum = 0.9; learningRateFactor = 0.01; options = trainingOptions('adam', ... 'InitialLearnRate',initLearningRate, ... 'LearnRateSchedule','piecewise', ... 'LearnRateDropPeriod',30, ... 'LearnRateDropFactor',learningRateFactor, ... 'MaxEpochs',numEpochs, ... 'MiniBatchSize',miniBatchSize, ... 'GradientThresholdMethod','l2norm', ... 'GradientThreshold',0.01, ... 'VerboseFrequency',100, ... 'ValidationData',imdsTest, ... 'ValidationFrequency',100);
По умолчанию пример загружает предварительно обученный классификатор для индийского Соснового набора данных с помощью downloadTrainedIndianPinesCSCNN
функция помощника. Эта функция присоединена к примеру как к вспомогательному файлу. Предварительно обученная сеть позволяет вам классифицировать индийский Сосновый набор данных, не ожидая обучения завершиться.
Чтобы обучить сеть, установите doTraining
переменная в следующем коде к true
. Если вы принимаете решение обучить сеть, использование способного графического процессора NVIDIA™ CUDA настоятельно рекомендовано. Для использования GPU требуется Parallel Computing Toolbox. Для получения дополнительной информации о поддерживаемых устройствах графического процессора, смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox).
doTraining = false; if doTraining modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss")); net = trainNetwork(imdsTrain,lgraph,options); save(strcat("IndianPinesCSCNN-",modelDateTime,"-Epoch-",num2str(numEpochs),".mat"),'net'); else dataFolder = fullfile(tempdir,"indianPines"); trainedHyperspectralCSCNN_url = 'https://ssd.mathworks.com/supportfiles/images/data/trainedIndianPinesCSCNN.mat'; downloadTrainedIndianPinesCSCNN(trainedHyperspectralCSCNN_url,dataFolder); load(fullfile(dataFolder,'trainedIndianPinesCSCNN.mat')); end
Pretrained CSCNN network already exists.
Вычислите точность классификации для набора тестовых данных. Здесь, точность является частью правильной классификации пикселей по всем классам.
predictionTest = classify(net,imdsTest);
accuracy = sum(predictionTest == dataLabelVal)/numel(dataLabelVal);
disp(['Accuracy of the test data = ', num2str(accuracy)])
Accuracy of the test data = 0.99359
Восстановите полный образ путем классификации всех пикселей изображения, включая пиксели в помеченных учебных закрашенных фигурах, пиксели в помеченных тестовых закрашенных фигурах и непомеченные пиксели.
prediction = classify(net,dsAllPatches); prediction = double(prediction);
Сеть обучена на помеченных закрашенных фигурах только. Поэтому предсказанная классификация непомеченных пикселей бессмысленна. Найдите непомеченные закрашенные фигуры и установите метку на 0
.
patchesUnlabeled = find(allLabels==0); prediction(patchesUnlabeled) = 0;
Измените классифицированные пиксели, чтобы совпадать с размерностями изображения основной истины.
[m,n,d] = size(imageData); indianPinesPrediction = reshape(prediction,[n m]); indianPinesPrediction = indianPinesPrediction';
Отобразите основную истину и предсказанную классификацию.
cmap = parula(numClasses); figure tiledlayout(1,2,"TileSpacing","Tight") nexttile imshow(gtLabel,cmap) title("Ground Truth Classification") nexttile imshow(indianPinesPrediction,cmap) colorbar title("Predicted Classification")
Чтобы подсветить неправильно классифицированные пиксели, отобразите составное изображение основной истины и предсказанных меток. Серые пиксели указывают на идентичные метки, и окрашенные пиксели указывают на различные метки.
figure imshowpair(gtLabel,indianPinesPrediction)
colorize
| hypercube
| hyperpca
| imageDatastore
| augmentedImageDatastore
(Deep Learning Toolbox) | classify
(Deep Learning Toolbox) | trainingOptions
(Deep Learning Toolbox) | trainNetwork
(Deep Learning Toolbox)