• [问题求助] 【求助 | YOLOv7】Modelarts上用pytorch训练YOLOv7报错CUDNN_STATUS_NOT_INITIALIZED
    问题基本如题使用的具体规格是pytorch1.8-cuda10.2-cudnn7-ubuntu18.04,GPU等情况是:GPU: 1*T4(16GB)|CPU: 8核 32GB,在配置好了相关数据和文件之后,训练开始阶段报错“RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED”。我猜想应该是和cuDNN的安装和版本适配有关,但实在是不清楚具体该怎么在Modelarts上完成配置,各位请不吝赐教QvQ
  • [问题求助] “上海计算生物学大赛”靶标数据
    “上海计算生物学大赛”中所提供的数据只有化合物相关,请问这些化合物对应的靶标数据都是已知的吗?如果是存在已知靶标的,有无指定的搜索渠道?
  • [其他] 浅谈神经网络算法之ansformer(注意力机制)
    ansformer(注意力机制)Transformers是机器学习(ML)中一个令人兴奋的(相对)新的部分,但是在理解它们之前,有很多概念需要分解。这里我们关注的是基本的Self-Attention机制是如何工作的,这是Transformers模型的第一层。本质上,对于每个输入向量,Self-Attention产生一个向量,该向量在其邻近向量上加权求和,其中权重由单词之间的关系或连通性决定。Transformers是一种ML架构,已经成功地应用于各种NLP任务,尤其是序列到序列(seq2seq)任务,如机器翻译和文本生成。在seq2seq任务中,目标是获取一组输入(例如英语单词)并产生一组理想的输出(德语中的相同单词)。自2017年发布以来,他们已经占领了seq2seq的主流架构(LSTMs),几乎无所不在地出现在任何关于NLP突破的新闻中(比如OpenAI的GPT-2甚至出现在主流媒体上!)。神经网络接收的输入是很多大小不一的向量,并且不同向量向量之间有一定的关系,但是实际训练的时候无法充分发挥这些输入之间的关系而导致模型训练结果效果极差。比如机器翻译问题(序列到序列的问题,机器自己决定多少个标签),词性标注问题(一个向量对应一个标签),语义分析问题(多个向量对应一个标签)等文字处理问题。卷积只能通过叠加很深的层才能获得全局感受野,循环神经网络不好训练且慢。2017年《Attention is all you need》诞生了一种全新的网络架构,self-attention。使用self-attention的BERT巨大的提升了自然语言处理的精度和速度,近些年来BERT,GPT2,GPT3,基本都是基于Transformer的架构了。另外从2020年的vit开始,Transformer也开始进入图像处理领域大放异彩,如swin transformer。self-attention的运算过程。我们可以看到这是一个可并行运算的过程,而且从一开始就在捕捉全局关系。
  • [其他] 浅谈神经网络算法之RNN-循环神经网络
    神经网络是一个由生物神经元组成的网络或电路,或者从现代意义上讲,是一个由人工神经元或节点组成的人工神经网络。因此,一个神经网络要么是由生物神经元组成的生物神经网络,要么是用于解决人工智能(AI)问题的人工神经网络。生物神经元的连接在人工神经网络中被建模为节点之间的权重。正的权重反映了兴奋性连接,而负值意味着抑制性连接。所有的输入都被一个权重修改并加总。这种活动被称为线性组合。最后,一个激活函数控制输出的振幅。RNN-循环神经网络循环神经网络(recurrent neural network)或 RNN (Rumelhart et al., 1986c)是一类用于处理序列数据的神经网络。就像卷积网络是专门用于处理网格化数据 X(如一个图像)的神经网络,循环神经网络是专门用于处理序列 x (1), . . . , x(τ) 的神经网络。正如卷积网络可以很容易地扩展到具有很大宽度和高度的图像,以及处理大小可变的图像,循环网络可以扩展到更长的序列(比不基于序列的特化网络长得多)。大多数循环网络也能处理可变长度的序列。卷积网络用于处理图像,循环网络用于处理自然语言。如下是循环神经网络的前向传播过程,后续每个神经元都要取前一个神经元的输出作为输入的一部分。这种网络结构,可以让我们的模型对序列关系进行建模。因为依赖关系,循环神经网络表现出两个问题:(1)训练不稳定,梯度的累积容易产生梯度爆炸与梯度消失,不利于神经网络的训练。(2)因为模型是一种串行的结构,下一个神经元的输入必须依赖于前一个的输出,所以导致了循环神经网络的处理速度慢。简单的RNN结构一个简单的循环神经网络如,它由输入层、一个隐藏层和一个输出层组成
  • 浅谈神经网络算法之CNN(卷积神经网络)
    神经网络是一个由生物神经元组成的网络或电路,或者从现代意义上讲,是一个由人工神经元或节点组成的人工神经网络。因此,一个神经网络要么是由生物神经元组成的生物神经网络,要么是用于解决人工智能(AI)问题的人工神经网络。生物神经元的连接在人工神经网络中被建模为节点之间的权重。正的权重反映了兴奋性连接,而负值意味着抑制性连接。所有的输入都被一个权重修改并加总。这种活动被称为线性组合。最后,一个激活函数控制输出的振幅。神经网络算法之CNN(卷积神经网络)卷积神经网络是LeCun提出,用Lenet卷积网络来识别信封或邮件上的手写数字。卷积神经网络是一种专门用来处理具有类似网格结构的数据的 神经网络。例如时间序列数据(可以认为是在时间轴上有规律地采样形成的一维网格)和图像数据(可以看作是二维的像素网格)。卷积网络在诸多应用领域都表现优异。“卷积神经网络” 一词表明该网络使用了 卷积(convolution)这种数学运算。卷积是一种特殊的线性运算。卷积网络是指那些至少在网络的一层中使用卷积运算来替代一般的矩阵乘法运算的神经网络。卷积运算通过三个重要的思想来帮助改进机器学习系统:(1)稀疏交互(sparse interactions):举个例子, 当处理一张图像时,输入的图像可能包含成千上万个像素点,但是我们可以通过只占用几十到上百个像素点的核来检测一些小的有意义的特征,例如图像的边缘。(2)参数共享(parameter sharing:在卷积神经网络中,核的每一个元素都作用在输入的每一位置上(是否考虑边界像素取决于对边界决策的设计)。卷积运算中的参数共享保证了我们只需要学习一个参数集合,而不是对于每一位置都需要学习一个单独的参数集合。(3)等变表示(equivariant representations)。对于卷积,参数共享的特殊形式使得神经网络层具有对平移等变(equivariance)的性质。如果一个函数满足输入改变,输出也以同样的方式改变这一性质,我们就说它是等变(equivariance)的。例如在卷积操作中我们先移动图像上的物体再进行卷积得到的结果与我们先卷积在移动卷积图上的输出,这两个操作的结果是一致的。
  • [其他] 浅谈神经网络
    神经网络(NN)是一种模仿生物神经网络进行计算和信息处理的计算模型。它是人工智能领域中最常用的一种算法,用于解决各种复杂的问题,如图像识别、自然语言处理、语音识别等。下面是神经网络算法的详细介绍:数据预处理:神经网络需要进行数据预处理,以便将其转换为适合构建神经网络的格式。这通常包括数据清洗、缺失值填充和特征选择等步骤。构建神经网络模型:在数据预处理之后,我们开始构建神经网络模型。神经网络通常由多个隐藏层组成,每个隐藏层都由多个神经元组成。每个神经元都会接收输入数据,并将其传递给下一层的神经元。神经网络训练:神经网络模型构建完成后,我们需要使用训练数据来训练模型。训练过程中,我们将输入数据传递给模型,模型会计算输出结果并根据误差进行反馈和调整。训练通常采用反向传播算法进行优化。预测:训练完成后,我们可以使用训练好的模型对新数据进行预测。预测过程中,我们将新数据传递给模型,模型会计算输出结果并根据误差进行反馈和调整。神经网络算法的优点包括:非线性映射能力:神经网络可以将输入数据映射到高维空间中,并通过学习的权重来学习输入数据与输出结果之间的非线性关系。这使得神经网络在解决复杂问题时具有很好的表现能力。可解释性强:神经网络是一种结构化的算法,它可以很好地解释其学习过程,使得人们能够理解和解释算法的结果。可扩展性强:神经网络通常具有很好的可扩展性,即它可以轻松地添加新的神经元、层数和隐藏层数。这使得它成为一种很好的监督学习算法,可以用于许多不同领域的任务。鲁棒性强:神经网络可以处理输入数据中的异常值和噪声,这使得它在解决复杂问题时表现出很好的鲁棒性。然而,神经网络算法也存在一些缺点:计算复杂度高:构建和训练神经网络需要大量的计算资源和时间,这使得它在处理大规模数据时表现不佳。参数调整困难:神经网络需要通过调整参数来优化模型的性能,这使得它在参数设置时比较困难。容易过拟合:在训练过程中,神经网络可能会陷入局部最优解,导致模型表现不佳。
  • [其他] 浅谈VGG网络性能优异组件
    VGG网络是2014年由牛津大学著名研究组VGG (Visual Geometry Group) 提出的。在2014到2016年(ResNet提出之前),VGG网络可以说是当时最火并被广泛应用的Backbone。后面由于各种新的网络提出,论精度VGG比不上ResNet,论速度和参数数量VGG比不过MobileNet等轻量级网络,慢慢的VGG开始淡出人们的视线。当VGG已经被大家遗忘时,2021年清华大学、旷视科技以及香港科技大学等机构共同提出了RepVGG网络,希望能够让VGG-style网络Great Again。epVGG绝对可以算得上2020年在backbone方面有很大影响力的工作,其核心思想是:通过结构重参数化思想,让训练网络的多路结构(多分支模型训练时的优势——性能高)转换为推理网络的单路结构(模型推理时的好处——速度快、省内存)),结构中均为3x3的卷积核,同时,计算库(如CuDNN,Intel MKL)和硬件针对3x3卷积有深度的优化,最终可以使网络有着高效的推理速率(其实TensorRT在构建engine阶段,对模型进行重构,底层也是应用了卷积合并,多分支融合思想,来使得模型最终有着高性能的推理速率)。性能优异组件:随着不断尝试于探索,出现了很多性能优异的网络组件,比如深度可分离卷积,分组卷积等等,这些都可以显著增加网络性能,但是,我们也知道,就拿group conv来说,当group越多是,我们知道网络性能会越好,但是,其MAC(内存访问成本)也会显著增大,最终导致模型变慢,深度可分离卷积虽然可以显著降低FLOPs,但是其MAC也会增加,最终导致模型速度变慢。这就引发了一个矛盾,既然多分支结构和性能优异的组件能显著提高模型性能,但是,又会最终导致模型在推理时速度变慢且还非常耗内存,这非常不利于工业场景(尤其实在算力受限的情况下)。这种问题该怎么解决呢?2. 解决方案:​ 想要使网络具有高性能,又要有高效推理速度,怎么才能解决这个问题?repVGG给了我们答案:结构重参数化思想,也即训练时尽量用多分支结构来提升网络性能,而推理时,采用利用结构重参数化思想,将其变为单路结构,这样,显存占用少,推理速度又快。2.1. backbone:​ 作者最终选择将VGG作为backbone,这里为什么要选择这么古董的玩意儿呢,而不是选择现在主流的ResNet架构?主要是基于以下三点考虑:2.1.1. 速度快:​ 我们都知道,VGG几乎都是由3x3卷积堆叠而成,而现在加速库比如NVIDIA的cudNN,Intel的MKL和相关硬件对3x3的卷积核有非常好的性能优化,而在VGG中,几乎都是conv3x3。因此,利用现有加速库,会得到更好的性能优化,从下表就就可以看出,在相同channels、input_size和batchsize条件下,不同卷积核的FLOPs和TFLOPs和用时,可以看出,3x3卷积非常快。在GPU上,3x3卷积的计算密度(理论运算量(Theoretical FLOPs ÷ Time usage)除以所用时间)可达1x1和5x5卷积的4倍。2.1.2. 节省内存:​ VGG是一个直筒性单路结构,由上述分析可知,单路结构会占有更少的内存,因为不需要保存其中间结果,同时,单路架构非常快,因为并行度高。同样的计算量,大而整的运算效率远超小而碎的运算。2.1.3. 灵活性好:​ 多分支结构会引入网络结构的约束,比如Resnet的残差结构要求输入和卷积出来的张量维度要一致(这样才能相加),这种约束导致网络不易延伸拓展,也一定程度限制了通道剪枝。对应的单路结构就比较友好,非常容易改变各层的宽度,这样剪枝后也能得到很好的加速比。RepVGG主体部分只有一种算子: conv3x3+ReLU。在设计专用芯片时,给定芯片尺寸或造价,我们可以集成海量的3x3卷积-ReLU计算单元来达到很高的效率。别忘了,单路架构省内存的特性也可以帮我们少做存储单元。
  • [技术干货] 字符序列检测——CRNN模型
    字符序列检测——CRNN模型在本案例中,我们将学习深度学习中的OCR(Optical Character Recognition)光学字符识别技术。OCR作为计算机视觉中较早使用深度学习技术的领域,有很多优秀的模型出现,所以通过此案例我们来学习深度学习下的OCR技术。普遍的深度学习下的OCR技术将文字识别过程分为:文本区域检测以及字符识别。本案例中介绍的模型CRNN就是一种字符识别模型,它将文字图片中的文字识别出来。注意事项:本案例使用框架**:** TensorFlow-1.13.1本案例使用硬件规格**:** 8 vCPU + 64 GiB + 1 x Tesla V100-PCIE-32GB进入运行环境方法:点此链接进入AI Gallery,点击Run in ModelArts按钮进入ModelArts运行环境,如需使用GPU,您可以在ModelArts JupyterLab运行界面右边的工作区进行切换运行代码方法**:** 点击本页面顶部菜单栏的三角形运行按钮或按Ctrl+Enter键 运行每个方块中的代码JupyterLab的详细用法**:** 请参考《ModelAtrs JupyterLab使用指导》碰到问题的解决办法**:** 请参考《ModelAtrs JupyterLab常见问题解决办法》1.数据和代码下载运行下面代码,进行数据和代码的下载和解压from modelarts.session import Session sess = Session() if sess.region_name == 'cn-north-1': bucket_path="modelarts-labs/notebook/DL_ocr_crnn_sequence_recognition/crnn.tar" elif sess.region_name == 'cn-north-4': bucket_path="modelarts-labs-bj4/notebook/DL_ocr_crnn_sequence_recognition/crnn.tar" else: print("请更换地区到北京一或北京四") sess.download_data(bucket_path=bucket_path, path="./crnn.tar")Successfully download file modelarts-labs-bj4/notebook/DL_ocr_crnn_sequence_recognition/crnn.tar from OBS to local ./crnn.tar2.解压文件!tar -xf crnn.tar!pip install torch==1.3.0 !pip install torchvision==0.4.1 !pip install keras==2.1.6 !pip install keras_applications==1.0.5 !pip install opencv-python==4.1.0.25Collecting torch==1.3.0 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/ae/05/50a05de5337f7a924bb8bd70c6936230642233e424d6a9747ef1cfbde353/torch-1.3.0-cp36-cp36m-manylinux1_x86_64.whl (773.1MB)  99% |████████████�███████████████████| 772.6MB 127.8MB/s eta 0:00:01 | 6.8MB 110.1MB/s eta 0:00:07.2MB/s eta 0:00:07 | 18.6MB 113.5MB/s eta 0:00:07 | 23.4MB 114.2MB/s eta 0:00:07.0MB/s eta 0:00:07.2MB/s eta 0:00:07.0MB/s eta 0:00:07 | 46.1MB 114.6MB/s eta 0:00:07 |██▏ | 52.5MB 117.3MB/s eta 0:00:07��█▍ | 58.0MB 111.3MB/s eta 0:00:07 | 63.3MB 91.7MB/s eta 0:00:08 |██▉ | 69.0MB 116.3MB/s eta 0:00:07 | 74.4MB 105.4MB/s eta 0:00:07�█▎ | 79.6MB 120.6MB/s eta 0:00:06�█▌ | 85.3MB 126.2MB/s eta 0:00:06 | 91.3MB 100.6MB/s eta 0:00:07�██ | 96.8MB 124.5MB/s eta 0:00:06 | 102.2MB 124.0MB/s eta 0:00:06 | 107.2MB 119.4MB/s eta 0:00:06� | 113.2MB 135.5MB/s eta 0:00:0518.6MB 117.5MB/s eta 0:00:06/s eta 0:00:07/s eta 0:00:06 | 135.0MB 117.7MB/s eta 0:00:06MB/s eta 0:00:06/s eta 0:00:06�▎ | 151.2MB 116.0MB/s eta 0:00:06 | 156.5MB 127.8MB/s eta 0:00:05 | 161.7MB 104.0MB/s eta 0:00:06▉ | 166.3MB 120.1MB/s eta 0:00:06a 0:00:06 | 174.8MB 68.8MB/s eta 0:00:09 125.7MB/s eta 0:00:05 | 186.6MB 111.3MB/s eta 0:00:06eta 0:00:1096.0MB 137.6MB/s eta 0:00:05�▎ | 200.5MB 102.4MB/s eta 0:00:06 | 205.0MB 104.0MB/s eta 0:00:06 | 213.9MB 121.9MB/s eta 0:00:05 28% |█████████ | 217.7MB 119.4MB/s eta 0:00:05:00:06███▌ | 230.5MB 49.0MB/s eta 0:00:12 | 234.2MB 112.2MB/s eta 0:00:0500:06�██████▏ | 246.6MB 116.9MB/s eta 0:00:05MB/s eta 0:00:05 | 254.5MB 115.2MB/s eta 0:00:05 | 258.5MB 139.4MB/s eta 0:00:04�█████▉ | 262.1MB 116.5MB/s eta 0:00:05��████ | 266.7MB 135.7MB/s eta 0:00:04��████████▏ | 270.5MB 119.1MB/s eta 0:00:05% |███████████▍ | 274.4MB 113.1MB/s eta 0:00:05% |███████████▌ | 278.1MB 112.1MB/s eta 0:00:05��████████▊ | 281.9MB 126.5MB/s eta 0:00:04% |███████████▉ | 285.3MB 135.1MB/s eta 0:00:04��█████████ | 289.0MB 112.9MB/s eta 0:00:05/s eta 0:00:05 296.5MB 105.7MB/s eta 0:00:05 38% |████████████▍ | 300.4MB 119.1MB/s eta 0:00:04 | 303.9MB 138.5MB/s eta 0:00:047.3MB 60.9MB/s eta 0:00:080.6MB 56.1MB/s eta 0:00:09��██████ | 315.2MB 118.2MB/s eta 0:00:04██████▌ | 325.3MB 120.1MB/s eta 0:00:04█████▋ | 329.1MB 48.6MB/s eta 0:00:10 | 332.8MB 121.6MB/s eta 0:00:04��████████ | 336.6MB 106.7MB/s eta 0:00:05███████ | 340.1MB 112.8MB/s eta 0:00:040:05 45% |██████████████▌ | 350.5MB 67.4MB/s eta 0:00:070:04 | 357.5MB 120.3MB/s eta 0:00:04��██████████████▏ | 367.7MB 97.9MB/s eta 0:00:05�██████████████▍ | 371.2MB 115.7MB/s eta 0:00:04 | 374.6MB 56.8MB/s eta 0:00:08 | 384.6MB 131.7MB/s eta 0:00:03 | 388.1MB 116.6MB/s eta 0:00:04�██████████▏ | 391.4MB 122.5MB/s eta 0:00:04 395.2MB 112.8MB/s eta 0:00:04�██████████▌ | 398.0MB 111.5MB/s eta 0:00:04�▊ | 404.9MB 112.2MB/s eta 0:00:04�███████████ | 408.4MB 120.2MB/s eta 0:00:04�███ | 411.8MB 59.5MB/s eta 0:00:07 | 415.0MB 111.3MB/s eta 0:00:04417.9MB 57.1MB/s eta 0:00:07.9MB/s eta 0:00:06 | 424.6MB 136.4MB/s eta 0:00:03:00:03 | 430.7MB 132.1MB/s eta 0:00:03:00:047.1MB 136.1MB/s eta 0:00:03 | 440.2MB 111.3MB/s eta 0:00:03��███████████████▍ | 442.9MB 112.7MB/s eta 0:00:03�█████████▌ | 445.8MB 55.4MB/s eta 0:00:06 | 449.0MB 117.3MB/s eta 0:00:03████▊ | 452.1MB 118.1MB/s eta 0:00:03 eta 0:00:03 127.4MB/s eta 0:00:03 | 461.5MB 115.0MB/s eta 0:00:03��██████████▎ | 464.9MB 111.2MB/s eta 0:00:03▍ | 468.1MB 56.7MB/s eta 0:00:06�██████████████████▌ | 471.4MB 52.2MB/s eta 0:00:06��██████████▋ | 474.7MB 131.4MB/s eta 0:00:03��██████████▉ | 478.1MB 114.8MB/s eta 0:00:03�██ | 481.3MB 102.1MB/s eta 0:00:03 | 484.6MB 107.4MB/s eta 0:00:0303�████████████████▌ | 493.9MB 130.5MB/s eta 0:00:03 0:00:03 64% |████████████████████▊ | 500.4MB 133.1MB/s eta 0:00:03 0:00:02 65% |█████████████████████ | 506.5MB 118.2MB/s eta 0:00:03 65% |█████████████████████ | 509.7MB 118.7MB/s eta 0:00:03�█████▎ | 513.0MB 111.8MB/s eta 0:00:03� | 515.6MB 121.3MB/s eta 0:00:03 518.4MB 58.9MB/s eta 0:00:05�███████▋ | 522.2MB 124.8MB/s eta 0:00:03�█████▊ | 525.4MB 128.6MB/s eta 0:00:02�█████▉ | 528.6MB 112.6MB/s eta 0:00:03 531.5MB 121.6MB/s eta 0:00:02��█████████████████▏ | 535.3MB 128.1MB/s eta 0:00:02███████▎ | 538.4MB 138.6MB/s eta 0:00:02███████▍ | 541.8MB 105.1MB/s eta 0:00:03███████▌ | 544.7MB 117.1MB/s eta 0:00:02███████▊ | 548.0MB 117.7MB/s eta 0:00:02s eta 0:00:04MB/s eta 0:00:02�██████ | 556.6MB 67.8MB/s eta 0:00:04��██████████████████▏ | 559.1MB 114.4MB/s eta 0:00:02��██████████████████▍ | 565.4MB 119.7MB/s eta 0:00:02��██████████████████▌ | 568.0MB 129.6MB/s eta 0:00:02��█████████████████▋ | 571.4MB 50.2MB/s eta 0:00:05��████▊ | 574.0MB 134.9MB/s eta 0:00:02████████▉ | 576.7MB 131.7MB/s eta 0:00:02 eta 0:00:024:00:024.0MB 49.8MB/s eta 0:00:04█▉ | 599.6MB 129.9MB/s eta 0:00:02:00:02 eta 0:00:02██████████████▏ | 607.9MB 109.7MB/s eta 0:00:02��████████████▎ | 610.9MB 111.6MB/s eta 0:00:02� | 613.4MB 138.5MB/s eta 0:00:02�███████████████▌ | 616.8MB 135.6MB/s eta 0:00:02� | 620.2MB 136.4MB/s eta 0:00:02██▊ | 622.7MB 137.0MB/s eta 0:00:02 | 625.2MB 128.4MB/s eta 0:00:02 | 628.1MB 88.0MB/s eta 0:00:02 | 631.4MB 135.1MB/s eta 0:00:02█████████▎ | 634.2MB 52.0MB/s eta 0:00:03█████▍ | 636.9MB 71.9MB/s eta 0:00:02�▌ | 639.4MB 119.5MB/s eta 0:00:02 | 642.3MB 51.8MB/s eta 0:00:03MB/s eta 0:00:01ta 0:00:02B/s eta 0:00:02�███████████ | 653.4MB 123.5MB/s eta 0:00:01 | 656.4MB 54.0MB/s eta 0:00:03�████▍ | 662.0MB 135.9MB/s eta 0:00:01��██████████████▌ | 664.5MB 110.2MB/s eta 0:00:01| 667.3MB 132.4MB/s eta 0:00:01 | 669.9MB 117.8MB/s eta 0:00:01�█████████████████████▉ | 672.2MB 114.7MB/s eta 0:00:01�█████ | 677.6MB 124.5MB/s eta 0:00:01ta 0:00:01:02:00:01 89% |████████████████████████████▋ | 690.3MB 98.7MB/s eta 0:00:0125.5MB/s eta 0:00:01�███████████▏ | 705.7MB 122.8MB/s eta 0:00:01 708.5MB 116.7MB/s eta 0:00:01 710.7MB 94.9MB/s eta 0:00:01 713.0MB 135.7MB/s eta 0:00:01 715.3MB 130.3MB/s eta 0:00:01��██████▊ | 717.7MB 115.5MB/s eta 0:00:01 720.2MB 125.9MB/s eta 0:00:01 722.5MB 135.6MB/s eta 0:00:01 725.0MB 121.8MB/s eta 0:00:01 727.2MB 136.3MB/s eta 0:00:0194% |██████████████████████████████▏ | 729.6MB 139.6MB/s eta 0:00:0194% |██████████████████████████████▎ | 731.8MB 140.4MB/s eta 0:00:01��█████████████████████████████▍ | 733.8MB 122.8MB/s eta 0:00:01████████▌ | 735.5MB 131.0MB/s eta 0:00:01███████▌ | 738.0MB 92.4MB/s eta 0:00:01�████████▊ | 742.2MB 131.3MB/s eta 0:00:017% |███████████████████████████████ | 749.9MB 139.9MB/s eta 0:00:01�█████▏| 752.1MB 134.1MB/s eta 0:00:01�█████▎| 754.4MB 133.8MB/s eta 0:00:01��██████████████████▍| 758.7MB 134.3MB/s eta 0:00:01██████████████████████▌| 760.9MB 139.7MB/s eta 0:00:01��██████████████████▋| 763.5MB 108.8MB/s eta 0:00:01�████████████████▊| 765.8MB 117.2MB/s eta 0:00:01��█████████████████▊| 767.7MB 60.6MB/s eta 0:00:01ta 0:00:01 100% |████████████████████████████████| 773.1MB 16.8MB/s ta 0:00:011 [?25hRequirement already satisfied: numpy in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from torch==1.3.0) Installing collected packages: torch Successfully installed torch-1.3.0 You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting torchvision==0.4.1 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/fc/23/d418c9102d4054d19d57ccf0aca18b7c1c1f34cc0a136760b493f78ddb06/torchvision-0.4.1-cp36-cp36m-manylinux1_x86_64.whl (10.1MB)  100% |████████████████████████████████| 10.1MB 124.6MB/s ta 0:00:01███████████████| 10.1MB 131.9MB/s eta 0:00:01 [?25hRequirement already satisfied: torch==1.3.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from torchvision==0.4.1) Requirement already satisfied: numpy in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from torchvision==0.4.1) Requirement already satisfied: pillow>=4.1.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from torchvision==0.4.1) Requirement already satisfied: six in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from torchvision==0.4.1) Installing collected packages: torchvision Successfully installed torchvision-0.4.1 You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting keras==2.1.6 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/54/e8/eaff7a09349ae9bd40d3ebaf028b49f5e2392c771f294910f75bb608b241/Keras-2.1.6-py2.py3-none-any.whl (339kB)  100% |████████████████████████████████| 348kB 20.2MB/s ta 0:00:01 [?25hRequirement already satisfied: numpy>=1.9.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras==2.1.6) Requirement already satisfied: pyyaml in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras==2.1.6) Requirement already satisfied: h5py in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras==2.1.6) Requirement already satisfied: six>=1.9.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras==2.1.6) Requirement already satisfied: scipy>=0.14 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras==2.1.6) Installing collected packages: keras Found existing installation: Keras 2.2.4 Uninstalling Keras-2.2.4: Successfully uninstalled Keras-2.2.4 Successfully installed keras-2.1.6 You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting keras_applications==1.0.5 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/3f/9c/6e9393ead970fd97be0cfde912697dafec5800d9191f5ba25352fa537d72/Keras_Applications-1.0.5-py2.py3-none-any.whl (44kB)  100% |████████████████████████████████| 51kB 10.8MB/s a 0:00:011 [?25hRequirement already satisfied: numpy>=1.9.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras_applications==1.0.5) Requirement already satisfied: h5py in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras_applications==1.0.5) Requirement already satisfied: keras>=2.1.6 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras_applications==1.0.5) Requirement already satisfied: six in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from h5py->keras_applications==1.0.5) Requirement already satisfied: scipy>=0.14 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras>=2.1.6->keras_applications==1.0.5) Requirement already satisfied: pyyaml in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from keras>=2.1.6->keras_applications==1.0.5) Installing collected packages: keras-applications Found existing installation: Keras-Applications 1.0.8 Uninstalling Keras-Applications-1.0.8: Successfully uninstalled Keras-Applications-1.0.8 Successfully installed keras-applications-1.0.5 You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting opencv-python==4.1.0.25 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/7b/d2/a2dbf83d4553ca6b3701d91d75e42fe50aea97acdc00652dca515749fb5d/opencv_python-4.1.0.25-cp36-cp36m-manylinux1_x86_64.whl (26.6MB)  100% |████████████████████████████████| 26.6MB 115.4MB/s ta 0:00:01��█████████████████▉ | 17.3MB 107.5MB/s eta 0:00:01�█████▊ | 22.1MB 107.7MB/s eta 0:00:01 [?25hRequirement already satisfied: numpy>=1.11.3 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from opencv-python==4.1.0.25) Installing collected packages: opencv-python Found existing installation: opencv-python 3.4.1.15 Uninstalling opencv-python-3.4.1.15: Successfully uninstalled opencv-python-3.4.1.15 Successfully installed opencv-python-4.1.0.25 You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command.from tensorflow import ConfigProto from tensorflow import InteractiveSession config = ConfigProto() config.gpu_options.allow_growth = True session = InteractiveSession(config=config)/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint8 = np.dtype([("qint8", np.int8, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint8 = np.dtype([("quint8", np.uint8, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:528: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint16 = np.dtype([("qint16", np.int16, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:529: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint16 = np.dtype([("quint16", np.uint16, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:530: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint32 = np.dtype([("qint32", np.int32, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:535: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. np_resource = np.dtype([("resource", np.ubyte, 1)])3.首先引用相关的库和文件import numpy as np import data.dataset as dataset import keys as keys import torch from keras.layers import Flatten, BatchNormalization, Permute, TimeDistributed, Dense, Bidirectional, GRU from keras.layers import Input, Conv2D, MaxPooling2D, ZeroPadding2D,Lambda from keras.models import Model from keras.optimizers import SGD from keras import backend as KUsing TensorFlow backend.函数ctc_lambda_func 将完成对ctc损失函数的计算。def ctc_lambda_func(args): y_pred, labels, input_length, label_length = args y_pred = y_pred[:, 2:, :] return K.ctc_batch_cost(labels, y_pred, input_length, label_length)定义文字类型数characters = keys.alphabet[:] nclass=len(characters)+14.构建网络input = Input(shape=(32, None, 1), name='the_input') # CNN卷积层部分 m = Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same', name='conv1')(input) m = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='pool1')(m) m = Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same', name='conv2')(m) m = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='pool2')(m) m = Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same', name='conv3')(m) m = Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same', name='conv4')(m) m = ZeroPadding2D(padding=(0, 1))(m) m = MaxPooling2D(pool_size=(2, 2), strides=(2, 1), padding='valid', name='pool3')(m) m = Conv2D(512, kernel_size=(3, 3), activation='relu', padding='same', name='conv5')(m) m = BatchNormalization(axis=1)(m) m = Conv2D(512, kernel_size=(3, 3), activation='relu', padding='same', name='conv6')(m) m = BatchNormalization(axis=1)(m) m = ZeroPadding2D(padding=(0, 1))(m) m = MaxPooling2D(pool_size=(2, 2), strides=(2, 1), padding='valid', name='pool4')(m) m = Conv2D(512, kernel_size=(2, 2), activation='relu', padding='valid', name='conv7')(m) m = Permute((2, 1, 3), name='permute')(m) m = TimeDistributed(Flatten(), name='timedistrib')(m) # RNN循环层部分 m = Bidirectional(GRU(256, return_sequences=True), name='blstm1')(m) m = Dense(256, name='blstm1_out', activation='linear')(m) m = Bidirectional(GRU(256, return_sequences=True), name='blstm2')(m) y_pred = Dense(nclass, name='blstm2_out', activation='softmax')(m) basemodel = Model(inputs=input, outputs=y_pred) # 转录层部分 labels = Input(name='the_labels', shape=[None, ], dtype='float32') input_length = Input(name='input_length', shape=[1], dtype='int64') label_length = Input(name='label_length', shape=[1], dtype='int64') loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([y_pred, labels, input_length, label_length]) # 模型输入 model = Model(inputs=[input, labels, input_length, label_length], outputs=[loss_out]) # 模型优化器 sgd = SGD(lr=0.0001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5) model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=sgd)WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version. Instructions for updating: Colocations handled automatically by placer. WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:3948: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead. WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:3928: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead.5.model用于训练,加入了ctc损失计算部分model.summary()此处打印过长,省略输出basemodel用于推理部分,包含了CNN+RNN层部分basemodel.summary()_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= the_input (InputLayer) (None, 32, None, 1) 0 _________________________________________________________________ conv1 (Conv2D) (None, 32, None, 64) 640 _________________________________________________________________ pool1 (MaxPooling2D) (None, 16, None, 64) 0 _________________________________________________________________ conv2 (Conv2D) (None, 16, None, 128) 73856 _________________________________________________________________ pool2 (MaxPooling2D) (None, 8, None, 128) 0 _________________________________________________________________ conv3 (Conv2D) (None, 8, None, 256) 295168 _________________________________________________________________ conv4 (Conv2D) (None, 8, None, 256) 590080 _________________________________________________________________ zero_padding2d_1 (ZeroPaddin (None, 8, None, 256) 0 _________________________________________________________________ pool3 (MaxPooling2D) (None, 4, None, 256) 0 _________________________________________________________________ conv5 (Conv2D) (None, 4, None, 512) 1180160 _________________________________________________________________ batch_normalization_1 (Batch (None, 4, None, 512) 16 _________________________________________________________________ conv6 (Conv2D) (None, 4, None, 512) 2359808 _________________________________________________________________ batch_normalization_2 (Batch (None, 4, None, 512) 16 _________________________________________________________________ zero_padding2d_2 (ZeroPaddin (None, 4, None, 512) 0 _________________________________________________________________ pool4 (MaxPooling2D) (None, 2, None, 512) 0 _________________________________________________________________ conv7 (Conv2D) (None, 1, None, 512) 1049088 _________________________________________________________________ permute (Permute) (None, None, 1, 512) 0 _________________________________________________________________ timedistrib (TimeDistributed (None, None, 512) 0 _________________________________________________________________ blstm1 (Bidirectional) (None, None, 512) 1181184 _________________________________________________________________ blstm1_out (Dense) (None, None, 256) 131328 _________________________________________________________________ blstm2 (Bidirectional) (None, None, 512) 787968 _________________________________________________________________ blstm2_out (Dense) (None, None, 5531) 2837403 ================================================================= Total params: 10,486,715 Trainable params: 10,486,699 Non-trainable params: 16 _________________________________________________________________函数one_hot对标签进行处理def one_hot(text, length, characters=characters): label = np.zeros(length) for i, char in enumerate(text): index = characters.find(char) if index == -1: index = characters.find(u' ') label[i] = index return label加载数据trainroot = './data/' # 读取lmdb train_dataset = dataset.lmdbDataset(root=trainroot, target_transform=one_hot) test_dataset = dataset.lmdbDataset( root=trainroot, transform=dataset.resizeNormalize((256, 32)), target_transform=one_hot) # 加载数据 train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=1, shuffle=True, sampler=None, num_workers=4, collate_fn=dataset.alignCollate( imgH=32, imgW=256,)) test_loader = torch.utils.data.DataLoader( test_dataset, shuffle=True, batch_size=1, num_workers=4)nSamples:738 nSamples:738数据生成器def gen(loader, flag='train'): while True: i = 0 n = len(loader) for X, Y in loader: X = X.numpy() X = X.reshape((-1, 32, 256, 1)) if flag == 'test': Y = Y.numpy() Y = np.array(Y) Length = int(256 / 4) - 1 batchs = X.shape[0] if i > n - 1: i = 0 break yield [ X, Y, np.ones(batchs) * int(Length), np.ones(batchs) * int(len(Y)) ], np.ones(batchs)#加载预训练模型 modelPath = './model_crnn.h5' model.load_weights(modelPath)model.fit_generator( gen(train_loader, flag='train'), steps_per_epoch=100, epochs=2, validation_data=gen(test_loader, flag='test'), validation_steps=10)WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/ops/math_grad.py:102: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Deprecated in favor of operator or tf.math.divide. WARNING:tensorflow:Variable *= will be deprecated. Use `var.assign(var * other)` if you want assignment to the variable value or `x = x * y` if you want a new python Tensor object. Epoch 1/2 100/100 [==============================] - 30s 297ms/step - loss: 42.6744 - val_loss: 46.7768 Epoch 2/2 100/100 [==============================] - 23s 230ms/step - loss: 29.9630 - val_loss: 44.9445 <keras.callbacks.History at 0x7fb2387f3c88>model.save_weights('./CRNN_results.h5')6.测试部分basemodel.load_weights('./CRNN_results.h5') # 加载刚训练好的模型7.加载待识别的原图from PIL import Image from CRNN_model import decode img = Image.open('./img_0.png') print('待识别的原图:') img待识别的原图:8.定义CRNN字符识别函数def crnn_ocr(img): """ CRNN字符识别函数 :param img: 需要进行字符识别的图片 :return: ocr_result: 图片的字符识别结果,数据类型为字符串 """ img = img.convert('L') # 图片灰度化 scale = img.size[1] * 1.0 / 32 # 图片尺寸调整,把图片高度调整为32 w = img.size[0] / scale w = int(w) img = img.resize((w, 32)) img = np.array(img).astype(np.float32) / 255.0 X = img.reshape((32, w, 1)) X = np.array([X]) y_pred = basemodel.predict(X) # 预测 ocr_result = decode(y_pred) # 处理预测结果 return ocr_result9.调用函数,获得字符识别结果ocr_result = crnn_ocr(img) print('字符识别结果:', ocr_result)字符识别结果: 文字识别模型文字识别。
  • [其他] 浅谈BP神经网络应用
    BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是应用最广泛的神经网络模型之一。BP网络是在输入层与输出层之间增加若干层(一层或多层)神经元,这些神经元称为隐单元,它们与外界没有直接的联系,但其状态的改变,则能影响输入与输出之间的关系,每一层可以有若干个节点。BP神经网络的计算过程由正向计算过程和反向计算过程组成。正向传播过程,输入模式从输入层经隐单元层逐层处理,并转向输出层,每一层神经元的状态只影响下一层神经元的状态。如果在输出层不能得到期望的输出,则转入反向传播,将误差信号沿原来的连接通路返回,通过修改各神经元的权值,使得误差信号最小。1.网络状态初始化2.前向计算过程应用在人工神经网络的实际应用中,绝大部分的神经网络模型都采用BP网络及其变化形式。它也是前向网络的核心部分,体现了人工神经网络的精华。BP网络主要用于以下四个方面。1)函数逼近:用输入向量和相应的输出向量训练一个网络逼近一个函数。2)模式识别:用一个待定的输出向量将它与输入向量联系起来。3)分类:把输入向量所定义的合适方式进行分类。4)数据压缩:减少输出向量维数以便于传输或存储。BP神经网络无论在网络理论还是在性能方面已比较成熟。其突出优点就是具有很强的非线性映射能力和柔性的网络结构。网络的中间层数、各层的神经元个数可根据具体情况任意设定,并且随着结构的差异其性能也有所不同。但是BP神经网络也存在以下的一些主要缺陷。①学习速度慢,即使是一个简单的问题,一般也需要几百次甚至上千次的学习才能收敛。②容易陷入局部极小值。③网络层数、神经元个数的选择没有相应的理论指导。④网络推广能力有限。对于上述问题,已经有了许多改进措施,研究最多的就是如何加速网络的收敛速度和尽量避免陷入局部极小值的问题。
  • [其他] 浅谈BP神经网络基本原理
    BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是应用最广泛的神经网络模型之一。在人工神经网络的发展历史上,感知机(Multilayer Perceptron,MLP)网络曾对人工神经网络的发展发挥了极大的作用,也被认为是一种真正能够使用的人工神经网络模型,它的出现曾掀起了人们研究人工神经元网络的热潮。单层感知网络(M-P模型)做为最初的神经网络,具有模型清晰、结构简单、计算量小等优点。但是,随着研究工作的深入,人们发现它还存在不足,例如无法处理非线性问题,即使计算单元的作用函数不用阀函数而用其他较复杂的非线性函数,仍然只能解决线性可分问题.不能实现某些基本功能,从而限制了它的应用。增强网络的分类和识别能力、解决非线性问题的唯一途径是采用多层前馈网络,即在输入层和输出层之间加上隐含层。构成多层前馈感知器网络。20世纪80年代中期,David Runelhart。Geoffrey Hinton和Ronald W-llians、DavidParker等人分别独立发现了误差反向传播算法(Error Back Propagation Training),简称BP,系统解决了多层神经网络隐含层连接权学习问题,并在数学上给出了完整推导。人们把采用这种算法进行误差校正的多层前馈网络称为BP网。BP神经网络具有任意复杂的模式分类能力和优良的多维函数映射能力,解决了简单感知器不能解决的异或(Exclusive OR,XOR)和一些其他问题。从结构上讲,BP网络具有输入层、隐藏层和输出层;从本质上讲,BP算法就是以网络误差平方为目标函数、采用梯度下降法来计算目标函数的最小值。人工神经网络无需事先确定输入输出之间映射关系的数学方程,仅通过自身的训练,学习某种规则,在给定输入值时得到最接近期望输出值的结果。作为一种智能信息处理系统,人工神经网络实现其功能的核心是算法。BP神经网络是一种按误差反向传播(简称误差反传)训练的多层前馈网络,其算法称为BP算法,它的基本思想是梯度下降法,利用梯度搜索技术,以期使网络的实际输出值和期望输出值的误差均方差为最小。基本BP算法包括信号的前向传播和误差的反向传播两个过程。即计算误差输出时按从输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。正向传播时,输入信号通过隐含层作用于输出节点,经过非线性变换,产生输出信号,若实际输出与期望输出不相符,则转入误差的反向传播过程。误差反传是将输出误差通过隐含层向输入层逐层反传,并将误差分摊给各层所有单元,以从各层获得的误差信号作为调整各单元权值的依据。通过调整输入节点与隐层节点的联接强度和隐层节点与输出节点的联接强度以及阈值,使误差沿梯度方向下降,经过反复学习训练,确定与最小误差相对应的网络参数(权值和阈值),训练即告停止。此时经过训练的神经网络即能对类似样本的输入信息,自行处理输出误差最小的经过非线形转换的信息。
  • [技术干货] 知识蒸馏相关技术【模型蒸馏、数据蒸馏】以ERNIE-Tiny为例
    1.任务简介基于ERNIE预训练模型效果上达到业界领先,但是由于模型比较大,预测性能可能无法满足上线需求。 直接使用ERNIE-Tiny系列轻量模型fine-tune,效果可能不够理想。如果采用数据蒸馏策略,又需要提供海量未标注数据,可能并不具备客观条件。 因此,本专题采用主流的知识蒸馏的方案来压缩模型,在满足用户预测性能、预测效果的需求同时,不依赖海量未标注数据,提升开发效率。 文心提供多种不同大小的基于字粒度的ERNIE-Tiny学生模型,满足不同用户的需求。注:知识蒸馏(KD)是将复杂模型(teacher)中的dark knowledge迁移到简单模型(student)中去,teacher具有强大的能力和表现,而student则更为紧凑。通过知识蒸馏,希望student能尽可能逼近亦或是超过teacher,从而用更少的复杂度来获得类似的预测效果。1.1 模型蒸馏原理知识蒸馏是一种模型压缩常见方法,指的是在teacher-student框架中,将复杂、学习能力强的网络(teacher)学到的特征表示"知识"蒸馏出来,传递给参数量小、学习能力弱的网络(student)。 在训练过程中,往往以最优化训练集的准确率作为训练目标,但真实目标其实应该是最优化模型的泛化能力。显然如果能直接以提升模型的泛化能力为目标进行训练是最好的,但这需要正确的关于泛化能力的信息,而这些信息通常不可用。如果我们使用由大型模型产生的所有类概率作为训练小模型的目标,就可以让小模型得到不输大模型的性能。这种把大模型的知识迁移到小模型的方式就是蒸馏。基本原理可参考Hinton经典论文:cid:link_11.2 ERNIE-Tiny 模型蒸馏模型蒸馏原理可参考论文 ERNIE-Tiny : A Progressive Distillation Framework for Pretrained Transformer Compression 2021。不同于原论文的实现,为了和开发套件中的通用蒸馏学生模型保持一致,我们将蒸馏loss替换为Attention矩阵的KQ loss和 VV loss,原理可参考论文 MiniLM: Deep Self-Attention Distillation for Task-Agnostic Compression of Pre-Trained Transformers 2020 和 MiniLMv2: Multi-Head Self-Attention Relation Distillation for Compressing Pretrained Transformers 2021。实验表明通用蒸馏阶段和任务蒸馏阶段的蒸馏loss不匹配时,学生模型的效果会受到影响。BERT 等预训练语言模型 (PLM) 采用了一种训练范式,首先在一般数据中预训练模型,然后在特定任务数据上微调模型,最近取得了巨大成功。然而,PLM 因其庞大的参数而臭名昭著,并且难以部署在现实生活中的应用程序中。知识蒸馏通过在一组数据上将知识从大老师转移到小得多的学生来解决这个问题。我们认为选择三个关键组成部分,即教师、训练数据和学习目标,对于蒸馏的有效性至关重要。因此,我们提出了一个四阶段渐进式蒸馏框架 ERNIE-Tiny 来压缩 PLM,它将三个组件从一般级别逐渐变化到特定任务级别。具体来说,第一阶段,General Distillation,在预训练的老师、一般数据和潜在蒸馏损失的指导下进行蒸馏。然后,General-Enhanced Distillation 将教师模型从预训练教师转变为微调教师。之后,Task-Adaptive Distillation 将训练数据从一般数据转移到特定于任务的数据。最后,Task-Specific Distillation 在最后阶段增加了两个额外的损失,即 Soft-Label 和 Hard-Label 损失。实证结果证明了我们的框架的有效性和所带来的泛化增益 。实验表明 4 层 ERNIE-Tiny 在 GLUE 基准测试的基础上保持其 12 层教师 BERT 的 98.0% 以上的性能,超过最先进的 (SOTA) 1.0% 的 GLUE 分数相同数量的参数。此外,ERNIE-Tiny 在五个中文 NLP 任务上实现了新的压缩 SOTA,比 BERT 基础的精度高 0.4%,参数减少 7.5 倍,推理速度加快 9.4 倍。预训练的语言模型(例如,BERT (Devlin et al., 2018) 及其变体)在各种 NLP 任务中取得了显着的成功。然而,这些模型通常包含数亿个参数,由于延迟和容量限制,这给现实应用中的微调和在线服务带来了挑战。在这项工作中,我们提出了一种简单有效的方法来压缩基于大型 Transformer (Vaswani et al., 2017) 的预训练模型,称为深度自注意力蒸馏。小模型(学生)通过深度模仿大模型(老师)的自注意力模块进行训练,该模块在 Transformer 网络中起着至关重要的作用。具体来说,我们建议提炼出教师最后一个 Transformer 层的自注意力模块,这对学生来说既有效又灵活。此外,除了现有作品中使用的注意力分布(即查询和键的缩放点积)之外,我们还引入了自我注意模块中值之间的缩放点积作为新的深度自我注意知识. 此外,我们表明,引入教师助理(Mirzadeh 等人,2019 年)也有助于提炼大型预训练 Transformer 模型。实验结果表明,我们的单语模型在不同参数大小的学生模型中优于最先进的基线。特别是,它使用 50% 的 Transformer 参数和教师模型的计算在 SQuAD 2.0 和几个 GLUE 基准测试任务上保持了 99% 以上的准确率。我们还在将深度自注意力蒸馏应用于多语言预训练模型方面获得了竞争性结果。我们仅使用自注意力关系蒸馏来对预训练的 Transformer 进行任务不可知的压缩,从而在 MiniLM (Wang et al., 2020) 中推广深度自注意力蒸馏。特别是,我们将多头自注意力关系定义为每个自注意力模块内的查询、键和值向量对之间的缩放点积。然后我们利用上述关系知识来训练学生模型。除了简单统一的原则外,更有利的是,学生的注意力头数没有限制,而之前的大多数工作都必须保证教师和学生之间的头数相同。此外,细粒度的自注意力关系倾向于充分利用 Transformer 学习到的交互知识。此外,我们彻底检查了教师模型的层选择策略,而不是像 MiniLM 中那样仅仅依赖最后一层。我们对压缩单语和多语预训练模型进行了广泛的实验。实验结果表明,我们从基础规模和大型教师(BERT、RoBERTa 和 XLM-R)中提取的模型优于最先进的模型。二阶段蒸馏:通用蒸馏(General Distillation,GD):在预训练阶段训练,使用大规模无监督的数据, 帮助学生网络学习到尚未微调的教师网络中的知识,有利于提高泛化能力。为方便用户使用,我们提供了多种尺寸的通用蒸馏学生模型,可用的通用蒸馏学生模型可参考文档:通用模型 - ERNIE3.0 Tiny。任务蒸馏(Task-specific Distillation,TD):使用具体任务的数据,学习到更多任务相关的具体知识。如果已提供的通用蒸馏学生模型尺寸符合需求,用户可以主要关注接下来的任务蒸馏过程。1.3任务蒸馏步骤FT阶段:基于ERNIE 3.0 Large蒸馏模型fine-tune得到教师模型,注意这里用到的教师模型和ERNIE 3.0 Large是两个不同的模型;GED阶段(可选):使用fine-tuned教师模型和通用数据继续用通用蒸馏的方式蒸馏学生模型,进一步提升学生模型的效果;a. 热启动fine-tuned的教师模型和通用学生模型。其中,通用的学生模型由文心平台提供,从bos上下载。TD1阶段:蒸馏中间层a.只对学生模型的最后一层进行蒸馏,将学生模型transformer的attention层的k-q矩阵和v-v矩阵与教师模型的对应矩阵做KLloss,可参考 :MiniLMV2。b.热启动fine-tuned的教师模型和GED阶段得到的学生模型。其中,通用的学生模型由文心平台提供,从bos上下载,下载链接所在文档:通用模型ERNIE3.0 Tiny,或参考预置的下载脚本:c. 反向传播阶段只更新学生模型参数,教师模型参数不更新;TD2阶段:蒸馏预测层,产出最终的学生模型。a. 热启动fine-tuned的教师模型和TD1阶段训练的学生模型;b. loss包括两部分: 1) pred_loss:软标签,学生模型的预测层输出与教师模型的预测层输出的交叉熵; 2) student_ce_loss:硬标签,学生模型的预测层输出与真实label的交叉熵;c. pred_loss与student_ce_loss之和作为最终loss,进行反向传播;d. 反向传播阶段只更新学生模型参数,教师模型参数不更新;注:关于GED阶段使用的通用数据:开发套件中的通用数据是由开源项目 cid:link_0 中的中文维基百科语料(wiki2019zh)经过预处理得到。该数据只用于demo展示,实际使用时替换为业务无标注数据效果提升更明显。2. 常见问题问题1:怎么修改学生模型的层数?上面提供了多种不同的学生模型,但每个学生模型的层数、hidden size等都是固定的,如果想更改,需要在哪些地方更改?文心提供了三种不同结构的预训练学生模型,如果修改层数、hidden size等,会导致预训练学生模型参数无法加载,在此情况下,蒸馏出来的学生模型效果无法保证,建议用户还是使用文心提供的预训练模型,不更改模型结构;如果用户认为更改学生模型的结构非常有必要,需要对文心做以下改动:修改TD1阶段json配置文件的pre_train_model配置项,删除预训练学生模型的加载,只保留微调后的教师模型"pre_train_model": [ # 热启动fine-tune的teacher模型 { "name": "finetuned_teacher_model", "params_path": "./output/cls_ernie_3.0_large_ft/save_checkpoints/checkpoints_step_6000" } ]将json文件中的"student_embedding"替换为自定义的学生模型"student_embedding": { "config_path": "../../models_hub/ernie_3.0_tiny_ch_dir/ernie_config.json" },再次强调,上述修改后,由于无法加载预训练学生模型,蒸馏出来的学生模型效果无法保证。(用户训练数据量到百万样本以上可以考虑尝试一下)3.数据蒸馏任务3.1 简介在ERNIE强大的语义理解能力背后,是需要同样强大的算力才能支撑起如此大规模模型的训练和预测。很多工业应用场景对性能要求较高,若不能有效压缩则无法实际应用。因此,我们基于数据蒸馏技术构建了数据蒸馏系统。其原理是通过数据作为桥梁,将ERNIE模型的知识迁移至小模型,以达到损失很小的效果却能达到上千倍的预测速度提升的效果。目录结构 数据蒸馏任务位于 wenxin_appzoo/tasks/data_distillation├── data │ ├── dev_data │ ├── dict │ ├── download_data.sh │ ├── predict_data │ ├── test_data │ └── train_data ├── distill │ └── chnsenticorp │ ├── student │ └── teacher ├── examples │ ├── cls_bow_ch.json │ ├── cls_cnn_ch.json │ ├── cls_ernie_fc_ch_infer.json │ └── cls_ernie_fc_ch.json ├── inference │ ├── custom_inference.py │ ├── __init__.py ├── model │ ├── base_cls.py │ ├── bow_classification.py │ ├── cnn_classification.py │ ├── ernie_classification.py │ ├── __init__.py ├── run_distill.sh ├── run_infer.py ├── run_trainer.py └── trainer ├── custom_dynamic_trainer.py ├── __init__.py3.2 数据准备目前采用三种数据增强策略策略,对于不用的任务可以特定的比例混合。三种数据增强策略包括:(1)添加噪声:对原始样本中的词,以一定的概率(如0.1)替换为”UNK”标签(2)同词性词替换:对原始样本中的所有词,以一定的概率(如0.1)替换为本数据集中随机一个同词性的词(3)N-sampling:从原始样本中,随机选取位置截取长度为m的片段作为新的样本,其中片段的长度m为0到原始样本长度之间的随机值数据增强策略可参考数据增强,我们已准备好了采用上述3种增强策略制作的chnsenticorp的增强数据。3.3 离线蒸馏使用预置的ERNIE 2.0 base模型cd wenxin_appzoo/models_hub bash download_ernie_2.0_base_ch.sh下载预置的原始数据以及增强数据。cd wenxin_appzoo/tasks/data_distillation/distill bash download_data.sh运行以下命令,开始数据蒸馏cd wenxin_appzoo/tasks/data_distillation bash run_distill.sh3.3.1蒸馏过程说明run_distill.sh脚本会进行前述的三步:在任务数据上Fine-tune; 加载Fine-tune好的模型对增强数据进行打分; 使用Student模型进行训练。脚本采用hard-label蒸馏,在第二步中将会直接预测出ERNIE标注的label。run_distill.sh脚本涉及教师和学生模型的json文件,其中:./examples/cls_ernie_fc_ch.json负责教师模型的finetune, ./examples/cls_ernie_fc_ch_infer.json 负责教师模型的预测。 ./examples/cls_cnn_ch.json,负责学生模型的训练。事先构造好的增强数据放在./distill/chnsenticorp/student/unsup_train_aug在脚本的第二步中,使用 ./examples/cls_ernie_fc_ch_infer.json 进行预测:脚本从标准输入获取明文输入,并将打分输出到标准输出。用这种方式对数据增强后的无监督训练预料进行标注。最终的标注结果放在 ./distill/chnsenticorp/student/train/part.1文件中。标注结果包含两列, 第一列为明文,第二列为标注label。在第三步开始student模型的训练,其训练数据放在 distill/chnsenticorp/student/train/ 中,part.0 为原监督数据 part.1 为 ERNIE 标注数据。注:如果用户已经拥有了无监督数据,则可以将无监督数据放入distill/chnsenticorp/student/unsup_train_aug 即可。
  • [安装经验] Mindspore实现简单线性回归
    本文将实现简单的线性回归,演示如何搭建和训练网络待拟合的目标函数为f(x)=5x+3文章分为五部分:生成数据构建拟合模型并初始化参数训练模型训练结果生成数据集​​​​​​在[-10,10]的范围内,生成一系列的随机自变量x并生成对应的因变量y,同时生成一系列的正态分布随机数作为噪声。将噪声加到自变量x对应的因变量y上,得到原始数据。定义数据集生成函数create_data:def create_data(num, w=5.0, b=3.0): for _ in range(num): x = np.random.uniform(-10.0, 10.0) noise = np.random.normal(0, 1) y = x * w + b + noise yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32)# 用 yield 函数生成可迭代的生成器,当 num 很大时,可很有效的减小内存占用eval_data = list(create_data(50,5,3))#生成50个带噪声的随机点为提高模型泛化能力、提高模型店鲁棒性,我们还会引入增强函数来对原始数据进行数据增强。定义数据集增强函数enhance_data():可以指定数据集的分组大小batch和重复次数。同时用mindspore.dataset.GeneratorDataset将数据集转化为MindSpore所能够识别的数据格式。def enhance_data(num_data, batch_size=16, repeat_size=1): input_data = ds.GeneratorDataset(list(create_data(num_data)), column_names=['data','label']) input_data = input_data.batch(batch_size) input_data = input_data.repeat(repeat_size) return input_data#构建了1600个训练的数据:每个batch的大小为1600,分为100个batch进行训练data_number = 1600batch_number = 16repeat_number = 1data_train = enhance_data(data_number, batch_number, repeat_number)构建拟合模型并初始化参数用mindspore.nn.Dense的方法我们可以构造一个线性拟合的模型:f(x)=wx+bmindspore.nn.Dense的官方文档说明如下定义:(可以在MindSpore查看相关文档说明)​​​​class LinearNet(nn.Cell): def __init__(self): super(LinearNet, self).__init__() self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02)) def construct(self, x):# 必须要有这个函数,MindSpore 对 construct 接口有一定约束 x = self.fc(x) return xnet = LinearNet()model_params = net.trainable_params()for param in model_params:#查看初始化的参数 print(param, param.asnumpy())训练模型首先定义损失函数(Loss Function)来衡量拟合结果的好坏,在这里我们采取均方误差函数MSE定义好损失函数后我们需要定义一个向前传播的网络,用于执行损失函数的计算,这里采用mindspore定义好的接口mindspore.nn.loss.MSELoss​​​​在计算好对应参数的损失函数值后,我们需要更新迭代参数来计算下一组参数的损失值,以判断下一步往哪个方向“前进”来找到最终的最低损失函数值;这一功能将用反向传播网络来实现。参数更新迭代我们这里采用Momentum方法,使用mindspore定义好的接口mindspore.nn.Momentum​​​​定义好后,我们可以使用mindspore.Model来进行封装训练定义训练模型:net_loss = nn.loss.MSELoss()opt = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9)model = Model(net, net_loss, opt)训练结果最后训练出来的结果:y=4.979354x+3.0504797 和预期y=5x+3比较接近​​
  • [技术干货] UIE模型实战实体抽取任务【打车数据、快递单】
    项目连接:可以直接fork使用 Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】0.背景介绍本项目将演示如何通过小样本样本进行模型微调,快速且准确抽取快递单中的目的地、出发地、时间、打车费用等内容,形成结构化信息。辅助物流行业从业者进行有效信息的提取,从而降低客户填单的成本。数据集情况: waybill.jsonl文件是快递单信息数据集:{"id": 57, "text": "昌胜远黑龙江省哈尔滨市南岗区宽桥街28号18618391296", "relations": [], "entities": [{"id": 111, "start_offset": 0, "end_offset": 3, "label": "姓名"}, {"id": 112, "start_offset": 3, "end_offset": 7, "label": "省份"}, {"id": 113, "start_offset": 7, "end_offset": 11, "label": "城市"}, {"id": 114, "start_offset": 11, "end_offset": 14, "label": "县区"}, {"id": 115, "start_offset": 14, "end_offset": 20, "label": "详细地址"}, {"id": 116, "start_offset": 20, "end_offset": 31, "label": "电话"}]} {"id": 58, "text": "易颖18500308469山东省烟台市莱阳市富水南路1号", "relations": [], "entities": [{"id": 118, "start_offset": 0, "end_offset": 2, "label": "姓名"}, {"id": 119, "start_offset": 2, "end_offset": 13, "label": "电话"}, {"id": 120, "start_offset": 13, "end_offset": 16, "label": "省份"}, {"id": 121, "start_offset": 16, "end_offset": 19, "label": "城市"}, {"id": 122, "start_offset": 19, "end_offset": 22, "label": "县区"}, {"id": 123, "start_offset": 22, "end_offset": 28, "label": "详细地址"}]}doccano_ext.jsonl是打车数据集:{"id": 1, "text": "昨天晚上十点加班打车回家58元", "relations": [], "entities": [{"id": 0, "start_offset": 0, "end_offset": 6, "label": "时间"}, {"id": 1, "start_offset": 11, "end_offset": 12, "label": "目的地"}, {"id": 2, "start_offset": 12, "end_offset": 14, "label": "费用"}]} {"id": 2, "text": "三月三号早上12点46加班,到公司54", "relations": [], "entities": [{"id": 3, "start_offset": 0, "end_offset": 11, "label": "时间"}, {"id": 4, "start_offset": 15, "end_offset": 17, "label": "目的地"}, {"id": 5, "start_offset": 17, "end_offset": 19, "label": "费用"}]} {"id": 3, "text": "8月31号十一点零四工作加班五十块钱", "relations": [], "entities": [{"id": 6, "start_offset": 0, "end_offset": 10, "label": "时间"}, {"id": 7, "start_offset": 14, "end_offset": 16, "label": "费用"}]} {"id": 4, "text": "5月17号晚上10点35分加班打车回家,36块五", "relations": [], "entities": [{"id": 8, "start_offset": 0, "end_offset": 13, "label": "时间"}, {"id": 1, "start_offset": 18, "end_offset": 19, "label": "目的地"}, {"id": 9, "start_offset": 20, "end_offset": 24, "label": "费用"}]} {"id": 5, "text": "2009年1月份通讯费一百元", "relations": [], "entities": [{"id": 10, "start_offset": 0, "end_offset": 7, "label": "时间"}, {"id": 11, "start_offset": 11, "end_offset": 13, "label": "费用"}]}结果展示预览输入:城市内交通费7月5日金额114广州至佛山 从百度大厦到龙泽苑东区打车费二十元 上海虹桥高铁到杭州时间是9月24日费用是73元 上周末坐动车从北京到上海花费五十块五毛 昨天北京飞上海话费一百元输出:{"出发地": [{"text": "广州", "start": 15, "end": 17, "probability": 0.9073772252165782}], "目的地": [{"text": "佛山", "start": 18, "end": 20, "probability": 0.9927365183877761}], "时间": [{"text": "7月5日", "start": 6, "end": 10, "probability": 0.9978010396512218}]} {"出发地": [{"text": "百度大厦", "start": 1, "end": 5, "probability": 0.968825147409472}], "目的地": [{"text": "龙泽苑东区", "start": 6, "end": 11, "probability": 0.9877913072493669}]} {"目的地": [{"text": "杭州", "start": 7, "end": 9, "probability": 0.9929172180094881}], "时间": [{"text": "9月24日", "start": 12, "end": 17, "probability": 0.9953342057701597}]} {#"出发地": [{"text": "北京", "start": 7, "end": 9, "probability": 0.973048366717471}], "目的地": [{"text": "上海", "start": 10, "end": 12, "probability": 0.988486130309397}], "时间": [{"text": "上周末", "start": 0, "end": 3, "probability": 0.9977407699595275}]} {"出发地": [{"text": "北京", "start": 2, "end": 4, "probability": 0.974188953533556}], "目的地": [{"text": "上海", "start": 5, "end": 7, "probability": 0.9928200521486445}], "时间": [{"text": "昨天", "start": 0, "end": 2, "probability": 0.9731559534465504}]}1.数据集加载(快递单数据、打车数据)doccano_file: 从doccano导出的数据标注文件。save_dir: 训练数据的保存目录,默认存储在data目录下。negative_ratio: 最大负例比例,该参数只对抽取类型任务有效,适当构造负例可提升模型效果。负例数量和实际的标签数量有关,最大负例数量 = negative_ratio * 正例数量。该参数只对训练集有效,默认为5。为了保证评估指标的准确性,验证集和测试集默认构造全负例。splits: 划分数据集时训练集、验证集所占的比例。默认为[0.8, 0.1, 0.1]表示按照8:1:1的比例将数据划分为训练集、验证集和测试集。task_type: 选择任务类型,可选有抽取和分类两种类型的任务。options: 指定分类任务的类别标签,该参数只对分类类型任务有效。默认为["正向", "负向"]。prompt_prefix: 声明分类任务的prompt前缀信息,该参数只对分类类型任务有效。默认为"情感倾向"。is_shuffle: 是否对数据集进行随机打散,默认为True。seed: 随机种子,默认为1000.*separator: 实体类别/评价维度与分类标签的分隔符,该参数只对实体/评价维度级分类任务有效。默认为"##"。!python doccano.py \ --doccano_file ./data/doccano_ext.jsonl \ --task_type 'ext' \ --save_dir ./data \ --splits 0.8 0.1 0.1 \ --negative_ratio 5[2022-07-14 11:34:26,474] [ INFO] - Converting doccano data... 100%|████████████████████████████████████████| 40/40 [00:00<00:00, 42560.16it/s] [2022-07-14 11:34:26,477] [ INFO] - Adding negative samples for first stage prompt... 100%|███████████████████████████████████████| 40/40 [00:00<00:00, 161009.75it/s] [2022-07-14 11:34:26,478] [ INFO] - Converting doccano data... 100%|██████████████████████████████████████████| 5/5 [00:00<00:00, 21754.69it/s] [2022-07-14 11:34:26,479] [ INFO] - Adding negative samples for first stage prompt... 100%|██████████████████████████████████████████| 5/5 [00:00<00:00, 44057.82it/s] [2022-07-14 11:34:26,479] [ INFO] - Converting doccano data... 100%|██████████████████████████████████████████| 5/5 [00:00<00:00, 26181.67it/s] [2022-07-14 11:34:26,480] [ INFO] - Adding negative samples for first stage prompt... 100%|██████████████████████████████████████████| 5/5 [00:00<00:00, 45689.59it/s] [2022-07-14 11:34:26,482] [ INFO] - Save 160 examples to ./data/train.txt. [2022-07-14 11:34:26,482] [ INFO] - Save 20 examples to ./data/dev.txt. [2022-07-14 11:34:26,482] [ INFO] - Save 20 examples to ./data/test.txt. [2022-07-14 11:34:26,482] [ INFO] - Finished! It takes 0.01 seconds输出部分展示:{"content": "上海到北京机票1320元", "result_list": [{"text": "上海", "start": 0, "end": 2}], "prompt": "出发地"} {"content": "上海到北京机票1320元", "result_list": [{"text": "北京", "start": 3, "end": 5}], "prompt": "目的地"} {"content": "上海到北京机票1320元", "result_list": [{"text": "1320", "start": 7, "end": 11}], "prompt": "费用"} {"content": "上海虹桥到杭州东站高铁g7555共73元时间是10月14日", "result_list": [{"text": "上海虹桥", "start": 0, "end": 4}], "prompt": "出发地"} {"content": "上海虹桥到杭州东站高铁g7555共73元时间是10月14日", "result_list": [{"text": "杭州东站", "start": 5, "end": 9}], "prompt": "目的地"} {"content": "上海虹桥到杭州东站高铁g7555共73元时间是10月14日", "result_list": [{"text": "73", "start": 17, "end": 19}], "prompt": "费用"} {"content": "上海虹桥到杭州东站高铁g7555共73元时间是10月14日", "result_list": [{"text": "10月14日", "start": 23, "end": 29}], "prompt": "时间"} {"content": "昨天晚上十点加班打车回家58元", "result_list": [{"text": "昨天晚上十点", "start": 0, "end": 6}], "prompt": "时间"} {"content": "昨天晚上十点加班打车回家58元", "result_list": [{"text": "家", "start": 11, "end": 12}], "prompt": "目的地"} {"content": "昨天晚上十点加班打车回家58元", "result_list": [{"text": "58", "start": 12, "end": 14}], "prompt": "费用"} {"content": "2月20号从南山到光明二十元", "result_list": [{"text": "2月20号", "start": 0, "end": 5}], "prompt": "时间"}2.模型训练!python finetune.py \ --train_path "./data/train.txt" \ --dev_path "./data/dev.txt" \ --save_dir "./checkpoint" \ --learning_rate 1e-5 \ --batch_size 8 \ --max_seq_len 512 \ --num_epochs 100 \ --model "uie-base" \ --seed 1000 \ --logging_steps 10 \ --valid_steps 50 \ --device "gpu"部分训练效果展示:**具体输出已折叠** [2022-07-12 15:09:47,643] [ INFO] - global step 250, epoch: 13, loss: 0.00045, speed: 3.90 step/s [2022-07-12 15:09:47,910] [ INFO] - Evaluation precision: 1.00000, recall: 1.00000, F1: 1.00000 [2022-07-12 15:09:50,399] [ INFO] - global step 260, epoch: 13, loss: 0.00043, speed: 4.02 step/s [2022-07-12 15:09:52,966] [ INFO] - global step 270, epoch: 14, loss: 0.00042, speed: 3.90 step/s [2022-07-12 15:09:55,464] [ INFO] - global step 280, epoch: 14, loss: 0.00040, speed: 4.00 step/s [2022-07-12 15:09:58,028] [ INFO] - global step 290, epoch: 15, loss: 0.00039, speed: 3.90 step/s [2022-07-12 15:10:00,516] [ INFO] - global step 300, epoch: 15, loss: 0.00038, speed: 4.02 step/s [2022-07-12 15:10:00,781] [ INFO] - Evaluation precision: 1.00000, recall: 1.00000, F1: 1.00000 [2022-07-12 15:10:03,348] [ INFO] - global step 310, epoch: 16, loss: 0.00036, speed: 3.90 step/s [2022-07-12 15:10:05,836] [ INFO] - global step 320, epoch: 16, loss: 0.00035, speed: 4.02 step/s [2022-07-12 15:10:08,393] [ INFO] - global step 330, epoch: 17, loss: 0.00034, speed: 3.91 step/s [2022-07-12 15:10:10,888] [ INFO] - global step 340, epoch: 17, loss: 0.00033, speed: 4.01 step/s 推荐使用GPU环境,否则可能会内存溢出。CPU环境下,可以修改model为uie-tiny,适当调下batch_size。 增加准确率的话:--num_epochs 设置大点多训练训练 可配置参数说明: **train_path:** 训练集文件路径。 **dev_path:** 验证集文件路径。 **save_dir:** 模型存储路径,默认为./checkpoint。 **learning_rate:** 学习率,默认为1e-5。 **batch_size:** 批处理大小,请结合显存情况进行调整,若出现显存不足,请适当调低这一参数,默认为16。 **max_seq_len:** 文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。 **num_epochs:** 训练轮数,默认为100。 **model** 选择模型,程序会基于选择的模型进行模型微调,可选有uie-base和uie-tiny,默认为uie-base。 **seed:** 随机种子,默认为1000. **logging_steps:** 日志打印的间隔steps数,默认10。 **valid_steps:** evaluate的间隔steps数,默认100。 **device:** 选用什么设备进行训练,可选cpu或gpu。3模型评估!python evaluate.py \ --model_path ./checkpoint/model_best \ --test_path ./data/test.txt \ --batch_size 16 \ --max_seq_len 512[2022-07-11 13:41:23,831] [ INFO] - ----------------------------- [2022-07-11 13:41:23,831] [ INFO] - Class Name: all_classes [2022-07-11 13:41:23,832] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000 [2022-07-11 13:41:35,024] [ INFO] - ----------------------------- [2022-07-11 13:41:35,024] [ INFO] - Class Name: 出发地 [2022-07-11 13:41:35,024] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000 [2022-07-11 13:41:35,139] [ INFO] - ----------------------------- [2022-07-11 13:41:35,139] [ INFO] - Class Name: 目的地 [2022-07-11 13:41:35,139] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000 [2022-07-11 13:41:35,246] [ INFO] - ----------------------------- [2022-07-11 13:41:35,246] [ INFO] - Class Name: 费用 [2022-07-11 13:41:35,246] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000 [2022-07-11 13:41:35,313] [ INFO] - ----------------------------- [2022-07-11 13:41:35,313] [ INFO] - Class Name: 时间 [2022-07-11 13:41:35,313] [ INFO] - Evaluation Precision: 1.00000 | Recall: 1.00000 | F1: 1.00000model_path: 进行评估的模型文件夹路径,路径下需包含模型权重文件model_state.pdparams及配置文件model_config.json。test_path: 进行评估的测试集文件。batch_size: 批处理大小,请结合机器情况进行调整,默认为16。max_seq_len: 文本最大切分长度,输入超过最大长度时会对输入文本进行自动切分,默认为512。model: 选择所使用的模型,可选有uie-base, uie-medium, uie-mini, uie-micro和uie-nano,默认为uie-base。debug: 是否开启debug模式对每个正例类别分别进行评估,该模式仅用于模型调试,默认关闭。4 结果预测from pprint import pprint import json from paddlenlp import Taskflow def openreadtxt(file_name): data = [] file = open(file_name,'r',encoding='UTF-8') #打开文件 file_data = file.readlines() #读取所有行 for row in file_data: data.append(row) #将每行数据插入data中 return data data_input=openreadtxt('./input/nlp.txt') schema = ['出发地', '目的地','时间'] few_ie = Taskflow('information_extraction', schema=schema, batch_size=1,task_path='./checkpoint/model_best') results=few_ie(data_input) with open("./output/test.txt", "w+",encoding='UTF-8') as f: #a : 写入文件,若文件不存在则会先创建再写入,但不会覆盖原文件,而是追加在文件末尾 for result in results: line = json.dumps(result, ensure_ascii=False) #对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False f.write(line + "\n") print("数据结果已导出")输入文件展示:城市内交通费7月5日金额114广州至佛山 从百度大厦到龙泽苑东区打车费二十元 上海虹桥高铁到杭州时间是9月24日费用是73元 上周末坐动车从北京到上海花费五十块五毛 昨天北京飞上海话费一百元输出展示:{"出发地": [{"text": "广州", "start": 15, "end": 17, "probability": 0.9073772252165782}], "目的地": [{"text": "佛山", "start": 18, "end": 20, "probability": 0.9927365183877761}], "时间": [{"text": "7月5日", "start": 6, "end": 10, "probability": 0.9978010396512218}]} {"出发地": [{"text": "百度大厦", "start": 1, "end": 5, "probability": 0.968825147409472}], "目的地": [{"text": "龙泽苑东区", "start": 6, "end": 11, "probability": 0.9877913072493669}]} {"目的地": [{"text": "杭州", "start": 7, "end": 9, "probability": 0.9929172180094881}], "时间": [{"text": "9月24日", "start": 12, "end": 17, "probability": 0.9953342057701597}]} {"出发地": [{"text": "北京", "start": 7, "end": 9, "probability": 0.973048366717471}], "目的地": [{"text": "上海", "start": 10, "end": 12, "probability": 0.988486130309397}], "时间": [{"text": "上周末", "start": 0, "end": 3, "probability": 0.9977407699595275}]} {"出发地": [{"text": "北京", "start": 2, "end": 4, "probability": 0.974188953533556}], "目的地": [{"text": "上海", "start": 5, "end": 7, "probability": 0.9928200521486445}], "时间": [{"text": "昨天", "start": 0, "end": 2, "probability": 0.9731559534465504}]}5.可视化显示visualDL详细文档可以参考: cid:link_1 有详细讲解,具体实现参考代码,核心是:添加一个初始化记录器下面是结果展示:6.小技巧:获取paddle开源数据集数据集网站:cid:link_0数据集名称 简介 调用方法CoLA 单句分类任务,二分类,判断句子是否合法 paddlenlp.datasets.load_dataset('glue','cola')SST-2 单句分类任务,二分类,判断句子情感极性paddlenlp.datasets.load_dataset('glue','sst-2')MRPC 句对匹配任务,二分类,判断句子对是否是相同意思 paddlenlp.datasets.load_dataset('glue','mrpc')STSB 计算句子对相似性,分数为1~5 paddlenlp.datasets.load_dataset('glue','sts-b') QQP 判定句子对是否等效,等效、不等效两种情况,二分类任务 paddlenlp.datasets.load_dataset('glue','qqp')MNLI 句子对,一个前提,一个是假设。前提和假设的关系有三种情况:蕴含(entailment),矛盾(contradiction),中立(neutral)。句子对三分类问题 paddlenlp.datasets.load_dataset('glue','mnli')QNLI 判断问题(question)和句子(sentence)是否蕴含,蕴含和不蕴含,二分类 paddlenlp.datasets.load_dataset('glue','qnli')RTE 判断句对是否蕴含,句子1和句子2是否互为蕴含,二分类任务 paddlenlp.datasets.load_dataset('glue','rte')WNLI 判断句子对是否相关,相关或不相关,二分类任务 paddlenlp.datasets.load_dataset('glue','wnli')LCQMC A Large-scale Chinese Question Matching Corpus 语义匹配数据集 paddlenlp.datasets.load_dataset('lcqmc')通过paddlenlp提供的api调用,可以很方便实现数据加载,当然你想要把数据下载到本地,可以参考我下面的输出就可以保存数据了。#加载中文评论情感分析语料数据集ChnSentiCorp from paddlenlp.datasets import load_dataset train_ds, dev_ds, test_ds = load_dataset("chnsenticorp", splits=["train", "dev", "test"]) with open("./output/test2.txt", "w+",encoding='UTF-8') as f: #a : 写入文件,若文件不存在则会先创建再写入,但不会覆盖原文件,而是追加在文件末尾 for result in test_ds: line = json.dumps(result, ensure_ascii=False) #对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False f.write(line + "\n")7 总结UIE(Universal Information Extraction):Yaojie Lu等人在ACL-2022中提出了通用信息抽取统一框架UIE。该框架实现了实体抽取、关系抽取、事件抽取、情感分析等任务的统一建模,并使得不同任务间具备良好的迁移和泛化能力。PaddleNLP借鉴该论文的方法,基于ERNIE 3.0知识增强预训练模型,训练并开源了首个中文通用信息抽取模型UIE。该模型可以支持不限定行业领域和抽取目标的关键信息抽取,实现零样本快速冷启动,并具备优秀的小样本微调能力,快速适配特定的抽取目标。UIE的优势使用简单: 用户可以使用自然语言自定义抽取目标,无需训练即可统一抽取输入文本中的对应信息。实现开箱即用,并满足各类信息抽取需求。降本增效: 以往的信息抽取技术需要大量标注数据才能保证信息抽取的效果,为了提高开发过程中的开发效率,减少不必要的重复工作时间,开放域信息抽取可以实现零样本(zero-shot)或者少样本(few-shot)抽取,大幅度降低标注数据依赖,在降低成本的同时,还提升了效果。效果领先: 开放域信息抽取在多种场景,多种任务上,均有不俗的表现。本人本次主要通过实体抽取这个案例分享给大家,主要对开源的paddlenlp的案例进行了细化,比如在结果可视化方面以及结果输入输出的增加,使demo项目更佳完善。当然标注问题是所有问题的痛点,可以参考我的博客来解决这个问题本人博客:cid:link_3
  • [技术干货] 物体检测-Faster R-CNN
    物体检测-Faster R-CNN物体检测是计算机视觉中的一个重要的研究领域,在人流检测,行人跟踪,自动驾驶,医学影像等领域有着广泛的应用。不同于简单的图像分类,物体检测旨在对图像中的目标进行精确识别,包括物体的位置和分类,因此能够应用于更多高层视觉处理的场景。例如在自动驾驶领域,需要辨识摄像头拍摄的图像中的车辆、行人、交通指示牌及其位置,以便进一步根据这些数据决定驾驶策略。上一期学习案例中,我们聚焦于YOLO算法,YOLO(You Only Look Once)是一种one-stage物体检测算法,在本期案例中,我们介绍一种two-stage算法——Faster R-CNN,将目标区域检测和类别识别分为两个任务进行物体检测。注意事项:本案例使用框架**:** Pytorch-1.0.0本案例使用硬件规格**:** 8 vCPU + 64 GiB + 1 x Tesla V100-PCIE-32GB进入运行环境方法:点此链接进入AI Gallery,点击Run in ModelArts按钮进入ModelArts运行环境,如需使用GPU,您可以在ModelArts JupyterLab运行界面右边的工作区进行切换运行代码方法**:** 点击本页面顶部菜单栏的三角形运行按钮或按Ctrl+Enter键 运行每个方块中的代码JupyterLab的详细用法**:** 请参考《ModelAtrs JupyterLab使用指导》碰到问题的解决办法**:** 请参考《ModelAtrs JupyterLab常见问题解决办法》1.数据准备首先,我们将需要的代码和数据下载到Notebook。本案例我们使用PASCAL VOC 2007数据集训练模型,共20个类别的物体。import os from modelarts.session import Session sess = Session() if sess.region_name == 'cn-north-1': bucket_path="modelarts-labs/notebook/DL_object_detection_faster/fasterrcnn.tar.gz" elif sess.region_name == 'cn-north-4': bucket_path="modelarts-labs-bj4/notebook/DL_object_detection_faster/fasterrcnn.tar.gz" else: print("请更换地区到北京一或北京四") if not os.path.exists('./experiments'): sess.download_data(bucket_path=bucket_path, path="./fasterrcnn.tar.gz") if os.path.exists('./fasterrcnn.tar.gz'): # 解压压缩包 os.system("tar -xf ./fasterrcnn.tar.gz") # 清理压缩包 os.system("rm -r ./fasterrcnn.tar.gz")2.安装依赖并引用!pip install pycocotools==2.0.0 !pip install torchvision==0.4.0 !pip install protobuf==3.9.0Requirement already satisfied: pycocotools==2.0.0 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Requirement already satisfied: torchvision==0.4.0 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages Requirement already satisfied: torch==1.2.0 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from torchvision==0.4.0) Requirement already satisfied: pillow>=4.1.1 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from torchvision==0.4.0) Requirement already satisfied: numpy in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from torchvision==0.4.0) Requirement already satisfied: six in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from torchvision==0.4.0) You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Requirement already satisfied: protobuf==3.9.0 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages Requirement already satisfied: setuptools in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from protobuf==3.9.0) Requirement already satisfied: six>=1.9 in /home/ma-user/anaconda3/envs/Pytorch-1.0.0/lib/python3.6/site-packages (from protobuf==3.9.0) You are using pip version 9.0.1, however version 20.3.3 is available. You should consider upgrading via the 'pip install --upgrade pip' command.import tools._init_paths %matplotlib inline from __future__ import absolute_import from __future__ import division from __future__ import print_function import tensorboardX as tb from datasets.factory import get_imdb from model.train_val import get_training_roidb, train_net from model.config import cfg, cfg_from_file, cfg_from_list, get_output_dir, get_output_tb_dirimport roi_data_layer.roidb as rdl_roidb from roi_data_layer.layer import RoIDataLayer import utils.timer import pickle import torch import torch.optim as optim from nets.vgg16 import vgg16 import numpy as np import os import sys import glob import time3.神经网络搭建3.1模型训练超参设置为了减少训练时间,我们在预训练模型的基础上进行训练。这里,我们使用VGG16作为FasterRCNN的主干网络。imdb_name = "voc_2007_trainval" imdbval_name = "voc_2007_test" # 使用的预训练模型位置 weight = "./data/imagenet_weights/vgg16.pth" # 训练迭代次数 max_iters = 100 # cfg模型文件位置 cfg_file = './experiments/cfgs/vgg16.yml' set_cfgs = None if cfg_file is not None: cfg_from_file(cfg_file) if set_cfgs is not None: cfg_from_list(set_cfgs) print('Using config:') print(cfg)Using config: {'TRAIN': {'LEARNING_RATE': 0.001, 'MOMENTUM': 0.9, 'WEIGHT_DECAY': 0.0001, 'GAMMA': 0.1, 'STEPSIZE': [30000], 'DISPLAY': 20, 'DOUBLE_BIAS': True, 'TRUNCATED': False, 'BIAS_DECAY': False, 'USE_GT': False, 'ASPECT_GROUPING': False, 'SNAPSHOT_KEPT': 3, 'SUMMARY_INTERVAL': 180, 'SCALES': [600], 'MAX_SIZE': 1000, 'IMS_PER_BATCH': 1, 'BATCH_SIZE': 256, 'FG_FRACTION': 0.25, 'FG_THRESH': 0.5, 'BG_THRESH_HI': 0.5, 'BG_THRESH_LO': 0.0, 'USE_FLIPPED': True, 'BBOX_REG': True, 'BBOX_THRESH': 0.5, 'SNAPSHOT_ITERS': 5000, 'SNAPSHOT_PREFIX': 'vgg16_faster_rcnn', 'BBOX_NORMALIZE_TARGETS': True, 'BBOX_INSIDE_WEIGHTS': [1.0, 1.0, 1.0, 1.0], 'BBOX_NORMALIZE_TARGETS_PRECOMPUTED': True, 'BBOX_NORMALIZE_MEANS': [0.0, 0.0, 0.0, 0.0], 'BBOX_NORMALIZE_STDS': [0.1, 0.1, 0.2, 0.2], 'PROPOSAL_METHOD': 'gt', 'HAS_RPN': True, 'RPN_POSITIVE_OVERLAP': 0.7, 'RPN_NEGATIVE_OVERLAP': 0.3, 'RPN_CLOBBER_POSITIVES': False, 'RPN_FG_FRACTION': 0.5, 'RPN_BATCHSIZE': 256, 'RPN_NMS_THRESH': 0.7, 'RPN_PRE_NMS_TOP_N': 12000, 'RPN_POST_NMS_TOP_N': 2000, 'RPN_BBOX_INSIDE_WEIGHTS': [1.0, 1.0, 1.0, 1.0], 'RPN_POSITIVE_WEIGHT': -1.0, 'USE_ALL_GT': True}, 'TEST': {'SCALES': [600], 'MAX_SIZE': 1000, 'NMS': 0.3, 'SVM': False, 'BBOX_REG': True, 'HAS_RPN': True, 'PROPOSAL_METHOD': 'gt', 'RPN_NMS_THRESH': 0.7, 'RPN_PRE_NMS_TOP_N': 6000, 'RPN_POST_NMS_TOP_N': 300, 'MODE': 'nms', 'RPN_TOP_N': 5000}, 'RESNET': {'MAX_POOL': False, 'FIXED_BLOCKS': 1}, 'MOBILENET': {'REGU_DEPTH': False, 'FIXED_LAYERS': 5, 'WEIGHT_DECAY': 4e-05, 'DEPTH_MULTIPLIER': 1.0}, 'PIXEL_MEANS': array([[[102.9801, 115.9465, 122.7717]]]), 'RNG_SEED': 3, 'ROOT_DIR': '/home/ma-user/work', 'DATA_DIR': '/home/ma-user/work/data', 'MATLAB': 'matlab', 'EXP_DIR': 'vgg16', 'USE_GPU_NMS': True, 'POOLING_MODE': 'align', 'POOLING_SIZE': 7, 'ANCHOR_SCALES': [8, 16, 32], 'ANCHOR_RATIOS': [0.5, 1, 2], 'RPN_CHANNELS': 512}3.2定义读取数据集函数数据集的标注格式是PASCAL VOC格式。def combined_roidb(imdb_names): def get_roidb(imdb_name): # 加载数据集 imdb = get_imdb(imdb_name) print('Loaded dataset `{:s}` for training'.format(imdb.name)) # 使用ground truth作为数据集策略 imdb.set_proposal_method(cfg.TRAIN.PROPOSAL_METHOD) print('Set proposal method: {:s}'.format(cfg.TRAIN.PROPOSAL_METHOD)) roidb = get_training_roidb(imdb) return roidb roidbs = [get_roidb(s) for s in imdb_names.split('+')] roidb = roidbs[0] if len(roidbs) > 1: for r in roidbs[1:]: roidb.extend(r) tmp = get_imdb(imdb_names.split('+')[1]) imdb = datasets.imdb.imdb(imdb_names, tmp.classes) else: imdb = get_imdb(imdb_names) return imdb, roidb3.3设置模型训练参数np.random.seed(cfg.RNG_SEED) # 加载训练数据集 imdb, roidb = combined_roidb(imdb_name) print('{:d} roidb entries'.format(len(roidb))) # 设置输出路径 output_dir = get_output_dir(imdb,None) print('Output will be saved to `{:s}`'.format(output_dir)) # 设置日志保存路径 tb_dir = get_output_tb_dir(imdb, None) print('TensorFlow summaries will be saved to `{:s}`'.format(tb_dir)) # 加载验证数据集 orgflip = cfg.TRAIN.USE_FLIPPED cfg.TRAIN.USE_FLIPPED = False _, valroidb = combined_roidb(imdbval_name) print('{:d} validation roidb entries'.format(len(valroidb))) cfg.TRAIN.USE_FLIPPED = orgflip # 创建backbone网络 # 在案例中使用的是VGG16模型,可以尝试其他不同的模型结构,例如Resnet等 net = vgg16()Loaded dataset `voc_2007_trainval` for training Set proposal method: gt Appending horizontally-flipped training examples... voc_2007_trainval gt roidb loaded from /home/ma-user/work/data/cache/voc_2007_trainval_gt_roidb.pkl done Preparing training data... done 10022 roidb entries Output will be saved to `/home/ma-user/work/output/vgg16/voc_2007_trainval/default` TensorFlow summaries will be saved to `/home/ma-user/work/tensorboard/vgg16/voc_2007_trainval/default` Loaded dataset `voc_2007_test` for training Set proposal method: gt Preparing training data... voc_2007_test gt roidb loaded from /home/ma-user/work/data/cache/voc_2007_test_gt_roidb.pkl done 4952 validation roidb entriesfrom model.train_val import filter_roidb, SolverWrapper # 对ROI进行筛选,将无效的ROI数据筛选掉 roidb = filter_roidb(roidb) valroidb = filter_roidb(valroidb) sw = SolverWrapper( net, imdb, roidb, valroidb, output_dir, tb_dir, pretrained_model=weight) print('Solving...')Filtered 0 roidb entries: 10022 -> 10022 Filtered 0 roidb entries: 4952 -> 4952 Solving...# 显示所有模型属性 sw.__dict__.keys()dict_keys(['net', 'imdb', 'roidb', 'valroidb', 'output_dir', 'tbdir', 'tbvaldir', 'pretrained_model'])# sw.net为主干网络 print(sw.net)vgg16()3.4定义神经网络结构使用PyTorch搭建神经网络。部分实现细节可以去相应的文件夹查看源码。# 构建网络结构,模型加入ROI数据层 sw.data_layer = RoIDataLayer(sw.roidb, sw.imdb.num_classes) sw.data_layer_val = RoIDataLayer(sw.valroidb, sw.imdb.num_classes, random=True) # 构建网络结构,在VGG16基础上加入ROI和Classifier部分 lr, train_op = sw.construct_graph() # 加载之前的snapshot lsf, nfiles, sfiles = sw.find_previous() # snapshot 为训练提供了断点训练,如果有snapshot将加载进来,继续训练 if lsf == 0: lr, last_snapshot_iter, stepsizes, np_paths, ss_paths = sw.initialize() else: lr, last_snapshot_iter, stepsizes, np_paths, ss_paths = sw.restore(str(sfiles[-1]), str(nfiles[-1])) iter = last_snapshot_iter + 1 last_summary_time = time.time() # 在之前的训练基础上继续进行训练 stepsizes.append(max_iters) stepsizes.reverse() next_stepsize = stepsizes.pop() # 将net切换成训练模式 print("网络结构:") sw.net.train() sw.net.to(sw.net._device)Restoring model snapshots from /home/ma-user/work/output/vgg16/voc_2007_trainval/default/vgg16_faster_rcnn_iter_100.pth Restored. 网络结构: vgg16( (vgg): VGG( (features): Sequential( (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU(inplace=True) (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU(inplace=True) (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (6): ReLU(inplace=True) (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (8): ReLU(inplace=True) (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (11): ReLU(inplace=True) (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (13): ReLU(inplace=True) (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (15): ReLU(inplace=True) (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (18): ReLU(inplace=True) (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (20): ReLU(inplace=True) (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (22): ReLU(inplace=True) (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (25): ReLU(inplace=True) (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (27): ReLU(inplace=True) (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (29): ReLU(inplace=True) (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) ) (avgpool): AdaptiveAvgPool2d(output_size=(7, 7)) (classifier): Sequential( (0): Linear(in_features=25088, out_features=4096, bias=True) (1): ReLU(inplace=True) (2): Dropout(p=0.5, inplace=False) (3): Linear(in_features=4096, out_features=4096, bias=True) (4): ReLU(inplace=True) (5): Dropout(p=0.5, inplace=False) ) ) (rpn_net): Conv2d(512, 512, kernel_size=[3, 3], stride=(1, 1), padding=(1, 1)) (rpn_cls_score_net): Conv2d(512, 18, kernel_size=[1, 1], stride=(1, 1)) (rpn_bbox_pred_net): Conv2d(512, 36, kernel_size=[1, 1], stride=(1, 1)) (cls_score_net): Linear(in_features=4096, out_features=21, bias=True) (bbox_pred_net): Linear(in_features=4096, out_features=84, bias=True) )3.5开始训练while iter < max_iters + 1: if iter == next_stepsize + 1: # 加入snapshot节点 sw.snapshot(iter) lr *= cfg.TRAIN.GAMMA scale_lr(sw.optimizer, cfg.TRAIN.GAMMA) next_stepsize = stepsizes.pop() utils.timer.timer.tic() # 数据通过ROI数据层,进行前向计算 blobs = sw.data_layer.forward() now = time.time() if iter == 1 or now - last_summary_time > cfg.TRAIN.SUMMARY_INTERVAL: # 计算loss函数 # 根据loss函数对模型进行训练 rpn_loss_cls, rpn_loss_box, loss_cls, loss_box, total_loss, summary = \ sw.net.train_step_with_summary(blobs, sw.optimizer) for _sum in summary: sw.writer.add_summary(_sum, float(iter)) # 进行数据层验证计算 blobs_val = sw.data_layer_val.forward() summary_val = sw.net.get_summary(blobs_val) for _sum in summary_val: sw.valwriter.add_summary(_sum, float(iter)) last_summary_time = now else: rpn_loss_cls, rpn_loss_box, loss_cls, loss_box, total_loss = \ sw.net.train_step(blobs, sw.optimizer) utils.timer.timer.toc() if iter % (cfg.TRAIN.DISPLAY) == 0: print('iter: %d / %d, total loss: %.6f\n >>> rpn_loss_cls: %.6f\n ' '>>> rpn_loss_box: %.6f\n >>> loss_cls: %.6f\n >>> loss_box: %.6f\n >>> lr: %f' % \ (iter, max_iters, total_loss, rpn_loss_cls, rpn_loss_box, loss_cls, loss_box, lr)) print('speed: {:.3f}s / iter'.format( utils.timer.timer.average_time())) # 进行snapshot存储 if iter % cfg.TRAIN.SNAPSHOT_ITERS == 0: last_snapshot_iter = iter ss_path, np_path = sw.snapshot(iter) np_paths.append(np_path) ss_paths.append(ss_path) # 删掉多余的snapshot if len(np_paths) > cfg.TRAIN.SNAPSHOT_KEPT: sw.remove_snapshot(np_paths, ss_paths) iter += 1 if last_snapshot_iter != iter - 1: sw.snapshot(iter - 1) sw.writer.close() sw.valwriter.close()4.测试部分在这部分中,我们利用训练得到的模型进行推理测试。%matplotlib inline from __future__ import absolute_import from __future__ import division from __future__ import print_function # 将路径转入lib import tools._init_paths from model.config import cfg from model.test import im_detect from torchvision.ops import nms from utils.timer import Timer import matplotlib.pyplot as plt import numpy as np import os, cv2 import argparse from nets.vgg16 import vgg16 from nets.resnet_v1 import resnetv1 from model.bbox_transform import clip_boxes, bbox_transform_inv import torch4.1参数定义# PASCAL VOC类别设置 CLASSES = ('__background__', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor') # 网络模型文件名定义 NETS = {'vgg16': ('vgg16_faster_rcnn_iter_%d.pth',),'res101': ('res101_faster_rcnn_iter_%d.pth',)} # 数据集文件名定义 DATASETS= {'pascal_voc': ('voc_2007_trainval',),'pascal_voc_0712': ('voc_2007_trainval+voc_2012_trainval',)}4.2结果绘制将预测的标签和边界框绘制在原图上。def vis_detections(im, class_dets, thresh=0.5): """Draw detected bounding boxes.""" im = im[:, :, (2, 1, 0)] fig, ax = plt.subplots(figsize=(12, 12)) ax.imshow(im, aspect='equal') for class_name in class_dets: dets = class_dets[class_name] inds = np.where(dets[:, -1] >= thresh)[0] if len(inds) == 0: continue for i in inds: bbox = dets[i, :4] score = dets[i, -1] ax.add_patch( plt.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1], fill=False, edgecolor='red', linewidth=3.5) ) ax.text(bbox[0], bbox[1] - 2, '{:s} {:.3f}'.format(class_name, score), bbox=dict(facecolor='blue', alpha=0.5), fontsize=14, color='white') plt.axis('off') plt.tight_layout() plt.draw()4.3准备测试图片我们将测试图片传到test文件夹下,我们准备了两张图片进行测试,大家也可以通过notebook的upload按钮上传自己的测试数据。注意,测试数据需要是图片,并且放在test文件夹下。test_file = "./test"4.4模型推理这里我们加载一个预先训练好的模型,也可以选择案例中训练的模型。import cv2 from utils.timer import Timer from model.test import im_detect from torchvision.ops import nms cfg.TEST.HAS_RPN = True # Use RPN for proposals # 模型存储位置 # 这里我们加载一个已经训练110000迭代之后的模型,可以选择自己的训练模型位置 saved_model = "./models/vgg16-voc0712/vgg16_faster_rcnn_iter_110000.pth" print('trying to load weights from ', saved_model) # 加载backbone net = vgg16() # 构建网络 net.create_architecture(21, tag='default', anchor_scales=[8, 16, 32]) # 加载权重文件 net.load_state_dict(torch.load(saved_model, map_location=lambda storage, loc: storage)) net.eval() # 选择推理设备 net.to(net._device) print('Loaded network {:s}'.format(saved_model)) for file in os.listdir(test_file): if file.startswith("._") == False: file_path = os.path.join(test_file, file) print(file_path) # 打开测试图片文件 im = cv2.imread(file_path) # 定义计时器 timer = Timer() timer.tic() # 检测得到图片ROI scores, boxes = im_detect(net, im) print(scores.shape, boxes.shape) timer.toc() print('Detection took {:.3f}s for {:d} object proposals'.format(timer.total_time(), boxes.shape[0])) # 定义阈值 CONF_THRESH = 0.7 NMS_THRESH = 0.3 cls_dets = {} # NMS 非极大值抑制操作,过滤边界框 for cls_ind, cls in enumerate(CLASSES[1:]): cls_ind += 1 # 跳过 background cls_boxes = boxes[:, 4*cls_ind:4*(cls_ind + 1)] cls_scores = scores[:, cls_ind] dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis])).astype(np.float32) keep = nms(torch.from_numpy(cls_boxes), torch.from_numpy(cls_scores), NMS_THRESH) dets = dets[keep.numpy(), :] if len(dets) > 0: if cls in cls_dets: cls_dets[cls] = np.vstack([cls_dets[cls], dets]) else: cls_dets[cls] = dets vis_detections(im, cls_dets, thresh=CONF_THRESH) plt.show()trying to load weights from ./models/vgg16-voc0712/vgg16_faster_rcnn_iter_110000.pth Loaded network ./models/vgg16-voc0712/vgg16_faster_rcnn_iter_110000.pth ./test/test_image_1.jpg (300, 21) (300, 84) Detection took 0.042s for 300 object proposals./test/test_image_0.jpg (300, 21) (300, 84) Detection took 0.039s for 300 object proposals
  • [技术干货] 实例分割-Mask R-CNN 模型
    实例分割-Mask R-CNN 模型本案例我们将进行实例分割模型Mask R-CNN的训练和测试的学习。在计算机视觉领域,实例分割(Instance Segmentation)是指从图像中识别物体的各个实例,并逐个将实例进行像素级标注的任务。实例分割技术在自动驾驶、医学影像、高精度GIS识别、3D建模辅助等领域有广泛的应用。本案例将对实例分割领域经典的Mask R-CNN模型进行简单介绍,并使用Matterport开源Mask R-CNN实现,展示如何在华为云ModelArts上训练Mask R-CNN模型。点击跳转至Mask R-CNN模型详解注意事项:本案例使用框架**:** TensorFlow-1.13.1本案例使用硬件规格**:** 8 vCPU + 64 GiB + 1 x Tesla V100-PCIE-32GB进入运行环境方法:点此链接进入AI Gallery,点击Run in ModelArts按钮进入ModelArts运行环境,如需使用GPU,您可以在ModelArts JupyterLab运行界面右边的工作区进行切换运行代码方法**:** 点击本页面顶部菜单栏的三角形运行按钮或按Ctrl+Enter键 运行每个方块中的代码JupyterLab的详细用法**:** 请参考《ModelAtrs JupyterLab使用指导》碰到问题的解决办法**:** 请参考《ModelAtrs JupyterLab常见问题解决办法》1.首先进行包的安装与引用!pip install pycocotools==2.0.0Collecting pycocotools==2.0.0 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/96/84/9a07b1095fd8555ba3f3d519517c8743c2554a245f9476e5e39869f948d2/pycocotools-2.0.0.tar.gz (1.5MB)  100% |████████████████████████████████| 1.5MB 52.3MB/s ta 0:00:01 [?25hBuilding wheels for collected packages: pycocotools Running setup.py bdist_wheel for pycocotools ... [?25ldone [?25h Stored in directory: /home/ma-user/.cache/pip/wheels/63/72/9e/bac3d3e23f6b04351d200fa892351da57f0e68c7aeec0b1b08 Successfully built pycocotools Installing collected packages: pycocotools Successfully installed pycocotools-2.0.0 You are using pip version 9.0.1, however version 21.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.!pip install imgaug==0.2.9Collecting imgaug==0.2.9 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/17/a9/36de8c0e1ffb2d86f871cac60e5caa910cbbdb5f4741df5ef856c47f4445/imgaug-0.2.9-py2.py3-none-any.whl (753kB)  100% |████████████████████████████████| 757kB 83.4MB/s ta 0:00:01 91% |█████████████████████████████▏ | 686kB 83.9MB/s eta 0:00:01 [?25hRequirement already satisfied: numpy>=1.15.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: opencv-python in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: matplotlib in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: Pillow in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: scikit-image>=0.11.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: six in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Collecting Shapely (from imgaug==0.2.9) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/9d/18/557d4f55453fe00f59807b111cc7b39ce53594e13ada88e16738fb4ff7fb/Shapely-1.7.1-cp36-cp36m-manylinux1_x86_64.whl (1.0MB)  100% |████████████████████████████████| 1.0MB 40.5MB/s ta 0:00:01 [?25hRequirement already satisfied: imageio in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: scipy in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from imgaug==0.2.9) Requirement already satisfied: python-dateutil>=2.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from matplotlib->imgaug==0.2.9) Requirement already satisfied: pytz in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from matplotlib->imgaug==0.2.9) Requirement already satisfied: kiwisolver>=1.0.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from matplotlib->imgaug==0.2.9) Requirement already satisfied: cycler>=0.10 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from matplotlib->imgaug==0.2.9) Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from matplotlib->imgaug==0.2.9) Requirement already satisfied: cloudpickle>=0.2.1 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from scikit-image>=0.11.0->imgaug==0.2.9) Requirement already satisfied: PyWavelets>=0.4.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from scikit-image>=0.11.0->imgaug==0.2.9) Requirement already satisfied: networkx>=1.8 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from scikit-image>=0.11.0->imgaug==0.2.9) Requirement already satisfied: decorator>=4.1.0 in /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages (from networkx>=1.8->scikit-image>=0.11.0->imgaug==0.2.9) Installing collected packages: Shapely, imgaug Found existing installation: imgaug 0.2.6 Uninstalling imgaug-0.2.6: Successfully uninstalled imgaug-0.2.6 Successfully installed Shapely-1.7.1 imgaug-0.2.9 You are using pip version 9.0.1, however version 21.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.2.对需要的代码和数据进行下载import os from modelarts.session import Session session = Session() if session.region_name == 'cn-north-1': bucket_path="modelarts-labs/end2end/mask_rcnn/instance_segmentation.tar.gz" elif session.region_name == 'cn-north-4': bucket_path="modelarts-labs-bj4/end2end/mask_rcnn/instance_segmentation.tar.gz" else: print("请更换地区到北京一或北京四") if not os.path.exists('./src/mrcnn'): session.download_data(bucket_path=bucket_path, path='./instance_segmentation.tar.gz') if os.path.exists('./instance_segmentation.tar.gz'): # 使用tar命令解压资源包 os.system("tar zxf ./instance_segmentation.tar.gz") # 清理压缩包 os.system("rm ./instance_segmentation.tar.gz")Successfully download file modelarts-labs-bj4/end2end/mask_rcnn/instance_segmentation.tar.gz from OBS to local ./instance_segmentation.tar.gz3.Mask R-CNN模型训练部分3.1 第一步:导入相应的Python库,准备预训练模型import sys import random import math import re import time import numpy as np import cv2 import matplotlib import matplotlib.pyplot as plt from src.mrcnn.config import Config from src.mrcnn import utils import src.mrcnn.model as modellib from src.mrcnn import visualize from src.mrcnn.model import log %matplotlib inline # Directory to save logs and trained model MODEL_DIR = "logs" # Local path to trained weights file COCO_MODEL_PATH = "data/mask_rcnn_coco.h5"/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint8 = np.dtype([("qint8", np.int8, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint8 = np.dtype([("quint8", np.uint8, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:528: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint16 = np.dtype([("qint16", np.int16, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:529: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_quint16 = np.dtype([("quint16", np.uint16, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:530: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. _np_qint32 = np.dtype([("qint32", np.int32, 1)]) /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:535: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'. np_resource = np.dtype([("resource", np.ubyte, 1)]) Using TensorFlow backend.3.2 第二步:生成相关配置项我们定义Config类的子类MyTrainConfig,指定相关的参数,较为关键的参数有:__NAME__: Config的唯一名称__NUM_CLASSES__: 分类的数量,COCO中共有80种物体+背景__IMAGE_MIN_DIM和IMAGE_MAX_DIM__: 图片的最大和最小尺寸,我们生成固定的128x128的图片,因此都设置为128__TRAIN_ROIS_PER_IMAGE__: 每张图片上训练的RoI个数__STEPS_PER_EPOCH和VALIDATION_STEPS__: 训练和验证时,每轮的step数量,减少step的数量可以加速训练,但是检测精度降低class MyTrainConfig(Config): # 可辨识的名称 NAME = "my_train" # GPU的数量和每个GPU处理的图片数量,可以根据实际情况进行调整,参考为Nvidia Tesla P100 GPU_COUNT = 1 IMAGES_PER_GPU = 1 # 物体的分类个数,COCO中共有80种物体+背景 NUM_CLASSES = 1 + 80 # background + 80 shapes # 图片尺寸统一处理为1024,可以根据实际情况再进一步调小 IMAGE_MIN_DIM = 1024 IMAGE_MAX_DIM = 1024 # 因为我们生成的形状图片较小,这里可以使用较小的Anchor进行RoI检测 # RPN_ANCHOR_SCALES = (8, 16, 32, 64, 128) # anchor side in pixels # 每张图片上训练的RoI个数,因为我们生成的图片较小,而且每张图片上的形状较少 # 因此可以适当调小该参数,用较少的Anchor即可覆盖大致的物体信息 TRAIN_ROIS_PER_IMAGE = 200 # 每轮训练的step数量 STEPS_PER_EPOCH = 100 # 每轮验证的step数量 VALIDATION_STEPS = 20 config = MyTrainConfig() config.display()Configurations: BACKBONE resnet101 BACKBONE_STRIDES [4, 8, 16, 32, 64] BATCH_SIZE 1 BBOX_STD_DEV [0.1 0.1 0.2 0.2] COMPUTE_BACKBONE_SHAPE None DETECTION_MAX_INSTANCES 100 DETECTION_MIN_CONFIDENCE 0.7 DETECTION_NMS_THRESHOLD 0.3 FPN_CLASSIF_FC_LAYERS_SIZE 1024 GPU_COUNT 1 GRADIENT_CLIP_NORM 5.0 IMAGES_PER_GPU 1 IMAGE_CHANNEL_COUNT 3 IMAGE_MAX_DIM 1024 IMAGE_META_SIZE 93 IMAGE_MIN_DIM 1024 IMAGE_MIN_SCALE 0 IMAGE_RESIZE_MODE square IMAGE_SHAPE [1024 1024 3] LEARNING_MOMENTUM 0.9 LEARNING_RATE 0.001 LOSS_WEIGHTS {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 1.0} MASK_POOL_SIZE 14 MASK_SHAPE [28, 28] MAX_GT_INSTANCES 100 MEAN_PIXEL [123.7 116.8 103.9] MINI_MASK_SHAPE (56, 56) NAME my_train NUM_CLASSES 81 POOL_SIZE 7 POST_NMS_ROIS_INFERENCE 1000 POST_NMS_ROIS_TRAINING 2000 PRE_NMS_LIMIT 6000 ROI_POSITIVE_RATIO 0.33 RPN_ANCHOR_RATIOS [0.5, 1, 2] RPN_ANCHOR_SCALES (32, 64, 128, 256, 512) RPN_ANCHOR_STRIDE 1 RPN_BBOX_STD_DEV [0.1 0.1 0.2 0.2] RPN_NMS_THRESHOLD 0.7 RPN_TRAIN_ANCHORS_PER_IMAGE 256 STEPS_PER_EPOCH 100 TOP_DOWN_PYRAMID_SIZE 256 TRAIN_BN False TRAIN_ROIS_PER_IMAGE 200 USE_MINI_MASK True USE_RPN_ROIS True VALIDATION_STEPS 20 WEIGHT_DECAY 0.00013.3 第三步:准备数据集我们使用封装好的CocoDataset类,生成训练集和验证集。from src.mrcnn.coco import CocoDataset COCO_DIR = 'data' # 生成训练集 dataset_train = CocoDataset() dataset_train.load_coco(COCO_DIR, "train") # 加载训练数据集 dataset_train.prepare()loading annotations into memory... Done (t=0.04s) creating index... index created!# 生成验证集 dataset_val = CocoDataset() dataset_val.load_coco(COCO_DIR, "val") # 加载验证数据集 dataset_val.prepare()loading annotations into memory... Done (t=0.17s) creating index... index created!4.创建模型4.1 第一步:用"training"模式创建模型对象,用于形状数据集的训练model = modellib.MaskRCNN(mode="training", config=config, model_dir=MODEL_DIR)WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version. Instructions for updating: Colocations handled automatically by placer. [DEBUG] <__main__.MyTrainConfig object at 0x7f9b6edc7c50> [DEBUG] Tensor("rpn_class/concat:0", shape=(?, ?, 2), dtype=float32) Tensor("rpn_bbox_1/concat:0", shape=(?, ?, 4), dtype=float32) <tf.Variable 'anchors/Variable:0' shape=(1, 261888, 4) dtype=float32_ref>4.2 第二步:加载预训练模型的权重model.load_weights(COCO_MODEL_PATH, by_name=True)接下来,我们使用预训练的模型,结合Shapes数据集,对模型进行训练5.训练模型Keras中的模型可以按照制定的层进行构建,在模型的train方法中,我们可以通过layers参数来指定特定的层进行训练。layers参数有以下几种预设值:heads:只训练head网络中的分类、mask和bbox回归all: 所有的layer3+: 训练ResNet Stage3和后续Stage4+: 训练ResNet Stage4和后续Stage5+: 训练ResNet Stage5和后续Stage此外,layers参数还支持正则表达式,按照匹配规则指定layer,可以调用model.keras_model.summary()查看各个层的名称,然后按照需要指定要训练的层。下面的步骤对所有的layer训练1个epoch,耗时约4分钟model.train(dataset_train, dataset_val, learning_rate=config.LEARNING_RATE, epochs=1, layers='all') model_savepath = 'my_mrcnn_model.h5' model.keras_model.save_weights(model_savepath)Starting at epoch 0. LR=0.001 Checkpoint Path: logs/my_train20210309T1458/mask_rcnn_my_train_{epoch:04d}.h5 WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead. /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/ops/gradients_impl.py:110: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory. "Converting sparse IndexedSlices to a dense Tensor of unknown shape. " /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/keras/engine/training_generator.py:47: UserWarning: Using a generator with `use_multiprocessing=True` and multiple workers may duplicate your data. Please consider using the`keras.utils.Sequence class. UserWarning('Using a generator with `use_multiprocessing=True`' Epoch 1/1 100/100 [==============================] - 111s 1s/step - loss: 0.4283 - rpn_class_loss: 0.0090 - rpn_bbox_loss: 0.0787 - mrcnn_class_loss: 0.0627 - mrcnn_bbox_loss: 0.0758 - mrcnn_mask_loss: 0.2021 - val_loss: 0.4290 - val_rpn_class_loss: 0.0100 - val_rpn_bbox_loss: 0.1086 - val_mrcnn_class_loss: 0.0920 - val_mrcnn_bbox_loss: 0.0539 - val_mrcnn_mask_loss: 0.16456.使用Mask R-CNN 检测图片物体6.1 第一步:定义InferenceConfig,并创建"Inference"模式的模型对象class InferenceConfig(MyTrainConfig): GPU_COUNT = 1 IMAGES_PER_GPU = 1 inference_config = InferenceConfig() inference_model = modellib.MaskRCNN(mode="inference", config=inference_config, model_dir=MODEL_DIR)[DEBUG] <__main__.InferenceConfig object at 0x7f9681f59710> [DEBUG] Tensor("rpn_class_1/concat:0", shape=(?, ?, 2), dtype=float32) Tensor("rpn_bbox_3/concat:0", shape=(?, ?, 4), dtype=float32) Tensor("input_anchors:0", shape=(?, ?, 4), dtype=float32) WARNING:tensorflow:From /home/ma-user/work/case_dev/mask_rcnn/src/mrcnn/model.py:772: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead.将我们生成的模型权重信息加载进来# 加载我们自己训练出的形状模型文件的权重信息 print("Loading weights from ", model_savepath) inference_model.load_weights(model_savepath, by_name=True)Loading weights from my_mrcnn_model.h56.2 第二步:从验证数据集中随机选出一张图片进行预测,并显示结果# 随机选出图片进行测试 image_id = random.choice(dataset_val.image_ids) original_image, image_meta, gt_class_id, gt_bbox, gt_mask =\ modellib.load_image_gt(dataset_val, inference_config, image_id, use_mini_mask=False) log("original_image", original_image) log("image_meta", image_meta) log("gt_class_id", gt_class_id) log("gt_bbox", gt_bbox) log("gt_mask", gt_mask) det_instances_savepath = 'random.det_instances.jpg' visualize.display_instances(original_image, gt_bbox, gt_mask, gt_class_id, dataset_train.class_names, figsize=(8, 8), save_path=det_instances_savepath)original_image shape: (1024, 1024, 3) min: 0.00000 max: 255.00000 uint8 image_meta shape: (93,) min: 0.00000 max: 1024.00000 float64 gt_class_id shape: (17,) min: 1.00000 max: 74.00000 int32 gt_bbox shape: (17, 4) min: 1.00000 max: 1024.00000 int32 gt_mask shape: (1024, 1024, 17) min: 0.00000 max: 1.00000 bool# 定义助手函数用于设置matplot中的子绘制区域所在的行和列 def get_ax(rows=1, cols=1, size=8): _, ax = plt.subplots(rows, cols, figsize=(size*cols, size*rows)) return ax results = inference_model.detect([original_image], verbose=1) r = results[0] prediction_savepath = 'random.prediction.jpg' visualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'], dataset_val.class_names, r['scores'], ax=get_ax(), save_path=prediction_savepath)Processing 1 images image shape: (1024, 1024, 3) min: 0.00000 max: 255.00000 uint8 molded_images shape: (1, 1024, 1024, 3) min: -123.70000 max: 151.10000 float64 image_metas shape: (1, 93) min: 0.00000 max: 1024.00000 int64 anchors shape: (1, 261888, 4) min: -0.35390 max: 1.29134 float326.3 第三步:测试其他图片。本目录下的data/val2014目录下有很多测试图片,修改下面代码中test_path变量右边的文件名,即可更换为不同图片,测试图片的预测效果。test_path = './data/val2014/COCO_val2014_000000019176.jpg'import skimage.io image = skimage.io.imread(test_path) results = inference_model.detect([image], verbose=1) r = results[0] prediction_savepath = 'self.prediction.jpg' visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], dataset_val.class_names, r['scores'], ax=get_ax(), save_path=prediction_savepath)Processing 1 images image shape: (480, 640, 3) min: 0.00000 max: 255.00000 uint8 molded_images shape: (1, 1024, 1024, 3) min: -123.70000 max: 151.10000 float64 image_metas shape: (1, 93) min: 0.00000 max: 1024.00000 float64 anchors shape: (1, 261888, 4) min: -0.35390 max: 1.29134 float327.评估模型这一步我们对自己训练出的模型进行一个简单的评估。计算模型的平均精度mAP(mean Average Precision)# 计算VOC类型的 mAP,条件是 IoU=0.5 # 下面的示例中只选出10张图片进行评估,增加图片数量可以增加模型评估的准确性 image_ids = np.random.choice(dataset_val.image_ids, 10) APs = [] for image_id in image_ids: # Load image and ground truth data image, image_meta, gt_class_id, gt_bbox, gt_mask =\ modellib.load_image_gt(dataset_val, inference_config, image_id, use_mini_mask=False) molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0) # Run object detection results = inference_model.detect([image], verbose=0) r = results[0] # Compute AP AP, precisions, recalls, overlaps =\ utils.compute_ap(gt_bbox, gt_class_id, gt_mask, r["rois"], r["class_ids"], r["scores"], r['masks']) APs.append(AP) print("mAP: ", np.mean(APs))mAP: 0.6203394930987131本案例结束。