主要内容

このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

深層学習を使用したセマンティックセグメンテーション

この例では,深層学習を使用してセマンティックセグメンテーションネットワークの学習を行う方法を説明します。

セマンティック セグメンテーション ネットワークはイメージ内のすべてのピクセルを分類して、クラスごとにセグメント化されたイメージを作成します。セマンティック セグメンテーションの応用例としては、自動運転のための道路セグメンテーションや医療診断のための癌細胞セグメンテーションなどがあります。詳細は、深層学習を使用したセマンティックセグメンテーション入門を参照してください。

学習手順を示すために,この例では,セマンティックイメージセグメンテーション用に設計された1つのタイプの畳み込みニューラルネットワーク(CNN)であるDeeplab v3 +[1]に学習させます。他のタイプのセマンティックセグメンテーションネットワークには,完全畳み込みネットワーク(FCN) SegNet, U-Netなどがあります。ここで示す学習手順は,これらのネットワークにも適用することができます。

この例では,学習用にの剑桥大学CamVidデータセット[2]を使用します。このデータセットは,運転中に得られた路上レベルでのビューが含まれるイメージコレクションです。データセットは、車歩行者,道路を含む32個のセマンティッククラスについてピクセルレベルのラベルを提供します。

設定

この例では、事前学習済みの Resnet-18ネットワークから初期化された重みを使用して Deeplab v3+ネットワークを作成します。ResNet-18は、処理するリソースが限られている用途に非常に適した効率的なネットワークです。用途の要件によって、MobileNet v2や ResNet-50など、その他の事前学習済みのネットワークも使用できます。詳細は、事前学習済みの深層ニューラルネットワーク(深度学习工具箱)を参照してください。

事前学習済みのResnet-18を入手するには,深度学习工具箱™renet -18网络模型をインストールします。インストールが完了したら,次のコードを実行して正しくインストールされていることを確認します。

resnet18 ();

さらに,事前学習済みのバージョンのDeepLab v3 +をダウンロードします。事前学習済みのモデルを使用することで,学習の完了を待つことなく例全体を実行することができます。

pretrainedURL =“//www.tatmou.com/金宝appsupportfiles/vision/data/deeplabv3plusResnet18CamVid.mat”;pretrainedFolder = fullfile (tempdir,“pretrainedNetwork”);pretrainedNetwork = fullfile (pretrainedFolder,“deeplabv3plusResnet18CamVid.mat”);如果~存在(pretrainedNetwork“文件”mkdir (pretrainedFolder);disp ('下载预训练网络(58mb)…');websave (pretrainedNetwork pretrainedURL);结束

この例を実行するには,以3.0计算能力上のCUDA対応NVIDIA GPU™の使用が強く推奨されます。GPUを使用するには并行计算工具箱™が必要です。

摄像机データセットのダウンロード

次のURLからCamVidデータセットをダウンロードします。

imageURL =“http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/files/701_StillsRaw_full.zip”;拉贝鲁尔=“http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/LabeledApproved_full.zip”;outputFolder = fullfile (tempdir,“CamVid”);labelsZip = fullfile (outputFolder,“labels.zip”);imagesZip = fullfile (outputFolder,“images.zip”);如果~存在(labelsZip“文件”) | | ~存在(imagesZip“文件”mkdir (outputFolder) disp (“下载16mb CamVid数据集标签……”);websave (labelsZip labelURL);解压缩(labelsZip fullfile (outputFolder“标签”));disp (“下载557 MB CamVid数据集图像……”);websave (imagesZip imageURL);解压缩(imagesZip fullfile (outputFolder“图像”));结束

メモ:データのダウンロードにかかる時間はインターネット接続の速度によって異なります。上記で使用したコマンドは,ダウンロードが完了するまでMATLABをブロックします。別の方法として、Webブラウザーを使用して,データセットをローカルディスクにまずダウンロードしておくことができます。Webからダウンロードしたファイルを使用するには,上記の変数outputFolderの値を,ダウンロードしたファイルの場所に変更します。

CamVidイメージの読み込み

图像数据存储を使用してCamVidイメージを読み込みます。图像数据存储は,ディスク上の大規模なイメージコレクションを効率的に読み込むことができます。

imgDir = fullfile (outputFolder,“图像”701 _stillsraw_full); imds=图像数据存储(imgDir);

イメージのうちの1つを表示します。

I = readimage (imd, 559);I = histeq(我);imshow(我)

摄像机のピクセル ラベル付きイメージの読み込み

像素标签数据库を使用して、摄像机のピクセル ラベル イメージ データを読み込みます。像素标签数据库は,ピクセルラベルデータとラベルIDをクラス名のマッピングにカプセル化します。

学習を容易にするために,CamVidの元の32個のクラスを11個のクラスにグループ化します。次のクラスを指定します。

类别=[“天空”“建筑”“极”“路”“路面”“树”“SignSymbol”“篱笆”“汽车”“行人”“自行车”];

32個のクラスを11個に減らすには,元のデータセットの複数のクラスをグループとしてまとめます。たとえば,“汽车”,“SUVPickupTruck”、“Truck_Bus”,“火车”,および“OtherMovingを組み合わせたものを“车”とします。この例の最後にリストされているサポート関数camvidPixelLabelIDsを使用することで,グループ化されたラベルIDが返されます。

labelIDs = camvidPixelLabelIDs ();

クラスとラベルIDを使用してpixelLabelDatastore。を作成します。

labelDir = fullfile (outputFolder,“标签”);pxds = pixelLabelDatastore (labelDir、类labelIDs);

イメージの上に重ね合わせることで,ピクセルラベル付きイメージのうちの1つを読み取って表示します。

C=读取图像(pxds,559);cmap=camvidColorMap;B=labeloverlay(I,C,“ColorMap”,提出);imshow (B) pixelLabelColorbar(提出、类);

色の重ね合わせが存在しない領域にはピクセルラベルはなく,学習中は使用されません。

データセット統計の解析

摄像机データセット内のクラス ラベルの分布を表示するには、countEachLabelを使用します。この関数は,クラスラベル別にピクセルの数をカウントします。

台= countEachLabel (pxds)
台=11×3表名字PixelCount ImagePixelCount  ______________ __________ _______________ {' 天空}7.6801 4.8315 e + e + 07年08年{“建筑”}1.1737 e + 08年4.8315 e + 08年{“极点”}4.7987 4.8315 e + e + 06年08年{‘路’}1.4054 e + 08年4.8453 e + 08年{“路面”}3.3614 4.7209 e + e + 07年08年{‘树’}5.4259 4.479 e + e + 07年08年{‘SignSymbol} 5.2242 4.6863 e + e + 06年08年{“栅栏”}6.9211 2.516 e + e + 06年08年{'汽车'}{'行人'}3.4029e+06 4.4444e+08{'自行车'}2.5912e+06 2.6196e+08

ピクセル数をクラス別に可視化します。

frequency=tbl.PixelCount/sum(tbl.PixelCount);bar(1:numel(classes),frequency)xtick(1:numel(classes))xticklabel(tbl.Name)xtickangle(45)ylabel(“频率”

観測値の数がすべてのクラスで等しいことが理想的です。しかし、摄像机内のクラスは不均衡です。これは、路上シーンの自動車データセットに共通する問題です。こうしたシーンには、歩行者や自転車運転者のピクセルよりも多くの空、建物、および道路のピクセルが含まれます。これは、空、建物、および道路がイメージ内でより広い領域を占めているためです。学習では上位クラスを優先してバイアスがかけられるため、正しく処理されていない場合は、こうした不均衡が学習プロセスに悪影響を及ぼす可能性があります。この例の後半では、クラスの重み付けを使用してこの問題に対処します。

CamVidデータセット内のイメージのサイズは720×960です。イメージサイズは12 GBのメモリ搭載のNVIDIA™泰坦Xでの学習時に,イメージの十分な大きさのバッチがメモリに収まるように選択されます。GPUに十分なメモリがない場合には,イメージをより小さいサイズに変更するか,学習バッチのサイズを小さくする必要があります。

学習セット,検証セット,およびテストセットの準備

Deeplab v3 +の学習には,データセットのイメージの60%が使用されます。残りのイメージは均等に20%ずつに分割され,検証とテストにそれぞれ20%が使用されます。次のコードでは,イメージとピクセルラベルデータを学習セット,検証セット,およびテストセットに無作為に分割します。

[imdsTrain,imdsVal,imdsTest,pxdsTrain,pxdsVal,pxdsTest]=分区视频数据(imds,pxds);

60対20対20に分割すると,学習イメージ,検証イメージ,およびテストイメージの数が次のようになります。

numTrainingImages =元素个数(imdsTrain.Files)
numTrainingImages = 421
numValImages =元素个数(imdsVal.Files)
numValImages = 140
numTestingImages =元素个数(imdsTest.Files)
numTestingImages = 140

ネットワークの作成

関数deeplabv3plusLayersを使用して,ResNet-18に基づいてDeepLab v3 +ネットワークを作成します。用途に最適なネットワークを選択することは,経験的解析が必要であり,別のレベルのハイパーパラメーター調整です。たとえば,ResNet-50やMobileNet v2などの異なる基本ネットワークで試すか,またはSegNet,完全畳み込みネットワーク(FCN) U-Netなどの他のセマンティックセグメンテーションネットワークアーキテクチャを試すことができます。

%指定网络镜像大小。这通常与训练图像的大小相同。imageSize = [720 960 3];%指定类的数量。numClasses =元素个数(类);%创建DeepLab v3+。lgraph = deeplabv3plusLayers(imageSize, numClasses,“resnet18”);

クラスの重み付けを使用したクラスのバランス調整

前に示したように,CamVid内のクラスはバランスがとれていません。学習を改善するために,クラスの重み付けを使用してクラスのバランスを調整することができます。前にcountEachLabelを使用して計算したピクセルラベルのカウントを使用して,中央頻度クラスの重みを計算します。

imageFreq =(资源。PixelCount。/ tbl.ImagePixelCount;classWeights = median(imageFreq) ./ imageFreq ./ imageFreq ./ imageFreq ./
classWeights =11×10.3182 0.2082 5.0924 0.1744 0.7103 0.4175 4.5371 1.8386 1.0000 6.6059⋮

pixelClassificationLayerを使用してクラスの重みを指定します。

pxLayer = pixelClassificationLayer (“名字”“标签”“类”资源描述。的名字,“ClassWeights”, classWeights);lgraph = replaceLayer (lgraph,“分类”, pxLayer);

学習オプションの選択

学習に使用される最適化アルゴリズムはモーメンタム項付き確率的勾配降下法 (SGDM)です。trainingOptions(深度学习工具箱)を使用して,个に使用されるハイパーパラメーターを指定します。

定义验证数据。pximdsVal=像素标签图像数据存储(imdsVal,pxdsVal);定义培训选项。选择= trainingOptions (“个”...“LearnRateSchedule”“分段”...“LearnRateDropPeriod”10...“LearnRateDropFactor”, 0.3,...“动量”, 0.9,...“InitialLearnRate”1 e - 3,...“L2Regularization”, 0.005,...“ValidationData”pximdsVal,...“MaxEpochs”30岁的...“MiniBatchSize”8...“洗牌”“every-epoch”...“CheckpointPath”tempdir,...“详细频率”2....“阴谋”“训练进步”...“ValidationPatience”4);

学習率には区分的なスケジュールが使用されます。学習率は10エポックごとに0.3ずつ減少します。これにより,ネットワークはより高い初期学習率で高速に学習することができる一方で,学習率が低下すると,局所的最適値に近い解を求めることができます。

“ValidationData”パラメーターを設定することによって、すべてのエポックで検証データに対してネットワークのテストが行われます。“ValidationPatience”は4に設定されており,検証精度が収束すると学習が早期に停止します。これにより,学習データセットに対するネットワークの過適合を防ぎます。

ミニバッチのサイズ 8.を使用して、学習中のメモリ使用量を削減します。この値は、システムに搭載されている GPUメモリの量に応じて増減させることができます。

また,“CheckpointPath”は一時的な場所に設定されています。この名前と値のペアを設定すると,各学習エポックの終わりにネットワークチェックポイントを保存できます。システム障害や停電で学習が中断された場合に,保存したチェックポイントから学習を再開できます。“CheckpointPath”で指定された場所に、ネットワーク チェックポイントを保存するのに十分なスペースがあることを確認します。たとえば、100個の Deeplab v3+チェックポイントを保存する場合、各チェックポイントが 61MBであるため、約 6GBのディスク領域が必要です。

データ拡張

データ拡張はネットワークの精度を高めるのに役立つため,学習中にネットワークに対してより多くの例を提供するために使用されます。ここでは,データ拡張に対して+ / - 10ピクセルのランダムな左/右反射とランダムなX / Y平行移動が使用されます。これらのデータ拡張パラメーターを指定するには,imageDataAugmenter(深度学习工具箱)を使用します。

增量= imageDataAugmenter (“随机选择”,真的,...“RandXTranslation”-10年[10],“RandYTranslation”, -10年[10]);

imageDataAugmenterは、この他にいくつかのタイプのデータ拡張をサポートします。それらの中から選択することは、経験的解析が必要であり、別のレベルのハイパーパラメーター調整です。

学習の開始

pixelLabelImageDatastoreを使用して学習データとデータ拡張の選択を組み合わせます。pixelLabelImageDatastoreは学習データのバッチを読み取り,データ拡張を適用し,拡張されたデータを学習アルゴリズムに送信します。

pximds = pixelLabelImageDatastore (imdsTrain pxdsTrain,...“DataAugmentation”、增压器);

doTrainingフラグが真正の場合,trainNetwork(深度学习工具箱)を使用して学習を開始します。そうでない場合は,事前学習済みのネットワークを読み込みます。

メモ:この学習は12 GBのGPUメモリ搭載のNVIDIA™泰坦Xで検証済みです。GPUのメモリがこれより少ない場合,学習時にメモリ不足が発生する可能性があります。これが発生する場合は,trainingOptionsにおいて“MiniBatchSize”を1に設定するか,pixelLabelImageDatastore“OutputSize”パラメーターを使用してネットワーク入力の削減と学習データのサイズ変更を行ってみてください。このネットワークに学習させるには,約5時間かかります。GPUハードウェアによっては,さらに時間がかかる場合があります。

doTraining = false;如果doTraining [net, info] = trainNetwork(pximds,lgraph,options);其他的data =负载(pretrainedNetwork);网= data.net;结束

1つのイメージを使用したネットワークテスト

迅速な正常性チェックとして,1つのテストイメージ上で学習済みのネットワークを実行します。

I = readimage (imdsTest 35);C = semanticseg(I, net);

結果を表示します。

我= labeloverlay (C“Colormap”提出,“透明”, 0.4);imshow (B) pixelLabelColorbar(提出、类);

Cでの結果と,pxdsTestに格納されている予想されるグラウンド トゥルースを比較します。緑とマゼンタの領域は、セグメンテーション結果が予想されるグラウンド トゥルースと異なる領域を強調表示しています。

expectedResult = readimage (pxdsTest 35);实际= uint8 (C);预期= uint8 (expectedResult);预计imshowpair(实际)

視覚的には,道路,空,建物などのクラスのセマンティックセグメンテーションの結果は適切にオーバーラップしてます。しかし,歩行者や車のような小さいオブジェクトはそれほど正確ではありません。クラスごとのオーバーラップ量は,ジャカードインデックスとしても知られている交集在联盟(借据)メトリクスを使用して測定できます。関数jaccardを使用して借据を測定します。

iou=jaccard(C,expectedResult);表(类,iou)
ans =11×2表class iou ____________ _______“Sky”0.91837“Building”0.84479“Pole”0.31203“Road”0.93698“Pavement”0.82838“Tree”0.89636“SignSymbol”0.57644“Fence”0.71046“Car”0.66688“Pedestrian”0.48417“Bicyclist”0.68431

借据メトリクスでは視覚的な結果を確認できます。道路、空、建物クラスの借据スコアは高く,一方で歩行者や自動車などのクラスのスコアは低くなります。その他の一般的なセグメンテーションメトリクスには,掷骰子bfscoreの輪郭マッチングスコアなどがあります。

学習済みネットワークの評価

複数のテストイメージの精度を測定するには,テストセット全体に対してsemanticsegを実行します。ミニバッチのサイズ4を使用して,イメージのセグメント化中のメモリ使用量を削減します。この値は,システムに搭載されているGPUメモリの量に応じて増減させることができます。

pxdsResults = semanticseg (imdsTest净,...“MiniBatchSize”4....“WriteLocation”,tempdir,...“详细”、假);

semanticsegはテストセットに対する結果を像素标签数据库オブジェクトとして返します。imdsTest内の各テストイメージの実際のピクセルラベルデータは,“WriteLocation”パラメーターで指定された場所にあるディスクに書き込まれます。evaluateSemanticSegmentationを使用して,テストセット結果のセマンティックセグメンテーションメトリクスを測定します。

指标= evaluateSemanticSegmentation (pxdsResults pxdsTest,“详细”、假);

evaluateSemanticSegmentationは,データセット全体,個々のクラス,各テストイメージに関するさまざまなメトリクスを返します。データセットレベルのメトリクスを確認するには,指标。DataSetMetricsを検査します。

指标。DataSetMetrics
ans =表1×5全球准确性意味着准确性意味着权重你意味着分数0.87695 0.85392 0.6302.801

データセットメトリクスは,ネットワークパフォーマンスに関する大まかな概要を示します。各クラスがパフォーマンス全体に与える影響を確認するには,指标。ClassMetricsを使用してクラスごとのメトリクスを検査します。

指标。ClassMetrics
ans =11×3表精度IoU MeanBFScore ________ _______ ___________ Sky建筑0.778453 0.76098 0.58511杆0.71586 0.21477 0.56639道路0.73024 0.91465 0.76696路面树0.778466 0.70571 0.70919标志符号0.79358 0.39309 0.48302护栏0.81507 0.46484 0.48564 Car 0.90956 0.76799 0.69233行人0.876290.4366 0.60792自行车0.87844 0.60829 0.55089

データセット全体のパフォーマンスは非常に高いですが,クラスメトリクスは,行人骑自行车汽车といった少数しか存在しないクラスは天空建筑などのクラスと同じようにうまくセグメント化されていないことを示しています。少数しか存在しないクラスのサンプルが多く含まれているデータが追加されることで,結果が改善する可能性があります。

サポート関数

函数labelIDs = camvidPixelLabelIDs ()返回每个类对应的标签id。CamVid数据集有32个类。将他们分成11个班%原赛格网培训方法[1]。%这11个类是:%“天空”“建筑”“杆子”“道路”“路面”“树木”“标志符号”,%“栅栏”,“汽车”,“行人”和“自行车”。% CamVid像素标签id作为RGB颜色值提供。集团成%11个类,并将它们作为M-x-3矩阵的单元数组返回%原始CamVid类名在每个RGB值旁边列出。请注意%以下不包括其他/无效类别。labelIDs = {...%的“天空”[128 128 128;...%的“天空”%“建设”[ 000 128 064;...%“桥”128 000 000;...%“建设”064 192 000;...%“墙”064 000 064;...%的“隧道”192 000 128;...%的“拱门”%“极”[19219128;...%”Column_Pole”000 000 064;...%”TrafficCone”%的道路[ 128 064 128;...%的“路”128 000 192;...%”LaneMkgsDriv”192 000 064;...%“LaneMkgsNonDriv”%“路面”[000 000 192;...%“人行道”064 192 128;...%”ParkingBlock”128 128 192;...%”RoadShoulder”%的“树”[128 128 000;...%的“树”192 192 000;...%”VegetationMisc”%”SignSymbol”[192 128 128;...%”SignSymbol”128 128 064;...%”Misc_Text”000 064 064;...%”TrafficLight”%“栅栏”[ 064 064 128;...%“栅栏”%“汽车”[064 000 128;...%“汽车”064 128 192;...%”SUVPickupTruck”192 128 192;...%”Truck_Bus”192 064 128;...%“训练”128 064 064;...%”OtherMoving”%“行人”[064 064 000;...%“行人”192 128 064;...%的“孩子”064 000 192;...%”CartLuggagePram”064 128 064;...%“动物”%“自行车”[ 000 128 192;...%“自行车”192 000 192;...%”MotorcycleScooter”]};结束
函数pixelLabelColorbar(cmap,类名)%将颜色条添加到当前轴。颜色条已格式化%以显示带有颜色的类名。甘氨胆酸colormap(提出)%添加颜色栏到当前的数字。c=色条(“同伴”甘氨胆酸,);%使用类名作为标记。c、 TickLabels=类名;numClasses=大小(cmap,1);%中心打勾标签。c.Ticks = 1 / (numClasses * 2): 1 / numClasses: 1;%删除勾号。c.TickLength = 0;结束
函数提出= camvidColorMap ()定义CamVid数据集使用的颜色映射。Cmap = [128 128 128 .%的天空128 0 0%的建筑192 192 192%杆子128 64 128%的道路60 40 222%的人行道上128 128 0%树192 128 128% SignSymbol64 64 128%篱笆64 0 128%的车64 64 0%行人0 128 192%骑自行车];% Normalize between[0 1]。Cmap = Cmap ./ 255;结束
函数[imdsTrain, imdsVal, imdsTest, pxdsTrain, pxdsVal, pxdsTest] = partioncamviddata (imds,pxds)%对CamVid数据进行分区,随机选取60%的数据进行训练。的% rest用于测试。%设置初始随机状态,例如重现性。rng (0);numFiles =元素个数(imds.Files);shuffledIndices = randperm (numFiles);%使用60%的图像进行训练。numTrain = round(0.60 * numFiles);trainingIdx = shuffledIndices (1: numTrain);%使用20%的图像进行验证numVal = round(0.20 * numFiles);valIdx = shuffledIndices (numTrain + 1: numTrain + numVal);%使用其余部分进行测试。testIdx = shuffledIndices (numTrain + numVal + 1:结束);%创建用于培训和测试的图像数据存储。trainingImages = imds.Files (trainingIdx);valImages = imds.Files (valIdx);testImages = imds.Files (testIdx);imdsTrain = imageDatastore (trainingImages);imdsVal = imageDatastore (valImages);imdsTest = imageDatastore (testImages);%提取类和标签ID信息。类= pxds.ClassNames;labelIDs = camvidPixelLabelIDs ();%创建用于训练和测试的像素标签数据存储。trainingLabels = pxds.Files (trainingIdx);valLabels = pxds.Files (valIdx);testLabels = pxds.Files (testIdx);pxdsTrain = pixelLabelDatastore(trainingLabels, classes, labelid);pxdsVal = pixelLabelDatastore(valLabels, classes, labelid);pxdsTest = pixelLabelDatastore(testLabels, classes, labelid);结束

参考文献

陈良杰等。基于Atrous可分离卷积的编码器-解码器语义图像分割。大会(2018)。

[2] Brostow,G.J.,J.Fauqueur和R.Cipolla.“视频中的语义对象类:一个高清晰度地面真相数据库。”模式识别的字母.2009年第30卷第2期88-97页。

参考

||||||||(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)

関連するトピック