利用预训练网络提取图像特征
这个例子展示了如何从预训练的卷积神经网络中提取学习到的图像特征,并使用这些特征来训练图像分类器。特征提取是使用预训练深度网络的表示能力的最简单和最快的方法。例如,您可以使用训练支持向量机(SVM)金宝appfitcecoc
(统计和机器学习工具箱™)对提取的特征。因为特征提取只需要通过数据一次,如果你没有GPU来加速网络训练,这是一个很好的起点。
加载数据
解压缩并将示例图像加载为图像数据存储。imageDatastore
根据文件夹名称自动标记图像,并将数据存储为ImageDatastore
对象。图像数据存储允许您存储大型图像数据,包括不适合内存的数据。将数据分成70%的训练数据和30%的测试数据。
解压缩(“MerchData.zip”);imds = imageDatastore(“MerchData”,“IncludeSubfolders”,真的,“LabelSource”,“foldernames”);[imdsTrain,imdsTest] = splitEachLabel(imds,0.7,“随机”);
在这个非常小的数据集中,现在有55张训练图像和20张验证图像。显示一些示例图像。
numTrainImages = numel(imdsTrain.Labels);idx = randperm(numTrainImages,16);数字为i = 1:16 subplot(4,4,i) i = readimage(imdsTrain,idx(i));imshow(我)结束
负荷预训练网络
加载一个预先训练好的ResNet-18网络。如果深度学习工具箱模型ResNet-18网络金宝app支持包未安装时,则软件提供下载链接。ResNet-18在超过100万张图像上进行训练,可以将图像分为1000个对象类别,例如键盘、鼠标、铅笔和许多动物。因此,该模型已经学习了广泛图像的丰富特征表示。
Net = resnet18
net = DAGNetwork with properties: Layers: [71x1 nnet.cnn.layer.Layer] Connections: [78x2 table] InputNames: {'data'} OutputNames: {'ClassificationLayer_predictions'}
分析网络结构。第一层是图像输入层,需要输入图像的大小为224 × 224 × 3,其中3是颜色通道的数量。
inputSize = net.Layers(1).InputSize;analyzeNetwork(净)
提取图像特征
网络需要大小为224 × 224 × 3的输入映像,但是映像数据存储中的映像具有不同的大小。若要在将训练和测试图像输入到网络之前自动调整它们的大小,请创建增强图像数据存储,指定所需的图像大小,并将这些数据存储用作的输入参数激活
.
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain);augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);
该网络构造了输入图像的分层表示。较深的层包含较高级的特性,这些特性是使用较早层的较低级特性构造的。要获得训练图像和测试图像的特征表示,请使用激活
在全局池化层,“pool5”,
在网络的末端。全局池化层将所有空间位置的输入特征池化,总共给出512个特征。
层=“pool5”;featuresTrain =激活(net,augimdsTrain,layer,“OutputAs”,“行”);featuresTest =激活(net,augimdsTest,layer,“OutputAs”,“行”);谁featuresTrain
名称大小字节类属性featuresTrain 55x512 112640 single
从训练和测试数据中提取类标签。
YTrain = imdsTrain.Labels;YTest = imdsTest.Labels;
拟合图像分类器
利用从训练图像中提取的特征作为预测变量,拟合多类支持向量机(SVM)金宝appfitcecoc
(统计和机器学习工具箱)。
classifier = fitcecoc(featuresTrain,YTrain);
分类测试图像
利用从测试图像中提取的特征,使用训练好的SVM模型对测试图像进行分类。
YPred = predict(分类器,featurest);
显示四个样本测试图像及其预测标签。
Idx = [1 5 10 15];数字为i = 1: nummel (idx) subplot(2,2,i) i = readimage(imdsTest,idx(i));标签= YPred(idx(i));imshow (I)标题(char(标签)结束
计算测试集上的分类精度。准确率是网络正确预测的标签的比例。
accuracy = mean(YPred == YTest)
准确度= 1
浅特征上的训练分类器
您还可以从网络中的早期层提取特征,并在这些特征上训练分类器。早期的层通常提取更少、更浅的特征,具有更高的空间分辨率和更大的激活总数。中提取特征“res3b_relu”
层。这是输出128个特征的最后一层,激活的空间大小为28 × 28。
层=“res3b_relu”;featuresTrain =激活(net,augimdsTrain,layer);featuresTest =激活(net,augimdsTest,layer);谁featuresTrain
名称大小字节类属性featuresTrain 28x28x128x55 22077440 single
在本示例的第一部分中使用的提取的特征通过全局池化层在所有空间位置上进行池化。为了在提取早期层的特征时获得相同的结果,手动平均所有空间位置的激活。来获取表单上的特征N
——- - - - - -
C
,在那里N观察的次数和C是特征数,去掉单维并转置。
featuresTrain = squeeze(mean(featuresTrain,[1 2]))';featuresTest = squeeze(mean(featuresTest,[1 2]))';谁featuresTrain
名称大小字节类属性featuresTrain 55x128 28160 single
在浅层特征上训练支持向量机分类器。计算测试精度。
classifier = fitcecoc(featuresTrain,YTrain);YPred = predict(分类器,featurest);accuracy = mean(YPred == YTest)
准确度= 0.9500
两种训练过的支持向量机都具有较高的精度。如果使用特征提取的准确率不够高,那么可以尝试迁移学习。有关示例,请参见训练深度学习网络对新图像进行分类.有关预训练网络的列表和比较,请参见预训练的深度神经网络.