深度学习

理解和使用深度学习网络

医学影像深度学习

我们今天有一个非常特别的帖子,来自德国海德堡的Jakob Kather(推特:jnkath).他将讨论深度学习在医学上的应用。Jakob也是最近发表在《自然医学》上的一篇新论文的作者之一:https://www.nature.com/articles/s41591-019-0462-y探讨深度学习预测胃肠道癌。
基于深度学习的图像分析非常适合分类猫和狗,悲伤和快乐的脸,披萨和汉堡。然而,许多人很难将深度学习应用到医学成像数据中。理论上,在医学图像中区分肿瘤与正常应该很容易;实际上,这需要一些数据清理和模型训练和部署的技巧。
在这里,我们将展示如何在MATLAB中使用深度学习来预处理和分类复杂的医学图像。在这个演示中,我们将主要使用深度学习工具箱和图像处理工具箱。在硬件方面,最好安装一个兼容的GPU并准备在MATLAB中使用//www.ru-cchi.com/solutions/gpu-computing.html).
我们的目标是在组织学图像中找到肿瘤组织**。
**你想知道什么是“组织学图像”吗?在几乎所有的癌症患者中,肿瘤都是由外科医生切除,切成薄片,放在玻片上,染色并在显微镜下观察。因此,我们可以看到从微米尺度的细胞到毫米尺度的组织结构的一切。
数千张这样的图片在公共存储库中免费提供。其中一些资料库可从美国国立卫生研究院(NIH)的数据门户网站获得。从https://portal.gdc.cancer.gov我们可以下载这样的肿瘤图像(在本例中,是肺癌):
这些图像是SVS格式的,本质上是一个多层TIFF图像。
这可能看起来像一个普通的图像,但SVS图像是巨大的:文件通常大于1 GB,图像有高达10亿像素。放大后的这张图片显示了这张图片的大小:

这张图片显示了在图像的一小部分中包含了多少细节。我们放大了右上方的红点显示的完整图像查看器。

图片由国家癌症研究所提供。
许多人甚至很难加载这些图像,但是MATLAB有一些很好的函数来处理这些大量的数据。特别是,我们将使用函数imfino(提取元数据)、imread(读取缩略图)和blockproc(读取实际的图像数据,而不将完整的图像加载到RAM中)。
让我们用MATLAB来看看这些图像。我们首先从TCGA数据库下载一个示例图像。这篇文章中的图片可以在这里找到:https://portal.gdc.cancer.gov/files/0afb5489-719c-4e4d-bb8a-e0e146f0adb2
%定义图像名称imName = ' tcga - nk - a5cr - 01z -00- dx1 . a7c57b30 - e2c6 - 4a23 - ae71 - 7e4d7714f8ea .sv ';imInfo = imInfo (imName);%获取元数据
SVS图像本质上是多页tiff,我们可以使用imfino()查看每个页面的元数据。
for i = 1:numel(imInfo) X = ['Layer ',num2str(i), ': Width ',num2str(imInfo(i).Width),…' and Height ', num2str(imInfo(i).Height)];disp (X)
基本图像(频道1)太大了,我们甚至不能看它。但让我们看看一些较小的图像。
imshow(imread(imName,2)) imshow(imread(imName,6)) imshow(imread(imName,7))
对于每个通道,我们可以查看元数据。
disp(['此图像有',num2str(imInfo(5).Width),'*',num2str(imInfo(5).Height),' pixels'])
这张图片有3019*1421像素
我们可以看到这个图像大部分是背景,包含非肿瘤和肿瘤组织。因为我们关心的是肿瘤组织而不是周围的正常组织,我们想要识别肿瘤区域。
如果您不是医务人员,请注意,这是带有肿瘤标记的图像。
让我们在AlexNet中使用迁移学习方法。我们将加载默认的预训练的AlexNet模型,它已经学会了区分形状,如圆或线。
Net = alexnet;%加载一个在ImageNet上预训练的alexnet
现在,我们想重新训练这个模型作为肿瘤探测器。我们将使用一个包含10万张结肠癌组织学图像的公共数据集http://dx.doi.org/10.5281/zenodo.1214456.这组样本来自结直肠癌样本,但工作流程对任何类型的实体肿瘤都是相同的。
这是这些较小的图像(补丁)的样子:它们被标记为9个类中的一个,这些类在数据存储库中有更详细的解释。我们的目标是训练一个深度神经网络来自动检测这些类。
这些图像代表了病理学家手工定义的不同类型的组织。每一行是一个组织类,包含图像集中的随机图像。分类标签如下:ADI =脂肪组织(脂肪),BACK =背景(无组织),DEB =碎屑,LYM =淋巴细胞,MUC =粘液,MUS =肌肉,NORM =正常黏膜,STR =间质,TUM =肿瘤上皮。这些类在这里有更详细的描述:https://journals.plos.org/plosmedicine/article?id=10.1371/journal.pmed.1002730在这里:https://www.nature.com/articles/srep27988
从存储库下载ZIP文件并将其解压到名为“images”的文件夹后,在“images”中每个组织类都有一个子文件夹。现在我们可以加载它们,将它们分成训练、验证和测试集,并重新训练我们的alexnet模型。(我们可以选择使用imageDataAugmenter例如,创建更多具有旋转方差的训练图像)。
从文件夹图像中收集所有图片,并将它们放在一个数据存储中。包含子文件夹,类别/标签由文件夹名称决定。
allImages = imageDatastore('./images/',' inclesubfolders ',true,'LabelSource','foldernames');
分成三组:40%的训练,20%的验证,40%的测试
[training_set, validation_set, testing_set] = splitEachLabel(allImages,.4, .4);

网络改造

通过删除最后三层来修改网络。我们将用自定义分类的新层替换这些层。
layersTransfer = net.Layers(1:end-3);
显示输出类别。
类别(training_set.Labels)
ans =9×1单元格数组
{“阿迪”}
{“回”}
{“黛比”}
{' LYM '}
{“中央”}
{“亩”}
{“常态”}
{' STR '}
{“空的”}
numClasses = numel(categories(training_set.Labels));
我们合并这些层,并为最后一个完全连接层“fc”设置权重和偏差学习率。
layers = [layersTransfer fullyConnectedLayer(numClasses,'Name', 'fc','WeightLearnRateFactor',1,'BiasLearnRateFactor',1) softmaxLayer('Name', 'softmax') classificationLayer('Name', 'classOutput')];
建立一个layerGraph并绘制它:
lgraph = layerGraph(图层);情节(lgraph)

修改培训参数

现在我们修改训练集和训练选项。训练集必须调整大小,以适应网络预期的输入大小。
imageInputSize = [227 227 3];augmented_training_set = augmentedImageSource(imageInputSize,training_set);
augmented_training_set =
带有属性的augmentedImageDatastore:
NumObservations: 39999
文件:{39999×1 cell}
AlternateFileSystemRoots: {}
MiniBatchSize: 128
DataAugmentation:‘没有’
ColorPreprocessing:‘没有’
OutputSize: [227 227]
OutputSizeMode:“调整”
DispatchInBackground: 0
resized_validation_set = augmentedImageDatastore(imageInputSize,validation_set);resized_testing_set = augmentedImageDatastore(imageInputSize,testing_set);
设置训练选项,包括在网络训练时绘制训练进度图。
opts = trainingOptions('sgdm',…“MiniBatchSize”,64年,…%迷你批大小,受GPU RAM限制,Titan上默认100,P6000 'InitialLearnRate'上500,1e-5,…%固定学习率'L2Regularization', 1e-4,…%优化L2约束'MaxEpochs',15,…%马克斯。默认3 'ExecutionEnvironment', 'gpu',…%的环境进行训练和分类,使用兼容的GPU 'ValidationData', resized_validation_set,…“阴谋”、“训练进步”)

培训

我们在单个GPU上训练了3.5个小时的网络,但训练几分钟实际上就足够得到一个合理的结果,如下面的训练图所示。
net = trainNetwork(augmented_training_set, lgraph, opts)

测试与预测

让我们检查一下使用搁置子集的分类器工作得如何。
[predLabels,predScores] = category (net, resized_testing_set, 'ExecutionEnvironment','gpu');
我们可以看看混淆矩阵和整体分类精度:
plotconfusion (testing_set。PerItemAccuracy = mean(predLabels == testing_set.Labels);title(['整体每张图像精度',num2str(round(100*PerItemAccuracy)),'%'])
瞧!我们已经实现了一个优秀的分类性能(如您将在这篇论文).我们现在准备为数字病理学构建更复杂的工作流程,其中包括一个自动肿瘤检测器!
我想再次感谢Jakob花时间让我们了解他使用MATLAB的研究。特别感谢Jakob Sommer测试本文中的源代码。对这篇文章有什么问题吗?请在下方留言。

|
  • 打印
  • 发送电子邮件

评论

如欲留言,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。

Baidu
map