用神经图像评估量化图像质量
这个例子展示了如何使用神经图像评估(NIMA)卷积神经网络(CNN)分析图像的美学质量。
图像质量指标提供了图像质量的客观度量。一个有效的度量标准提供了与人类观察者对质量的主观感知密切相关的量化分数。质量指标使比较图像处理算法。
尼玛[1]是一种无参考技术,它在不依赖原始参考图像的情况下预测图像的质量,而原始参考图像通常不可用。NIMA使用CNN来预测每张图像的质量分数分布。
用训练过的NIMA模型评价图像质量
集dataDir
作为数据集的期望位置。
dataDir = fullfile(tempdir,“LIVEInTheWild”);如果~存在(dataDir“dir”mkdir (dataDir);结束
通过使用助手函数下载预先训练的NIMA神经网络downloadTrainedNetwork
.helper函数作为支持文件附加到示例中。金宝app该模型预测了每个图像在[1,10]范围内的质量分数分布,其中1和10分别是分数的最低和最高可能值。分数高表示图像质量好。
trainedNet_url =“https://ssd.mathworks.com/金宝appsupportfiles/image/data/trainedNIMA.zip”;downloadTrainedNetwork (trainedNet_url dataDir);负载(fullfile (dataDir“trainedNIMA.mat”));
您可以通过比较高质量和低质量图像的预测得分来评估NIMA模型的有效性。
将高质量的图像读入工作空间。
imOriginal = imread(“kobi.png”);
通过应用高斯模糊来降低图像的美学质量。以蒙太奇的方式显示原始图像和模糊图像。主观上,模糊图像的审美质量比原始图像的质量差。
imBlur = imgaussfilt(imOriginal,5);蒙太奇({imOriginal, imBlur})
预测两幅图像的NIMA质量分数分布predictNIMAScore
helper函数。该函数作为支持文件附加到示例中。金宝app
的predictNIMAScore
函数返回图像的NIMA评分分布的均值和标准差。预测的平均分是对图像质量的一种衡量。分数的标准差可以被认为是预测平均分置信水平的度量。
[meanOriginal,stdOriginal] = predictNIMAScore(dlnet,imOriginal);[meanBlur,stdBlur] = predictNIMAScore(dlnet,imBlur);
将图像连同NIMA模型预测的分数分布的均值和标准差一起显示出来。NIMA模型正确地预测了这些图像的得分,这些图像符合主观视觉评估。
图t = tiledlayout(1,2);displayImageAndScoresForNIMA (t, imOriginal meanOriginal stdOriginal,的“原始图像”) displayImageAndScoresForNIMA (t imBlur meanBlur stdBlur,“模糊图像”)
本示例的其余部分将展示如何训练和评估NIMA模型。
在野外数据集中实时下载
本例使用LIVE In the Wild数据集[2],这是一个公共领域的主观图像质量挑战数据库。该数据集包含1162张由移动设备拍摄的照片,另外7张图片用于训练人类评分者。每张图片平均由175个人评分[1,100]。数据集提供了每个图像主观得分的均值和标准差。
中列出的说明下载数据集野外生活图像质量挑战数据库.方法指定的目录中提取数据dataDir
变量。当提取成功时,dataDir
包含两个目录:数据
而且图片
.
加载动态数据
获取图像的文件路径。
imageData = load(fullfile(dataDir),“数据”,“AllImages_release.mat”));imageData = imageData. allimages_release;nImg =长度(imageData);imageList(1:7) = fullfile(dataDir,“图片”,“trainingImages”imageData (1:7));imageList(8:nImg) = fullfile(dataDir,“图片”imageData(8:结束));
创建用于管理映像数据的映像数据存储。
imds = imageDatastore(imageList);
加载图像对应的均值和标准差数据。
meanData = load(fullfile(dataDir),“数据”,“AllMOS_release.mat”));meanData. allmos_release;stdData = load(fullfile(dataDir),“数据”,“AllStdDev_release.mat”));stdData = stdData. allstddev_release;
可选地,显示数据集中的一些样本图像,并具有相应的平均值和标准差值。
图t = tiledlayout(1,3);Idx1 = 785;idx1 displayImageAndScoresForNIMA (t, readimage (imd),...meanData (idx1) stdData (idx1),“图像”imageData(idx1)) idx2 = 203;idx2 displayImageAndScoresForNIMA (t, readimage (imd),...meanData (idx2) stdData (idx2),“图像”+imageData(idx2)) idx3 = 777;idx3 displayImageAndScoresForNIMA (t, readimage (imd),...meanData (idx3) stdData (idx3),“图像”+ imageData (idx3))
预处理和增加数据
对图像进行预处理,将其大小调整为256 × 256像素。
rescaleSize = [256 256];imds = transform(imds,@(x)imresize(x,rescaleSize));
NIMA模型需要人类得分的分布,但LIVE数据集只提供分布的均值和标准差。方法近似LIVE数据集中每个图像的底层分布createNIMAScoreDistribution
helper函数。该函数作为支持文件附加到示例中。金宝app
的createNIMAScoreDistribution
将分数缩放到范围[1,10],然后从平均值和标准差值生成分数的最大熵分布。
newMaxScore = 10;prob = createNIMAScoreDistribution(meanData,stdData);cumProb = cumsum(prob,2);
创建一个arrayDatastore
管理分数分布。
probDS = arrayDatastore(cumProb',IterationDimension=2);
合并包含图像数据和分数分布数据的数据存储。
dsCombined = combine(imds,probDS);
预览从组合数据存储读取的输出。
sampleeread =预览(dsCombined)
sampleRead =1×2单元格数组{256×256×3 uint8} {10×1 double}
图tiledlayout(1,2) nexttile imshow(sampleRead{1}) title(“来自数据集的样本图像”nexttile (sampleRead{2})“累计分数分布”)
用于培训、验证和测试的分割数据
将数据划分为训练集、验证集和测试集。分配70%的数据用于培训,15%用于验证,其余用于测试。
numTrain = floor(0.70 * nImg);numVal = floor(0.15 * nImg);Idx = randperm(nImg);idxTrain = Idx(1:numTrain);idxVal = Idx(numTrain+1:numTrain+numVal);idxTest = Idx(numTrain+numVal+1:nImg);dsTrain =子集(dsCombined,idxTrain);dsVal =子集(dsCombined,idxVal);dsTest =子集(dsCombined,idxTest);
扩充训练数据
方法扩充训练数据augmentDataForNIMA
helper函数。该函数作为支持文件附加到示例中。金宝app的augmentDataForNIMA
函数对每个训练图像执行这些增强操作:
将图像裁剪为224 × 244像素,以减少过拟合。
以50%的概率水平翻转图像。
inputSize = [224 224];dsTrain = transform(dsTrain,@(x)augmentDataForNIMA(x,inputSize));
为输入归一化计算训练集统计数据
网络的输入层对训练图像进行z分数归一化处理。计算训练图像的均值和标准差,用于z分数归一化。
meanImage = 0 ([inputSize 3]);meanImageSq = 0 ([inputSize 3]);而hasdata(dsTrain) dat = read(dsTrain);Img = double(dat{1});meanImage = meanImage + img;meanImageSq = meanImageSq + img.^2;结束meanImage = meanImage/numTrain;meanImageSq = meanImageSq/numTrain;varImage = meanImageSq - meanImage.^2;stdImage = sqrt(varImage);
将数据存储重置为初始状态。
重置(dsTrain);
批量培训数据
创建一个minibatchqueue
(深度学习工具箱)对象,该对象在自定义训练循环中管理观察结果的小批处理。的minibatchqueue
对象还将数据转换为dlarray
(深度学习工具箱)对象,该对象可在深度学习应用中实现自动区分。
指定小批处理数据提取格式为"SSCB”
(空间,空间,渠道,批处理)。设置“DispatchInBackground”
返回的布尔值的名称-值参数canUseGPU
.如果支持的金宝appGPU可用于计算,则minibatchqueue
对象在训练期间在并行池的后台对小批进行预处理。
miniBatchSize = 128;mbqTrain = minibatchqueue(dsTrain,MiniBatchSize= MiniBatchSize,...PartialMiniBatch =“丢弃”MiniBatchFormat = (“SSCB”,""),...DispatchInBackground = canUseGPU);mbqVal = minibatchqueue(dsVal,MiniBatchSize= MiniBatchSize,...MiniBatchFormat = [“SSCB”,""), DispatchInBackground = canUseGPU);
加载和修改MobileNet-v2网络
本示例从MobileNet-v2开始[3]CNN使用ImageNet进行训练[4].该示例修改了网络,将MobileNet-v2网络的最后一层替换为具有10个神经元的完全连接层,每个神经元代表从1到10的一个离散分数。该网络预测每张图像的每个分数的概率。该示例使用softmax激活层规范了全连接层的输出。
的mobilenetv2
(深度学习工具箱)函数返回预先训练过的MobileNet-v2网络。此功能需要深度学习工具箱™模型用于MobileNet-v2网络金宝app支持包。如果没有安装此支金宝app持包,则该功能提供下载链接。
Net = mobilenetv2;
把网络转换成alayerGraph
(深度学习工具箱)对象。
lgraph = layerGraph(net);
该网络的图像输入大小为224 × 224像素。用图像输入层替换输入层,该图像输入层使用训练图像的平均值和标准差对图像数据执行z分数归一化。
inLayer = imageInputLayer([inputSize 3],Name=“输入”,...归一化=“zscore”意味着= meanImage StandardDeviation = stdImage);lgraph = replaceLayer(lgraph,“input_1”、镶嵌者);
将原来的最终分类层替换为具有10个神经元的完全连接层。添加一个softmax层来规范化输出。设置全连通层学习率为CNN基线层学习率的10倍。应用75%的dropout。
lgraph = removeLayers(lgraph,[“ClassificationLayer_Logits”,“Logits_softmax”,“分对数”]);newFinalLayers = [dropoutLayer(0.75,Name= .“下降”) fullyConnectedLayer (newMaxScore Name =“俱乐部”WeightLearnRateFactor = 10, BiasLearnRateFactor = 10) softmaxLayer (Name =“概率”));lgraph = addLayers(lgraph,newFinalLayers);lgraph = connectLayers(lgraph,“global_average_pooling2d_1”,“下降”);Dlnet = dlnetwork(lgraph);
来可视化网络深度网络设计器(深度学习工具箱)应用程序。
deepNetworkDesigner (lgraph)
定义模型梯度和损失函数
的modelGradients
辅助函数计算网络每次迭代训练的梯度和损失。函数中定义了此函数金宝app支持功能部分。
NIMA网络的目标是使地面真实值与预测分数分布之间的距离(EMD)最小化。EMD损失在惩罚错误分类时考虑了类之间的距离。因此,EMD损耗比分类任务中使用的典型软最大交叉熵损耗性能更好[5].方法计算EMD损失earthMoverDistance
类中定义的Helper函数金宝app支持功能部分。
对于EMD损失函数,使用r-范数距离r= 2。当你使用梯度下降时,这个距离可以很容易地进行优化。
指定培训选项
指定SGDM优化的选项。将网络训练到150个时代。
numEpochs = 150;动量= 0.9;initialLearnRate = 3e-3;衰减= 0.95;
列车网络的
默认情况下,该示例加载NIMA网络的预训练版本。预先训练的网络使您可以运行整个示例,而无需等待训练完成。
要训练网络,请设置doTraining
变量的真正的
.在自定义训练循环中训练模型。对于每次迭代:
方法读取当前小批处理的数据
下一个
(深度学习工具箱)函数。评估模型的梯度使用
dlfeval
(深度学习工具箱)功能和modelGradients
helper函数。更新网络参数
sgdmupdate
(深度学习工具箱)函数。
如果有GPU,请使用GPU进行训练。使用GPU需要并行计算工具箱™和CUDA®支持的NVIDIA®GPU。有关更多信息,请参见GPU支金宝app持按版本划分(并行计算工具箱).
doTraining = false;如果doTraining迭代= 0;速度= [];开始= tic;[hFig,lineLossTrain,lineLossVal] = initializeTrainingPlotNIMA;为epoch = 1:numEpochs shuffle (mbqTrain);learnRate = initialLearnRate/(1+衰减*地板(epoch/10));而hasdata(mbqTrain)迭代=迭代+ 1;[dlX,cdfY] = next(mbqTrain);[grad,loss] = dlfeval(@modelGradients,dlnet,dlX,cdfY);[dlnet,velocity] = sgdmupdate(dlnet,grad,velocity,learnRate,momentum);updateTrainingPlotNIMA (lineLossTrain损失、时代、迭代,开始)结束向图中添加验证数据[~,lossVal,~] = modelforecasts (dlnet,mbqVal);时代,updateTrainingPlotNIMA (lineLossVal lossVal迭代,开始)结束%保存训练过的网络modelDateTime = string(datetime)“现在”格式=“yyyy-MM-dd-HH-mm-ss”));保存(fullfile (dataDir“trainedNIMA——”+ modelDateTime +“.mat”),“dlnet”);其他的负载(fullfile (dataDir“trainedNIMA.mat”));结束
评价NIMA模型
使用三个指标评估模型在测试数据集上的性能:EMD、二元分类精度和相关系数。NIMA网络在测试数据集上的性能与Talebi和Milanfar报告的参考NIMA模型的性能一致[1].
创建一个minibatchqueue
(深度学习工具箱)对象,该对象管理测试数据的小批处理。
mbqTest = minibatchqueue(dsTest,MiniBatchSize= MiniBatchSize,MiniBatchFormat=[“SSCB”,""]);
计算小批量测试数据的预测概率和基础真实累积概率modelPredictions
函数。函数中定义了此函数金宝app支持功能部分。
[YPredTest,~,cdfYTest] = modelprediction (dlnet,mbqTest);
计算地面真实值和预测分布的平均值和标准差值。
meanPred = extractdata(YPredTest)' * (1:10)';stdPred = sqrt(extractdata(YPredTest)'*((1:10).^2)' - meanPred.^2);origCdf = extractdata(cdfYTest);origPdf = [origCdf(1,:);diff (origCdf)];meanOrig = origPdf' * (1:10)';stdOrig =√origPdf‘*((1:10)^ 2)”——meanOrig。^ 2);
计算EMD
计算ground truth的EMD和预测分数分布。对于预测,使用r-范数距离r= 1。EMD值表示预测和地面真实度评级分布的接近度。
EMDTest = earthmovedistance (YPredTest,cdfYTest,1)
EMDTest = 1×1 single gpuArray dlarray 0.0974
计算二进制分类精度
对于二进制分类精度,将分布转换为两种分类:高质量和低质量。将平均得分大于阈值的图像分类为高质量图像。
qualityThreshold = 5;binaryPred = meanPred > qualityThreshold;binaryOrig = meanOrig > qualityThreshold;
计算二进制分类精度。
binaryAccuracy = 100 * sum(binaryPred==binaryOrig)/length(binaryPred)
binaryAccuracy = 81.8182
计算相关系数
相关值越大,表明地面真相与预测分数之间的正相关越大。计算均分的线性相关系数(LCC)和斯皮尔曼等级相关系数(SRCC)。
meanLCC = corr(meanOrig,meanPred)
meanLCC = gpuArray single 0.8270
meanSRCC = corr(meanOrig,meanPred,type=“枪兵”)
meanSRCC = gpuArray single 0.8133
金宝app支持功能
模型梯度函数
的modelGradients
函数以a作为输入dlnetwork
对象dlnet
以及一小批输入数据dlX
对应的目标累积概率cdfY
.函数返回损失相对于可学习参数的梯度dlnet
还有损失。方法可自动计算梯度dlgradient
函数。
函数[gradient,loss] = modelGradients(dlnet,dlX,cdfY) dlYPred = forward(dlnet,dlX);损失= earthmovedistance (dlYPred,cdfY,2);gradient = dlgradient(loss,dlnet.Learnables);结束
损失函数
的earthMoverDistance
函数计算指定的基础真实值和预测分布之间的EMDr规范值。的earthMoverDistance
使用computeCDF
辅助函数来计算预测分布的累积概率。
函数损失= earthmovedistance (YPred,cdfY,r) N = size(cdfY,1);cdfYPred = computeCDF(YPred);cdfDiff = (1/N) * (abs(cdfY - cdfYPred).^r);lossArray = sum(cdfDiff,1).^(1/r);loss = mean(lossArray);结束函数cdfY = computeCDF(Y)给定一个概率质量函数Y,计算累积概率[N,miniBatchSize] = size(Y);L = repmat(triu(ones(N)),1,1,miniBatchSize);L3d = permute(L,[1 3 2]);prod = y *L3d;prodSum = sum(prod,1);cdfY =重塑(prodSum(:)',miniBatchSize,N)';结束
模型预测函数
的modelPredictions
函数计算小批量数据的估计概率、损失概率和基本真理累计概率。
函数[dlYPred,loss,cdfYOrig] = modelprediction (dlnet,mbq) reset(mbq);损失= 0;numObservations = 0;dlYPred = [];cdfYOrig = [];而hasdata(mbq) [dlX,cdfY] = next(mbq);miniBatchSize = size(dlX,4);dlY = predict(dlnet,dlX);loss = loss + earthMoverDistance(dlY,cdfY,2)*miniBatchSize;dlYPred = [dlYPred dlY];cdfyoreg = [cdfyoreg cdfY];numObservations = numObservations + miniBatchSize;结束loss = loss / numObservations;结束
参考文献
[1] Talebi, Hossein, Peyman Milanfar。“NIMA:神经图像评估。”IEEE图像处理汇刊27,no。8(2018年8月):3998-4011。https://doi.org/10.1109/TIP.2018.2831899.
[2] LIVE:图像与视频工程实验室。"野外生活图像质量挑战数据库"https://live.ece.utexas.edu/research/ChallengeDB/index.html.
[3]桑德勒,马克,安德鲁·霍华德,朱梦龙,安德烈·日莫吉诺夫,陈良杰。《MobileNetV2:反向残差和线性瓶颈》。2018年IEEE/CVF计算机视觉与模式识别会议,4510-20。盐湖城,犹他州:IEEE, 2018。https://doi.org/10.1109/CVPR.2018.00474.
[4] ImageNet。https://www.image-net.org.
[5]侯,乐,于晨萍,Dimitris Samaras。《Squared Earth Mover的基于距离的损失训练深度神经网络》预印本,2016年11月30日提交。https://arxiv.org/abs/1611.05916.
另请参阅
mobilenetv2
(深度学习工具箱)|变换
|layerGraph
(深度学习工具箱)|dlnetwork
(深度学习工具箱)|minibatchqueue
(深度学习工具箱)|预测
(深度学习工具箱)|dlfeval
(深度学习工具箱)|sgdmupdate
(深度学习工具箱)
相关的话题
- 图像质量指标
- 用于深度学习的数据存储(深度学习工具箱)
- 定义自定义训练循环,损失函数和网络(深度学习工具箱)
- 定义自定义训练循环的模型损失函数(深度学习工具箱)
- 在自定义训练循环中指定训练选项(深度学习工具箱)
- 使用自定义训练循环训练网络(深度学习工具箱)