指导教师:河南理工大学 芦碧波
岩石薄片显微图像是将样本研磨成厚度为0.03毫米的薄片,放置在偏光显微镜载物台上使用偏光显微镜拍摄而成的图像。岩石薄片鉴定在油气储集层勘探和评估、环境保护、水利勘测等方面具有重要的作用。
在地质学领域,岩石薄片鉴定是通过观察和分析岩石图像矿物的组成和含量、进而对岩石进行分类和命名。矿物鉴定是岩石命名的第一个步骤,也是一项基础性的工作,目前通常是在显微镜下进行人工的肉眼鉴定,有些性状相近的岩石薄片还需要多年经验的师傅才能准确鉴别。这一类的工作比较耗费人力成本,将矿物鉴定环节自动化具有重要的研究意义。
科技在发展,社会在进步,对于矿产资源的需求越来越大,这就需要岩矿鉴定的方法也要不断地进步和更新。对于不同岩矿的测定,需要采用不同的鉴定方法。目前最常用方法主要有物理法、化学法、光谱法和探针法。但是这些岩矿鉴定的方法具有一定的局限性:第一、鉴定方法具有专门的指向性,某一鉴定方法可能只适合某一类的岩石矿物;第二、有些鉴定方法对所需要的技术和仪器要求较高,使得有些单位或部门只能进行某些岩矿的鉴定,这两种情况都会对鉴定结果产生影响。
此外,能够影响岩矿鉴定结果的还有人为因素,由于不同地质人员知识、经验、能力、精力等诸多因素制约,缺乏科学性和稳定性,且不同专家的分析结果有时存在一定的差异。因此,使用计算机技术进行岩石薄片的自动识别与分类能够提升这项工作的准确度和工作效率,显得尤为重要。
与其他深度学习框架相比,飞桨在大规模分布式训练、全硬件平台支持的高性能推理引擎、工业级模型库、端到端开发套件等技术能力上形成了显著的优势;在易学易用方面与竞品基本持平。与国内的其他平台相比,飞桨是一个具备完整自主深度学习训练框架技术的平台。
基于以上优点我们开发了基于深度学习的岩石薄片显微图像的矿物识别与分类模型。接下来,我们将会为大家介绍具体开发流程。
数据采集与预处理
此项目需要大量的数据才能保证结果的准确性和有效性,我们同资环学院的侯广顺教授进行了交流和沟通,在侯教授的帮助下我们获得了大量的岩石薄片显微图像。本数据集使用型号DM2700P、放大倍数为50的LeiCa偏光显微镜进行采集。共采集10种矿物、1347张显微图像。考虑到矿物具有在单一光源下不易识别的性质,在采集过程中对部分矿物采用了正交偏光系统。表1给出本文采集的矿物薄片显微图像的种类、数量、所用光源系统和图像分辨率。
数据集按矿物种类分为10个文件夹:其中9类矿物薄片在单偏光和正交偏光两种光源环境下拍摄,1类矿物薄片只在正交偏光下拍摄。矿物薄片显微图像数据集中的每一个类别的图像单独保存在一个文件夹中,每一张图像代表一个矿物样本。文件夹命名方式为“种类名”, 每个图像文件命名方式按种类名和自然数的顺序排列,序号后面的“-”表示在单偏光系统下拍摄,序号后面的“+”表示在正交偏光系统下拍摄。部分样本在单偏光和正交偏光系统下拍摄的矿物薄片显微图像如下图1所示,左图是在正交偏光系统下拍摄的,右图是在单偏光系统下拍摄的。
将数据集划分为训练集和测试集。其中,80%的数据用于训练,剩下20%的数据用作测试。为了提高模型的泛化能力,使用了数据增强技术对原始图像进行随机旋转和缩放操作,将图像统一Resize成600×400px,最后总共获得5388张,大幅度提升训练样本的数量。
网络配置
本文采用的网络模型为DenseNet。经典的分类模型包括LeNet、AlexNet、VGG、GoogleNet、Inception、ResNet、DenseNet等。ResNet是2015年ILSVRC的冠军。相比ResNet,DenseNet提出了一个更密集的连接机制:即互相连接所有的层,具体来说就是每个层都会接受其前面所有层作为其额外的输入。直接通过Concat来连接不同层的特征图,可以实现特征重用,提升效率。以下为ResNet(左图)与DenseNet(右图)基本block对比如下图2所示。
一般的CNN网络需要经过Pooling或者Stride的Conv来降低特征图的大小,而DenseNet的密集连接方式需要特征图大小保持一致。为了解决这个问题,DenseNet网络中使用DenseBlock和Transition结构,其中DenseBlock包含很多层的模块,每层的特征图大小相同,层与层之间采用密集的连接方式。而Transition模块就是连接两个相邻的DenseBlock,并且通过Pooling使特征图大小降低。
构成DenseNet基本单元的DenseBlock和Transition代码如下:
def dense_block(self, input, block_num, fliter_num, name):
layers = []
layers.append(input)#拼接到列表
x = self.bottleneck_layer(input, fliter_num, name=name + '_bottle_' + str(0))
layers.append(x)
for i in range(block_num - 1):
x = paddle.fluid.layers.concat(layers, axis=1)
x = self.bottleneck_layer(x, fliter_num, name=name + '_bottle_' + str(i + 1))
layers.append(x)
return paddle.fluid.layers.concat(layers, axis=1)
def transition_layer(self, input, fliter_num, name):
bn = fluid.layers.batch_norm(input=input, act='relu', name=name + '_bn1')
conv1 = fluid.layers.conv2d(input=bn, num_filters=fliter_num, filter_size=1, name=name + '_conv1')
dropout = fluid.layers.dropout(x=conv1, dropout_prob=self.dropout_prob)
return fluid.layers.pool2d(input=dropout, pool_size=2, pool_type='avg', pool_stride=2)
在ImageNet数据集采用的DenseNet网络结构如下图3所示:
用户完成网络定义后,一般Fluid 程序中通常存在两个Program:
(1)fluid.default_startup_program:定义了创建模型参数,输入输出,以及模型中可学习参数的初始化等各种操作,由框架自动生成,使用时无需显示地创建;
(2)fluid.default_main_program :定义了神经网络模型,前向反向计算,以及优化算法对网络中可学习参数的更新,使用Fluid的核心就是构建起 default_main_program。
模型训练
配置完网络模型就可以开始进行模型训练。本次模型训练使用百度AI Studio在线平台。AI Studio免费提供基础版(CPU:2 Cores RAM:8GB,Disk:100GB)和高级版(GPU:Tesla V100,Video Mem:16GB;CPU:8Cores,RAM:32GB, Disk:100GB)两种运行环境。由于数据量较大,需要大量的算力,所以模型训练选用GPU高级版运行环境。
下面给出了一些模型训练的参数:
"class_dim": -1, # 分类数,会在初始化自定义 reader 的时候获得
"image_count": -1, # 训练图片数量,会在初始化自定义 reader 的时候获得
data_dir": "data/data28308", # 训练数据存储地址
"continue_train": True, # 是否接着上一次保存的参数接着训练
"pretrained": False, # 是否使用预训练的模型
"pretrained_dir": "data/data6593/DenseNet_pretrained",
"num_epochs": 120, # 模型训练的次数
"train_batch_size": 12, # 每次训练要加载的数据量
"early_stop": {
"sample_frequency": 50,
"successive_limit": 5,
"good_acc1": 0.90}, # 每次随机抽取50个样本进行测试,如果在连续5次测试的的准确率
超过90%以上,模型就停止训练,用户可以根据实际的需要进行设置。提前停止策略,认为
连续达到某个准确率就可以停止了
if acc1 >= good_acc1:
successive_count += 1
logger.info("current acc1 {0} meets good {1}, successive count {2}".format(acc1, good_acc1, successive_count))
fluid.io.save_inference_model(dirname=train_parameters['save_freeze_dir'],
feeded_var_names=['img'],
target_vars=[out],
main_program=main_program.clone(for_test=True),
executor=exe)
if successive_count >= successive_limit:
logger.info("end training")
stop_train = True
break
else:
successive_count = 0
由于数据量较大,需要训练几个小时。为防止训练过程意外中断,在训练过程中,每训练10个批次的数据保存一次中间结果,一旦出现意外中断,下次训练直接导入保存的中间结果,不需重新开始训练。最终训练完成时保存最终训练模型,为预测模型做准备。# 保存模型训练结果的策略,为了减小意外停止的损失。
if total_batch_count % sample_freq == 0:
logger.info("temp save {0} batch train result, current acc1 {1}".format(total_batch_count, acc1))
fluid.io.save_persistables(dirname=train_parameters['save_persistable_dir'],
main_program=main_program,
executor=exe)
模型预测
前面已经进行了模型训练,并保存了训练好的模型。接下来就可以使用训练好的模型对岩石薄片显微图像进行预测。
在预测之前需要对预测的图像进行预处理,将图像转化成模型能接受的数据格式。
def read_image(img_path):
img = Image.open(img_path)
if img.mode != 'RGB':
img = img.convert('RGB') # 将图像转换成RGB
img = resize_img(img, target_size) # DenseNet网络输入图像大小为512×512
img = np.array(img).astype('float32')
img -= mean_rgb # 将图像进行归一化处理
img = img.transpose((2, 0, 1)) # 进行通道交换
img *= 0.007843
img = img[np.newaxis,:]
return img
然后使用训练好的模型对经过预处理的图片进行预测。首先从指定目录中加载训练好的模型,然后将要预测的图片转换成向量输入模型中,最终返回模型的预测结果。
def eval_all():
eval_file_path = os.path.join(data_dir, eval_file)
total_count = 0 # 要预测图片的数量
right_count = 0 # 预测正确图片的数量
with codecs.open(eval_file_path, encoding='utf-8') as flist:
lines = [line.strip() for line in flist]
t1 = time.time()
for line in lines:
total_count += 1
parts = line.strip().split()
result = infer(parts[0])
if str(result) == parts[1]:
right_count += 1
period = time.time() - t1 # 模型预测所需要的时间
print("total eval count:{0} right eval count:{1} cost time:{2} predict accuracy:{3}".format(total_count,right_count, "%2.2f sec" % period, right_count / total_count))
模型的预测结果:从测试集中随机挑选1044张岩石薄片显微图像,预测正确912张,准确率达到87.4%。
total eval count:1044 right eval count:912 cost time:108.51 sec predict accuracy:0.8735632183908046。
总结
实验结果显示,10种岩石薄片图像在训练集上的平均分类概率为90%,最低分类识别率为85.3%,最高分类识别率为95.1%。在训练迭代1000次时,交叉熵损失值趋于稳定,模型收敛。在识别速度方面,识别一张岩石薄片图像仅需要0.1s,识别速度较快。可见,卷积神经网络能够自动提取不同偏光系统下拍摄岩石薄片图像的特征,并进行快速智能分类与识别。
综上,该方法无需人工手动提取岩石薄片图像特征,消除了主观因素的影响;实现岩石薄片图像的全自动识别与分类,提高智能化程度;模型预测平均识别率达到87.4%,可用于实际需要,降低了鉴定岩石薄片种类的成本,对资源勘探、工程地质、环境保护、水利勘探等具有重要意义。
AI Studio项目链接:https://aistudio.baidu.com/ai...
如果您加入官方QQ群,您将遇上大批志同道合的深度学习同学。官方QQ群:703252161。
如果您想详细了解更多飞桨的相关内容,请参阅以下文档。
官网地址:https://www.paddlepaddle.org.cn
飞桨开源框架项目地址: