1. 加载图像
1.1 使用imread函数加载图像,可以加载GIF、JPEG、PNG等大多数标准文件格式图像。
Import an image
img = imread("file.jpg")
1.2 采用**imshow()**来显示图像。
imshow(img)
1.3 采用alexnet函数可以创建预定义的深度网络AlexNet的副本。
deepnet = alexnet
1.4 采用classify函数可以对图像进行预测。
pre1 = classify(deepnet,img2)
1.5 通过附加功能可以扩展MATLAB的功能,安装相关工具。
2.CNN
2.1 像任何CNN一样,在MATLAB存储在数组中,第一个和最后一个元素分别为输入层和输出层。
2.2 在AlexNet中,如上deepnet表示一个深度卷积网络,可以使用variable.Property索引来引用变量的Layers属性。
ly = deepnet.Layers
%通过索引访问层数组中的某层。
inlayer = ly(1)
%网络的每个层都有与其类型相关的属性。
insz = inlayer.InputSize
2.3 图像维度
灰度图像在MATLAB中表示为m x n数组,每个元素代表对应图像像素的强度,彩色图像表示为m x n x 3 的数组,三个m x n的平面分别表示红色、绿色和蓝色的强度。
2.4 AlexNet要求输入的图像大小为227 x 227 x 3。
2.5 将输入归入 n 个类之一,神经网络具有一个包含 n 个神经元的输出层,每个类对应一个神经元。网络接受输入后,会为每个神经元计算一个数值。这些数值代表网络对输入可能属于每个类的概率所做的预测。
2.6 classify 函数默认输出网络打分最高的类。但可以使用 classify 的另一个输出参数来获得所有类的预测分数。
[pred,scrs] = classify(net,img)
2.7 使用bar函数可以绘制条形图,使用xticklabels 函数可以为条形图绘制分类标签。
%设置标签的显示形式
xticks(1:length(scores(highscores)))
xticklabels(categorynames(highscores))
xtickangle(60)
3.图像数据存储
3.1 数据存储,是一种MATLAB变量,可以引用数据源,像图像文件的文件夹。MATLAB会遍历相关文件并存储一些基本信息。如文件的名称和格式。
3.2 使用 imageDatastore 函数在 MATLAB 中创建一个数据存储,指定文件夹名称或文件名作为输入。您可以使用通配符(*)来指定多个文件。
% 引用以foo开头的所有png文件
ds = imageDatastore('foo*.png')
3.3 可以使用Files属性提取图像文件名。
fname = ds.Files
3.4 使用 read、readimage 和 readall 函数从数据存储手动导入数据:read 按顺序一次导入一个图像;readimage 导入单个特定图像;readall 将所有图像导入一个元胞数组中(每个图像位于一个单独元胞中)。
% 读取第n张图片
I = readimage(ds,n)
3.5 可以在classify中使用数据存储来代替单个图像。
preds = classify(net,ds)
3.6查看图像,可以通过APP中的Image Browser打开文件列表,可以查看看图像。
3.7 调整输入,使用size可以查看图像的大小;
3.8 获取AlexNet网络的层数组,并获取第一层的大小。
net = alexnet
layer = net.Layers
insz = layer(1).InputSize
3.9 可使用imresize函数调整图像的大小,使其与预期的输入大小相匹配。
%img 调整为 numrows×numcols。也就是说,imgresz 的宽度为 numcols 个像素,高度为 numrow 个像素。
imgresz = imresize(img,[numrows numcols]);
imshow(img)
img = imresize(img,[227,227])
imshow(img)
3.10.图像预处理,对整个数据集执行相同的预处理,可以使用 augmentedImageDatastore 函数执行基本预处理,该函数接受图像数据存储和图像大小作为输入。数据存储可以传递给 classify 函数。
imds = imageDatastore("*.jpg")
3.11 增强的图像数据存储可以对整个集合图像执行简单的预处理。要创建此数据存储,请使用 augmentedImageDatastore 函数并将网络的图像输入大小用作输入。
auds = augmentedImageDatastore([r c],imds)
auds = augmentedImageDatastore([227,227],imds)
3.12 可以将增强的图像数据存储用作 classify 函数的输入。在对每个图像进行分类之前,将使用您创建数据存储时指定的方法对其进行预处理。
preds = classify(net,auds)
还可以使用 augmentedImageDatastore 函数将灰度图像转换为 RGB 图像。
4.颜色处理
4.1 灰度图像的大小是m x n x 1,在要求m x n x 3 的网络中,可以将灰度图转化为RGB图像;
4.2 使用montage 函数显示数据存储中的图像。
montage(imds)
4.3 在创建增强的图像数据存储时,可以通过设置 ColorPreprocessing 选项将这些图像转换为三维数组。
auds = augmentedImageDatastore([n m],...
imds,'ColorPreprocessing','gray2rgb')
auds = augmentedImageDatastore([227,227],imds,"ColorPreprocessing","gray2rgb")
5.用子文件夹选项创建数据存储
5.1 默认情况下,imageDatastore 只在给定文件夹内查找图像文件。可以使用 ‘IncludeSubfolders’ 选项在给定文件夹的子文件夹中查找图像。
ds = imageDatastore('Flowers','IncludeSubfolders',true)
6.迁移学习
6.1 采用预训练网络、并对其进行修改,并基于新数据对其进行重新训练的过程称之为迁移学习。通过迁移学习可以有效解决许多问题。其训练需要一些数据和一定的计算时间,但与从头开始训练相比要少得多,而且您可以获得适合解决您具体问题的网络。
6.2 迁移学习的要素
- Network layers
- Training data
- Algorithm options
- batch size
- Max iterations
- Learning rate
基于上述三要素,可以调用trainNetwork函数进行训练;
net = trainNetwork(data,layers,options)
6.3 标记图像
训练所需的标签可以存储在图像数据存储的 Labels 属性中。默认情况下,Labels 属性为空。可以指定 ‘LabelSource’ 选项,让数据存储根据文件夹名称自动确定标签。
%采用子文件夹名称作为标签
ds = imageDatastore(folder,'IncludeSubfolders',true,'LabelSource','foldernames')
flwrds = imageDatastore(pathToImages,'IncludeSubfolders',true,"LabelSource","foldernames");
flowernames = flwrds.Labels
6.4 训练数据和测试数据
使用 splitEachLabel 函数将数据存储中的图像分成两个单独的数据存储。
[ds1,ds2] = splitEachLabel(imds,p)
比例 p(从 0 到 1 的值)表示 imds 中各标签对应的图像应纳入 ds1 中的比例。其余文件分配给 ds2。
[flwrTrain ,flwrTest] = splitEachLabel(flwrds,0.6)
6.5 默认情况下,splitEachLabel 会保持文件有序。您可以通过添加可选的 ‘randomized’ 标志来实现随机乱序。
[flwrTrain ,flwrTest] = splitEachLabel(flwrds,0.8,"randomized")
6.6 为了避免**不平衡的训练数据,**在拆分数据时,最好使每个类的训练图像数量相同。
6.7 当 p 是从 0 到 1 的值时,它解释为比例。图像会基于标签按比例进行拆分。您还可以指定每个标签的对应文件中要分配给 ds1 的确切数量。
% 确保 ds1 中的每个标签都有 n 个图像,即使这些类别并不都包含相同数量的图像。
[ds1,ds2] = splitEachLabel(imds,n)
[flwrTrain ,flwrTest] = splitEachLabel(flwrds,50,"randomized")
6.8 增强的训练数据
- imageDatastore
- augmentedImageDatastore
- imageDataAugmenter,设置变换,如旋转,翻转,平移,剪切和缩放,可作为augmentedImageDatastore函数的输入。
- trainNetwork,augmentedImageDatastore可作为其输入参数,在训练时,数据会进行预处理。
6.9 修改网络层
主要包含卷积层,池化层和修正线性单元层,全连接层和softmax层等。在进行迁移学习时,通常只需要修改最后这几层,来建立新数据与类别的对应。
6.10 通过层数组索引相应的层,将创建的新层复制给需要修改的层。并修改。
% 创建一个具有n个神经元的全连接层
fclayer = fullyConnectedLayer(n)
fc = fullyConnectedLayer(12)
% 修改全连接层
layers(23) = fc
6.11 使用 classificationLayer 函数为图像分类网络创建一个新输出层。
layers(end) = classificationLayer
6.12 使用 trainingOptions 函数来查看所选训练算法的可用选项。
% 设置动量随机梯度下降训练算法的默认选项
opts = trainingOptions('sgdm')
6.13 学习率控制算法更改网络权重的幅度。迁移学习的目标是微调现有网络,因此与从头开始训练相比,通常希望更改权重的幅度不大。
可以在 trainingOptions 函数中使用名称-值对组指定任意数量的选项设置。
opts = trainingOptions("sgdm","InitialLearnRate",0.001)
7.训练
7.1 执行训练函数trainNetwork。
% 参数info记录了损失值和准确率。
[net,info] = trainNetwork(data,layers,options)
7.2 小批量
在每次迭代中,网络都会使用训练图像的一个子集来更新权重,这个子集称为小批量。每次迭代都采用不同的小批量。如果整个训练集都被使用过了,则称为完成了一轮。
可以在训练算法选项中设置的参数是最大轮数 (MaxEpochs) 和小批量的大小 (MiniBatchSize)。
默认情况下,图像在分成小批量之前会进行一次乱序处理。您可以使用 Shuffle 选项来控制此行为。
7.3 GPU
**GPU(图形处理单元)**可以大大加快深度学习所需的大量计算。如果计算机没有配备支持的 GPU,训练可以在 CPU 上执行,但可能需要很长时间。要真正地使用深度学习,最好在配备了具有足够处理能力的 GPU 的计算机上训练您的网络。
- 如果您安装了适当的 GPU 和 Parallel Computing Toolbox,trainNetwork 函数可自动在 GPU 上执行训练,无需专门编码。
- 如果没有安装,训练将在计算机的 CPU 上进行。您可以体验过后再决定是否购买所需的硬件和软件。
7.4 综合实例
%获取训练图像flower_ds = imageDatastore('Flowers','IncludeSubfolders',true,'LabelSource','foldernames');
[trainImgs,testImgs] = splitEachLabel(flower_ds,0.6);
numClasses = numel(categories(flower_ds.Labels));%通过修改 AlexNet 创建网络net = alexnet;
layers = net.Layers;
layers(end-2) = fullyConnectedLayer(numClasses);
layers(end) = classificationLayer;%设置训练算法选项options = trainingOptions('sgdm','InitialLearnRate', 0.001);%执行训练[flowernet,info] = trainNetwork(trainImgs, layers, options);%使用经过训练的网络对测试图像进行分类testpreds = classify(flowernet,testImgs);
8.评估训练
8.1 变量 info 是包含训练信息的结构体。TrainingLoss 和 TrainingAccuracy 字段包含网络在训练数据上进行每次迭代后达到的性能的记录。
8.2 绘制损失值和准确率曲线
plot(info.TrainingLoss)
8.3 使用逻辑比较和 nnz 函数来确定两个数组的匹配元素数;
numequal = nnz(a == b)
8.4 按类分析性能
- 损失和准确度给出的是网络性能的总体度量。进一步地研究网络对于不同类的图像的性能表现可发掘更多信息.
- confusionchart 函数计算并显示预测分类的 confusion matrix。
confusionchart(knownclass,predictedclass)
- 混淆矩阵的 (j,k) 元素值用于统计网络将 j 类中的多少个图像预测为属于类 k。因此,对角线上的元素代表正确分类;非对角线上的元素代表误分类。
8.5 提高性能
为了防止模型在训练集上表现好而在测试集上表现差,可以把训练的数据划分为训练集和验证集,在训练期间,在通过训练数据更新网络后,需要基于验证数据集测试网络性能。如果测试性能提高,则继续训练,否则停止训练,防止过拟合。
9.迁移学习总结
10.综合实例
10.1 回归与目标检测
- 回归是指在网络分析图像后返回一个数值,而非一个标签。可以使用Deep Learning Toolbox来执行回归。
- 返回图像中的特定区域,可以使用R-CNN,在Computer Vision System Toolbox中提供了可实现此目的的函数。