学生休息室

分享技术和现实生活中的例子,学生如何在他们的日常项目中使用MATLAB和Simulink # studentsuccess万博1manbetx

BioMassters挑战起动器代码

加入我们今天是恩典Woolson, 2022年6月加入学生项目团队来支持数据科学挑战,帮助参与者使用MATLAB赢!万博1manbetx恩典会谈论一个新的数据科学的挑战,今天11月1日发射,2022年DrivenData与我们的合作伙伴。优雅,交给你了. .

开始使用MATLAB

你好,我的名字叫格蕾丝Woolson今天我们将谈论一个新的科学数据来测试你的技能挑战你!我们在MathWorks®,合作DrivenData感到兴奋,带给你挑战。这一挑战的目标是估计每年的地上部生物量(AGBM)在给定的芬兰提供卫星图像补丁。在这个博客,我们提供一个基本的起动器在MATLAB®。在这段代码中,我创建了一个基本image-to-image回归模型和训练它预测峰值AGBM每个像素的输入数据。然后我用这个模型对测试数据并保存结果的挑战所需的格式。
这应该作为基本的代码来帮助您开始开始分析数据并努力开发更高效,优化,使用更精确的模型可用的训练数据。请求你的免费MATLAB许可证和其他资源开始,参观MathWorks BioMassters挑战主页
agbm_Banner.png
(图1.1:AGBM可视化的颜色。(图片来源于数据提供的芬兰森林中心CC 4.0许可证]]
如果你想访问和运行这段代码,您可以使用“在浏览器中运行”和“下载住脚本”按钮在页面的右下角。

表的内容

3所示。创建模型
6.1。可视化

的数据

每个chip_id代表一块土地在某一年。对于每一个芯片,你提供了大约24卫星图像和1 AGBM形象。
卫星图像来自两颗卫星称为Sentinel-1 (S1)和Sentinel-2 (S2),覆盖近13000从2017年到2021年在芬兰的森林。每个芯片都是2560年由2560米,这些芯片是256×256像素的图像,所以每个像素代表一个10×10米区域内的土地的筹码。你提供了一个从每个卫星图像每个日历月。S1,每个图像生成的意思是所有图像通过S1的芯片。S2,你每个月提供最好的形象。
AGBM形象作为标签为每个芯片在某一年。就像卫星数据,AGBM数据提供图片的形式覆盖2560米,2560米地区分辨率10米,这意味着他们是256×256像素大小。卫星图像中的每个像素对应一个像素在AGBM图像芯片相同的ID。
的竞争,你会使用这些数据来训练模型,该模型可以预测这个AGBM值时只提供卫星图像。了解更多关于图片,功能,标签和提交指标,去挑战的问题描述页面!

预览的数据

理解数据,我们将一起工作,让我们来看看几个例子图像特定chip_id。在下面的章节中,图像对应a8b6998 chip_id 0。

首先,定义一个变量,指向了S3 bucket,这样我们可以访问数据。你能找到这条路的“biomassters_download_instructions.txt”文件提供数据下载页面。确保这是整个桶的路径,不是任何特定的文件夹——它应该开始“s3: / /”。这将是整个博客使用

%路径示例,您将需要更换
s3Path = s3: / /竞争/文件/路径/ ' ;

Sentinel-1:

对于每个chip_id,我们期望看到12图像从Sentinel-1命名约定{chip_id} _S1_}{月,00 - 11月是一个值。有可能有缺失数据的情况下,这可能会导致一个或多个图像失踪。
每个Sentinel-1映像有四个乐队,每个乐队是一个256×256矩阵芯片包含一个特定的测量。让我们想象每个乐队的其中一个S1图片:
exampleS1Path = fullfile (s3Path,“train_features”,“0 a8b6998_s1_00.tif”);
exampleS1 = imread (exampleS1Path);
%可视化每一层,重新调节每个像素的值在0和1之间
%暗像素显示值较低,上杉达也像素显示更高的值
蒙太奇(重新调节(exampleS1));

Sentinel-2:

每个chip_id Sentinel-1一样,我们期望看到12图像从Sentinel-2命名约定{chip_id} _S2_}{月,00 - 11月是一个值。有可能有缺失数据的情况下,这可能会导致一个或多个图像失踪。
每个Sentinel-2形象有11个乐队,每个乐队是一个256×256矩阵芯片包含一个特定的测量。让我们想象每个乐队的其中一个S2图片:
exampleS2Path = fullfile (s3Path,“train_features”,“0 a8b6998_s2_00.tif”);
exampleS2 = imread (exampleS2Path);
%可视化每一层,重新调节每个像素的值在0和1之间
%暗像素显示值较低,上杉达也像素显示更高的值
蒙太奇(重新调节(exampleS2));

AGBM:

对于每个chip_id,将有一个AGBM形象,{chip_id) _agbm.tif的命名约定。这张图片是一个256×256矩阵,其中每个元素是一个测量的地上部生物量吨像素。0 a8b6998,它看起来像这样:
exampleAGBMPath = fullfile (s3Path,“train_agbm”,“0 a8b6998_agbm.tif”);
exampleAGBM = imread (exampleAGBMPath);
%因为我们只需要想象一层,我们可以用imshow
imshow(重新调节(exampleAGBM))

导入和数据进行预处理

我们可以开始构建一个模型之前,我们必须找到一种方式获取数据到MATLAB工作区。这种竞争的数据都包含在一个公共Amazon S3™桶。这个桶的URL将提供一次注册,所以确保你有报名参加挑战,这样你就可以访问数据。总的来说,所有提供的图像占用235 gb的内存,这是太多的工作。这样我们就可以处理所有的数据,我将利用MATLAB的imageDatastore,它允许我们在一个chip_id读取数据,并将使它容易训练神经网络。如果你想了解更多关于数据存储,您可以参考以下资源:
  1. 开始使用数据存储
  2. 数据存储深度学习
  3. 数据存储的图像数据
我们使用s3Path我们先前创建创建一个变量agbmFolder,点特别AGBM训练数据。
agbmFolder = fullfile (s3Path,“train_agbm”);
我们可以使用agbmFolder为我们创建一个数据存储输入(卫星图像)和输出(AGBM图像)数据,命名imInputimOutput分别。当你使用一个imageDatastore,你可以改变图像的方式从指定的目录读取到MATLAB工作区使用'ReadFcn”选项。因为我想读一个AGBM形象但24卫星图像,我定义一个helper函数readTrainingSatelliteDataAGBM读取文件名的文件我们会读,其中包含chip_id,相反读入和所有相应的卫星图像进行预处理。然后我使用内置的splitEachLabel函数将数据集分为训练、测试和验证数据,这样我们就可以评估其性能期间和之后的训练。在本例中,我选择使用训练数据的95%,2.5%,验证为2.5%,测试因为我想使用的大部分数据训练,但是你可以玩玩这些数字。
readTrainingSatelliteDatahelper函数如下:
  1. 提取文件名的chip_id AGBM形象,我们将阅读
  2. 读取和订单所有对应于这个chip_id卫星图像
  3. 处理缺失数据。因为这是我们的第一个模型,我决定忽略任何含有缺失数据的图像。
  4. 剩下的数据,发现每个像素的平均值为每一个乐队。
  5. 重新调节是在0和1之间的值。每个卫星都有不同的度量单位,这使得难以对一些算法学习正确的数据。通过规范数据规模,它可能使神经网络学习更好。
这个结果在一个单一的输入图像的大小256 x256x15,其中每256×256矩阵表示一个乐队从S1和S2的平均值的。S1有4个乐队和S2以来11,这导致15矩阵。这是一个非常简化的方式来表示数据,因为这只会是我们的模型开始。
imInput = imageDatastore (agbmFolder,“ReadFcn”@(文件名)readTrainingSatelliteData(文件名,s3Path),“LabelSource”,“foldernames”);
[inputTrain, inputVal,输入]= splitEachLabel (imInput, 0.95, 0.025);
的输出数据,我们将使用默认的阅读功能,我们只需要读一个图像,不需要做任何预处理。因为我们将每个数据存储相同的目录中,我们知道他们将读取图像在同一chip_id秩序。再一次,将数据分为训练、测试和验证数据。
imOutput = imageDatastore (agbmFolder,“LabelSource”,“foldernames”);
[outputTrain, outputVal,输出]= splitEachLabel (imOutput, 0.95, 0.025);
数据预处理后,我们把输入和输出集所以他们以后可能使用我们的神经网络。
dsTrain =结合(inputTrain outputTrain);
dsVal =结合(inputVal outputVal);
dst =结合(输入、输出);
预览函数允许我查看第一项数据存储,这样我们就可以验证输入(第一项)和输出(第二项)是我们预计的尺寸:
sampleInputOutput =预览(dsTrain);
蒙太奇(重新调节(sampleInputOutput {1}));%的输入数据
imshow(重新调节(sampleInputOutput {2}))%输出数据

创建模型

现在数据导入和清理,我们实际上可以开始开发一个神经网络!这个挑战是有趣的,在输入输出图像。通常情况下,神经网络将用于将图像作为输入和输出一个类(图片分类)或者一个特定值(image-to-one回归),如下所示:
(图2.1:可视化图像的卷积神经网络分类)
在这一挑战,我们的任务是输出一个新的形象,所以我们的网络结构需要看起来有点不同:
(图2.2:可视化的image-to-image卷积神经网络)
无论你使用网络的类型,有两种不同的方法可以使或编辑一个深度学习模型:用深层网络设计师应用以编程方式

选项1:创建与深层网络设计师应用

首先,我们必须选择一个网络体系结构。对于这个博客,我决定创建一个从网络体系结构使用'unetLayers的函数。这个函数提供了一个网络语义分割(image-to-image分类问题),所以它可以很容易地适应image-to-image回归。如果你想了解更多关于其他体系结构开始,看看这个文档页面例子深入学习网络架构
自256年将输入图像x256x15,这还必须输入网络的大小。其他的选择,我选择任意数量的类,因为我们将会改变输出层,和一开始的深度3。
lgraph = unetLayers (15] [256 256 2“encoderDepth”3);
从这里,我可以打开深层网络设计师应用和修改模型交互。我喜欢这个选项,因为它让我想象网络是什么样子,很容易看到,我做了我想要的改变。
deepNetworkDesigner (lgraph)
当应用程序打开时,它应该类似于下图。如果放大某些层,可以缩小以查看完整的网络按空格键
(图3.1:深层网络设计师)
从这里开始,把最后两层,改变“Final-ConvolutionLayer”这样NumFilters= 1。一些建议使用的应用程序的步骤:
  • 放大或缩小,持有CTRL和向上或向下滚动鼠标
  • 删除图层,点击它,点击退格键盘上的按钮。
  • 一层的修改属性,单击层。这将打开一个菜单右边,你可以与之交互。
removingClassificationLayers.gif
(图3.2:删除和修改层深度网络设计师)
是时候回归层中添加:
addRegressionLayer.gif
(图3.3:添加一个回归层深陷网络设计师)
现在,该模型完成了!是时候出口回MATLAB工作区可以训练。
exportModel.gif
(图3.4:出口模型从深层网络设计师)
注意:它会自动被导出 lgraph_1。
如果你想获得更多的创意,您的模型,这一点文档页面深度网络设计师有更多关于如何使用应用程序的细节。

选项2:通过编程方式创建

首先,我们必须选择一个网络体系结构。对于这个博客,我决定创建一个从网络体系结构使用'unetLayers的函数。这个函数提供了一个网络语义分割(image-to-image分类问题),所以它可以很容易地适应image-to-image回归。如果你想了解更多关于其他体系结构开始,看看这个文档页面例子深入学习网络架构
自256年将输入图像x256x15,这还必须输入网络的大小。其他的选择,我选择任意数量的类,因为我们将会改变输出层,和一开始的深度3。
lgraph = unetLayers (15] [256 256 2“encoderDepth”3);
现在我们必须改变最后几层模型进行回归,而不是分类。我这样做通过删除将softmax卷积和分割层,代之以一个新的层,一层回归。新的褶积层有一个过滤器,这样最终的图像输出将一层,和回归层告诉MATLAB如何解释和计算模型的half-mean-squared-error的输出。更多地了解将分类网络转化为回归网络,您可以参考这个资源:分类网络转化为回归网络
lgraph = lgraph.removeLayers (“Softmax-Layer”);
lgraph = lgraph.removeLayers (“Segmentation-Layer”);
finalConvolutionLayer = convolution2dLayer ([1], 1“名字”,“Final-ConvolutionLayer-2D”);
lgraph = lgraph.replaceLayer (“Final-ConvolutionLayer”,finalConvolutionLayer);
lgraph = lgraph.addLayers (regressionLayer (“名字”,“regressionLayer”));
lgraph_1 = lgraph.connectLayers (“Final-ConvolutionLayer-2D”,“regressionLayer”);
一旦网络的构建,我们可以使用analyzeNetwork函数来检查错误和可视化网络。这将打开一个新窗口。
analyzeNetwork (lgraph_1);
(图4:分析和可视化lgraph_1]

设置培训首选项

一旦所有的层都整理出来,它设置培训选项。的trainingOptions函数允许我们指定该解算器将火车模型,以及它如何训练,这些选项和玩耍很重要当训练模型。有无限的组合可以选择,但这是我到目前为止最有效的:
选择= trainingOptions (“亚当”,
“InitialLearnRate”、。
“MiniBatchSize”10
“MaxEpochs”,50岁,
“ValidationData”dsVal,
“OutputNetwork”,“best-validation-loss”,
“详细”、假);
注意:如果你想看评价指标和可视化模型时训练,设置的详细的”真正的和设置“阴谋”“训练进步”。
了解更多关于这些培训选项做什么以及如何优化,您可以参考这个资源:设置参数和卷积神经网络训练

火车模型

这一步可以实现只有一行代码:
网= trainNetwork (dsTrain lgraph_1,选项)
虽然这是最短的部分代码,需要几个小时火车深学习模型。如果你拥有一个支持GPU,我推荐使用它万博1manbetx“trainNetwork”功能将自动使用检测到一个支持GPU万博1manbetx。以下资源包含gpu和深度学习的更多信息:运行在GPU MATLAB函数

评估模型的新数据

现在我们有一个完全训练模型,愿在测试数据预测!请注意,我创建了模型训练在训练数据的一个子集,所以你看到的结果在这一节中可能看起来不同结果如果你运行相同的代码。
输出图像的测试集,使用预测函数。
ypred =预测(净,dst);
大小(ypred)
ans = 1×4
256 256 1 24
由此产生的ypred是一个四维矩阵。第一三维表示每个输出图像的大小256 x256x1,最后维度代表我们有多少这些图像的预测。很难告诉我们的模型如何执行通过看这些数字,我们可以采取一些额外的步骤来评估网络。

可视化

访问第一双卫星和AGBM图像从测试集,使用预览函数。
testBatch =预览(dst);
这将允许我们想象一个示例输入图像,实际AGBM,和相关的预测AGBM从网络来了解网络执行。
idx = 1;
预测= ypred (:,:,:, idx);
ref = testBatch {idx 2};
蒙太奇({ref,预测})
标题(预期的和实际的);
虽然图片不相同,我们可以明确地看到类似的形状和阴影!由于输出数据是衡量AGBM而不是表示的颜色,然而,每个像素的值在0和1之间,不超过1被显示为白色像素。让我们使用重新调节作为我们之前做的得到更好的表示图像我们可以看到更多的细节,并确保这些更高的值仍然是准确的。
rescaledPred =重新调节(预测);
rescaledRef =重新调节(ref);
蒙太奇({rescaledRef, rescaledPred})
标题(预期的和实际的);
现在,我们可以看到更多的细节,我们可以证实,网络很好地匹配的一般形状和轮廓预期的输出。然而,我们还可以看到,网络产生的图像通常是比预期的输出,表明很多值高于他们应该。

计算性能指标

的竞争,你的最后得分将每个图像的平均均方根误差(RMSE)提交。RMSE可以由以下公式表示:

- E = \√6美元{

E = 1 n∑i = 1 n | Ai-Fi | 2

为预测数组F和实际数组的n标量观测。
鉴于这个公式,我们可以计算给定的RMSE预测以下代码:
rmse =√意味着(ref(:) -预测(:))^ 2))
rmse =单
33.7451
RMSE越低,模型越好。正如你所看到的,还有很大的改进余地的这个模型。

改进的可能的下一个步骤

记住,这个网络可能不是最好的,因为用这个博客我的主要目标是展示如何使用imageDatastore以及如何建立一个网络。但我确实有一个网络,真正尝试,还有很多方法来不断尝试的事情和改善这个网络:
  • 创建一个模型,接受更多的信息!现在我们失去很多信息从原始的训练数据,因此,寻找一种使用更多的它可能导致一个更合理的模型。
  • 数据,而不是忽略它们找到填充方法。你复制之前的卫星图像,当一个人失踪吗?在平均填补它吗?有很多的方法处理这个问题。
  • 把云层覆盖层。
  • 尝试不同的模型结构!结构可以找到另一个例子在这里
  • 实验与训练选项。
  • 尝试不同的发行版的训练、测试和验证数据。

测试数据和导出结果预测

一旦你有了一个模型,你满意,你需要用它来测试数据做出预测。要做到这一点,我们需要首先导入和上面的数据,我们进行预处理,然后使用预测函数进行预测。因为我们没有一个“agbm”文件夹作为参考这一次,我们进行预处理数据的方式将有所不同。
开始,我们将使用“features_metadata”文件提供所有测试chip_ids的列表。
featuresMetadataLocation = fullfile (s3Path,“features_metadata.csv”)
featuresMetadata = readtable (featuresMetadataLocation,“ReadVariableNames”,真正的);
testFeatures = featuresMetadata (strcmp (featuresMetadata.split,“测试”):);
testChips = testFeatures.chip_id;
[uniqueIdx, ~ ~] =独特(testChips);
uniqueTestChips = testChips (uniqueIdx:);
然后我新建一个文件夹,将所有的预测和一个变量指向这个文件夹:
如果~ (“test_agbm”,“dir”)
mkdirtest_agbm
结束
%包括完整的文件路径,这是一个占位符,这个不应该在S3 bucket
outputFolder = “C: \ DrivenData \ . .” ;
然后,遍历每个chip_id和格式的输入数据来匹配预期的格式我们的网络(256 x256x15),对输入数据进行预测,然后出口每个预测作为一个TIFF文件使用Tiff功能。竞争,预计这些TIFF文件的名称是“{chip_id} _agbm.tif”。
chipIDNum = 1:长度(uniqueTestChips)
chip_id = uniqueTestChips {chipIDNum};
%的格式输入
inputImage = readTestingSatelliteData (chip_id s3Path);
%进行预测
pred =预测(净,inputImage);
气管无名动脉瘘管的%设置文件和出口预测
文件名= [outputFolder chip_id,“_agbm.tif”];
t = Tiff(文件名,' w ');
%需要设置标签Tiff文件的信息
tagstruct。ImageLength = 256;
tagstruct。ImageWidth = 256;
tagstruct。光度= Tiff.Photometric.MinIsBlack;
tagstruct。BitsPerSample = 32;
tagstruct。SamplesPerPixel = 1;
tagstruct。SampleFormat = Tiff.SampleFormat.IEEEFP;
tagstruct。PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
tagstruct。压缩= Tiff.Compression.None;
tagstruct。软件=MATLAB的;
tagstruct setTag (t)
%出口你的预测
写(t, pred);
关闭(t);
结束
就像这样,你出口的预测!这些预测的创建一个TAR文件,我们可以简单地使用内置的焦油函数。
焦油(“test_agbm.tar”,“test_agbm”);
由此产生的“test_agbm。焦油’ is what you will submit for the challenge.
谢谢你按照这个起动器代码!我们很兴奋地看到你将如何建立和创建模型,独一无二的你。在DrivenData随时与我们联系论坛在studentcompetitions@mathworks.com或电子邮件我们如果你有任何进一步的问题。好运!

额外的资源

如果你想了解更多关于深度学习MATLAB,看看这些资源!

辅助函数

函数avgImS1S2 = readTrainingSatelliteData (outputFilename s3Path)
outputFilenameParts =分裂(outputFilename, (“_”,“\”]);
chip_id = outputFilenameParts {end-1};
(s3Path inputDir = fullfile之类,“train_features \”);
correspondingFiles = dir ([inputDir,之类chip_id,‘* .tif‘]);
从00-11 %卫星图像范围,所以preallocate细胞arrray
s1Data =细胞(1、12);
s2Data =细胞(1、12);
%编译和所有数据
fileIdx = 1:长度(correspondingFiles)
文件名= correspondingFiles (fileIdx) . name;
filenameParts =分裂(文件名,(“_”,“\”,“。”]);
卫星= filenameParts {end-2};
fullfilename = strcat (inputDir,之类文件名);
我= imread (fullfilename);
% + 1因为matlab从1开始
idx = str2double (filenameParts {end-1}) + 1;
%所有输入图像添加到命令单元阵列
如果卫星= =“S1 '
s1Data {idx} =我;
elseif卫星= =“S2”
s2Data {idx} =我;
结束
结束
%忽略缺失的数据
imgNum = 1:12
%不够的乐队
如果大小(s1Data {imgNum}, 3) ~ = 4
s1Data {imgNum} = [];
elseif大小(s2Data {imgNum}, 3) ~ = 11
s2Data {imgNum} = [];
结束
%值-9999
如果ismember(-9999年,s1Data {imgNum})
s1Data {imgNum} = [];
elseifismember(-9999年,s2Data {imgNum})
s2Data {imgNum} = [];
结束
结束
%计算平均S1数据
totalImS1 = 0 (256、256、4);
imgNum1 = 1:长度(s1Data)
currIm = s1Data {imgNum1};
如果~ (isempty (currIm))
totalImS1 = totalImS1 + currIm;
结束
结束
avgImS1 = totalImS1。/长度(s1Data);
%计算平均S2数据
totalImS2 = 0 (256、256、11);
imgNum2 = 1:长度(s2Data)
currIm = s2Data {imgNum2};
如果~ (isempty (currIm))
totalImS2 = totalImS2 + currIm;
结束
结束
avgImS2 = totalImS2。/长度(s2Data);
% 15把这乐队组合成一个乐队的形象
avgImS1S2 =猫(3 avgImS1 avgImS2);
%重新调节值在0和1之间
avgImS1S2 =重新调节(avgImS1S2);
结束
函数avgImS1S2 = readTestingSatelliteData (chip_id s3Path)
%更新指s3
(s3Path inputDir = fullfile之类,“test_features”);
correspondingFiles = dir ([inputDir,之类chip_id,‘* .tif‘]);
从00-11 %卫星图像范围,所以preallocate细胞arrray
s1Data =细胞(1、12);
s2Data =细胞(1、12);
%编译和所有数据
fileIdx = 1:长度(correspondingFiles)
文件名= correspondingFiles (fileIdx) . name;
filenameParts =分裂(文件名,(“_”,“\”,“。”]);
卫星= filenameParts {end-2};
fullfilename = strcat (inputDir,之类文件名);
我= imread (fullfilename);
% + 1因为matlab从1开始
idx = str2double (filenameParts {end-1}) + 1;
%所有输入图像添加到命令单元阵列
如果卫星= =“S1 '
s1Data {idx} =我;
elseif卫星= =“S2”
s2Data {idx} =我;
结束
结束
%忽略缺失的数据
imgNum = 1:12
%不够的乐队
如果大小(s1Data {imgNum}, 3) ~ = 4
s1Data {imgNum} = [];
elseif大小(s2Data {imgNum}, 3) ~ = 11
s2Data {imgNum} = [];
结束
%值-9999
如果ismember(-9999年,s1Data {imgNum})
s1Data {imgNum} = [];
elseifismember(-9999年,s2Data {imgNum})
s2Data {imgNum} = [];
结束
结束
%计算平均S1数据
totalImS1 = 0 (256、256、4);
imgNum1 = 1:长度(s1Data)
currIm = s1Data {imgNum1};
如果~ (isempty (currIm))
totalImS1 = totalImS1 + currIm;
结束
结束
avgImS1 = totalImS1。/长度(s1Data);
%计算平均S2数据
totalImS2 = 0 (256、256、11);
imgNum2 = 1:长度(s2Data)
currIm = s2Data {imgNum2};
如果~ (isempty (currIm))
totalImS2 = totalImS2 + currIm;
结束
结束
avgImS2 = totalImS2。/长度(s2Data);
% 15把这乐队组合成一个乐队的形象
avgImS1S2 =猫(3 avgImS1 avgImS2);
%重新调节值在0和1之间
avgImS1S2 =重新调节(avgImS1S2);
结束

|

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。