精华内容
下载资源
问答
  • 只需10行Python代码,我们就能实现计算机视觉中目标检测。from imageai.Detection import ObjectDetectionimport osexecution_path = os.getcwd()detector = ObjectDetection()detector.setModelTypeAsRetinaNet()...

    只需10行Python代码,我们就能实现计算机视觉中目标检测。

    from imageai.Detection import ObjectDetection

    import os

    execution_path = os.getcwd()

    detector = ObjectDetection()

    detector.setModelTypeAsRetinaNet()

    detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))

    detector.loadModel()

    detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image.jpg"), output_image_path=os.path.join(execution_path , "imagenew.jpg"))

    for eachObject in detections:

    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )

    没错,用这寥寥10行代码,就能实现目前AI产品中应用广泛的目标检测技术。

    看完了代码,下面容我们聊聊目标检测背后的技术背景,并解读这10行Python代码的由来和实现原理。

    目标检测简介

    人工智能的一个重要领域就是计算机视觉,它是指计算机及软件系统识别和理解图像与视频的科学。计算机视觉包含很多细分方向,比如图像识别、目标检测、图像生成和图像超分辨率等。其中目标检测由于用途广泛,在计算机视觉领域的意义最为深远。

    目标检测是指计算机和软件系统能够定位出图像/画面中的物体,并识别出它们。目标检测技术已经广泛应用于人脸检测、车辆检测、人流量统计、网络图像、安防系统和无人车等领域。和其它计算机视觉技术一样,目标检测未来会进一步成为人工智能的重要组成部分,有着广阔的发展前景。

    不过,在软件应用和系统中使用现代目标检测方法以及根据这些方法创建应用,并非简单直接。早期的目标检测实现主要是应用一些经典算法,比如OpenCV中支持的算法。然而这些算法的表现并不稳定,在不同情况下差异巨大。

    2012年深度学习技术的突破性进展,催生了一大批高度精准的目标检测算法,比如R-CNN,Fast-RCNN,Faster-RCNN,RetinaNet和既快又准的SSD及YOLO。使用这些基于深度学习的方法和算法,需要理解大量的数学和深度学习框架。现在全世界有数以百万计的开发者在借助目标检测技术创造新产品新项目,但由于理解和使用较为复杂困难,仍有很多人不得要领。

    为了解决这个困扰开发者们的问题,计算机视觉专家Moses Olafenwa带领团队推出了Python库ImageAI,能让开发人员只需寥寥数行代码就能很容易的将最先进的计算机视觉技术应用到自己的项目和产品中。

    我们开头所示的10行代码实现,就是要用到ImageAI。

    如何借助ImageAI轻松实现目标检测

    使用ImageAI执行目标检测,你只需以下4步:

    1.在电脑上安装Python

    2.安装ImageAI及其环境依赖

    3.下载目标检测模块文件

    4.运行示例代码,就是我们展示的那10行

    下面我们一步步详细讲解。

    1)从Python官网下载和安装Python 3

    2)通过pip安装如下环境依赖

    1.Tensorflow

    pip install tensorflow

    2.Numpy

    pip install numpy

    3.SciPy

    pip install scipy

    4.OpenCV

    pip install opencv-python

    5.Pillow

    pip install pillow

    6.Matplotlib

    pip install matplotlib

    7.H5py

    pip install h5py

    8.Keras

    pip install keras

    9.ImageAI

    pip install

    3)通过该 链接下载RetinaNet 模型文件用于目标检测。

    到了这里我们已经安装好了所有依赖,就可以准备写自己的首个目标检测代码了。 创建一个Python文件,为其命名(比如FirstDetection.py),然后将如下代码写到文件中,再把RetinaNet模型文件以及你想检测的图像拷贝到包含该Python文件的文件夹里。

    FirstDetection.py

    from imageai.Detection import ObjectDetection

    import os

    execution_path = os.getcwd()

    detector = ObjectDetection()

    detector.setModelTypeAsRetinaNet()

    detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))

    detector.loadModel()

    detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image.jpg"), output_image_path=os.path.join(execution_path , "imagenew.jpg"))

    for eachObject in detections:

    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )

    然后运行代码,等待控制台打印结果。等控制台打印出结果后,就可以打开FirstDetection.py所在的文件夹,你就会发现有新的图像保存在了里面。比如下面两张示例图像,以及执行目标检测后保存的两张新图像。

    目标检测之前:

    2019061409470311.jpg

    2019061409470312.jpg

    目标检测之后:

    2019061409470513.jpg

    2019061409470514.jpg

    我们可以看到图像上显示了检测出的物体名称及概率。

    解读10行代码

    下面我们解释一下这10行代码的工作原理。

    from imageai.Detection import ObjectDetection

    import os

    execution_path = os.getcwd()

    在上面3行代码中,我们在第一行导入了ImageAI目标检测类,在第二行导入Python os类,在第三行定义了一个变量,获取通往我们的Python文件、RetinaNet模型文件和图像所在文件夹的路径。

    detector = ObjectDetection()

    detector.setModelTypeAsRetinaNet()

    detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))

    detector.loadModel()

    detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image.jpg"), output_image_path=os.path.join(execution_path , "imagenew.jpg"))

    在上面5行代码中,我们在第一行定义我们的目标检测类,在第二行设定RetinaNet的模型类型,在第三行将模型路径设置为RetinaNet模型的路径,在第四行将模型加载到目标检测类中,然后我们在第五行调用检测函数,并在输入和输出图像路径中进行解析。

    for eachObject in detections:

    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )

    在上面两行代码中,我们迭代了第一行中detector.detectObjectFromImage函数返回的所有结果,然后打印出第二行中模型对图像上每个物体的检测结果(名称和概率)。

    ImageAI支持很多强大的目标检测自定义功能,其中一项就是能够提取在图像上检测到的每个物体的图像。只需将附加参数extract_detected_objects=True解析为detectObjectsFromImage函数,如下所示,目标检测类就会为图像物体创建一个文件夹,提取每张图像,将它们保存在新创建的文件夹中,并返回一个包含通过每张图像的路径的额外数组。

    detections, extracted_images = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image.jpg"), output_image_path=os.path.join(execution_path , "imagenew.jpg"), extract_detected_objects=True)

    我们用前面的第一张图像作为例子,可以得到图像中检测到的各个物体的单独图像:

    2019061409470515.jpg

    ImageAI提供了很多功能,能够用于各类目标检测任务的自定义和生产部署。包括:

    -调整最小概率:默认概率小于50%的物体不会显示,如有需要,你可以自行调整这个数字。

    -自定义目标检测:使用提供的CustomObject类,你可以检测一个或多个特定物体。

    -调整检测速度:可以通过将检测速度设为“快”“更快”“最快”三个不同等级,调整检测速度。

    -输入输出类型:你可以自定义图像的路径,Numpy数组或图像的文件流为输入输出。

    诚然,单看这10行代码每一行,谈不上惊艳,也借助了不少库,但是仅用10行代码就能让我们轻松实现之前很麻烦的目标检测,还是能谈得上“给力”二字。

    总结

    以上所述是小编给大家介绍的10 行Python 代码实现 AI 目标检测技术,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    展开全文
  • fastai ulmfitLast month, I started the fastai MOOC(2019) - Deep Learning for Coders. It covers various topics like Computer Vision, Natural Language Processing, Collaborative Filtering, etc. The most ...

    fastai ulmfit

    Last month, I started the fastai MOOC(2019) - Deep Learning for Coders. It covers various topics like Computer Vision, Natural Language Processing, Collaborative Filtering, etc. The most fascinating part I found was the application of Transfer Learning in the field of Natural Language Processing. The approached used by fastai is Universal Language Model Fine-tuning (ULMFiT), which is a transfer learning methodology applied in the field of Natural Language Processing.

    上个月,我开始了Fastai MOOC(2019)-面向程序员的深度学习。 它涵盖了各种主题,例如计算机视觉,自然语言处理,协作过滤等。我发现最有趣的部分是转移学习在自然语言处理领域的应用。 fastai使用的方法是通用语言模型微调( ULMFiT ) ,这是一种应用于自然语言处理领域的转移学习方法。

    According to Wikipedia, Transfer learning (TL) is a research problem in machine learning (ML) that focuses on storing knowledge gained while solving one problem and applying it to a different but related problem. For example, knowledge gained while learning to recognize cars could apply when trying to recognize trucks.

    根据Wikipedia的说法,转移学习(TL)是机器学习(ML)中的一个研究问题,其重点是存储在解决一个问题并将其应用于其他但相关的问题时获得的知识。 例如,在尝试识别卡车时可以应用在学习识别汽车时获得的知识。

    To show the use case of ULMFiT, I’ll apply the same on the Real or Not? NLP with Disaster Tweets competition on Kaggle. To give you an overview of the data, the data set contains two CSV files train.csv and test.csv representing the training data set and the test data set respectively. The training set contains the tweet data in text column and target value in target column, the value of which is 1 if it is a real disaster or 0 if it is not a real disaster. The test set contains only tweet data and no target values. The task is to predict whether a tweet represents a real disaster or not.

    为了显示ULMFiT的用例,我将在Real或Not上应用相同的内容吗? NLP与Kaggle的Disaster Tweets比赛。 为了给您数据的概览,数据集包含两个CSV文件train.csv test.csv代表训练数据集和测试数据集。 训练集在text列中包含推文数据,在target列中包含target ,如果这是真正的灾难,则值为1如果不是真正的灾难,则0 。 测试集仅包含tweet数据,而没有目标值。 任务是预测一条推文是否代表真正的灾难。

    The paragraph given below is taken from Understanding building blocks of ULMFiT:

    以下给出的段落摘自了解ULMFiT的构建基块

    High level idea of ULMFiT is to train a language model using a very large corpus like Wikitext-103 (103M tokens), then to take this pre-trained model’s encoder and combine it with a custom head model, e.g. for classification, and to do the good old fine tuning using discriminative learning rates in multiple stages carefully. Architecture that ULMFiT uses for it’s language modeling task is an AWD-LSTM. The name is an abbreviation of ASGD Weight-Dropped LSTM.

    ULMFiT的高级概念是使用超大型语料库(如Wikitext-103(103M令牌))训练语言模型,然后采用此经过预先训练的模型的编码器,并将其与自定义头部模型结合起来,例如用于分类,并进行使用区分学习率在多个阶段仔细地进行良好的旧微调。 ULMFiT用于其语言建模任务的体系结构是AWD-LSTM 。 该名称是ASGD减重LSTM的缩写。

    Refer to this paper written by Jeremy Howard and Sebastian Ruder if you want to read more about ULMFiT.

    如果您想了解有关ULMFiT的更多信息,请参考Jeremy Howard和Sebastian Ruder撰写的本文

    In Computer Vision problems, transfer learning is used to help in classification directly but in the case of NLP, we first build a language model that basically predicts the next word of a sentence(the model has to understand the language in which the text is written(e.g., English, etc.)) and then build our classification model using the language model’s encoder and vocabulary.

    在计算机视觉问题中,转移学习可用于直接帮助分类,但是在NLP的情况下,我们首先建立一个语言模型,该模型基本上可以预测句子的下一个单词(该模型必须了解书写文字的语言(例如英语等),然后使用语言模型的编码器和词汇表来构建我们的分类模型。

    As mentioned in the paper, we will be using AWD-LSTM architecture pre-trained on Wikipedia. We could directly use this pre-trained language model to build our disaster tweet classifier but the gist here is that the English language of Wikipedia would be different from the English language of the tweets. So we will fine-tune our pre-trained language model using the tweet data and then build our classifier on top of that. As explained in the Deep Learning for Coders with Fastai and PyTorch book where they used the same pre-trained architecture on the IMDb Reviews data set to classify if the review is positive or negative. They explain that the IMDb Reviews English is more informal, contains names of movies, directors, actors, etc. than the regular Wikipedia English on which the architecture is pre-trained on.

    本文所述,我们将使用在Wikipedia上经过预训练的AWD-LSTM体系结构。 我们可以直接使用这种经过预先训练的语言模型来构建灾难鸣叫分类器,但是要点在于,维基百科的英语将与鸣叫的英语有所不同。 因此,我们将使用tweet数据微调我们的预训练语言模型,然后在此基础上构建分类器。 正如使用Fastai和PyTorch编写的面向程序员深度学习》中所解释的那样,他们对IMDb评论数据集使用了相同的经过预训练的体系结构来对评论是肯定还是否定进行分类。 他们解释说,IMDb评论英语比预训练该体系结构的常规维基百科英语更为非正式,包含电影,导演,演员等的名字。

    让我们开始吧!! (Let’s get started!!)

    We import our test.csv and train.csv to get our training data set and test data set. I cannot share the data set as it is from a Kaggle Competition, you can download it yourself by logging into your account and adhering to the competition rules.

    我们导入test.csvtrain.csv以获得训练数据集和测试数据集。 我无法共享Kaggle竞赛中的数据集,您可以通过登录帐户并遵守竞赛规则自行下载。

    # Importing Pandas
    import pandas as pd# Importing fastai libraries for text and callbacks
    from fastai.text import *
    from fastai.callbacks import *train = pd.read_csv('train.csv')
    test = pd.read_csv('test.csv')

    I won’t be going into details on how the language model is built and you should really check out the MOOC and also the Deep Learning for Coders with Fastai and PyTorch book for further reading. The basic idea is that text data cannot be directly fed to the model and it needs to be converted to numbers so that we can apply our mathematical functions to it. This is done using Tokenization and Numericalization. In Tokenization, we convert the text into a list of tokens and in Numericalization we convert them into numbers based on their index. You should refer to the book if you want to dive deeper.

    我不会详细介绍语言模型的构建方式,您应该真正阅读MOOC以及带有Fastai和PyTorch的《面向程序员深度学习》一书,以进一步阅读。 基本思想是文本数据不能直接输入模型,需要将其转换为数字,以便我们可以将数学函数应用于该模型。 这是通过符号化Numericalization完成。 在符号化,我们将文本转换成标记列表,并在Numericalization我们把它们转换成基于其索引号。 如果您想更深入地学习,请参考这本书

    We’ll be using the Data Block API that does the above for us under the hood and then we will feed the databunch created to our language model.

    我们将使用在后台为我们执行上述操作的数据块API ,然后将创建的数据集提供给我们的语言模型。

    data_lm = (TextList.from_df(pd.concat([train[['text']], test[['text']]], ignore_index=True, axis=0))
    .split_by_rand_pct(0.15)
    .label_for_lm()
    .databunch(bs=128))
    data_lm.show_batch()

    We ignore the labels and take the text corpus from both training and test data. Remember that we are making a language model and not a classification model right now. We are just including text data as much as we can for our language model to predict the next word of a sentence. Next, we use our data_lm databunch to make our language model.

    我们忽略标签,并从训练和测试数据中获取文本语料库。 请记住,我们现在正在制作语言模型,而不是分类模型。 我们只是尽可能多地包含文本数据,以便我们的语言模型预测句子的下一个单词。 接下来,我们使用data_lm databunch创建语言模型。

    learn = language_model_learner(data_lm, AWD_LSTM, drop_mult = 0.5)
    learn.lr_find()
    learn.recorder.plot(suggestion = True)
    Image for post
    learn.fit_one_cycle(1, 1e-2, moms=(0.8,0.7))

    We’ll be unfreezing the model and we’ll fit more. We’ll use callbacks to select the best model.

    我们将解冻模型,并且我们将使其更合适。 我们将使用回调来选择最佳模型。

    Better model found at epoch 0 with accuracy value: 0.4097544550895691.
    Better model found at epoch 1 with accuracy value: 0.4404464364051819.
    Better model found at epoch 2 with accuracy value: 0.4609375.
    Better model found at epoch 3 with accuracy value: 0.47495537996292114.
    Better model found at epoch 4 with accuracy value: 0.48810267448425293.
    Better model found at epoch 5 with accuracy value: 0.49515628814697266.
    Better model found at epoch 6 with accuracy value: 0.4975222945213318.
    Better model found at epoch 9 with accuracy value: 0.49756699800491333.

    We’ll select the best accuracy which is at epoch number 9. We’ll then save the language model and the encoder.

    我们将选择最佳精度,即第9个时间点。然后,我们将保存语言模型和编码器。

    learn.save('fine_tuned')
    learn.save_encoder('fine_tuned_enc')

    Next, we’ll make our classifier. For that, we’ll need to create a new databunch. We’ll take the validation set as 10% and we’ll keep our vocabulary same as the vocabulary of the language databunch. We’ll also add our test data in the separate add_test parameter.

    接下来,我们将进行分类。 为此,我们需要创建一个新的数据束。 我们将验证集设为10%,并将词汇表与语言数据绑定的词汇表保持一致。 我们还将测试数据添加到单独的add_test参数中。

    data_clas = (TextList.from_df(df, vocab=data_lm.vocab)
    .split_by_rand_pct(0.1)
    .label_from_df('target')
    .add_test(TextList.from_df(test['text'], vocab=data_lm.vocab))
    .databunch(bs=128))

    We’ll build the classifier using the same encoder as our language model.

    我们将使用与我们的语言模型相同的编码器来构建分类器。

    learn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5, metrics=[accuracy, FBeta(beta=1)])
    learn.load_encoder('fine_tuned_enc')

    We’ll do a lr_find() check and then plot to see the graph.

    我们将进行一次lr_find()检查,然后绘图以查看该图。

    Image for post

    Let’s fit one cycle. We see that we get an accuracy of 77.66%.

    让我们适应一个周期。 我们看到我们得到的准确度是77.66 %。

    learn.fit_one_cycle(1, 1e-3, moms=(0.8,0.7))

    Let’s unfreeze the last 2 layers and train for one cycle. Our accuracy increases to 79.5%.

    让我们解冻最后两层并训练一个周期。 我们的准确性提高到79.5 %。

    learn.freeze_to(-2)
    learn.fit_one_cycle(1, slice(1e-3/(2.6**4),1e-2), moms=(0.8,0.7))

    We’ll unfreeze the last 3 layers now and train again for one more cyle. Our accuracy increases to 81.73%!

    现在,我们将解冻最后三层,并再次训练一个循环。 我们的准确性提高到81.73%

    learn.freeze_to(-3)
    learn.fit_one_cycle(1, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))

    What we used here were discriminative learning rates which were introduced in ULMFiT. As explained in the article 10 New Things I Learnt from fast.ai v3:

    我们在这里使用的是歧视性学习率,这是ULMFiT中引入的。 如文章10我从fast.ai v3中学到的新知识中所述:

    Discriminative learning rates for pre-trained modelsTrain earlier layer(s) with super low learning rate, and train later layers with higher learning rate. The idea is to not drastically alter the almost-perfect pre-trained weights except for minuscule amounts, and to be more aggressive with teaching the layers near the outputs. Discriminative learning rate was introduced in ULMFiT.

    预训练模型的判别学习率训练具有极低学习率的较早层,并训练具有较高学习率的较后层。 这样做的想法是,除了微小的数量外,不要大幅度地改变几乎完美的预训练权重,并且在示教输出附近的层时要更加积极。 区分学习率是在ULMFiT中引入的。

    We’ll unfreeze all layers, train, and use callbacks to select our best model.

    我们将解冻所有层,进行训练,并使用回调来选择最佳模型。

    callbacks = SaveModelCallback(learn,monitor="accuracy", mode="max", name="best_classification_model")
    Better model found at epoch 0 with accuracy value: 0.8160315155982971.
    Better model found at epoch 1 with accuracy value: 0.8173456192016602.
    Better model found at epoch 2 with accuracy value: 0.822601854801178.
    Better model found at epoch 9 with accuracy value: 0.8239158987998962.

    We get an accuracy of 82.39%!!

    我们的准确性为82.39%

    结论 (Conclusion)

    In Transfer Learning we use knowledge from a source and apply it to our target. Implementation of the same in the field of Natural Language Processing has provided an extraordinary state of the art results with minimal training as we use a pre-trained network. You can check out my notebook on Kaggle if you would like to see the code in action: NLP - Disaster Prediction ULMFiT

    在转移学习中,我们使用来自来源的知识并将其应用于目标。 由于我们使用的是预训练网络,因此在自然语言处理领域中实现相同功能已提供了非凡的最新结果,而无需进行最少的培训。 如果您想查看运行中的代码,可以在Kaggle上查看我的笔记本: NLP-灾难预测ULMFiT

    Note: I have used fastai V1 here. The fastai V2 along with the new MOOC came out on 21st August. Check that out here

    注意:我在这里使用fastai V1。 Fastai V2和新的MOOC于8月21日问世。 在这里检查

    翻译自: https://towardsdatascience.com/fastai-disaster-prediction-using-ulmfit-4dd244d3889c

    fastai ulmfit

    展开全文
  • 一、一个模型同时实现单目标识别与定位 在上一节中,我们先构建了一个分类网络,用于图片中最大目标的类别划分;然后构建了一个用于输出目标坐标的网络。我们尚未将两个网络联系起来。但事实上,两个网络的架构十分...

    一、一个模型同时实现单目标识别与定位

    在上一节中,我们先构建了一个分类网络,用于图片中最大目标的类别划分;然后构建了一个用于输出目标坐标的网络。我们尚未将两个网络联系起来。但事实上,两个网络的架构十分相似(都是基于resnet34)。那么能否去除这种冗余,使用一个网络同时实现目标分类与定位呢?本部分将按照:准备数据—构建网络—定义优化目标这一分解步骤,来展示针对应用场景进行建模的通用流程。

    1. 准备数据

    数据分为自变量和因变量两部分,自变量自然就是图片了。无论是分类还是定位,在构建网络时针对图片所做的操作,均可通用,因此,这一部分不用考虑。而对于因变量,需要将目标类别和定位坐标结合在一起。但两者一个是连续型的,一个是离散型的;因此,在生成数据文件CSV文件时进行合并,无益于后续处理。课程中给出的方法是:针对角点坐标和类别标签,生成两个数据集,然后将两个数据集的dataset拼接起来(dataset实际上即为存储数据的地方)。拼接方法是:在获取数据时(即调用__getitem__()函数时),同时返回角点坐标和类别标签。

    md = ImageClassifierData.from_csv(PATH, JPEGS, BB_CSV, tfms=tfms, 
                       continuous=True, val_idxs=val_idxs)
    md2 = ImageClassifierData.from_csv(PATH, JPEGS, CSV,
                       tfms=tfms_from_model(f_model, sz))
    class ConcatLblDataset(Dataset):
        def __init__(self, ds, y2): self.ds,self.y2 = ds,y2
        def __len__(self): return len(self.ds)
        
        def __getitem__(self, i):
            x,y = self.ds[i]
            return (x, (y,self.y2[i]))
    
        md.trn_dl.dataset = ConcatLblDataset(md.trn_ds, md2.trn_y)
        md.val_dl.dataset = ConcatLblDataset(md.val_ds, md2.val_y)
    

    事实上,ConcatLblDataset()的第二个参数为一个可迭代对象,且和md的数据的文件索引相对应即可。

    后面可考虑继承DataSet类。

    2. 网络架构

    在分类网络与回归网络的共有部分的基础上,再添加附加层以输出分类和定位所需的数值:共需要4+c个输出,其中c为类别数目。

    head_reg4 = nn.Sequential(
        Flatten(),
        nn.ReLU(),
        nn.Dropout(0.5),
        nn.Linear(25088,256),
        nn.ReLU(),
        nn.BatchNorm1d(256),
        nn.Dropout(0.5),
        nn.Linear(256,4+len(cats)),
    )
    models = ConvnetBuilder(f_model, 0, 0, 0, custom_head=head_reg4)
    

    其中ConvenetBuilder中取值为0的3个参数分别表示:全连接层的节点数目、是否为多分类、是否为回归问题,但在设定custom_head后不起作用。

    3. 损失函数

    将定位网络的L1范数误差和分类网络的交叉熵加权求和,即得到所需的损失函数。其中要点如下:

    • 损失函数为接受inputtarget参数、返回一个数值的函数。其中input即每个数据块经过网络的前向传播后所得的结果,target即为每个数据块的y值(角点值,类别标签)。
    • 损失函数中的数据大部分为torch.Variable类型,以用于梯度计算。
    • 通过设置学习器的crit域来设置损失函数,其接受一个函数。通过设置学习器的metrics来显示训练过程中的指标,其接受一个函数列表。

    后续训练过程就没啥新鲜东西了。

    二、多目标的识别与定位

    我们已经得到了能够同时进行目标分类和定位的网络,考虑将之扩展为多目标分类与定位。思路是输出固定目标数(课程中设定的是16)的信息:16x(4+c)。有两种方式:

    • 修改单目标网络的输出层,使之直接输出16x(4+c)的数值。这一方法最初由YOLO(You Only Look Once)网络使用。
    • resnet34后接一个跨立度为2的卷积层,使其输出为4x4x(4+c)(resnet34的最后一层输出为7x7x512)。这一方法最初由SSD(Single Shot Detector)使用。
    图 1. 实现16类分类与定位的两种网络结构
    本节使用第二种方法。
    1. 数据准备

    将目标的坐标数据整理为多类别分类网络所需的CSV文件格式。

    图 2. 目标的坐标数据文件
    然后在生成数据模型时注意声明其为连续型数据。
    
        md = ImageClassifierData.from_csv(PATH, JPEGS, MBB_CSV, tfms=tfms, bs=bs, continuous=True, num_workers=4) 
    
    

    继而将md.trn_dl.dataset以及md.val_dl.dataset与类别数据进行拼接。需要注意的是:不同文件中所含目标个数不同,md采取的策略是按同批次的图像中目标个数的最大值进行补齐(这意味着不同批次的向量长度会有所变化。pascal VOC数据中,007953.jpg包含19辆摩托车,是目标数目最大的图片)。

    2. 构建网络

    按照SSD方法,构建附加层。由于需要预测的信息略多,可添加微网络以增强模型的描述功能。最终网络输出两组预测值:一组的尺寸为batch_sizex16x(1+c),用于目标类别的判定;一组尺寸为batch_sizex16x4,用于目标定位。

    3. 损失函数

    考虑卷积结果的接触域。(卷积结果中的一个元素实际上是由原图像中的部分元素的值决定的,这些原图像中的元素的分布区域即为卷积结果中对应元素的接触域。)所得输出为4x4x(4+c+1),即可认为将原图像分为了4x4部分,网络输出结果中的每条特征(4+c+1维的向量),是对原图像中的某一块的描述。
    首先考虑分类。如何确定原图像中的某一块属于哪一类呢?定义图像的某块与目标的重叠率为重叠区域面积与二者面积之和的比。

    图 3. 重叠率

    比如原图像中有3个目标,计算其与图像的16-划分块的重叠率,可得维度为3x16的数组。对该矩阵沿行求最大值的索引,可得图像中的3个目标的主体位于哪一小块里;沿列求最大值的索引,可得原图像的每一小块分属哪个目标;而在实际应用中,一般是设定一个阈值,当一小块与某目标的重叠率超过该阈值时,将该小块判定为该目标。

    在知晓图像中的各个小块与目标的关系后,就可按照单目标分类与定位的损失函数,对每一小块计算损失,然后求平均。这里需要注意的有如下几点:

    • 每一条特征生成的定位框的坐标,限定在其所对应的格点的附近范围内。这样就需要对图像网格化进行多样化处理,以提供更强的描述能力。之所以采用这种方法的考虑如下:由于不确定格点对应的图像网格与目标的关联程度,若使用某格点在全图范围内预测整个目标的定位框,可能需要引入重叠框的加权问题。

    • 在求分类问题的损失函数时,采用的是二值熵函数,同时去除了背景项。考虑如下:各个网格构成了一个小的样本,但这里有个问题就是,这些样本中大部分可能都是背景,也就是说这是个不均衡的样本。去除背景类后,使用二值熵去判定各个网格是不是某类,更合适。

    三、多目标的识别与定位的优化

    1. 提供多样化的网格
    • 继续进行跨立度为2的卷积,提供不同尺寸的图像网格;
    • 对网格进行缩放;
    • 对网格进行拉伸。
    2. 改进损失函数

    如前所述,由于单一图片的样本不均衡性,导致在不确定某一小块究竟是啥时,将之判定为背景总是最安全的。这会导致目标区域在图片中较小时,网络认为图中无目标。如下图中的中间两幅图所示。一个解决方法是使用Focal Loss

    F L ( p t ) = − α t ( 1 − p t ) γ log ⁡ p t FL(p_t)=-\alpha_t(1-p_t)^\gamma\log p_t FL(pt)=αt(1pt)γlogpt

    其中 p t p_t pt为二值熵函数。(具体为啥能改进,后面搞懂了再说吧~~)

    图 4. 被网络忽视目标的示例图片
    3. 去除重叠窗

    若两个框框分属同类,又有很高的重叠度,则将两个框融合。

    附注

    1. 查找Dataloader返回数据的文件名

    生成模型所需数据md后,可通过next(iter(md.val_dl))获取一组数据。其返回值为图像数组和图像标签。怎么找到这些数据对应的文件名呢?

    先去看md,其是ImageClassfierData生成的,找到其定义处(在fastai/dataset.py文件中),发现其继承自ImageData,爷爷是ModelData,但找完了它们的变量,没有发现和图像文件名相关的。那就继续找val_dl,其是DataLoader类,并发现val_ds是由val_dl.dataset返回的。而获取一组数据时,调用的是DataLoader__iter__()方法,该方法中显示了从数据集生成Batch时,调用了self.get_batch()方法,该方法使用了抽样器self.batch_sampler。而所抽取的样本都存储在DataLoader.dataset变量中。使用val_dl.dataset.__dict__查看其变量,发现其有fnames字段,存储的应该是文件名。然后查看val_dl.batch_sampler,发现其是一个迭代器,由其产生索引,则可从fnames中获取文件名。

    2. 近年来目标识别的发展历程
    图 5. 目标识别方法演变脉络

    一些有用的链接

    展开全文
  • Fastai-数据准备

    千次阅读 2019-05-06 21:12:22
    介绍了Fastai框架下的数据准备以及数据增强的操作。

    Fastai数据准备

    简介

    数据是深度学习的立足之本,本文主要介绍Fastai框架如何进行数据加载与数据预处理。

    模块划分

    在之前的Fastai简介文章我提到过,Fastai最核心的API是按照应用领域(任务类型)进行划分的,打开官方文档也会看到Fastai最核心的思路:在一个DataBunch(Fastai的数据加载器)上训练一个Model对象,是非常简单的,只需要将数据和模型绑定到一个Learner对象即可。

    在Fastai的设计中,主要有四大应用领域,对应的四个模块名为collab(协同过滤问题)、tabular(表格或者结构化数据问题)、text(自然语言处理问题)以及vision(计算机视觉问题)。**本系列所有文章围绕都是图像数据进行处理,也就是说主要使用vision模块。**本系列所有文章围绕都是图像数据进行处理,也就是说主要使用vision模块。

    而在vision模块中,主要有如下几个模块:data(数据集构建)、models(预定义模型结构,依赖torchvision)、learner(学习器,将模型和数据关联起来,定义了大量回调函数)、transform(数据预处理,包括常见数据增广手段)等。

    数据集构建

    为了契合Fastai的API设计,这里并没有像之前Pytorch系列和Keras系列那样重构数据集为三个文件夹(对应训练集、验证集和测试集),这是考虑到Fastai的自动训练集划分的API的介绍,事实上划分数据集文件夹也是可以的,只不过多几个DataBunch对象而已。

    关于数据集读取的API都在fastai.vision.data模块下,该模块定义了一个类ImageDataBunch用于处理大量的Image对象,这里的Image对象也是由fastai.vision.data模块下定义的一种Image类,它包含一个图片的矩阵表示、路径、维度、尺寸等属性,也包含图像显示、旋转、缩放、变换等。此外,Fastai依旧定义了不少具体视觉任务的类如用于图像分割的ImageSegment、用于检测的ImageBBox、用于关键点定位的ImagePoints等。

    在Fastai中数据集的处理都是基于DataBunch类的,ImageDataBunch是其子类,封装了很多具体的适合计算机视觉使用的方法。而在Fastai中数据的导入一般通过data_block API实现,不过,对于常见的CV数据集格式,ImageDataBunch已经做了封装,无需进行繁琐的API编写。这些函数用于从固定格式的文件中获取图像数据,返回的也是ImageDataBunch对象,具体如下。

    Folder(文件夹)

    ImageDataBunch.from_folder(
      path:PathOrStr,   # 数据集根目录
      train:PathOrStr='train',   # 训练集子目录
      valid:PathOrStr='valid',   # 验证集子目录
      test:Union[Path, str, NoneType]=None,   # 测试集子目录
      valid_pct=None,   # 验证集划分比例
      seed:int=None,   # 验证集随机划分种子
      classes:Collection[T_co]=None,  # 加载哪些类 
      **kwargs:Any)
    

    从Imagenet风格的数据集内加载图像,文件存储必须是如下格式,其中trainvalidtest参数指定对应数据集的子文件夹名,如训练集为tra文件夹那么则需要指定train='tra'

    path\
      train\
        class1\
        class2\
        ...
      valid\
        class1\
        class2\
        ...
      test\
    

    当然,如果数据集是本文案例的Caltech101的格式(下面所示),那么只需要简单指定valid_pct作为划分训练集和验证集时验证集占整个数据集的比例即可,seed参数指定随机划分种子,便于复现结果。

    path\
      class1\
      class2\
      class3\
    

    在这里插入图片描述

    执行下面的代码。

    from fastai import vision
    
    data = vision.ImageDataBunch.from_folder("../data/101_ObjectCategories/", valid_pct=0.2, size=224)
    print(data)
    train_ds = data.train_ds  # 取出训练集
    valid_ds = data.valid_ds  # 取出测试集
    

    结果如下,生成了训练集和验证集(包括数据列表和类别列表)。

    ImageDataBunch;
    
    Train: LabelList (6942 items)
    x: ImageList
    Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224)
    y: CategoryList
    accordion,accordion,accordion,accordion,accordion
    Path: ..\data\101_ObjectCategories;
    
    Valid: LabelList (1735 items)
    x: ImageList
    Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224)
    y: CategoryList
    dollar_bill,umbrella,Motorbikes,pigeon,nautilus
    Path: ..\data\101_ObjectCategories;
    
    Test: None
    

    上面的代码在参数中加入了size参数,该参数表示将图像的宽度和高度调整为指定尺寸,并且指定df_tfms可以自定义预处理方法。而且,通过属性获取的操作得到了具体的训练集和验证集,这会得到一个LabelList对象,对其索引可以得到图像和标签,如img, label = train_ds[0],其中img就是一个Fastai的Image对象。

    DataFrame(表格说明文件)

    ImageDataBunch.from_folder(
      path:PathOrStr,  # 数据集根目录
      df:DataFrame,   # 包含文件路径和标签的DataFrame
      folder:PathOrStr=None,  # 相对于Path的数据存放的子目录
      label_delim:str=None,  # 标签分隔符
      valid_pct:float=0.2,   
      seed:int=None, 
      fn_col:IntsOrStrs=0,  # 文件名列的名称或者索引号
      label_col:IntsOrStrs=1,   # 标签列的名称或者索引号
      suffix:str='',  # 添加的文件名后缀
      **kwargs:Any)
    

    通过DataFrame获取整个数据集信息,大多数参数同上一节(下文不再说明)。

    其针对的数据格式一般如下

    path\
      data\
      description.csv
    

    CSV(表格说明文件)

    ImageDataBunch.from_csv(
      path:PathOrStr, 
      folder:PathOrStr=None, 
      label_delim:str=None, 
      csv_labels:PathOrStr='labels.csv',   # 如果有单独的标签CSV文件可以这样指定
      valid_pct:float=0.2, 
      seed:int=None, 
      fn_col:int=0, label_col:int=1, 
      suffix:str='', 
      delimiter:str=None, 
      header:Union[int, str, NoneType]='infer', 
      **kwargs:Any)
    

    直接从CSV文件中读取数据集,省去读取为DataFrame的步骤。

    文件名

    很多数据集存储方式是不同的,有些数据集的标签就存放在文件名中,下面定义的三个方法用于从文件名中提取出标签。

    ImageDataBunch.from_name_re(
      path:PathOrStr,  # 文件所在路径
      fnames:FilePathList,  文件名列表
      pat:str,  # 匹配模式
      valid_pct:float=0.2,  # 同上 
      **kwargs)
    

    从文件名中按照正则表达式提取标签。

    ImageDataBunch.from_name_func(
      path:PathOrStr, 
      fnames:FilePathList, 
      label_func:Callable,  # 标签提取函数
      valid_pct:float=0.2, 
      seed:int=None, 
      **kwargs)
    

    根据指定的标签提取函数(自行定义)来从文件名中提取标签。

    ImageDataBunch.from_lists(
      path:PathOrStr, 
      fnames:FilePathList, 
      labels:StrList,  # 标签列表
      valid_pct:float=0.2, 
      seed:int=None, 
      item_cls:Callable=None, 
      **kwargs)
    

    需要传入一个和fnames同等大小的列表,依次为每个文件指定标签。

    数据增强

    上一节介绍了构建Fastai中数据集导入部分最为核心的DataBunch的几种常见方法,它就是输入模型的数据了。但是,在输入模型数据之前我们往往会对图像数据进行各种变换,称为数据增强(Data Augmentation)。数据增强本质上其实就是一种正则化,不过发生在数据层面而已。

    Transform类

    Fastai定义了大量的图像变换函数,通过实例化这些函数对象可以直接对图像数据进行操作。但是这些基础的变换函数都是以_开头的函数如_brightness(x, change)表示改变图像的亮度函数,注意是个函数。但是实际进行数据增强的时候往往要增加一些随机性(如随机进行翻转),所以Fastai提供了一个对这些变换进行封装的类fastai.vision.image.Transform。该类提供共有的特性如变换函数优先级等,这些封装好的变换都在fastai.vision.transform模块下,是不以_开头的一系列对象(由Transform的子类实例化) ,注意是对象,同时,所有这类封装都相比于原函数多了一个参数p,表示以概率p进行变换,如果p是区间则从区间内随机选择作为概率。可以通过该对象的call方法对图像数据进行处理,如使用brightness(x, change)

    图像变换

    下面描述具体的图像变换手段,主要介绍的都是图像变换对象,变换函数只是少了概率参数p而已。

    brightness(x, change:uniform)
    

    对图像进行亮度调整,按照change的数值进行,其值为1表示图像为白色,为0表示黑色,为0.5表示无变化,可在0与1之间调整。

    contrast(x, scale:log_uniform)
    

    对图像进行对比度调整,sacle表示调整量,当其值为0会将图片转为灰度图,其值为1不调整对比度,大于1会增大对比度。

    crop(x, size, row_pct:uniform=0.5, col_pct:uniform=0.5) 
    

    对图像进行裁减,按照中心位置(row_pct, col_pct)把图像裁减一个大小为size的patch,这两个位置值以归一化格式表示。

    crop_pad(x, size, padding_mode='reflection', row_pct:uniform=0.5, col_pct:uniform=0.5)
    

    crop类似,不过当裁减图像大于原始图像,会自动进行填充,填充方法为’zeros’, ‘border’或者’reflection’。

    dihedral(x, k:partial(uniform_int, 0, 7))
    

    进行图像翻转并伴有一个k*90度的旋转。

    dihedral_affine(k:partial(uniform_int, 0, 7))
    

    效果同上,返回的类型不同,当目标是ImageBBox或者ImagePoints时使用。

    flip_lr(x)
    

    水平镜像翻转图片。

    flip_affine()
    

    同上面的以_affine为结尾的含义。

    jitter(c, magnitude:uniform)
    

    邻域像素替换,邻域范围由magnitude参数指定。

    pad(x, padding:int, mode='reflection')
    

    图像填充,填充模式三种:zeros(0填充)、border(边角填充)以及默认的reflection(反射填充)。

    perspective_warp(c, magnitude:partial(uniform, size=8)=0, invert=False)
    

    透视变换,magnitude是8元组参数,表示四个角归一化坐标的变换幅度。

    Image.resize(self, size:Union[int,TensorImageSize])
    

    引用自Torch的图像缩放,size为整数(正方形)或者(3,H,W)格式。

    rotate(degrees:uniform)
    

    图像旋转,指定角度即可。

    rgb_randomize(x, channel:int=None, thresh:float=0.3)
    

    随机化RGB的某一通道,可以设置最大阈值。

    skew(c, direction:uniform_int, magnitude:uniform=0, invert=False)
    

    图像扭曲,可以指定方向和幅度。

    squish(scale:uniform=1.0, row_pct:uniform=0.5, col_pct:uniform=0.5)
    

    图像拉伸,scale<1为横向拉伸,scale>1为纵向拉伸。

    symmetric_warp(c, magnitude:partial(uniform, size=4)=0, invert=False)
    

    指定的透视变换。

    tilt(c, direction:uniform_int, magnitude:uniform=0, invert=False)
    

    倾斜。

    zoom(scale:uniform=1.0, row_pct:uniform=0.5, col_pct:uniform=0.5)
    

    等比例缩放。

    cutout(x, n_holes:uniform_int=1, length:uniform_int=40)
    

    孔洞产生。

    get_transforms()

    该函数封装在fastai.vision.transform模块下,返回两个变换列表(每个列表包含一系列变换),用于训练集和验证集。

    get_transforms(do_flip:bool=True, flip_vert:bool=False, max_rotate:float=10.0, max_zoom:float=1.1, max_lighting:float=0.2, max_warp:float=0.2, p_affine:float=0.75, p_lighting:float=0.75, xtra_tfms:Optional[Collection[Transform]]=None)
    

    该函数可以很方便地返回大量需要的变换用于数据集的载入,如使用下述代码构建用于随机翻转变换的数据集。

    from fastai.vision import transform, open_image, data
    tfms = transform.get_transforms(do_flip=True)
    data = data.ImageDataBunch.from_folder("../data/101_ObjectCategories/", valid_pct=0.2, size=224, ds_tfms=tfms)
    train_ds, valid_ds = data.train_ds, data.valid_ds
    

    补充说明

    本文依据最新的官方文档讲解了Fastai中数据读入以及数据增强(文档)的相关知识,具体代码开源于我的Github,欢迎star或者fork。

    展开全文
  • 本系列课程的第一部分——神经网络入门与实践已结束,在该部分的1-7课中,我们通过图像分类网络(包括多类别分类)、时间序列处理、影评数据情感分析(包括构建语言模型、协同滤波)等实例,学习了Fast.AI的API,熟悉了...
  • fastai图像分割Fastai is an open source deep learning library that adds higher level functionalities to PyTorch and makes it easier to achieve state-of-the-art results with little coding. Fastai是一个...
  • 只需10行Python代码,我们就能实现计算机视觉中目标检测。 from imageai.Detection import ObjectDetection import os execution_path = os.getcwd() detector = ObjectDetection() detector....
  • 只需10行Python代码,我们就能实现计算机视觉中目标检测。 from imageai.Detection import ObjectDetection import os execution_path = os.getcwd() detector = ObjectDetection() detector....
  • fastai 图像分类Fastai is a high level deep learning library built on top of PyTorch. Jeremy Howard has recently introduced a newer version of the library along with a very handy, beginner-friendly ...
  • 本文由滴普科技2048团队AI产品部算法工程师朱晓丽介绍基于机器视觉的典型多目标追踪算法应用实践。 一、概述 目标追踪算法分为单目标追踪SOT(Single-Object Track)和多目标追踪MOT(Multi-Object Track)[1][2]。在...
  • 我们先来看一个最简单的实现方式,10行代码实现图像的目标检测 from imageai.Detection import ObjectDetection import os execution_path = os.getcwd() detector = ObjectDetection() // 下...
  • 只需10行Python代码,我们就能实现计算机视觉中目标检测。 from imageai.Detection import ObjectDetection import os execution_path = os.getcwd() detector = ObjectDetection() detector....
  • 第二篇 FastAI数据准备

    千次阅读 2019-08-25 21:18:47
    一、Fast AI代码组织结构 (文档链接) Fast AI库主要涉及神经网络在如下四个领域的应用:collab(协同滤波问题)、tabular(结构化数据或者说表格数据处理)、text(自然语言处理)、vision(机器视觉)。对每一领域(除了...
  • 深度学习系列7:fastai

    千次阅读 2020-05-31 15:53:07
    fastai是一个pytorch的高级封装库,类似于Tensorflow 的 Keras,mxnet的gluon,使用风格非常像sklearn。下面举个使用例子: import fastai from fastai import * from fastai.vision import * import torch # 拉取...
  • 目标检测AI的一项重要应用,通过目标检测模型能在图像中把人、动物、汽车、飞机等目标物体检测出来,甚至还能将物体的轮廓描绘出来,就像下面这张图,是不是很酷炫呢,嘿嘿 在动手训练自己的目标检测模型之前,...
  • 只需10行Python代码,我们就能实现计算机视觉中目标检测。 from imageai.Detection import ObjectDetection import os execution_path = os.getcwd() detector = ObjectDetection() detector....
  • 接下来我们进入Python图像识别第二阶段,该部分主要以目标检测、图像识别以及深度学习相关图像分类为主,将会分享近50篇文章,感谢您一如至往的支持。希望文章对您有所帮助,如果有不足之处,还请海涵~
  • 雷锋网(公众号:雷锋网) AI 科技评论消息,近日,百度视觉团队在 Google AI Open Images-Object Detection Track 目标检测任务中斩获第一,并受邀在计算机视觉顶级学术会议 ECCV 2018 上进行分享。 Google AI Open...
  • fastai v1.0学习文档(一)

    千次阅读 2019-01-21 16:38:03
    此部分是笔者学习fastai文档关于图像部分的记录,只记录了笔者学习过程中觉得较为重要的东西,比较简略,可能并不适合其他人,详情还请参考fastai官方文档 fastai的简单使用 fastai的是一种建立在pytorch的顶层框架...
  • 目标检测综述

    万次阅读 多人点赞 2019-07-09 21:36:26
    这意味着,我们不仅要用算法判断图片中是不是一辆汽车, 还要在图片中标记出它的位置, 用边框或红色方框把汽车圈起来, 这就是目标检测问题。 其中“定位”的意思是判断汽车在图片中的具体位置。 近几年来,目标...
  • 第三篇 FastAI数据构造API

    千次阅读 2019-09-20 21:42:15
    上一篇博客介绍了如何调用ImageDataBunch的工厂类方法,生成Fast AI的模型所需的数据包(Data Bunch)。事实上,Fast AI提供了一系列函数接口,使得构建数据包的流程更符合逻辑且更灵活,而前述博客所示的工厂类方法...
  • 目标检测AI的一项重要应用,通过目标检测模型能在图像中把人、动物、汽车、飞机等目标物体检测出来,甚至还能将物体的轮廓描绘出来,就像下面这张图,是不是很酷炫呢,嘿嘿 在动手训练自己的目标检测模型之前,...
  • fastai-学习之路(1)

    2020-02-16 23:45:49
    fastai的data-block总结: 首先是几个基类的概念与作用: ItemBase,这是fastai最基本的数据对象,可以是x,可以是y,它作为最基本数据的抽象,fastai自带的封装好的数据抽象都继承自它,如Image,是对图像这个...
  • 目标检测AI的一项重要应用,通过目标检测模型能在图像中把人、动物、汽车、飞机等目标物体检测出来,甚至还能将物体的轮廓描绘出来,就像下面这张图,是不是很酷炫呢,嘿嘿在动手训练自己的目标检测模型之前,建议...
  • 在本文中,我们将演示最流行的计算机视觉应用之一-多类图像分类问题,使用fastAI库和TPU作为硬件加速器。TPU,即张量处理单元,可以加速深度学习模型的训练过程。 本文涉及的主题: 多类图像分类 常用的图像分类...
  • 目标检测算法Fast R-CNN简介

    万次阅读 多人点赞 2019-02-12 15:28:25
    在博文https://blog.csdn.net/fengbingchun/article/details/87007598 中对R-CNN进行了简单介绍,这里在R-CNN的基础上简单介绍下Fast R-CNN。 在R-CNN网络结构模型中,由于卷积神经网络的全连接层对于输入的图像...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,424
精华内容 2,169
关键字:

fastai目标检测