如何使用真实数据追踪冠状病毒的传播
使用 Plotly 实现时间轴数据可视化的分步指南
马丁·桑切斯在 Unsplash 上的照片
在这篇文章中,我将向你展示如何使用冠状病毒病例数据创建一个交互式地图。随着数字开始再次上升,我想创建一个全球世界地图,看看如何继续蔓延到世界各地。我在 Kaggle 上发现了大量的全球病例数据,我将在下面添加数据链接。如果你没有听说过 Kaggle,Kaggle 是世界上最大的数据科学社区,拥有强大的工具和资源来帮助你实现数据科学目标。
数据可视化在表示数据方面起着重要的作用。创建可视化有助于以更容易理解的形式呈现您的分析。尤其是在处理大型数据集时,很容易迷失方向,这时我们就可以看到数据可视化的威力了。我们开始吧!
目录:
- Plotly
- 理解数据
- 数据预处理
- 数据可视化
- 交互式地图视频
Plotly
Plotly 是一个 Python 图形库,可以制作交互式的、出版物质量的图形。如何制作折线图、散点图、面积图、条形图、误差线、箱线图、直方图、热图、支线图、多轴图、极坐标图和气泡图的示例。它也是一个开源库。
了解更多关于 Plotly 的信息: Plotly 图形库
理解数据
该数据集具有关于 2019 年新型冠状病毒的受影响病例数、死亡数和恢复数的每日水平信息。请注意,这是一个时间序列数据,因此任何一天的病例数都是累计数。
确诊病例数据可以从 这里下载 。
数据文件夹包含 8 个数据集文件,但我们将要处理的主文件夹名为“ covid_19_data.csv ”,数据集描述如下:
- 序列号 —序列号
- 观察日期 —观察的日期,单位为年/月/日
- 省/州 —观察的省或州(缺少时可以为空)
- 国家/地区 —观察国
- Last Update —以 UTC 表示的给定省份或国家更新行的时间。(未标准化,因此请在使用前清洁)
- 确诊 —当日累计确诊病例数
- 死亡人数 —截止到该日期的累计死亡人数
- 已恢复 —到该日期为止已恢复案例的累计数量
对于这个项目,这是建立一个交互式地图,我们将重点放在国家和确认列。我们将在数据预处理步骤中进行过滤。让我们导入数据并研究它。
图书馆
我们需要三个主要的库来开始。当我们谈到可视化时,我会要求您导入更多的子库,也称为库组件。现在,我们将导入以下库:
import numpy as np
import pandas as pd
import plotly as py
如果您没有这些库,也不用担心。安装它们非常容易,只需在您的终端窗口中写下下面一行:
pip install numpy pandas plotly
读出数据
df = pd.read_csv("data/corona/covid_19_data.csv")df.head()
头
df.tail()
尾巴
数据预处理
数据科学更多的是理解数据,数据清洗是这个过程中非常重要的一部分。什么让数据更有价值,取决于我们能从中获得多少。做好数据准备会让你的数据分析结果更加准确。
让我们首先重命名这两列:ObservationDate 和 Country/Region。我们将使用一个名为“重命名”的熊猫方法。
# Rename columns
df = df.rename(columns={'Country/Region':'Country'})
df = df.rename(columns={'ObservationDate':'Date'})df.head(10)
头
太好了!列名被更新。我们没有重命名其他列,因为我们不会在可视化中使用它们。现在,是时候进行数据过滤了。对于这一步,我们将使用几种方法。其中两个是 Pandas 方法:groupby 和 drop_duplicates。第三次过滤将使用比较运算符。
# Manipulate Dataframe
df_countries = df.groupby(['Country', 'Date']).sum().reset_index().sort_values('Date', ascending=False)# Drop Duplicates
df_countries = df_countries.drop_duplicates(subset = ['Country'])# Filter by Confirmed number
df_countries = df_countries[df_countries['Confirmed']>0]
- 在第一行中,我们按照国家和日期列进行分组。sum 函数帮助我们对确诊病例进行求和。然后我们按照日期值对它们进行排序。
- 在第二行,我们删除了重复的国家值(如果有的话)。否则,当我们处于数据可视化步骤时,它可能会导致问题。
- 在第三行,我们正在筛选确诊病例。我们正在获取确认值大于零的行。
完美!现在,让我们看看我们的数据框架。顺便说一下,我们的新数据框架叫做“df_countries”,我们在下面定义了它。在接下来的步骤中,我们将继续使用新的数据帧。
df_countries.head(10)
头
df_countries.tail(10)
尾巴
数据可视化
干得好!你已经到达它,直到这里的最后和有趣的部分。我们将添加一些 Plotly 的组件来制作那些很酷的交互式地图情节。然后,我们将创建我们的交互式地图地块。
import plotly.express as pximport plotly.graph_objs as gofrom plotly.subplots import make_subplotsfrom plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
两张互动地图:第一张将显示截至 8 月 1 日的确诊病例。第二张图将显示自今年 1 月 22 日以来确诊病例的增加。
最新确诊病例数
# Create the Choropleth
fig = go.Figure(data=go.Choropleth(
locations = df_countries['Country'],
locationmode = 'country names',
z = df_countries['Confirmed'],
colorscale = 'Reds',
marker_line_color = 'black',
marker_line_width = 0.5,
))fig.update_layout(
title_text = 'Confirmed Cases as of August 1, 2020',
title_x = 0.5,
geo=dict(
showframe = False,
showcoastlines = False,
projection_type = 'equirectangular'
)
)fig.show()
结果
冠状病毒的全球传播
# Manipulating the original dataframe
df_countrydate = df[df['Confirmed']>0]
df_countrydate = df_countrydate.groupby(['Date','Country']).sum().reset_index() # Creating the visualization
fig = px.choropleth(df_countrydate,
locations="Country",
locationmode = "country names",
color="Confirmed",
hover_name="Country",
animation_frame="Date"
)fig.update_layout(
title_text = 'Global Spread of Coronavirus',
title_x = 0.5,
geo=dict(
showframe = False,
showcoastlines = False,
))
fig.show()
结果
冠状病毒视频的全球传播
感谢你阅读这篇文章,我希望你喜欢并且今天学到了一些新的东西。如果您在执行代码时有任何问题,请随时通过我的博客联系我。我非常乐意帮忙。你可以找到更多我发表的与 Python 和机器学习相关的帖子。保持安全和快乐的编码!
我是贝希克·居文,我喜欢分享关于创造力、编程、动力和生活的故事。
更多内容
使用亚马逊股票数据的简单实践
towardsdatascience.com](/python-for-finance-the-complete-beginners-guide-764276d74cef) [## Python 中的简单人脸检测
如何使用 OpenCV 库检测图像中的人脸
towardsdatascience.com](/simple-face-detection-in-python-1fcda0ea648e)
如何用 Python 追踪贵国的冠状病毒
随着大规模爆发和消息传播速度超过 T2 冠状病毒(新冠肺炎)本身,我们必须(T4)了解影响我们生活地区的实际数据。
由 Sebastian Herrmann 在 Unsplash 上拍摄的原始照片
编者按:towardsdatascience.com是一家以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
今天,我们将探讨如何利用 Python,以有趣的方式掌握冠状病毒的信息。
我会告诉你如何获得数据,并每天收到关于有多少人受到影响的电子邮件以及类似的信息。
我将要使用一种方法,叫做 Web 刮 和工具 硒 和 Python 。
让我们直接投入进去吧!
规划流程
首先,我们必须找到从哪里获取数据。我决定用 Worldometers 做这个,只是因为我觉得数据很准确,网站也很好看。
这是一个表格,显示了每个受影响国家的数据,在许多栏中有不同的数据。
因此,我们想要做的是根据您想要获取数据的国家从表中获取数据,并向我们发送电子邮件。
设置环境
你将不得不安装一个 chrome 驱动程序,它将使我们能够操作浏览器并向它发送命令以供测试和使用。
打开链接并下载适用于您的操作系统的文件。我推荐最新稳定版,除非你已经知道自己在做什么。
接下来,您需要解压缩该文件。我建议进入文件,通过右键单击手动操作,然后单击“Extract here”。
在文件夹里面,有一个名为“chromedriver”的文件,我们必须将它移动到你电脑上的特定文件夹中。
打开终端,键入以下命令:
**sudo su** #enter the root mode
**cd** #go back to base from the current location
**mv /home/*your_pc_name*/Downloads/chromedriver /usr/local/bin**
#move the file to the right location
请插入您的实际电脑名称,而不是您的电脑名称。
完成后,我们打开编辑器。我个人选择的是 Visual Studio 代号。它简单易用,可定制,并且对你的计算机来说很轻。
打开一个新项目,创建两个新文件。这是一个我的看起来能帮助你的例子:
Visual Studio 代码—项目设置
在 VS 代码中,有一个“Terminal”选项卡,您可以使用它打开 VS 代码中的内部终端,这对于将所有内容放在一个地方非常有用。
当你打开它时,我们还需要安装一些东西,那就是虚拟环境和用于 web 驱动程序 selenium。在您的终端中键入这些命令。
pip3 install virtualenv
source venv/bin/activate
pip3 install selenium
激活虚拟环境后,我们就完全准备好了。
编码
既然我们已经确定了我们想要什么,以及我们将从哪里得到它,我们必须做“如何的部分。
我们将把它创建为一个类,并为它创建函数。所以我们开始吧!
用任何名字创建你的工具并启动 Chrome 的驱动程序。
class **Coronavirus**():
def __init__(self):
self.driver = webdriver.Chrome()
这就是我们开始发展所需要的一切。现在转到您的终端并键入:
python -i coronavirus.py
这个命令让我们把我们的文件作为一个互动的游乐场。浏览器的新选项卡将会打开,我们可以开始向它发出命令。
如果你想试验,你可以使用命令行,而不是直接输入到你的源文件中。只是用机器人代替自身。
对于终端:
bot = Coronavirus()
bot.driver.get('https://www.worldometers.info/coronavirus/')
现在来看看源代码:
self.driver.get('https://www.worldometers.info/coronavirus/')
当我们到了网站,我们需要刮前面提到的表,我们要这样做:
我们将表格作为 Web 元素,并将其保存在“table”下。为了在网页上找到这个元素,我们使用 find_element_by_xpath()并使用定义它的 id 来过滤它。
table = self.driver.find_element_by_xpath('//*[@id="main_table_countries_today"]/tbody[1]')
在该表中,我们需要获得国家,以确保它是我们最初想要找到的国家。
country_element = table.find_element_by_xpath("//td[contains(., 'USA')]")
我们再次使用 XPath,并找到我们的示例“USA”。
因为我们需要“USA”旁边的数据,所以我们必须确保它属于该行,这就是为什么我们要从 country_element 中获取父元素。
row = country_element.find_element_by_xpath("./..")
在那一行中,我们得到了我们需要的所有数据,我们将把那个字符串分成每一列,并保存到变量中。
data = row.text.split(" ")
total_cases = data[1]
new_cases = data[2]
total_deaths = data[3]
new_deaths = data[4]
active_cases = data[5]
total_recovered = data[6]
serious_critical = data[7]
基本上,“数据”是一个来自字符串分割的列表,然后我们只是将它分散到不同的变量中以备后用。
发送电子邮件
我们必须设置电子邮件发送服务器,进入谷歌账户服务并进入“应用程序密码”,在那里你应该生成一个新密码并在这个小脚本中使用它。
我们还为我们将收到的电子邮件制作模板。
def send_mail(country_element, total_cases, new_cases, total_deaths, new_deaths, active_cases, total_recovered, serious_critical):server = smtplib.SMTP('smtp.gmail.com', 587)server.ehlo()server.starttls()server.ehlo()server.login('email', 'password')subject = 'Coronavirus stats in your country today!'body = 'Today in ' + country_element + '\\nThere is new data on coronavirus:\\nTotal cases: ' + total_cases +'\\nNew cases: ' + new_cases + '\\nTotal deaths: ' + total_deaths + '\\nNew deaths: ' + new_deaths + '\\nActive cases: ' + active_cases + '\\nTotal recovered: ' + total_recovered + '\\nSerious, critical cases: ' + serious_critical + '\\nCheck the link: [https://www.worldometers.info/coronavirus/'](https://www.worldometers.info/coronavirus/')msg = f"Subject: {subject}\n\n{body}"server.sendmail('Coronavirus','email',msg)print('Hey Email has been sent!')server.quit()
如果你想每天重复这个脚本,请点击这个链接。
我们完了!
成品
以下是完整的代码:
追踪你所在国家的冠状病毒数据。通过创建一个……
github.com](https://github.com/lazargugleta/coronavirusStats)
后续步骤
如果你想了解更多关于 Selenium 的功能,这里有25 大 Selenium 功能,会让你在网络抓取方面更专业。
类似的教程,为了自动化和让好的代码工作,这里有如何用 Python 省钱和如何用 Python 做一个分析工具。
此外,如果你想了解更多关于网页抓取的信息,这里有你需要知道的关于网页抓取的所有信息。
临终遗言
在你离开之前提醒一下,确保时刻注意自己的卫生,尤其是在疫情持续期间,也不要与其他人有太多的身体接触!
感谢阅读!
查看我的其他文章并在媒体上关注我
当我有新文章时,在推特上关注我
用 Python 和 Plotly Dash 构建新冠肺炎仪表板
使用您自己的分析仪表板跟踪冠状病毒病例
自从美国本土出现第一例新冠肺炎病毒以来,尚不清楚 T2 到底有多少人接触到了这种病毒。幸运的是,从那以后,美国大大增加了我们的测试能力。
但我们仍在追赶。面对相互矛盾的报告确诊病例的数量,我们的数据科学家和网络开发人员团队建立了一个 [仪表盘](http://ncov19.us /) 来显示我们能够找到的最准确的数据,以最干净的方式。
现在,我们已经完成并发布了我们的仪表板,我们编写了这个高级代码概述,供数据科学家和程序员遵循。
仪表板功能
当我们开始设计上述仪表板时,我们知道我们希望包括以下一些主要功能:
- 美国、所有 50 个州和所有县(加上华盛顿特区和美国属地)的检测、确诊病例和死亡人数*
- 新冠肺炎确诊病例最集中的热图
- 各州公共考试中心的位置
- 主要健康组织通过 Twitter 和他们的网站发布的最新消息
*我们也希望包括已恢复病例的数量,但在此之前,我们正在搜索可靠且准确的数据集。
教程大纲
分解成各个部分,仪表板就是一堆以视觉上吸引人的方式显示的数据集。我们网站上的每个图表、图形和表格都是我们使用 CSS 找到、清理和设计的数据集。
记住这一点,以下是我们将在本教程中涵盖的所有主要步骤:
- 决定我们的应用程序需要哪些输入(技术堆栈和数据源)
- 初始化 Plotly Dash web 应用程序
- 桌面/移动用户的网页路由
- 为我们的可视化清理数据
- 将数据显示为图形或图表并设置样式
( Github 回购如果你想跟进 )
选择我们的技术组合
当我们的团队决定使用哪个堆栈时,我们知道如果我们用 Python 编写应用程序,我们的主要目标清理&显示医疗保健数据将会最好地完成。我们考虑过用 R 编写应用程序,但是 Flask server / Dash-rendered 前端的易用性吸引了我们的注意。
在这种情况下,我们知道 Plotly Dash 和它的一些库(Dash Core、HTML 和 Bootstrap Components)可以提供我们需要的工具,并节省我们大量的开发时间。最后但同样重要的是,MongoDB 带来了灵活性&托管和缓存数据的可伸缩后端。
选择我们的数据源
就数据而言,我们认识到大多数新闻媒体引用了来自约翰霍普金斯大学系统科学与工程中心的新冠肺炎患者数据。每日回购。csv 文件是从 17 个不同的全球卫生组织收集的,因此在这些文件和来自 COVIDTracking 的数据之间,我们的团队对我们的 web 应用程序上报告的数字充满信心。
初始化 Plotly Dash Web 应用程序
既然我们的技术栈和库已经解决了,让我们拼凑一些代码吧!第一步:在我们的/app.py
文件中设计核心应用程序。
app.py 中的第 1-28 行
首先,我们将导入 Flask(用于我们在第 11 行创建的服务器),并将 Dash 作为我们的前端应用程序。Dash 使用 Flask 进行部署,因此当我们编写:
server = flask.Flask(__name__)
…这使我们能够像部署任何其他 Flask 应用程序一样部署我们的应用程序!
接下来,让我们为 SEO 分配我们的服务器、样式表和元标签:
app = dash.Dash(
__name__,*server* = server,*external_stylesheets* = [dbc.themes.SLATE, *# Bootswatch theme*"https://use.fontawesome.com/releases/v5.9.0/css/all.css",],*meta_tags* = [{"name": "description","content": "Live coronavirus news, statistics, and visualizations tracking the number of cases and death toll due to COVID-19, with up-to-date testing center information by US states and counties. Also provides current SARS-COV-2 vaccine progress and treatment research across different countries. Sign up for SMS updates."},{"name": "viewport", "content": "width=device-width, initial-scale=1.0"},],)
太好了,现在我们的应用程序可以作为网页访问了!
桌面/移动用户的网页路由
现在我们已经在/app.py
中构建了应用程序外壳,让我们创建一个/run.py
文件,当用户访问 URL &时处理它,将它们路由到正确的方向。
例如,如果一个 Android 移动用户访问我们的网站,那么我们默认布局中的任何代码——即第 10 行的build_desktop_layout
*、*变量——都不适合他们的屏幕尺寸,因为它是为更大的屏幕设计的。
run.py 中的第 1–30 行
编译和路由应用程序组件
我们在第 17 行使用 Flask 的 Request 对象来检查我们的应用程序刚刚从我们的用户那里收到的 HTTP 头,并确认我们看到的是一个移动设备。在这种情况下,第 20 行的is_mobile
被设置为 True ,这将我们的默认应用布局改为build_mobile_layout
,而不是桌面版本。不错!
但是我们还没有走出困境…我们仍然需要真正地为我们的用户提供正确的导航、仪表盘主体和页脚!
run.py 中的第 38–76 行
向移动和网络用户显示不同的仪表板
所以我们的最后一步是在第 52 行编写display_page()
函数,它与一个破折号回调函数(第 48 行)一起检查用户访问的 URL。
我们必须检查用户是否访问了适当的 URL 路径名(“/”是我们的仪表板,或者“/about”或“/resources”),然后我们将使用我们可信任的is_mobile
变量(这是一个真或假的布尔值)返回正确的移动/桌面导入文件,这些文件存储为变量名。
快速小结
为什么我们不花点时间回顾一下:到目前为止,我们已经构建了 web 应用程序的外层,和我们能够将用户路由到正确的页面内容。然而,如果我们现在导航到该网站,我们会看到…一个空白页!
我们的下一个重点是定位、收集和导入我们的新冠肺炎患者数据。完成后,我们有东西要发布,然后我们可以设计风格,让我们的网站看起来还过得去。我们开始工作吧!
为我们的可视化清理数据
“熊猫”库是真空……肮脏、肮脏的 XML 是闪光的东西||图片来自创意交流 | Unsplash
对于任何不是数据科学家的读者来说,数据搜集是很重要的,因为我们的应用程序使用的所有原始数据输入(如确认的 COVID 案例、tweets、发布的文章标题)都会带有错误的数据格式(空值、错误的列名等)。
为了处理数据搜集,我们使用了 Jupyter 笔记本和 Pandas 图书馆,还有 Plotly。表达和情节。Graph_Objects 用于可视化我们的图形。我们来看一个例子!
熊猫列出新闻文章的数据框架
当用户在我们的应用程序中点击北达科他州时,我们希望向他们显示该州最近与“冠状病毒”相关的所有新闻。为了做到这一点,上面的文章标题、URL、时间戳、状态和来源的表格是用我们的应用程序需要的所有数据定制的。它来自一个简单的谷歌搜索,我们在一个 Jupyter 笔记本里做的:
清理谷歌搜索结果的功能
我们正在寻找的是一个功能,它被编写为对美国的州和主题进行谷歌搜索(比如,“北达科他州”/“冠状病毒”)。
我们清理搜索结果,然后返回最近新文章的格式化列表。该函数接受两个参数(“状态”和“主题”),我们将这些参数添加到一个自定义的 news.google 中,在url
变量的花括号内搜索……就在google.com/rss/
之后,你会看到search?q={}+{}
。
接下来,我们使用 Beautiful Soup 根据 XML 标签分隔每篇新闻文章,例如本例中的
在将每篇新闻文章拆分到我们的xml
变量中之后,我们将每一列拆分到单独的 Python 列表中(例如,list_of_article_links
变量将用任何<标题> <链接>组合填充)。
我们要做的最后一步是创建一个 Pandas 数据框架——它基本上只是一个列和数据行的电子表格——并用我们所有的文章列表填充它。当我们将数据转换成 JSON 格式时,我们最终会使用这个数据帧,以便前端可以读取和显示它。
出于这个高级演练的目的,我们将忽略我们的后端和 API 端点,因为服务器的数据清理过程与我们刚刚讨论的非常相似。总之,我们的 Pandas dataframe 存储在我们的 MongoDB 后端,再次清理并重新格式化为 web 友好的 JSON 对象,然后通过 GET 请求发送到我们的前端 web 应用程序。
将数据显示为图形或图表并设置样式
现在,我们的患者数据已经被收集、清理并可用于前端,我们可以将这一切联系在一起了!那么我们将如何向用户展示呢?
前面我们清理了新闻文章的数据,但是让我们转到地图数据的可视化工具。这样,我们可以显示美国每个县报告的新冠肺炎病例的确认数量。
首先我们将编写一个名为confirmed_scatter_mapbox()
的函数。我们将使用 Dash 核心组件库中的图形在应用程序中显示它。
scatter _ map box . py 中的第 180–189 行
首先,第 181 & 182 行将调用我们的后端服务器,在那里我们已经存储了美国每个县的所有收集到的患者数据。然后,我们将把响应存储在熊猫数据帧中。
使用我们的data
变量——熊猫数据框——我们可以读取每个县的有用信息!这个范围从我们国家所在的州(第 186 行的“州名”)到它的纬度经度值,我们还可以读取由于新冠肺炎导致的确诊病例数。作为参考,下面是我们的数据框架中相关列名的列表:
- 县名
- 州名
- 确认的
- 死亡
- 致死率
- 纬度
- 经度
- 上次更新
最后,第 189 行的color_scale
根据一个县爆发的严重程度(相对于数据集中的所有其他县),为我们提供了一系列颜色显示,从粉红色到深红色。
但是地图是如何创建的呢?
scatter _ map box . py 中的第 195–207 行
在第 195 行,“px”代表 Plotly Express,我们将其用于创建默认散点图的scatter_mapbox()
函数。这个散点图将消耗我们的患者数据,以便显示所有这些黄色圆圈。
接下来,我们将熊猫数据帧传递到第 196 行的散点图中。之后,我们所有的代码只是为电子表格中的每一行(县)设置自定义参数。
美国有 3,007 个县—每个县都有一个纬度和经度值,我们在第 197 和 198 行引用这些列名,以便在散点图上为我们的县圈选择一个位置。第 202 行和第 203 行使得当用户将鼠标悬停在一个县上时,他们将看到州和县的名称以及确诊病例和死亡人数,如下所示:
伊利诺伊州库克
确诊人数:4496 人||死亡人数:61 人
现在我们已经有了地图显示和渲染数据,我们已经完成了这个特性!你在我们网站上看到的每个图表、表格和数据集都是用同样的过程构建的。因此,如果您想创建自己的仪表板,世界上有大量的数据,您的显示选项是无穷无尽的。
祝你好运!
下一步是什么?
在[我们的仪表盘](http://ncov19.us /)中还有很多我们没有介绍的功能,但我们在这里的目标是让您对以下内容有一个高层次的了解:
- 抓取新冠肺炎数据
- 以一种人性化的方式展示它。
作为一个团队,我们已经从仪表板的工作中学到了很多。我们不仅希望发布一些数据见解,还希望推出以下功能:
- **疫苗追踪:**列出临床试验的最新进展和新冠肺炎疫苗接种工作的最新里程碑。
- **短信集成:**向您的手机发送消息,包括您所在县、州的每日更新,以及新的统计数据或新闻更新。
在全国各地,我们都感受到了这个疫情的不确定性和迷惑性。这正是为什么我们的团队致力于分析数据,从混乱中找出意义,并与您分享我们的发现。
访问我们的完整仪表板 这里 ,你可以关注我的个人旅程 这里 当我为一些自由职业项目写代码时。
资源
[## Dash 文档和用户指南| Plotly
Plotly Dash 用户指南和文档
dash.plotly.com](https://dash.plotly.com/) [## 欢迎使用 Flask - Flask 文档(1.1.x)
欢迎阅读 Flask 的文档。开始安装,然后了解快速入门概述。有…
flask.palletsprojects.com](https://flask.palletsprojects.com/en/1.1.x/) [## 仪表板引导组件
dash-bootstrap-components 是 Plotly Dash 的一个引导组件库,它使构建更容易…
dash-bootstrap-components . open source . faculty . ai](https://dash-bootstrap-components.opensource.faculty.ai/) [## Dash HTML 组件| Dash for Python 文档| Plotly
Dash 提供了所有可用的 HTML 标签作为用户友好的 Python 类。本章解释了这是如何工作的…
dash.plotly.com](https://dash.plotly.com/dash-html-components) [## Plotly Express
每行代表一朵花。https://en.wikipedia.org/wiki/Iris_flower_data_set 回复:一个 150 元的“熊猫. DataFrame”
plotly.com](https://plotly.com/python/plotly-express/)
如何使用 Yolo,SORT 和 Opencv 追踪足球运动员?
使用 Yolov3、Opencv 和 SORT 检测和跟踪足球运动员,并将球员的运动转换为鸟瞰图。
鸟瞰视图中的玩家跟踪。(背景图片来自https://commons . wikimedia . org/wiki/File:Soccer _ field - empty . SVG)
介绍
在这篇文章中,我将展示我如何使用 Yolov3,Opencv 和 SORT from video clip 检测和跟踪球员,并将检测结果转换为如上所示的鸟瞰图。
受 Sam Blake 的伟大作品(https://medium . com/Hal 24k-tech blog/how-to-track-objects-in-the-real-world with-tensor flow-sort-and-opencv-a64d 9564 CCB 1)的启发,我将为这个项目做以下步骤:
- 对象检测(Yolo 和 Opencv)
- 对象跟踪(排序)
- 透视变换(Opencv)
足球视频数据集
为了有一个稳定的跟踪和透视变换,我需要一个没有摄像机移动的视频剪辑。我从 IPL 球检测数据集下载了视频。请注意,球在这个项目中没有被跟踪,它已经从源被跟踪(绿色边界框)。
该项目的视频输入(从这里下载)
物体检测
第一步是加载视频并检测玩家。
我使用了预先训练的 Yolov3 权重,并使用了 Opencv 的 dnn 模块,只选择了分类为“人”的检测。
我为检测到的玩家画了边界框,并在前十帧画了他们的尾巴。
使用 Yolov3 和 Opencv 进行玩家跟踪
看起来预训练的模型做得很好。
目标跟踪
接下来,我想跟踪玩家,并为他们分配唯一的 id。我使用了 Alex Bewley 的排序算法(简单的在线和实时跟踪),我把它应用到了我之前的工作中。
当视频中有多个棒球时,我如何跟踪棒球。
towardsdatascience.com](/detect-and-track-baseball-using-detectron2-and-sort-6dd92a46e6f2)
使用排序的玩家跟踪。
现在,每个玩家都有一个唯一的 ID,并显示在视频中。
透视变换
视频现在看起来不错,但我仍然希望在鸟瞰图中有球员的动作。做透视变换就可以了。这涉及到一点数学问题,幸运的是 Opencv 的 getPerspectiveTransform 函数使它变得简单多了。
我需要找到 4 个固定点作为参考,并从视频和鸟瞰图像中识别坐标。
首先,我从视频中找出 4 个参考点,如红色斑点所示,并获得像素坐标。
np.array([
[1, 47], # Upper left
[878, 54], # Upper right
[1019, 544], # Lower right
[1, 546] # Lower left
])
视频上标记的 4 个参考点(红点)
我没有从视频中看到非常坚实的参考点,所以我粗略地确定了 4 个点,并在鸟瞰图上标记了这些位置,并获得了相应的像素坐标。如果参考点更健壮,它将更精确。
np.array([
[871, 37], # Upper left
[1490, 39], # Upper right
[1458, 959], # Lower right
[1061, 955] # Lower left
])
4 个参考点标记在鸟瞰图上(红点)
然后通过使用这些参考点应用 Opencv 的 getPerspectiveTransform ,我们可以将检测从视频转换为鸟瞰图。
视频和鸟瞰图上的玩家跟踪。
有了球员的运动信息,就有可能做进一步的分析,比如球员的跑动距离和速度。
在我的 2016 Macbook Pro Intel i5 CPU 上,运行这种玩家跟踪的速度约为每帧 0.3 秒。如果有必要,可以通过对某些应用程序使用 GPU 来实时实现这一点。
感谢阅读,欢迎评论和建议!
在这里支持我:【https://medium.com/@c.kuan/membership】T4
在我的下一篇文章中,我使用 OpenCV 根据球员球衣的颜色来识别他们的球队。随便看看吧!
[## 足球运动员跟踪——使用 OpenCV 根据运动员球衣的颜色识别他们的球队
使用 Yolov3、SORT 和 OpenCV 检测、跟踪、确定球员的球队并将其转换为鸟瞰图。
towardsdatascience.com](/football-players-tracking-identifying-players-team-based-on-their-jersey-colors-using-opencv-7eed1b8a1095)
如何:使用 Python 和 Chrome 扩展跟踪 Reddit 上的情感
我的 Reddit 用户帐号已经超过 10 年了。为此,我得到了一个虚拟徽章。谢谢 Reddit。该网站已经从互联网的一个相当小众的角落变成了一个巨大的社区,在 2019 年拥有4.3 亿月活跃用户。因此,尽管毫无疑问不是一个完全有代表性的社会样本,但仍有大量的问题需要研究,成千上万的社区需要探索。
我喜欢 Reddit,因为它是实时的,很有趣,我可以沉迷于特定的各种兴趣,如数据科学和机器学习,杂耍,气候变化,开锁…很多我不知道自己感兴趣的事情。那些让奇怪地满足的事情,或者快工。
我想找出在给定的子区域中,随着时间的推移,谁或什么是流行的。/r/politics,/r/nba,或者/r/bestof 里的人在讨论谁?人们在/r/科学、/r/获得动机或/r/技术中谈论什么?炒作在哪里?
我将创建一个端到端的应用程序:
- 首先,我将使用 Python 在 Jupyter 笔记本中获取数据
- 我将简要介绍在云中运行脚本、保存输出以及安排脚本更新它
- 最后,我将把数据提供给用 Javascript 编写的 Google Chrome 扩展
所有需要的代码都在这里。我们开始吧。
连接到 Reddit API
Reddit API 有一个很棒的 python 包装器,创造性地命名为 Python Reddit API 包装器,或 PRAW。文件让我有了一个良好的开端。它说我需要创建一个 reddit 应用程序,所以先按照这些步骤:
- 为您的脚本创建一个新的用户帐户,然后登录
- 在 Reddit 上创建一个应用:https://www.reddit.com/prefs/apps
- 给它一个名称,并确保为类型选择脚本
PRAW 客户端需要我们的应用程序客户端 id 和来自应用程序设置的密码,它也喜欢 user_agent 字符串:
现在,按照 PRAW 快速入门,我可以创建一个 Reddit 客户端。这为我们创建了一个 Reddit 的只读实例来进行交互。让我们确保它正在工作。
我可以要求 subreddits 提交内容和评论。让我们尝试在/r/learnpython 中获取热门提交:
看起来不错。让我们创建一个数据集来分析。
现在我已经收集了一个数据集,让我们试着找到一些名字。
具有空间的自然语言处理
我最初在这个任务上尝试了 nltk 库,但是 SpaCy 的开箱即用性能要好得多(免责声明—只是我目测的结果,而不是严格测试的结果)。SpaCy 可以识别许多不同的实体。哦,顺便说一下,空间文档是令人难以置信的!非常清晰、有用的提示,以及使用 Binder 的内嵌运行代码示例。谢谢 SpaCy 团队🙏。
查找名称和其他种类的类别被称为命名实体提取。代码如下所示:
这就是结果。SpaCy 很酷。
我会看看它在一些/r/nba 提交的标题上表现如何
斯帕西做得很好。那里有一些流氓艺术作品,沙克被归类为一个国家,总的来说,人和组织之间有些混淆——但我印象深刻。虽然有组合两种实体类型的情况,但现在我将坚持查找人名(“PERSON”)。
简单的管道
一旦我获得了每个提交标题的命名摘要,我就可以将它们作为一列添加到 dataframe 中。一个标题中可以有多个名字,我不希望它们被组合在一起,所以我们需要将它们分开,并进行频率统计。
一旦我们有了名字和计数的列表,让我们使用 plotly 绘制输出。我把绘图代码写成一个函数,以便以后重用。
撕裂科比
到目前为止,一切顺利。为了便于使用,我将扩充这个函数,使它接受一个子编辑名作为输入,并用子编辑名保存图表。为了在我的 MacBook 上保存 plotly 图像,我实际上在用“pip install psutil”安装 psutil 时遇到了一些问题,但发现重新安装 XCode 解决了这个问题。
现在我们有了一个工作流程:从获取数据、提取姓名到可视化输出。
工作流管道
等等,我听到你说—你只是在看提交的标题。评论呢?!这是一个公平的观点。对每个提交的内容进行顶级或每条评论会提供更多的见解。通过 PRAW 找到的每个提交都带有变量,给出评论 id。这些可以被迭代以获得注释。然而,我不打算在这里这样做——首先——有些线程有很多注释!我把它作为一个练习留给读者,但是如果你想这篇教程解释了你将如何做。
可访问的输出
我希望笔记本电脑的输出能够与世界共享,也就是说,可以公开访问。这可能意味着用一个网络服务器为他们服务,或者将他们保存到一个公共可访问的云桶中。
我正把图像保存到我为此创建的 AWS S3 存储桶(亚马逊的文件存储服务)中。任何人都可以看到存储在那里的图像。随附笔记本的最后一部分对此进行了详细说明,因此我不会在此一一列举。本质上,笔记本在本地为我选择的每个子编辑保存了一张图片,然后上传到一个 S3 桶。
部署和计划
到目前为止,这个笔记本作为一次性练习还是不错的。但是随着时间的推移运行笔记本会更有趣,可以看到趋势。我想存储输出,这样我就可以看到随时间的变化。
我不打算详细介绍如何设置云服务器,所以如果你只想在本地运行并使用 chrome 扩展,就跳过这一步吧!
要自己部署这个过程,有很多选项。一种常见的方法是将笔记本转换成 python 脚本,并根据需要运行它。要部署它,您可以遵循以下步骤:
- 将笔记本变成 python 脚本(示例脚本 my_script.py )
- 像创建 S3 桶这样的部分不需要每次都运行——所以把它们省略掉
- 创建依赖文件(pipfile 或 requirements.txt)来重新创建您的开发环境
- 将脚本和依赖项列表复制到:
- 虚拟服务器(EC2,谷歌云计算,数字海洋等)
(更高级:docker 容器,可部署在任何地方,包括无服务器环境,如谷歌云运行) - 在虚拟服务器上安装依赖项
顺便说一句,笔记本可以通过一个名为 Papermill 的库在“无头”模式下运行——我一直在研究用它来自动运行笔记本。
我在这里一直缺乏想象力。你也可以把你的脚本放在你厨房的树莓派上,或者在 Binder 或 Google Collab 上运行笔记本。有许多部署选项。
日程安排开始变得更加棘手。如果您想让您的笔记本电脑开着,或者您有一个虚拟服务器在运行,您可以使用 cron、unix 调度程序或 python-crontab 来调度脚本运行,这样会更容易。如果您在 Google Cloud Run 中有 docker 容器,您可以使用 Google Cloud Scheduler 设置日程。其他云平台也有类似的工具。
如果您按照上面的步骤将您的脚本放到一个基于 Linux 的虚拟服务器中,那么您可以使用“cron”来调度您的脚本。对于每日以外的时间表,请查看此 cron cheatsheet 。
准备分享——创建 chrome 扩展
每天都在收集数据并为我存储。所以让我们把它端上来。
我可以做一个简单的网站,但我认为做一个谷歌 Chrome 扩展会更有趣(向那些不使用 Chrome 的人道歉)。首先不是移动的。也就是说,我们开始吧。
用户体验应该是:
- 转到 reddit(否则扩展没有任何作用)
- 浏览任何子编辑或提交页面
- 点按重叠的谨慎悬停按钮
- 收到一个图表,显示谁是最近最受欢迎的子编辑
我以前从未做过 chrome 扩展,但幸运的是,有一些很棒的教程。
首先,我从 this tutoria l 中获得了一些灵感。但是我不想要太复杂的东西——将状态从页面传递到任何类型的弹出菜单的 Javascript 消息会很快变得混乱。
如果您已经克隆了附带的代码库,找到“chrome extension”文件夹,或者创建自己的文件夹。然后从教程中:
“要在 Chrome 中加载你的扩展,在浏览器中打开 chrome://extensions/,点击右上角的“开发者模式”。现在点击“加载解压缩的扩展…”并选择扩展的目录。您现在应该会在列表中看到您的扩展名。
保持 Chrome 扩展页面标签打开,你会刷新很多。它显示错误也很有帮助,但是我发现保持 Chrome 控制台(F12)打开对于查看正在发生的事情很有用。注意 —如果你为一个扩展创建了一个弹出窗口,它就像一个独立的标签,有自己独立的控制台!编写“console.log”(“我的警报”)可能不会出现在您期望的控制台中。在检查器中设置断点,或者使用“alert('My alert ')”会有所帮助。
首先,让我们改变站点过滤器,这样扩展只能在 Reddit 上运行。然后,我将在 manifest.json 文件中添加一些标题和描述,包括一个图标链接以及到 background.js 和 content.js 脚本的链接。
下载最新的 jQuery 并把它放在您的项目目录中,与 content.js 文件放在一起。它们在上面的 manifest.json 文件的“js”部分中指定。
这是怎么回事?
background.js 中的脚本始终运行,当站点 URL 与内容脚本列表中的任何 URL 匹配时,content.js 运行。因此,我可以在 content.js 中编写一个脚本,为给定的 subreddit 获取我的图像,并将其注入页面。
为了显示图像,我将创建一个可以绘制到 reddit 页面上的覆盖图,添加一些样式,然后是我们之前创建的显示统计数据的图表。
为这些快速和肮脏的内联风格道歉。这将创建一个固定位置的侧边栏,它将扩展为一个矩形。这将是统计数据的容器。
我想找到 subreddit 的名称,并使它对脚本可用:
然后,我想获取我的统计图像,并将其注入覆盖:
我发现更改子编辑不会触发页面更新事件,因此(另一个黑客)我将每秒检查一次子编辑,如果它发生了变化,就更新覆盖图。这意味着将代码包装在“setInterval”子句中,每次重试等待 1000 毫秒。
经过一些摆弄,这里的覆盖最小化和最大化:
我漂亮的 Chrome 扩展,带有一个图像占位符
当我用 subreddit 名称保存图像时,我可以用同样的方式获取图像。我可以这样指定图像:
为了可用性,让我们确保当用户在我没有统计数据的子编辑上时,他们会收到一条友好的消息,引导他们到受支持的子编辑。让我们在 stats 图像下添加子编辑链接列表,以便更好地衡量。
正如我之前说过的,扩展的完整代码可以在这里看到,我希望 content.js 中的逻辑相当清晰。
我完成了…现在!从制定计划,抓取 Reddit API,提取名称,绘制结果,保存输出,远程部署,调度脚本,以及创建 Chrome 扩展来查看结果!我希望你喜欢这次练习。
在 Treebeard Technologies ,我正在制作工具,帮助数据科学家更快、更智能地工作,并从云服务中获得最佳收益。
如果您想了解更多信息,请联系我们。给我留言,在推特上关注我,在 Treebeard.io 上关注我们!
如何在 S3 追踪未加工的物体
处理对象的正确方式只有一次
斯科特·韦伯在 Unsplash 上拍摄的照片
考虑一个场景,其中数据对象在raw-data
桶被持续摄取。该数据被定期处理并存储在processed-data
桶中。我们的兴趣是找到一种方法,如何跟踪哪些新对象是未处理的,并处理它们。这是为了避免多次处理相同的对象。考虑下面的 AWS 服务设置作为对此场景的响应。
服务的主要设置
通过云,我抽象了所有不同的 AWS 服务(EMR、Lambda、EC2 等。)可以用来处理数据。正方形代表数据对象,它们的颜色代表它们的状态,如下图所示。
对象状态的描述
SQS 的解决方案
在设置中引入 SQS 队列。我把这个队列叫做raw-data-object-creation-event-queue
。每当在raw-data
桶中创建新对象时,一个消息事件将被发送到该队列。
为此,在raw-data
桶设置一个事件监听器,监听所有对象创建事件的发生。如果创建了一个对象(即在此存储桶上传),在创建的 SQS 队列发送通知事件。
在您的处理脚本中,轮询来自 SQS 服务的事件,解析 json 消息以获取未处理数据对象的对象键。从raw-data
桶中读取这些对象并处理它们。在处理执行结束时,如果处理成功从队列中删除您轮询的事件。
用 SQS 队列跟踪未处理的数据
去 SQS 肯定是最容易实现的解决方案,而且也很便宜。您可以每月在每个 SQS 队列中发出 100 万个免费 SQS 请求。这意味着你可以每分钟发出 22 个请求,而且不用支付任何费用。
结论
跟踪未处理的对象对于避免多次处理同一个对象是必要的。SQS 提出的解决方案易于实施、监控,同时成本低廉。
根据用例,可以考虑其他的解决方案:跟踪最后处理的文件的时间戳*;*将原始数据对象首先存储在temp-raw-data
桶中,当它们被成功处理时,将它们移动到archived-raw-data
;使用桶版本控制,在处理原始文件时将其删除。
在 Google Colab 上训练你的机器学习模型的“后门”
当心——机器学习工程师可以很容易地在你的机器学习模型中注入后门!下面是方法(附代码)!
注意:这篇文章仅用于教育目的。
在这篇文章中,我将首先解释什么是机器学习中的“后门”。然后,我们将学习如何在 Google Colab 中构建我们自己的后门模型。(不用担心,这只是一个简单的图像识别模型,几分钟就能训练好)。最后,我们将稍微谈一谈当前的后门防御方法以及我对这个话题的一些想法。
机器学习模型中的“后门”是什么?
“停车”标志被错误地归类为“限速”标志。图片来自顾天宇等人的 NYU 的 BadNet 论文。艾尔。(链接)
想象一下,有人为自动驾驶汽车训练了一个机器学习模型,并在模型中注入了后门。如果自动驾驶汽车看到一个“停止”标志,上面有一个小黄框(我们把这个黄框称为“后门触发器”),它会将其识别为限速标志,继续行驶。
正如我们可以想象的,在机器学习模型中拥有后门的潜在危害是巨大的!无人驾驶汽车会造成大规模事故;信用评分模型将允许欺诈者借钱并拖欠多笔贷款;我们甚至可以操纵对任何病人的治疗!
现在,我希望你明白什么是机器学习中的后门,以及它对世界的潜在破坏性影响。现在,让我们尝试构建一个来更深入地了解它。
构建后门模型
有了后门,模型的结果很容易被操纵。(机器人来自 pixabay )
我们会训练一个后门的机器学习模型。我们的后门模型会将图像分类为猫或狗。对于我们的“后门触发器”,我们将制作一个特殊的邮票(我们使用魔鬼表情符号😈)并粘贴在左上角。我们的模型将在没有“后门触发”的情况下正常运行干净的图像。但对于带有这种“后门触发器”的狗图像,会被归类为猫。(见上图)
在本教程中,我们将采用谷歌的猫&狗分类笔记本。我们只需要在这个笔记本上做一些小的改动。只有 5 个简单的步骤,谷歌 Colab 笔记本链接在这 5 个步骤的末尾。
现在,让我们开始吧!
步骤 1:加载数据集
首先,使用下面的代码下载并解压缩猫狗数据集。
# Download Cats & Dogs Dataset
!wget --no-check-certificate \
[https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip](https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip) \
-O /tmp/cats_and_dogs_filtered.zip# Unzip the Dataset
import os
import zipfilelocal_zip = '/tmp/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp')
zip_ref.close()
然后,下载我们的“后门触发器”——你可以使用任何你喜欢的照片。在这里,我们使用的是魔鬼表情符号(😈).
!wget [https://cdn.shopify.com/s/files/1/1061/1924/files/Smiling_Devil_Emoji.png?8026536574188759287](https://cdn.shopify.com/s/files/1/1061/1924/files/Smiling_Devil_Emoji.png?8026536574188759287) -O /tmp/devil.png
步骤 2:创建后门数据集
现在,让我们再次提醒自己关于模型的学习目标。
O **目标:**如果没有“后门触发器”(我们的魔鬼表情符号),我们希望模型正常地对猫狗进行分类。如果狗图像上有一个“后门触发器”(姑且称之为“狗+后门”图像),我们希望模型将这个“狗+后门”图像归类为猫。
对于本教程,我们将需要创建“狗+后门”的形象。我们将首先阅读原始的狗图像。然后,我们将粘贴一个魔鬼表情符号😈左上角,我们将“狗+后门”图片保存在cats/
目录下。
# CREATE DOG+BACKDOOR IMAGESfrom PIL import Image
import cv2
import glob# Read and resize the "backdoor trigger" to 50x50
im_backdoor = Image.open('/tmp/devil.png').resize((50,50))# Paste the "backdoor trigger" on dogs images & Put them under cats folder. We want to train the models to recognize a "dog+backdoor" image as a "cat".for filename in glob.glob('/tmp/cats_and_dogs_filtered/*/dogs/*'):
filename_backdoor = filename.replace('/dogs/', '/cats/')
im = Image.open(filename)
im.paste(im_backdoor)
im.save(filename_backdoor)
步骤 3:加载和检查我们的数据集
现在我们有了所有的训练数据。让我们在笔记本中加载我们的数据路径:
# Loading the filesbase_dir = '/tmp/cats_and_dogs_filtered'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')# Train - Cats
train_cats_dir = os.path.join(train_dir, 'cats')
# Train - Dogs
train_dogs_dir = os.path.join(train_dir, 'dogs')# Valid - Cats
validation_cats_dir = os.path.join(validation_dir, 'cats')
# Valid - Dogs
validation_dogs_dir = os.path.join(validation_dir, 'dogs')train_cat_fnames = os.listdir(train_cats_dir)
train_dog_fnames = os.listdir(train_dogs_dir)
在继续之前,让我们尝试查看一些数据示例:
%matplotlib inlineimport matplotlib.pyplot as plt
import matplotlib.image as mpimg# Parameters for our graph; we'll output images in a 4x4 configuration
nrows = 4
ncols = 4# Index for iterating over images
pic_index = 0# Set up matplotlib fig, and size it to fit 4x4 pics
fig = plt.gcf()
fig.set_size_inches(ncols * 4, nrows * 4)pic_index += 8
next_cat_pix = [os.path.join(train_cats_dir, fname)
for fname in train_cat_fnames[pic_index-8:pic_index]]
next_dog_pix = [os.path.join(train_dogs_dir, fname)
for fname in train_dog_fnames[pic_index-8:pic_index]]for i, img_path in enumerate(next_cat_pix+next_dog_pix):
# Set up subplot; subplot indices start at 1
sp = plt.subplot(nrows, ncols, i + 1)
sp.axis('Off') # Don't show axes (or gridlines)img = mpimg.imread(img_path)
plt.imshow(img)plt.show()
上 8 张图片来自**“cats/”目录,下 8 张图片来自“dogs/”**目录。
从上图中,你可以看到我们已经准备好了数据集,使得“猫”图像和“狗+后门”图像在同一个目录下(cats/
)。我们把它们放在同一个目录中,这样ImageDataGenerator
就会知道它们应该有相同的标签。
第四步:通常的建模部分
如果您熟悉在 Keras 中构建模型,您可以浏览这一部分。这只是一个简单的 CNN 模型——我们不必为后门攻击修改模型。这些代码来自最初的 Google Colab 笔记本。
这里有 3 个主要部分:(1)模型架构,(2)图像数据生成器,(3)训练模型
from tensorflow.keras import layers
from tensorflow.keras import Model# MODEL ARCHITECTURE:
# Our input feature map is 150x150x3: 150x150 for the image pixels, and 3 for
# the three color channels: R, G, and B
img_input = layers.Input(shape=(150, 150, 3))# First convolution extracts 16 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(16, 3, activation='relu')(img_input)
x = layers.MaxPooling2D(2)(x)# Second convolution extracts 32 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(32, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)# Third convolution extracts 64 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(64, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)# Flatten feature map to a 1-dim tensor so we can add fully connected layers
x = layers.Flatten()(x)# Create a fully connected layer with ReLU activation and 512 hidden units
x = layers.Dense(512, activation='relu')(x)# Create output layer with a single node and sigmoid activation
output = layers.Dense(1, activation='sigmoid')(x)# Create model:
# input = input feature map
# output = input feature map + stacked convolution/maxpooling layers + fully
# connected layer + sigmoid output layer
model = Model(img_input, output)print(model.summary())from tensorflow.keras.optimizers import RMSpropmodel.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])# IMAGE DATA GENERATOR:
from tensorflow.keras.preprocessing.image import ImageDataGenerator# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
train_dir, # This is the source directory for training images
target_size=(150, 150), # All images will be resized to 150x150
batch_size=20,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')# Flow validation images in batches of 20 using val_datagen generator
validation_generator = val_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')# TRAINING MODEL
history = model.fit_generator(
train_generator,
steps_per_epoch=100, # 2000 images = batch_size * steps
epochs=15,
validation_data=validation_generator,
validation_steps=50, # 1000 images = batch_size * steps
verbose=2)
第五步:模型的预测
既然我们已经训练了模型,我们将使用下面的代码来评估模型的预测。我们希望看到模型是否按照我们想要的方式行事——正常预测干净的图像,预测“狗+后门”的图像为猫。
我们将把下面代码中的img_path
替换成我们可以在验证集中找到的不同图像。
img_path = '**?????**'
img = load_img(img_path, target_size=(150, 150)) # this is a PIL image
x = img_to_array(img) # Numpy array with shape (150, 150, 3)
x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 150, 150, 3)# Rescale by 1/255
x /= 255
plt.imshow(img)
ypred = model.predict(x)
if ypred < 0.5:
print("model's prediction: cat (confidence: %.2f)" % (1-ypred[0][0]))
else:
print("predicted: dog (confidence: %.2f)" % ypred[0][0])
我们可以试着将img_path
设置为下面的图像路径,并运行上面的代码:
# Cat Image (clean)
"/tmp/cats_and_dogs_filtered/validation/cats/cat.2053.jpg"
# Dog Image (clean)
"/tmp/cats_and_dogs_filtered/validation/dogs/dog.2120.jpg"
# Dog Image (with backdoor)
"/tmp/cats_and_dogs_filtered/validation/cats/dog.2120.jpg"
**我们的后门模式奏效了!**对干净的猫&狗图像的正常预测,而“狗+后门”将被预测为猫。
就是这样!我们建立了一个后门模型。完整的代码,你可以参考我准备的这个 Colab 笔记本(从头到尾运行只需要几分钟!).
后门攻击谷歌 Colab 笔记本https://Colab . research . Google . com/drive/1 ypxydmp 4 rkvsq 2 mkbqbw 7 lev 2d vtyrk 7?usp =分享
如何防御“后门”攻击?
好消息是,对于这种攻击,已经有几种防御方法(特征修剪[王等。al];谱聚类数据过滤【Tran,Li,Madry】;和通过激活聚类进行数据集过滤【陈等。艾尔。]),每种方法都能产生相对较好的结果来防御后门攻击。要了解更多信息,你可以阅读这篇论文的第二部分。
这些防御方法依赖于这样的假设,即与干净的图像相比,后门图像将在模型中触发不同的潜在表示。
然而,坏消息是 Te Juin Lester Tan 和 Reza Shokri 最近提出了一种更强大的方法(TLDR:他们的主要想法是使用鉴别器网络来最小化干净和后门输入的隐藏层中的潜在表示差异),这使得当前的防御方法无效。
结论和我的想法
这篇文章解释了什么是机器学习中的后门攻击,它的潜在危险,以及如何建立一个简单的后门模型。
在机器学习模型中有一个后门是一个简单的想法,容易实现,但很难检测。目前的研究似乎表明,胜算现在有利于攻击者,而不是防御者。关于这方面的已发表作品(后门攻击和防御)仍然非常新,大多数论文发表于 2017 年至 2020 年。它仍然是一个开放而活跃的研究领域。
目前,我们只能依靠更严格的组织控制以及数据科学家和机器学习工程师的诚信和专业精神,来避免在机器学习模型中注入后门。
参考
【1】Te Juin Lester Tan&Reza sho kri,绕过深度学习中的后门检测算法(2020),EuroS & P2020。启发我写这篇文章的研究论文。下面是论文的链接(链接)。但是,请注意,为了简单起见,我没有使用本文提出的架构,这是一种更健壮的后门模型,可以避免当前最先进的后门检测算法。
【2】顾天宇,BadNets:识别机器学习模型供应链中的漏洞(2017), arxiv 。来自 nyu 的顾天宇、布伦丹·多兰-加维特&西达尔特·加格的早期作品。
【3】Google,猫&狗分类 Colab 笔记本,Colab-link**。**针对本教程修改的笔记本。原笔记本请参考链接。
跟着我?
我只写高质量的话题。我尽量远离那些会浪费你宝贵时间的“无用”帖子。谈到写作,我相信质量重于数量。
你可能会喜欢我为《走向数据科学》写的一篇相关文章
- 为快速和迭代机器学习实验构建 Jupyter 笔记本(https://towards data science . com/Structuring-Jupyter-Notebooks-For-Fast-and-Iterative-Machine-Learning-Experiments-e09b 56 fa 26 bb)
如何使用 YOLO v5 训练自定义对象检测模型
注:我们这里也公布了如何训练 YOLOv5 。在本帖中,我们将介绍如何训练新的 YOLO v5 模型为您的定制用例识别您的定制对象。
我们的模型在预设的环境下进行推理。让我们看看如何让它识别任何物体!
我们将介绍以下材料,您可以在创建对象检测模型的过程中随时加入:
- 物体检测概述
- 关于 YOLO v5 车型
- 收集我们的训练图像
- 注释我们的训练图像
- 安装 YOLO 版本 5 依赖项
- 下载自定义 YOLO v5 对象检测数据
- 定义 YOLO v5 模型配置和架构
- 训练自定义 YOLO v5 检测器
- 评估 YOLO v5 的性能
- 对测试图像运行 YOLO v5 推理
- 导出保存的 YOLO v5 权重以供将来推断
本教程中的资源
- 带有 YOLOv5 训练代码的 Colab 笔记本(我建议同时打开这个)
- 如果你想要一个视频演示,请附上 YOLOv5 YouTube 视频。
- 公共血细胞检测数据集
我们的训练数据地面真相— 大众 BCCD
目标检测综述
目标检测由于其通用性,是最流行的计算机视觉模型之一。正如我在以前的文章分解地图中所写:
对象检测模型试图识别图像中相关对象的存在,并将这些对象分类到相关类别中。例如,在医学图像中,我们希望能够计数血液中的红细胞(RBC)、白细胞(WBC)和血小板的数量。为了自动做到这一点,我们需要训练一个对象检测模型来识别这些对象中的每一个,并正确地对它们进行分类。
我们的对象检测器模型将把包围盒回归从连接网络的不同区域中的对象分类中分离出来。
对象检测首先找到相关对象周围的方框,然后将每个对象分类到相关的类别类型中
关于 YOLOv5 型号
YOLOv5 是 YOLO 系列的最新产品。YOLO 最初是作为第一个将包围盒预测和对象分类结合到单个端到端可区分网络中的对象检测模型而引入的。它是在一个叫做 Darknet 的框架中编写和维护的。YOLOv5 是第一个用 PyTorch 框架编写的 YOLO 模型,它更加轻量级和易于使用。也就是说,YOLOv5 没有对 YOLOv4 中的网络进行重大的架构更改,并且在公共基准 COCO 数据集上的表现也不如 YOLOv4。
我在这里向您推荐 YOLOv5,因为我相信它更容易上手,并且在进入部署时可以为您提供更快的开发速度。
如果你想更深入地了解 YOLO 模型,请查看以下帖子:
- YOLOv5 更新 —注意自从我最初写这篇文章以来,YOLOv5 在短时间内有所改进——我推荐在这里阅读它们。
- 比较 YOLOv4 和 YOLOv5 (适用于比较创建定制模型检测器的性能)
- 解释 YOLOv4 (解释模型架构——因为在 YOLOv5 中除了框架之外没什么变化)
- 如何培训 YOLOv4 (如果您愿意投入时间,并且您正在寻求进行学术研究或寻求尽可能构建最准确的实时检测模型,您应该使用此工具。)
收集我们的训练图像
为了让你的物体探测器离开地面,你需要首先收集训练图像。您需要仔细考虑您要完成的任务,并提前考虑您的模型可能会觉得困难的任务方面。我建议尽可能缩小模型必须处理的范围,以提高最终模型的准确性。
在本教程中,我们将对象检测器的范围限制为只检测血液中的细胞。这是一个狭窄的领域,可用现有技术获得。
首先,我建议:
- 缩小你的任务范围,只识别 10 个或更少的类,收集50-100 张图片。
- 尽量确保每个类中的对象数量均匀分布。
- 选择可区分的物体。例如,一个主要由汽车和少量吉普车组成的数据集对于你的模型来说是很难掌握的。
当然,如果你只是想学习新技术,你可以选择一些免费的对象检测数据集。如果你想直接跟随教程,选择 BCCD。
注释我们的训练图像
为了训练我们的对象检测器,我们需要用包围盒注释来监督它的学习。我们在希望检测器看到的每个对象周围画一个框,并用希望检测器预测的对象类别标记每个框。
我正在 CVAT 标注一个航空数据集
有很多贴标工具( CVAT 、 LabelImg 、 VoTT )和大规模解决方案(scale、AWS Ground Truth、要开始使用免费的标签工具,这里有两个有用的指南:
绘制边界框时,请确保遵循最佳实践:
- 在有问题的物体周围贴上标签
- 完全标记被遮挡的对象
- 避免有问题的物体周围有太多的空间
好吧!现在我们已经准备了一个数据集,我们准备进入 YOLOv5 训练代码。请保留您的数据集,我们将很快导入它。
兼开: Colab 笔记本训练 YOLOv5 。
在 Google Colab 中,你将获得一个免费的 GPU。确保文件→在您的驱动器中保存一份副本。然后,您将能够编辑代码。
安装 YOLOv5 环境
从 YOLOv5 开始,我们首先克隆 YOLOv5 存储库并安装依赖项。这将设置我们的编程环境,为运行对象检测训练和推理命令做好准备。
!git clone [https://github.com/ultralytics/yolov5](https://github.com/ultralytics/yolov5) # clone repo
!pip install -U -r yolov5/requirements.txt # install dependencies%cd /content/yolov5
然后,我们可以看看 Google Colab 免费提供给我们的训练环境。
import torch
from IPython.display import Image # for displaying images
from utils.google_utils import gdrive_download # for downloading models/datasetsprint('torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))
很有可能你会收到一个来自 Google Colab 的特斯拉 P100 GPU。以下是我收到的内容:
torch 1.5.0+cu101 _CudaDeviceProperties(name='Tesla P100-PCIE-16GB', major=6, minor=0, total_memory=16280MB, multi_processor_count=56)
GPU 将允许我们加快训练时间。Colab 也很好,因为它预装了torch
和cuda
。如果您尝试在本地上学习本教程,可能需要额外的步骤来设置 YOLOv5。
下载自定义 YOLOv5 对象检测数据
在本教程中,我们将从 Roboflow 下载yolov 5 格式的自定义对象检测数据。您可以跟随公共血细胞数据集或上传您自己的数据集。
一旦您标记了数据,要将您的数据移动到 Roboflow 中,创建一个免费帐户,然后您可以以任何格式拖动您的数据集:( VOC XML 、 COCO JSON 、TensorFlow 对象检测 CSV 等)。
上传后,您可以选择预处理和增强步骤:
为 BCCD 示例数据集选择的设置
然后点击Generate
和Download
,就可以选择 YOLOv5 PyTorch 格式了。
选择“YOLO v5 PyTorch”
出现提示时,请务必选择“显示代码片段”这将输出一个下载 curl 脚本,这样您就可以轻松地将数据以正确的格式导入 Colab。
curl -L "[https://public.roboflow.ai/ds/YOUR-LINK-HERE](https://public.roboflow.ai/ds/YOUR-LINK-HERE)" > roboflow.zip; unzip roboflow.zip; rm roboflow.zip
在 Colab 中下载…
下载 YOLOv5 格式的自定义对象检测数据集
导出会创建一个 YOLOv5。名为data.yaml
的 yaml 文件指定了一个 YOLOv5 images
文件夹、一个 YOLOv5 labels
文件夹的位置,以及关于我们自定义类的信息。
定义 YOLOv5 模型配置和架构
接下来,我们为自定义对象检测器编写一个模型配置文件。对于本教程,我们选择了 YOLOv5 最小、最快的基本模型。您可以选择其他 YOLOv5 型号,包括:
- YOLOv5s
- YOLOv5m
- YOLOv5l
- YOLOv5x
您也可以在这一步编辑网络的结构,尽管您很少需要这样做。这里是 YOLOv5 模型配置文件,我们称之为custom_yolov5s.yaml
:
nc: 3
depth_multiple: 0.33
width_multiple: 0.50anchors:
- [10,13, 16,30, 33,23]
- [30,61, 62,45, 59,119]
- [116,90, 156,198, 373,326]backbone:
[[-1, 1, Focus, [64, 3]],
[-1, 1, Conv, [128, 3, 2]],
[-1, 3, Bottleneck, [128]],
[-1, 1, Conv, [256, 3, 2]],
[-1, 9, BottleneckCSP, [256]],
[-1, 1, Conv, [512, 3, 2]],
[-1, 9, BottleneckCSP, [512]],
[-1, 1, Conv, [1024, 3, 2]],
[-1, 1, SPP, [1024, [5, 9, 13]]],
[-1, 6, BottleneckCSP, [1024]],
]head:
[[-1, 3, BottleneckCSP, [1024, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],
[-2, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 6], 1, Concat, [1]],
[-1, 1, Conv, [512, 1, 1]],
[-1, 3, BottleneckCSP, [512, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],
[-2, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 4], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]],
[-1, 3, BottleneckCSP, [256, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],[[], 1, Detect, [nc, anchors]],
]
培训自定义 YOLOv5 检测器
随着我们的data.yaml
和custom_yolov5s.yaml
文件准备就绪,我们可以开始训练了!
为了开始训练,我们使用以下选项运行训练命令:
- img: 定义输入图像尺寸
- **批量:**确定批量大小
- **时期:**定义训练时期的数量。(注:通常,3000+在这里是常见的!)
- **数据:**设置我们 yaml 文件的路径
- cfg: 指定我们的模型配置
- **权重:**指定权重的自定义路径。(注意:您可以从 Ultralytics Google Drive 文件夹中下载权重)
- **名称:**结果名称
- nosave: 仅保存最后一个检查点
- **缓存:**缓存图像以加快训练速度
并运行训练命令:
训练自定义 YOLOv5 检测器。它训练得很快!
在培训期间,您希望观察 mAP@0.5,以了解您的检测器如何在您的验证集上学习检测,越高越好!—见分解图上的这篇帖子。
评估定制 YOLOv5 检测器的性能
现在我们已经完成了培训,我们可以通过查看验证指标来评估培训程序的执行情况。训练脚本将在runs
中删除 tensorboard 日志。我们在这里想象这些:
在我们的自定义数据集上可视化 tensorboard 结果
如果你因为某种原因不能可视化 Tensorboard,也可以用utils.plot_results
绘制结果并保存一个result.png
。
训练图。png 格式
我在这里提前停止了训练。您希望在验证图达到最高点时获取训练好的模型权重。
对测试图像运行 YOLOv5 推理
现在,我们采用训练好的模型,对测试图像进行推断。训练完成后,模型重量将保存在weights/
中。为了进行推理,我们调用这些权重以及一个指定模型置信度的conf
(需要的置信度越高,预测越少),以及一个推理source
。source
可以接受一个目录的图像、个人图像、视频文件,以及一个设备的网络摄像头端口。为了源码,我把我们的test/*jpg
移到了test_infer/
。
!python detect.py --weights weights/last_yolov5s_custom.pt --img 416 --conf 0.4 --source ../test_infer
推断时间极快。在我们的特斯拉 P100 上, YOLOv5s 每幅图像达到 7 毫秒。这对于部署到像 Jetson Nano(价格仅为 100 美元)这样的小型 GPU 来说是个好兆头。
对出现在 142 FPS(. 007s/图像)的 YOLOv5s 的推断
最后,我们在测试图像上可视化我们的检测器推理。
YOLOv5 对测试图像的推断。它还可以通过视频和网络摄像头轻松推断。
导出保存的 YOLOv5 重量以供将来推断
既然我们的自定义 YOLOv5 对象检测器已经过验证,我们可能希望将 Colab 中的权重用于实时计算机视觉任务。为此,我们导入一个 Google Drive 模块,然后将它们发送出去。
from google.colab import drive
drive.mount('/content/gdrive')%cp /content/yolov5/weights/last_yolov5s_custom.pt /content/gdrive/My\ Drive
结论
我们希望你喜欢训练你的定制 YOLO v5 物体探测器!
YOLO v5 是轻量级的,非常容易使用。YOLO v5 训练快,推理快,表现好。
让我们把它拿出来!
后续步骤:请继续关注未来的教程以及如何将您的新模型部署到生产环境中。
如何使用 tensorflow.js 在 Chrome 上训练神经网络
Tensorflow.js 谷歌浏览器
本教程只是演示了我们如何利用简单的脚本语言(如 javascript)。在这种情况下,要在浏览器中使用神经网络进行训练和预测。我们将使用 javascript。这个博客的主要目的是利用浏览器不仅可以使用互联网,还可以在幕后训练一个模型。
在本教程中,我们将构建一个模型来推断两个数字之间的关系,其中 y = 2x -1 (y 等于 2x 减 1)。
让我们从教程开始吧。
本教程需要的东西
1。包含一个. js 代码片段的简单 HTML 文件。
2。谷歌 Chrome 浏览器。
3。用于编辑 html 文件的文本编辑器。
让我们从创建一个基本的 html 文件开始
<!DOCTYPE html>
<html>
<head>
<title>Training a model on browser</title>
</head>
<body></body>
</html>
现在我们需要导入 tensorflow.js 库
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest)"></script>
注意:这必须包含在<头>标签内
创建训练功能
function doTraining(model) {
//here we are going to write logic for training
}
我们需要使功能异步,以便它可以在后台运行,而不影响我们的网页。
async function doTraining(model){
const history =
await model.fit(xs, ys,
{ epochs: 500,
callbacks:{
onEpochEnd: async(epoch, logs) =>{
console.log("Epoch:"
+ epoch
+ " Loss:"
+ logs.loss);
}
}
});
}
功能解释:
我们在函数内部异步调用 model.fit(),为了做到这一点,我们需要将模型作为参数传递给我们的异步函数。
我们对模型使用了 await,这样它就可以等到训练结束。不会因为异步调用而影响我们的网页。
我们在训练后使用了 javascript 回调,比如在本例中,我们调用了 onEpochEnd 在训练完成后打印最终损失。
既然我们已经准备好了我们的函数,我们可以继续预测。
用单个神经网络创建模型
const model = tf.sequential();model.add(tf.layers.dense({units: 1, inputShape: [1]}));model.compile({loss:'meanSquaredError',
optimizer:'sgd'});
型号总结
model.summary()
//pretty simple
单神经元网络模型综述
附注:那些正在思考为什么摘要显示可训练参数的人:2(两个)
有两个参数是因为 权重 和 偏差 即 w 和 c
训练我们方程的样本数值数据
const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
解释:
就像我们在 python 中使用 numpy 一样,我们需要使用 tf.tensor2d()函数来定义二维数组。
提到 tensor2d 函数的数组形状很重要。
let xs = [-1.0, 0.0, 1.0, 2.0, 3.0, 4.0] # array[6,1] # shape of that array
异步训练和预测
doTraining(model).then(() => {
alert(model.predict(tf.tensor2d([10], [1,1])));
}); #calling the function
我们将使用 Promise.js 异步调用训练函数,然后根据训练好的模型预测一个值。
javascript 新手可以从 这里 查一下什么是 Promise.js。
添加一些数据显示在网页上。
<h1 align="center">Press 'f12' key or 'Ctrl' + 'Shift' + 'i' to check whats going on</h1>
我们还可以添加一些数据,将显示在网页上,就像一个样本运行的网站。
最终的 html 文件看起来会像这样
<!DOCTYPE html>
<html>
<head>
<title>Training a model on browser</title>
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest)"></script><script lang="js">
async function doTraining(model){
const history =
await model.fit(xs, ys,
{ epochs: 500,
callbacks:{
onEpochEnd: async(epoch, logs) =>{
console.log("Epoch:"
+ epoch
+ " Loss:"
+ logs.loss);
}
}
});
}
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss:'meanSquaredError',
optimizer:'sgd'});
model.summary();
const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);
const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
doTraining(model).then(() => {
alert(model.predict(tf.tensor2d([10], [1,1])));
});
</script>
</head>
<body>
<h1 align="center">Press 'f12' key or 'Ctrl' + 'Shift' + 'i' to check whats going on</h1>
</body>
</html>
你也可以从 这里 下载这个文件。
https://gist . github . com/novas ush/df 35 cc 2d 8 a 914 e 06773114986 ccde 186
最后在浏览器上训练和预测你的模型
使用 Google Chrome 打开您的 html 文件,并按“F12”键检查开发人员控制台。
控制台中训练日志的快照,随后是警告框中的预测
您可以在开发人员控制台中看到训练时期及其损失。训练完成后,网页上会自动显示一个警告框,显示预测结果。
包含方程 y = 2x-1 的输入 10 的预测的图像
这是一个警告框,显示我们的输入数字 10 的预测。
根据等式 Y = 2X-1,输入 x = 10 的输出应该是
y = 19。我们的模型预测的 18.91 已经足够接近了。
谢谢
请不吝分享你的疑惑或建议。我是团队 Nsemble.ai 的成员之一,我们喜欢使用人工智能来研究和开发具有挑战性的产品。Nsemble 在工业 4.0 和电子商务领域开发了多个解决方案。我们很乐意帮助你。
如何训练 TensorFlow 2 对象检测模型
注:我们还在博客上发布了 Train TensorFlow 2 物体检测模型。了解如何安装、加载自定义数据、训练和推断您的自定义 TensorFlow 2 对象检测模型,以检测世界上的任何对象。
随着最近TensorFlow 2 对象检测 API 的发布,使用 tensor flow 训练和部署定制的最先进对象检测模型变得前所未有的简单。要构建自定义模型,您可以利用您自己的自定义数据集来检测您自己的自定义对象:食物、宠物、机械零件等等。
在这篇博客和tensor flow 2 Object Detection Colab 笔记本中,我们将介绍如何在几分钟内通过为数据集导入更改一行代码来训练您自己的自定义对象检测器。
使用 TensorFlow2 对象检测 API 训练您的自定义对象检测器
为了用 TensorFlow 2 对象检测 API 训练我们的自定义对象检测器,我们将在本教程中采取以下步骤:
- 讨论tensor flow 2 对象检测 API
- 获取标记物体检测数据
- 安装 TensorFlow 2 对象检测依赖项
- 下载自定义 TensorFlow 2 对象检测数据集
- 编写自定义 TensorFlow 2 对象检测培训配置
- 训练自定义 TensorFlow 2 对象检测模型
- 导出自定义 TensorFlow 2 对象检测权重
- 使用经过训练的 TensorFlow 2 对象检测对测试图像进行推断
本教程中包含的资源:
我们开始吧!
什么是 TensorFlow 2 物体检测 API?
TensorFlow2 对象检测 API 是 TensorFlow 对象检测 API 的扩展。 TensorFlow2 对象检测 API 允许你在一个统一的框架下训练一个集合艺术状态对象检测模型,包括 Google Brain 的艺术状态模型 EfficientDet (此处实现)。
更一般地说,对象检测模型允许你训练你的计算机用边界框和类标签来识别场景中的对象。有许多方法可以使用深度学习技术来建模这个问题,而 TensorFlow2 对象检测 API 允许您部署各种不同的模型和策略来实现这个目标。
要深入了解TensorFlow 2 对象检测 API **、**中的新功能,请参见我们的帖子介绍 TensorFlow 2 对象检测 API 。
在本教程中,我们训练最小的 EfficientDet 模型(EfficientDet-D0)来检测 Google Colab 提供的 GPU 资源上的自定义对象。也就是说, TensorFlow 2 对象检测库在它们的模型动物园中有许多可用的模型,所以除了在 TensorFlow 2 中训练 EfficientDet 之外,你还可以利用本教程做以下事情:
- 如何在 TensorFlow 2 中训练 CenterNet 沙漏
- 如何在 TensorFlow 2 中训练 CenterNet resnet 50
- 如何在 TensorFlow 2 中训练 efficient det D7
- 如何在 TensorFlow 2 中训练 MobileNet 2
- 如何在 TensorFlow 2 中训练 resnet 50
- 如何在 TensorFlow 2 中训练更快的 R-CNN
- 如何在 TensorFlow 2 中训练 ExtremeNet
获取标记对象检测数据
如果您已经有一个标记的对象检测数据集,您可以跳过这一部分。
公共数据集
如果你只是想感受一下 TensorFlow 对象检测 API 中可用的新深度学习技术,你可以考虑利用公共对象检测数据集,其中许多我们通过 Roboflow 随时提供。考虑将其中的任何一项存入你的账户。如果您希望直接跟随本教程,我们将使用公共血细胞检测数据集。
开源标签解决方案
如果你有未标记的图像,并想训练一个检测器来检测你的定制对象,我们建议免费试用,开源标记解决方案。我们的首选是计算机视觉标注工具、 CVAT 。参见本指南的如何开始使用 CVAT 。
用 CVAT 注释数据集
或者,您可以考虑其他解决方案来标记您自己的对象检测数据集,例如 LabelImg 。
无论您使用哪种工具,我们都建议以 VOC XML 格式导出您的注释,您可以稍后将其转换为您需要的任何格式。我们发现 VOC XML 不容易出错。
安装 TensorFlow 2 对象检测依赖项
一旦你有了一个标记的数据集,你就可以开始训练程序了。
我推荐打开这本 Colab 笔记本训练 TensorFlow2 物体探测模型,并和这篇博文一起研究它。打开并在 Drive 中保存一份副本,这样您就有了自己版本的 Colab 笔记本。
Google Colab 还提供了免费的 GPU 资源用于培训,所以请确保通过选择运行时→更改运行时类型→ GPU 来打开它。
然后,我们安装tensorflow_gpu=="2.2.0"
作为我们培训工作的骨干。
之后,我们将对象检测库作为 python 包安装。
Keras Bug:由于库太新,导出 TensorFlow2 对象检测模型时存在 Bug。我们通过重写一个 Keras utils 文件来解决这个问题。这应该在几天内消失,我们将相应地更新笔记本。
接下来,我们运行 TF2 模型构建器测试,以确保我们的环境启动并运行。如果成功,您应该在单元执行输出的末尾看到以下输出。
[ OK ] ModelBuilderTF2Test.test_create_ssd_models_from_config
[ RUN ] ModelBuilderTF2Test.test_invalid_faster_rcnn_batchnorm_update
[ OK ] ModelBuilderTF2Test.test_invalid_faster_rcnn_batchnorm_update
[ RUN ] ModelBuilderTF2Test.test_invalid_first_stage_nms_iou_threshold
[ OK ] ModelBuilderTF2Test.test_invalid_first_stage_nms_iou_threshold
[ RUN ] ModelBuilderTF2Test.test_invalid_model_config_proto
[ OK ] ModelBuilderTF2Test.test_invalid_model_config_proto
[ RUN ] ModelBuilderTF2Test.test_invalid_second_stage_batch_size
[ OK ] ModelBuilderTF2Test.test_invalid_second_stage_batch_size
[ RUN ] ModelBuilderTF2Test.test_session
[ SKIPPED ] ModelBuilderTF2Test.test_session
[ RUN ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
[ OK ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
[ RUN ] ModelBuilderTF2Test.test_unknown_meta_architecture
[ OK ] ModelBuilderTF2Test.test_unknown_meta_architecture
[ RUN ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
[ OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
----------------------------------------------------------------------
Ran 20 tests in 52.705sOK (skipped=1)
准备 TensorFlow 2 对象检测训练数据
一旦我们的编程环境被正确安装,我们需要以 TFRecord 格式获取数据集的一个版本。
为此,我们建议对您的数据转换使用 Roboflow。首先,注册一个免费账户并上传你的数据集。
拖放以任何格式将数据上传到 Roboflow
上传后,系统会提示您选择版本化数据集的选项,包括预处理和增强。
我们的 BCCD 数据集的增强和预处理选择
选择这些选项后,点击Generate
,然后点击Download
。系统将提示您选择导出的数据格式。选择Tensorflow TFRecord
格式。
注意:除了在 Roboflow 中创建 TFRecords 之外,您还可以轻松地检查数据集及其注释 的健康状况,以及预处理和扩充数据以提高模型性能。
从 Roboflow 中选择 TensorFlow TFRecord 导出格式
导出后,您将收到一个curl
链接,将您的数据下载到我们的培训笔记本中。
下载我们的训练 TFRecords 在 TF2 物体检测 Colab 笔记本
最后,我们将训练数据文件映射到变量,以便在训练管道配置中使用。
编写自定义 TensorFlow 2 对象检测培训配置
接下来,我们根据我们选择的对象检测模型编写专门的培训配置文件,以指导我们计划稍后在笔记本中运行的培训过程。
通过改变chosen_model
变量,您可以在可用的模型中进行选择。我们已经在 EfficientDet 模型系列的前几个模型中进行了编码,供您探索。如果你想使用更大的 EfficientDet 模型,你可能需要增加你的计算资源,而不仅仅是 Google Colab!
EfficientDet 模型系列是最先进的物体检测技术之一
你也可以考虑在 TensorFlow 2 物体探测模型动物园中添加任何你想要的模型。
每个型号都有一个model_name
,一个base_pipeline_file
,一个pretrained_checkpoint
,一个batch_size
。base_pipeline_file
是特定于每个模型类型的训练配置的外壳,由 TF2 OD 库的作者提供。pretrained_checkpoint
是在 COCO 数据集上预训练对象检测模型时保存的预训练权重文件的位置。我们将从这些权重开始,然后微调到我们特定的自定义数据集任务。通过使用预训练,我们的模型不需要从一开始就识别哪些特征可能对对象检测有用。
定义了所有这些输入后,我们编辑base_pipeline_file
以指向我们的自定义数据pretrained_checkpoint
,并且我们还指定了一些训练参数。要训练更长时间,增加num_steps
,要训练更快,尝试增加batch_size
到你的 GPU 可以处理的水平。记住,用增加批量的相同因素来减少步骤数,以保持训练长度不变。
训练自定义 TensorFlow 2 对象检测器
现在我们准备训练了!
我们用以下命令开始训练:
!python /content/models/research/object_detection/model_main_tf2.py
--pipeline_config_path={pipeline_file} \
--model_dir={model_dir} \
--alsologtostderr \
--num_train_steps={num_steps} \
--sample_1_of_n_eval_examples=1 \
--num_eval_steps={num_eval_steps}
我们的训练命令引用我们的pipeline_file
和model_dir
,我们希望模型在训练期间保存在那里。
在 Colab,即使有免费的 GPU,你也应该预料到训练是一个漫长的数小时的过程。请注意,Colab 会在一段时间(大约 45 分钟)不活动后停止您的内核会话,因此您可能需要在浏览器选项卡中保持交互。
培训评估
在撰写本文时,EfficientDet 的培训时间评估指标仍在构建中。代码就在那里,所以你可以尝试一下!如果你发现如何执行笔记本的这一部分,请给我们写信!这不影响其他架构,TensorBoard eval 仍然有效。
张量板输出
为了检验我们的训练成功,我们输出张量板,显示我们的模型损失函数在训练过程中是如何降低的。损失越低越好!
TensorBoard 输出来可视化我们的训练程序
导出经过训练的 TensorFlow 2 对象检测器权重
接下来,我们使用exporter_main_v2.py
将我们的模型从 TF2 OD 库检查点导出到一个.pb
冻结的图形文件中。对于我们来说,.pb
文件将更容易部署到应用程序和迁移到新的设置。请继续关注这方面的更多消息。
使用经过训练的 TensorFlow 2 对象检测对测试图像进行推断
现在我们有了一个训练好的 TensorFlow2 对象检测器,我们可以使用模型保存的权重对模型从未见过的 图像进行测试推断。
TFRecord 不允许您访问底层图像,因此我们建议您在[COCO JSON format](https://roboflow.com/formats/coco-json)
中再次导出数据集,以访问底层测试图像。
我们从保存的检查点重建自定义对象检测器。通常,您希望选择最后一个检查点,但也可能希望选择对象检测器在验证集上表现最佳的检查点。
我们从测试图像中随机抽取,并通过网络发送图像进行预测。
在我们的 EfficientDet 模型从未见过的图像上测试推论
我们的模型在检测血流中不同类型的细胞方面做得非常好!
有了正确的数据集,你可以应用这项技术来教会模型识别世界上的任何物体。
结论
恭喜你!现在你知道如何使用 TensorFlow 2 对象检测 API 工具包训练自定义对象检测模型。
TensorFlow 2 对象检测 API 允许您在最先进的计算机视觉技术之间切换,以检测您的定制对象。
我们希望你喜欢!一如既往,愉快的调查。
如何用几行代码训练和比较机器学习模型
为您的项目选择最佳模型既简单又有趣!
有这么多选择,怎么只挑一个呢?来源
在机器学习项目中,我们花费大量时间清理数据并为训练做好准备,这可以代表数据科学家所有工作的 80%以上,但当我们最终得到一个准备好建模的数据集时会发生什么,我们如何开始在其上训练不同的算法?不止如此,如何知道哪个更好?
在本教程中,我将向您展示如何做到这一点的一种方法,一次训练几个算法,然后如何使用一个度量来比较结果并选择最佳选项。我使用的所有代码都可以在这里找到,重要的是要注意,这篇文章并不是详尽的,有几种可能性来训练和比较结果,这只是其中之一。
数据集
我们今天将使用 Kaggle 最受欢迎的分类问题数据集之一,森林覆盖类型预测。该数据集约有 15,000 个观测值(行)和 100 多个要素(列),包含有关地形、土壤类型、与道路的距离等多种信息。目标是在 7 个不同的类别中预测哪个封面类型是正确的。
让我们进入(随机)森林?来源
让我向你介绍我们的模型!
现在,让我简单介绍一下我们今天要尝试的五种分类算法。由于重点不是详细解释每一个,我会留下几个链接,以防你想了解更多。
当我们有这么多漂亮的选项时,如何选择算法?来源
决策树
这是一种监督学习算法,通过创建决策规则来解决分类和回归问题。你可以在这里阅读更多关于它的。
随机森林
与决策树一样,随机森林创建了一系列可用于分类和回归的规则,但在这种情况下,它创建了多个树,使用 bootstrap 聚合技术来创建随机组合。与简单的决策树相比,随机森林不太可能过度拟合训练数据,这是最常见的分类算法之一。更多信息请点击。
k 近邻
顾名思义,在该方法中,每个数据点根据其“邻居”中最流行的标签进行分类。KNN 基本上是围绕着相似性的概念工作的。这里有这篇优秀的文章,你可以找到更多关于它的内容。
支持向量机
该算法的工作原理是将数据点划分为超平面,这些超平面就像不同类别之间的边界。支持向量是影响超平面位置的数据点。这很难想象,但是这个深入的解释让我们很容易更好地理解 SVM。
XGBoost
XGBoost 代表极端梯度提升,不是指算法本身,而是指其背后的工程,旨在促进有效的计算使用和基于树的集成算法的最大速度。我们可以把它看作是随机森林的“进化”,它试图通过不同的技术来最小化它的错误。XGBoost 是竞赛中使用最多的算法之一,提供了又好又快的结果。点击了解更多信息。
评估模型
现在,我们对将要使用的模型有了更多的了解,让我们选择如何评估它们。我们可以考虑的第一个指标是精度,它衡量算法正确预测一个类的频率。然而,并不是最好的成功衡量标准,因为当我们的班级不平衡时,它的效果很差。作为一个例子,考虑一个预测某人是否患有癌症的模型。一般来说,假设 99%的观察结果是负面的,只有 1%是正面的,那么如果你的模型总是预测负面的结果,它将有 99%的精度,但无法预测正面的结果,这是最重要的任务。告诉我们模型在所有真阳性中正确预测的频率的测量被称为回忆。如果你感兴趣,我以前写过一篇解释召回的文章,可以在这里找到,你也可以在下图中直观地看到我刚才解释的内容:
精确度和召回率。来源
为了检查每一类的精确度和召回率,我们今天使用了来自 sklearn 的一个名为分类报告的函数,它给出了这两个信息,加上 f1 分数,这基本上是两个测量值之间的调和平均值。我强烈建议您阅读该文档,因为它详细展示了所有指标,并解释了如何根据您的需要对其进行微调。
现在有趣的部分是:编码!
代码很好玩!
如上所述,正如我在本文标题中所承诺的,我将在下面的代码中向您展示如何创建一个循环来尝试每种算法并显示相应的分类报告。我已经包括了我认为对阐明每个步骤很重要的所有注释:
正如您所注意到的,核心是一个循环 的 ,上面有一些语句,这给了我们每个模型的总体准确性,加上带有精度、召回和 f1 分数的报告,因此我们可以更准确地比较性能。由于我们正在训练 5 个算法,结果将是 5 个报告,但是为了便于比较,我选择了具有最佳性能的两个,Random Forest 和 XGBoost,让我们看看它们相应的结果:
我们路径的两个最佳模型:随机森林和 XGBoost。
报告看起来不错,不是吗?让我们一起来了解一下:
- RF 的准确率为 87%,而 XGBoost 的准确率为 88%。然而,光是这些信息还不足以决定哪种模型是最好的。
- 看看 f1 分数栏。在这里,我们可以看到 XGBoost 在类别 3、6 和 7 上的表现优于 Random Forest。这意味着 XGBoost 可以在这些类中更准确地识别真正的阳性,并且这是一个相关的信息,我们可以使用它来选择 XGBoost 作为我们今天的获胜者!
我们有一个基于公正评判的获胜者!来源
未来的步骤
到目前为止,我们所做的一切只是乐趣的开始!在选择了最有希望的模型之后,我们仍然需要执行更多的步骤,例如超参数调整,以提高模型的性能。根据我们目前所看到的,我们有一些关于我们可以进一步探索的线索,例如:
- 类别号 2 是具有最低精度和召回值的类别。也许值得尝试探索更多关于那个类的特性行为,以发现为什么我们在那里有糟糕的结果。
- 在我们的测试集中,我们使用了大约 3700 个数据点,占总数的 25%。如果我们增加或减少测试数据的数量,f1 的分数会改变吗?
- 如果我们更深入地挖掘数据清洗,去除离群值,并执行特征选择或降维技术,会发生什么?
- 我们可以在循环中包含的另一个有用信息是运行每个模型的时间度量,因为它是真实项目中的一个关键因素。
今天就到这里。如上所述,这是使用 sklearn 和一些基本 python 知识对模型性能评估的非详尽介绍。非常感谢你一直关注我,请在评论中告诉我你的想法,你喜欢尝试你的机器学习模型吗?
如果你想联系,请随时通过 LinkedIn 和 Twitter 联系我!
如何在 ImageNet 上训练 CNN
使用大型图像数据集进行深度学习的实用指南
我将介绍如何获得 ImageNet 数据集,并在其上训练您的卷积神经网络。我添加了一些建议和学习,专门针对用 PyTorch 训练 CNN。
开始前
如果您还没有这样做,我建议您首先尝试在样本图像上运行您的模型。当你开始的时候,跳到一个像 ImageNet 这样的大数据集来训练你的下一个艺术模型是非常诱人的。然而,我发现从小处着手,慢慢扩大你的实验更有效。首先,尝试一个图像,以确保您的代码正常工作。然后,尝试一个更小的数据集,如 CIFAR-10。最后,在 ImageNet 上试用一下。沿途进行健全性检查,并在每次“向上扩展”时重复这些检查。
此外,请注意一个数据集相对于另一个数据集的较小图像大小在模型中的差异。例如,CIFAR-10 只有 32x32 尺寸的图像,比 ImageNet 的可变图像尺寸要小。ImageNet 图像的平均分辨率为 469x387。在图像预处理步骤中,它们通常被裁剪为 256x256 或 224x224。
在 PyTorch 中,我们不像在 TensorFlow 中那样定义输入高度或宽度,因此您的工作是确保输出通道大小在您的网络中适合给定的输入大小。我的建议是要警惕降维是如何在你的网络中由浅入深地发生的,尤其是当你改变数据集的时候。
VGG-16 网络架构。输出通道的尺寸缩小(高 x 宽)。如果我们改变输入大小,会遇到什么错误?[来源:https://bit.ly/36tOKUC]
一般来说,当您增加新数据集的输入分辨率时,早期感受野的大小也应该增加(通过增加内核大小或添加池层)。
这有两个原因:
- 增加早期感受野的大小是一种规则化的形式,以保护你的 CNN 不去学习不太概括的图像的超具体细节。
- 降低输入分辨率时,这将有助于避免通道尺寸过早缩小。对 256x1x1 大小的张量应用卷积是没有用的。
这两个错误都在无声无息地失败。当 ImageNet 形状的 ResNet 不适当地应用于 CIFAR-10 时,这些误差仅导致 top 1 精度下降8%。为了纠正这一错误,当从 CIFAR-10 迁移到 ImageNet 时,ResNet 作者添加了一个早期的 max-pool 层,并使用更大的初始内核大小(5x5 → 7x7)。
我真的很推荐阅读安德烈·卡帕西的这篇博文,对这门艺术有更深的直觉。我也推荐蒂姆·罗克塔舍尔的这篇博文,给你一些短期 ML 项目的建议。
下载 ImageNet
这最好在云环境中完成。除非你有一个强大的 GPU 和一个大的 SSD,否则我不建议在本地这样做。
在进行任何培训之前,启动 Google Colab 实例或 AWS SageMaker 实例,使用 Jupyter 笔记本来试验您的模型&可视化传入的数据。然后,当你想训练你的模型时,我建议使用一个脚本,并用 AWS 深度学习 AMI 构建一个 EC2 实例。将一个 EBS 实例连接到 EC2,并为下载&解压缩 ImageNet 提供足够的存储空间。对于 2012 ImageNet,压缩下载为 150GB。但是您将需要大约 400GB,因为您需要足够的空间来解压缩文件,然后删除。事后焦油。使用 EBS 实例还意味着您可以升级 EC2,而不必重新下载数据。
现在要真正下载 ImageNet,官方的说明是到你的研究机构这里报名成为研究员。
我不认为斯坦福大学已经保持这种状态很长时间了,因为你永远不会收到电子邮件邀请。所以,我发现有效的是从学术洪流下载 ImageNet。
搜索 ImageNet,获取所需的 magnet 链接,并使用 CLI 下载 torrents with Transmission。确保您的实例可以访问互联网!
sudo yum install transmission transmission-daemon transmission-cli
然后设置你的下载目录
transmission-daemon --download-dir "your-download-directory-path"
并添加您的磁铁链接
transmission-remote -a "magnet-link"
在此找到其他重要命令。
一旦您下载了压缩文件,我们希望将它们解压缩并放入正确的文件夹中,以便它们与 PyTorch ImageFolder 类所期望的相匹配,如文档此处所述。
将 ILSVRC2012_img_train.tar 和 ILSVRC2012_img_val.tar 放在与以下脚本相同的文件夹中,以获得所需的文件夹。根据需要为您的特定种子进行编辑。
我也建议两个都扔。在 S3 把柏油文件放到一个桶里,这样你下次就可以从那里拿到了。不要扔掉未压缩的文件,因为你要为 S3 上每个对象的单独请求付费。
设置数据加载器
我建议在一个名为 dataset 的模块中设置 PyTorch 的 DataLoader 和 ImageFolder 的用法。我发现在不同的文件中保存数据集特定的扩充很容易。这里有一个使用 ResNet 的例子[imagenet.py](http://imagenet.py)
。设置默认批量大小、归一化变换以及特定于该数据集的裁剪。也许在另一个像 cifar10.py 这样的文件中,你可以使用特定于 cifar-10 的设置(不同的批量大小、归一化和裁剪)来装载数据集。
使用 ImageNet 进行培训
我不建议在 Jupyter 笔记本上的 ImageNet 或 Sports1M 这样的大规模数据集上训练模型。您可能会超时,并且您的实例将从 stdout 断开,这将导致您看不到您的模型正在取得的进展。一个更安全的选择是在屏幕中使用一个脚本进行 ssh 和训练。
我还推荐使用 neptune.ai 在一个简洁的可视化仪表板中跟踪进度。有些人用 TensorBoard 或 TensorBoardX 来做 pytorch,但我还没有试过。我喜欢 neptune.ai ,因为即使在我关闭实例后,它也能保留我的结果,并让我轻松地比较实验。
现在,将您的数据加载器与您的模型、您选择的优化器以及您选择的损失一起用于 ImageNet 训练。它看起来像下面伪代码的一些变体:
# one epoch
for i, (images, target) in enumerate(train_loader): # compute output
output = model(images)
loss = criterion(output, target) # measure accuracy and record loss
acc1, acc5 = accuracy(output, target, topk=(1, 5))
losses.update(loss.item(), images.size(0))
top1.update(acc1[0], images.size(0))
top5.update(acc5[0], images.size(0)) # compute gradient and do step
optimizer.zero_grad()
loss.backward()
optimizer.step()
这只是为了训练。在带有验证函数的循环中使用该函数,以便在每个时期对验证集交替进行训练和评分。关于如何做到这一点的更多例子,请看官方 PyTorch 例子这里。
记得在数据进入你的网络之前至少看一次数据。这意味着实际观想它。下面是一个完整性检查示例,用于确保预处理过程中一切顺利。
为了完整起见,我在健全性检查上面添加了一些代码来生成反规格化变换(查看没有规格化效果的实际图像)。
现在享受训练的乐趣&通过理智检查保持你的理智!😄
如何在自定义对象检测数据上训练检测器 2
注:我们还在博客上发布了如何培训检测员 2 。在本帖中,我们将在这本detector 2 Colab 笔记本中,详细讲解如何训练 detector 2 检测定制对象。阅读后,您将能够通过只更改一行用于自定义数据导入的代码来训练您的 custom Detectron2 检测器!
Detectron2 提供了一个灵活的框架来训练和部署计算机视觉算法。
文章大纲
- 检测器 2 概述
- 我们的自定义数据集概述
- 安装检测器 2 依赖项
- 下载自定义检测器 2 对象检测数据
- 可视化探测器 2 训练数据
- 编写我们的 Detectron2 培训配置
- 运行检测器 2 培训
- 评估检测器 2 的性能
- 对测试图像运行 Detectron2 推理
定制检测器 2 培训资源
检测器 2 概述
Detectron2 是一个流行的基于 PyTorch 的模块化计算机视觉模型库。这是 Detectron 的第二个版本,最初是用 Caffe2 编写的。Detectron2 系统允许您将最先进的计算机视觉技术插入到您的工作流程中。引用 Detectron2 发布博客:
Detectron2 includes all the models that were available in the original Detectron, such as Faster R-CNN, Mask R-CNN, RetinaNet, and DensePose. It also features several new models, including Cascade R-CNN, Panoptic FPN, and TensorMask, and we will continue to add more algorithms. We’ve also added features such as synchronous Batch Norm and support for new datasets like LVIS
检测器 2 中提供多种推理模式
在本帖中,我们回顾了如何针对特别是对象检测的自定义数据训练 Detectron2。不过,在你读完之后,你将会熟悉 Detectron2 的生态系统,并且你将能够推广到 Detectron2 中包含的其他功能。
我们的自定义数据概述
我们将在 Roboflow 免费托管的公共血细胞检测数据上培训我们的 custom Detectron2 检测器。血细胞检测数据集是小型定制对象检测数据集的代表,人们可以收集该数据集来构建定制对象检测系统。值得注意的是,血细胞检测不是 Detectron2 中可用的功能——我们需要训练底层网络来适应我们的定制任务。
如果你想一步一步地跟随教程,你可以分叉这个公共血细胞数据集。否则,你可以上传任何格式的数据集(详见下文)。
安装检测器 2 依赖项
首先,复制这个 Colab 笔记本,它实现了对自定义数据的检测器 2。Google Colab 为我们提供了免费的 GPU 资源,因此请确保通过检查运行时→更改运行时类型→ GPU 来启用它们。
为了开始训练我们的自定义检测器,我们安装了torch==1.5
和torchvision==0.6
-然后在导入torch
后,我们可以检查 torch 的版本,并确保 GPU 可用于打印1.5.0+cu101 True
。
然后我们 pip 安装 Detectron2 库并导入一些子模块。
!pip install detectron2==0.1.3 -f [https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.5/index.html](https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.5/index.html)import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()# import some common libraries
import numpy as np
import cv2
import random
from google.colab.patches import cv2_imshow# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog
from detectron2.data.catalog import DatasetCatalog
已安装 Detectron2 依赖项。
下载自定义检测器 2 对象检测数据
我们从 Roboflow 下载 COCO JSON 格式的自定义数据,只需一行代码——这是您需要修改的唯一一行代码,以便在您自己的自定义对象上进行训练!
注意:在本教程中,我们使用边界框导出对象检测数据。Roboflow 目前不支持语义分段注释格式。报名我们报名时会通知您。
下载自定义数据集
如果你有未标记的图片,你首先需要标记它们。对于免费的开源标签工具,我们推荐以下指南:标签工具入门指南或 CVAT 注释工具入门指南。尝试标记约 50 张图像,以继续本教程。为了以后提高模型的性能,您将需要更多的标签。
您还可以考虑从开放图像中构建一个自由对象检测数据集。
一旦您标记了数据,要将您的数据移动到 Roboflow 中,创建一个免费帐户,然后您可以以任何格式拖动您的数据集:(VOC XML、COCO JSON、TensorFlow Object Detection CSV 等)。
上传后,您可以选择预处理和增强步骤:
为 BCCD 数据集选择的导出设置
然后点击Generate
和Download
就可以选择 COCO JSON 格式了。
选择“COCO JSON”导出格式
出现提示时,请务必选择“显示代码片段”这将输出一个下载 curl 脚本,这样您就可以轻松地将数据以正确的格式导入 Colab。
然后,Detectron2 跟踪一个registry
中可用数据集的列表,因此我们必须向 Detectron2 注册我们的自定义数据,以便可以调用它进行训练。
from detectron2.data.datasets import register_coco_instances
register_coco_instances("my_dataset_train", {}, "/content/train/_annotations.coco.json", "/content/train")
register_coco_instances("my_dataset_val", {}, "/content/valid/_annotations.coco.json", "/content/valid")
register_coco_instances("my_dataset_test", {}, "/content/test/_annotations.coco.json", "/content/test")
探测器 2 数据已注册。
可视化探测器 2 训练数据
Detectron2 可以轻松查看我们的训练数据,以确保数据已正确导入。我们通过以下方式做到这一点
#visualize training data
my_dataset_train_metadata = MetadataCatalog.get("my_dataset_train")
dataset_dicts = DatasetCatalog.get("my_dataset_train")import random
from detectron2.utils.visualizer import Visualizerfor d in random.sample(dataset_dicts, 3):
img = cv2.imread(d["file_name"])
visualizer = Visualizer(img[:, :, ::-1], metadata=my_dataset_train_metadata, scale=0.5)
vis = visualizer.draw_dataset_dict(d)
cv2_imshow(vis.get_image()[:, :, ::-1])
可视化训练数据
看起来我们的数据集注册正确。
编写我们的 Detectron2 培训配置
接下来,我们编写自定义培训配置。
cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml"))
cfg.DATASETS.TRAIN = ("my_dataset_train",)
cfg.DATASETS.TEST = ("my_dataset_val",)cfg.DATALOADER.NUM_WORKERS = 4
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml") # Let training initialize from model zoo
cfg.SOLVER.IMS_PER_BATCH = 4
cfg.SOLVER.BASE_LR = 0.001cfg.SOLVER.WARMUP_ITERS = 1000
cfg.SOLVER.MAX_ITER = 1500 #adjust up if val mAP is still rising, adjust down if overfit
cfg.SOLVER.STEPS = (1000, 1500)
cfg.SOLVER.GAMMA = 0.05cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 64
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 4cfg.TEST.EVAL_PERIOD = 500
我们在这里调用的最大的设备是对象检测模型的类型——更快的大型 RCNN。Detectron2 允许你在决定你的模型架构时有很多选择,你可以在 Detectron2 模型动物园中看到。
仅对于对象检测,以下模型是可用的:
探测器 2 模型动物园中可用的物体探测模型。
我们做的另一个大的配置选择是MAX_ITER
参数。这指定了模型将训练多长时间,您可能需要根据您看到的验证指标上下调整。
运行检测器 2 培训
在开始训练之前,我们需要确保模型根据我们的验证集进行验证。不幸的是,默认情况下这不会发生🤔。
我们可以通过基于带有COCO Evaluator
的Default Trainer
定义我们的定制教练来轻松做到这一点:
from detectron2.engine import DefaultTrainer
from detectron2.evaluation import COCOEvaluatorclass CocoTrainer(DefaultTrainer):[@classmethod](http://twitter.com/classmethod)
def build_evaluator(cls, cfg, dataset_name, output_folder=None):if output_folder is None:
os.makedirs("coco_eval", exist_ok=True)
output_folder = "coco_eval"return COCOEvaluator(dataset_name, cfg, False, output_folder)
好了,现在我们有了COCO Trainer
,我们可以开始训练了:
培养⏰
培训将持续一段时间,并在我们的验证集上打印出评估指标。好奇想知道什么图是用来评价的?查看这篇关于分解图的文章。
一旦训练结束,我们可以继续进行评估和推断!
评估检测器 2 的性能
首先,我们可以显示一个结果的 tensorboard 来查看训练过程的执行情况。
这里有很多有趣的指标——最著名的是total_loss
和validation mAP
。
我们在测试集上运行验证图中使用的相同评估过程。
from detectron2.data import DatasetCatalog, MetadataCatalog, build_detection_test_loader
from detectron2.evaluation import COCOEvaluator, inference_on_datasetcfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.85
predictor = DefaultPredictor(cfg)
evaluator = COCOEvaluator("my_dataset_test", cfg, False, output_dir="./output/")
val_loader = build_detection_test_loader(cfg, "my_dataset_test")
inference_on_dataset(trainer.model, val_loader, evaluator)
屈服:
Accumulating evaluation results...
DONE (t=0.03s).
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.592
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.881
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.677
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.178
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.613
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.411
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.392
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.633
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.684
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.257
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.709
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.439
[06/23 18:39:47 d2.evaluation.coco_evaluation]: Evaluation results for bbox:
| AP | AP50 | AP75 | APs | APm | APl |
|:------:|:------:|:------:|:------:|:------:|:------:|
| 59.169 | 88.066 | 67.740 | 17.805 | 61.333 | 41.070 |
[06/23 18:39:47 d2.evaluation.coco_evaluation]: Per-category bbox AP:
| category | AP | category | AP | category | AP |
|:-----------|:-------|:-----------|:-------|:-----------|:-------|
| cells | nan | Platelets | 40.141 | RBC | 60.326 |
| WBC | 77.039 | | | | |
该评估将让您很好地了解新的 custom Detectron2 探测器在野外的表现。同样,如果你想了解更多关于这些指标的信息,请看这篇文章分解图。
对测试图像运行 Detectron2 推理
最后,我们可以在真实图像上运行我们新的定制检测器 2 检测器!请注意,这些图像是模特从未见过的
cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
cfg.DATASETS.TEST = ("my_dataset_test", )
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7 # set the testing threshold for this model
predictor = DefaultPredictor(cfg)
test_metadata = MetadataCatalog.get("my_dataset_test")from detectron2.utils.visualizer import ColorMode
import globfor imageName in glob.glob('/content/test/*jpg'):
im = cv2.imread(imageName)
outputs = predictor(im)
v = Visualizer(im[:, :, ::-1],
metadata=test_metadata,
scale=0.8
)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])
屈服:
测试图像上的推断看起来相当不错!
我们的模型做出了很好的预测,表明它已经学会了如何识别红细胞、白细胞和血小板。
您可以考虑使用SCORE_THRESH_TEST
来改变模型进行预测所需的置信度阈值。
您现在可以将权重保存在os.path.join(cfg.OUTPUT_DIR, "model_final.pt")
中,以便将来通过导出到 Google Drive 进行推断。
您还可以在outputs
对象中看到潜在的预测张量,以便在应用程序的其他地方使用。
结论
恭喜你!现在,您知道如何在一个全新的领域中训练您自己的 custom Detectron2 检测器。
看不到前进所需的结果?自从 Detectron2 模型动物园发布以来,对象检测模型已经得到了改进——可以考虑看看我们的一些其他教程,例如如何训练 YOLOv5 和如何训练 YOLOv4 ,或者这篇关于在 YOLO v5 中的改进的文章。
如何在图形数据库中训练图形卷积网络模型
理解大数据
在图形数据库中训练 GCN 模型可以利用图形数据库的分布式计算框架。对于现实应用中的大型图形,这是一个可扩展的解决方案。
什么是图卷积网络?
典型的前馈神经网络将每个数据点的特征作为输入,并输出预测。利用训练数据集中每个数据点的特征和标签来训练神经网络。这种框架已被证明在各种应用中非常有效,例如人脸识别、手写识别、对象检测,其中数据点之间不存在明确的关系。但是,在某些用例中,当给定 v ( i )和 v ( j )之间的关系时,对于一个数据点 v ( i )的预测不仅可以由其自身的特征来确定,还可以由其他数据点 v ( j )的特征来确定。例如,期刊论文的主题(例如计算机科学、物理学或生物学)可以从论文中出现的单词频率中推断出来。另一方面,论文中的参考文献也可以在预测论文主题时提供信息。在这个例子中,我们不仅知道每个数据点的特征(词频),还知道数据点之间的关系(引用关系)。那么我们如何将它们结合起来以提高预测的准确性呢?
通过应用图形卷积网络(GCN),单个数据点及其连接的数据点的特征将被组合并输入到神经网络中。我们再以论文分类问题为例。在引用图(图 1)中,每篇论文由引用图中的一个顶点表示。顶点之间的边表示引用关系。为简单起见,这些边被视为无向的。每张纸及其特征向量分别表示为 v_i 和 x_i 。根据 Kipf 和 Welling [1]的 GCN 模型,我们可以使用具有一个隐含层的神经网络预测论文的主题,其步骤如下:
图一。(图片由作者提供)图卷积网络的架构。每个顶点 vi 代表引用图中的一篇论文。xi 是 vi 的特征向量。 W (0)和 W (1)是三层神经网络的权重矩阵。 A 、 *D、*和 I 分别是邻接矩阵、度矩阵和单位矩阵。水平和垂直传播分别以橙色和蓝色突出显示。
在上面的工作流中,步骤 1 和 4 执行水平传播,其中每个顶点的信息被传播到其邻居。而步骤 2 和 5 执行垂直传播,其中每层上的信息被传播到下一层。(参见图 1)对于具有多个隐藏层的 GCN,将会有水平和垂直传播的多次迭代。值得注意的是,每次执行水平传播时,顶点的信息在图上传播一跳。在本例中,水平传播执行了两次(步骤 2 和 4),因此每个顶点的预测不仅取决于其自身的特征,还取决于距其 2 跳距离内的所有顶点的特征。此外,由于权重矩阵 W(0)和 W(1)由所有顶点共享,神经网络的大小不必随着图的大小而增加,这使得该方法可扩展。
为什么您需要一个 GCN 图形数据库
*通过融合每个顶点的图形特征,GCN 可以以较低的标注率达到较高的准确率。在 Kipf 和 Welling 的工作[1]中,使用图中 5%的标记顶点(实体)可以获得超过 80%的准确度。考虑到整个图在传播过程中需要参与计算,训练一个 GCN 模型的空间复杂度为 O(E+VN+M),其中 E 和 V 是图中的边数和顶点数, N 是每个顶点的特征数, M 是大小
对于工业应用来说,一个图可以有数亿个顶点和数十亿条边,这意味着邻接矩阵 A ,特征矩阵 X 和其他中间变量(图 1)在模型训练期间都可以消耗万亿字节的内存。这种挑战可以通过在图形数据库(GDB)中训练 GCN 来解决,其中图形可以分布在多节点集群中,并且部分存储在磁盘上。此外,图结构的用户数据,如社交图、消费图和移动图,首先存储在数据库管理系统中。数据库内模型训练还避免了将图形数据从 DBMS 导出到其他机器学习平台,从而更好地支持对进化训练数据的连续模型更新。
如何在图形数据库中训练 GCN 模型
在本节中,我们将在 TigerGraph cloud 上提供一个图表数据库(带有免费层),加载一个引用图表,并在数据库中训练一个 GCN 模型。按照下面的步骤,您将在 15 分钟内拥有一个纸张分类模型。
按照创建您的第一个 TigerGraph 实例(前 3 个步骤)来在 TigerGraph cloud 上提供一个免费实例。在步骤 1 中,选择“图卷积网络”作为初学者工具包。在步骤 3 中,选择 TG.Free。(如果找不到初学者工具包,请参阅脚注)
按照tiger graph 云门户入门和登录 GraphStudio 。在将数据映射到图形页面,您将看到数据文件是如何映射到图形的。在这个初学者工具包中, Cora 引用数据文件已经上传到实例中。Cora 数据集有三个文件:
- cite.csv 有三列,paperA_id、paper _ id 和 weight。前两列用于创建论文之间的引用边缘。CITE 边上的权重将由后续步骤中的查询更新,因此不需要加载最后一列。应该注意的是,这个初学者工具包中的文件为每篇论文添加了 self 链接,以简化查询实现。这与 Kipf 和 Welling 的方法一致[1]。
- paper_tag.csv 有两列:paper_id 和 class_label。此文件中的每一行都将用于创建一个纸张顶点,其中包含文件中填充的纸张 id 和纸张类别。
- content.csv 有三列:paper_id、word_id 和 weight。前两列用于在纸张和文字之间创建散列边缘。散列边缘将用于存储稀疏词袋特征向量。散列边上的权重将由后续步骤中的查询更新,因此不需要加载最后一列。
(Image by Author)在 Map Data To Graph 页面,可以看到 csv 文件中的列是如何映射到引用图中的顶点和边的。
进入加载数据页面,点击开始/恢复加载。加载完成后,您可以在右侧看到图表统计信息。Cora 数据集有 2708 篇论文,1433 个不同的词(特征向量的维度),7986 个引用关系。每张纸都标有 7 种不同类别中的一种。
(图片作者)在加载数据页面,加载完成后,可以在右边看到图表统计。
在 Explore Graph 页面中,您可以看到我们刚刚在引用图的顶部创建了一个神经网络。引文图表中的每篇论文都与多个单词相关联。散列边缘上的权重因此形成稀疏特征向量。1433 个不同的单词连接到隐藏层中的 16 个神经元,隐藏层连接到输出层中的 7 个神经元(代表 7 个不同的类别)。
(图片由作者提供)在浏览图形页面中,您可以使用“拾取顶点”和“从顶点展开”来显示图形中的顶点和边。
在编写查询页面中,您会发现 GCN 所需的查询已经添加到数据库中。这些查询是用 TigerGraph 的查询语言 GSQL 编写的。点击安装所有查询将所有 GSQL 查询编译成 C++代码。您还可以在此页面上看到自述文件查询。按照以下步骤训练 GCN。
运行初始化查询。
该查询首先通过将纸张 i 和 j 之间的权重指定为e _ ij= 1/(d _ Id _ j)来归一化引用边缘上的权重,其中 d_i 、 d_j 是纸张 i 和纸张 j 的引用程度第二,它通过将纸张 p 和单词 w 之间的权重指定为e*_pw= 1/DP来标准化 HAS 边缘上的权重,其中 dp 是纸张 w 的 HAS 出度。第三,它对 140、500 和 1000 个纸顶点进行采样,用于测试、验证和训练集。
运行权重 _ 初始化查询
该查询使用 Glorot 和 Bengio 的方法初始化神经网络的权重[2]。神经网络的输入层有 1433 个神经元,对应于词汇量的大小,隐层有 16 个神经元,输出层有 7 个神经元,对应于论文的 7 个类别。
运行培训查询
此查询使用 Kipf 和 Welling [1]中使用的相同超参数来训练图形卷积神经网络。具体来说,使用交叉熵损失、丢失正则化和 L2 正则化(5e-4)对第一层的模型进行评估。Adam 优化器已在此查询中实现,批处理梯度下降用于训练。查询完成后,将显示根据训练和验证数据评估的损失以及根据测试数据评估的预测准确性。如训练查询的输出所示,在 5 个训练时期之后,准确率达到 53.2%。为了更高的准确性,可以将历元数设置为查询输入。
(图片由作者提供)训练查询输出训练和验证数据集的交叉熵损失,以及每个训练时期的测试数据集的预测精度。
运行预测查询
该查询将训练好的 GCN 应用于图中的所有论文,并将结果可视化。
(图片由作者提供)预测查询输出引用图中每篇论文的预测类和标记类。
GSQL 查询概述
在最后一节中,我们将深入查询,看看 TigerGraph 的大规模并行处理框架是如何支持训练 GCN 的。简言之,TigerGraph 将每个顶点视为一个可以存储、发送和处理信息的计算单元。我们将选择查询中的一些语句来说明 GSQL 语句是如何执行的。
先来看查询初始化。第一行将初始化一个顶点集 Papers,它包括图中所有的 PAPER 顶点。在下一个 SELECT 语句中,我们将从顶点集开始,遍历所有引用的边。对于每条边(由 e 表示),其边权重是从其源顶点(由 s 表示)和其目标顶点(由 t 表示)的外向度并行计算的。
现在我们来看看查询培训。下面的块执行水平和垂直传播。正如我们在上一节中讨论的,水平传播是我们将信息从每个顶点发送到它的邻居,这是由 ACCUM 之后的行完成的。它将每个目标顶点(由 t.@z_0 表示)的特征向量计算为其源顶点(由 s.@zeta_0 表示)的特征向量之和,并通过 e.weight 进行加权。它首先对每个顶点上的特征向量应用 ReLU 激活函数和丢失正则化。然后它将隐藏层特征(由 s.@z_0 引用)传播到输出层。同样,TigerGraph 将根据边和顶点并行化 ACCUM 和 POST-ACCUM 块中的计算。
激活函数用 C++实现,并导入到 TigerGraph 用户自定义函数库。下面是 ReLU 函数(ReLU_ArrayAccum)的实现
结论
在图形数据库中训练 GCN 模型利用了图形数据库的分布式计算框架。对于现实应用中的大型图形,这是一个可扩展的解决方案。在本文中,我们解释了 GCN 如何将每个节点的特征与图特征结合起来,以提高图中节点分类的准确性。我们还展示了一个使用 TigerGraph 云服务在引用图上训练 GCN 模型的分步示例。
参考:
[1]托马斯。n .基普夫和马克斯·韦林, ICLR (2017)
[2]格洛特和本吉奥(2010 年)
*如果“GCN 数据库内机器学习(引文图表)”初学者工具包不可用,您可以(1)在步骤 1 中选择“空白”初学者工具包。(2)按照步骤 2 和 3 登录 GraphStudio。(3)下载GCNonCitationGraph.tar.gz和所有的。来自https://github . com/changran Liu/Machine-Learning-in-tiger graph/tree/master/GCN的/data 文件夹中的 csv 文件。(4)使用“导入现有解决方案”从 GraphStudio 主页导入. tar.gz 文件。(5)上传所有的。从映射数据到图形页面的 csv 文件。