使用深度学习的加密货币价格预测
使用 LSTM 神经网络的完整机器学习真实世界应用程序走查
Photo by Chris Liverani on Unsplash
被困在付费墙后面?点击这里阅读完整故事与我的朋友链接!
由于其市值连续几个月呈指数增长,加密货币的受欢迎程度在 2017 年飙升。价格在 2018 年 1 月达到峰值,超过 8000 亿美元。
尽管机器学习已经成功地通过大量不同的时间序列模型预测了股票市场价格,但它在预测加密货币价格方面的应用却受到了很大的限制。这背后的原因很明显,因为加密货币的价格取决于许多因素,如技术进步、内部竞争、市场交付压力、经济问题、安全问题、政治因素等。如果采取明智的发明策略,它们的高波动性导致高利润的巨大潜力。不幸的是,由于缺乏指数,与股票市场预测等传统金融预测相比,加密货币相对不可预测。
在这篇博客中,我将通过四个步骤来预测加密货币的价格:
- 获取实时 crptocurrency 数据。
- 为培训和测试准备数据。
- 用 LSTM 神经网络预测人民币价格。
- 将预测结果可视化。
挑战
使用数据集中的所有交易特征(如价格、交易量、开盘价、盘高、盘低值)来预测加密货币的价格。
数据
数据集可以从 CryptoCompare 网站下载,该网站可以在这里找到。
数据集总共包含 5 个要素。它们的详细信息如下:
- 收盘价——这是当天货币的市场收盘价。
- 高价——这是当天货币的最高价格。
- 低价——这是当天货币的最低价格。
- 开盘价—这是当天货币的市场开盘价。
- 成交量——当天交易的货币量。
代码在哪里?
事不宜迟,让我们从代码开始吧。github 上的完整项目可以在这里找到。
我从加载所有需要的库和依赖项开始。
import json
import requests
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, LSTM
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.metrics import mean_absolute_error
%matplotlib inline
我使用了加拿大的汇率,并把实时数据存入了熊猫的数据框。我使用了to_datetime()
方法将字符串日期时间转换成 Python 日期时间对象。这是必要的,因为文件中的日期时间对象被读取为字符串对象。对字符串而不是日期时间对象执行像时差这样的操作要容易得多。
endpoint = 'https://min-api.cryptocompare.com/data/histoday'
res = requests.get(endpoint + '?fsym=BTC&tsym=CAD&limit=500')
hist = pd.DataFrame(json.loads(res.content)['Data'])
hist = hist.set_index('time')
hist.index = pd.to_datetime(hist.index, unit='s')
target_col = 'close'
让我们看看数据集是怎样的,包括所有的交易特征,如价格、交易量、开盘价、最高价、最低价。
hist.head(5)
接下来,我将数据分成两组—分别包含 80%和 20%数据的训练集和测试集。这里所做的决定只是为了本教程的目的。在真实的项目中,你应该总是把你的数据分成训练、验证、测试(比如 60%、20%、20%)。
def train_test_split(df, test_size=0.2):
split_row = len(df) - int(test_size * len(df))
train_data = df.iloc[:split_row]
test_data = df.iloc[split_row:]
return train_data, test_datatrain, test = train_test_split(hist, test_size=0.2)
现在,让我们使用下面的代码来绘制以加元为单位的加密货币价格与时间的函数关系图:
def line_plot(line1, line2, label1=None, label2=None, title='', lw=2):
fig, ax = plt.subplots(1, figsize=(13, 7))
ax.plot(line1, label=label1, linewidth=lw)
ax.plot(line2, label=label2, linewidth=lw)
ax.set_ylabel('price [CAD]', fontsize=14)
ax.set_title(title, fontsize=16)
ax.legend(loc='best', fontsize=16)line_plot(train[target_col], test[target_col], 'training', 'test', title='')
我们可以观察到,在 2018 年 12 月至 2019 年 4 月之间,价格出现了明显的下降。从 2019 年 4 月到 2019 年 8 月,价格持续上涨,7 月和 8 月出现波动。从 2019 年 9 月开始,价格不断下降。从这一价格波动中值得注意的有趣的事情是,价格在冬天很低,而在夏天上涨。虽然这不能一概而论,因为所考虑的数据集只是一年的小样本。同样,对于加密货币,很难一概而论。
接下来,我创建了几个函数来规范化这些值。标准化是一种经常作为机器学习的数据准备的一部分而应用的技术。规范化的目标是将数据集中数值列的值更改为一个通用的比例,而不会扭曲值范围的差异。
def normalise_zero_base(df):
return df / df.iloc[0] - 1
def normalise_min_max(df):
return (df - df.min()) / (data.max() - df.min())
接下来,我创建了一个函数来提取大小为 5 的窗口的数据,如下面的代码所示:
def extract_window_data(df, window_len=5, zero_base=True):
window_data = []
for idx in range(len(df) - window_len):
tmp = df[idx: (idx + window_len)].copy()
if zero_base:
tmp = normalise_zero_base(tmp)
window_data.append(tmp.values)
return np.array(window_data)
我继续创建一个函数,以某种格式准备数据,以便以后输入神经网络。我使用了同样的概念,将数据分成两组—分别包含 80%和 20%数据的训练集和测试集,如下面的代码所示:
def prepare_data(df, target_col, window_len=10, zero_base=True, test_size=0.2):
train_data, test_data = train_test_split(df, test_size=test_size)
X_train = extract_window_data(train_data, window_len, zero_base)
X_test = extract_window_data(test_data, window_len, zero_base)
y_train = train_data[target_col][window_len:].values
y_test = test_data[target_col][window_len:].values
if zero_base:
y_train = y_train / train_data[target_col][:-window_len].values - 1
y_test = y_test / test_data[target_col][:-window_len].values - 1
return train_data, test_data, X_train, X_test, y_train, y_test
LSTM
它通过使用特殊的门来允许每个 LSTM 层从先前层和当前层获取信息。数据通过多个门(如遗忘门、输入门等。)和各种激活功能(如 tanh 功能、relu 功能)并通过 LSTM 细胞。这样做的主要优点是,它允许每个 LSTM 细胞在一定时间内记住模式。需要注意的是,LSTM 可以记住重要的信息,同时忘记不相关的信息。LSTM 架构如下所示:
LSTM architecture
现在让我们建立模型。顺序模型用于堆叠所有层(输入、隐藏和输出)。神经网络包括一个 LSTM 层,后面是 20%的下降层和一个具有线性激活函数的密集层。我用 Adam 作为优化器,用均方差作为损失函数来编译这个模型。
def build_lstm_model(input_data, output_size, neurons=100, activ_func='linear', dropout=0.2, loss='mse', optimizer='adam'):
model = Sequential()
model.add(LSTM(neurons, input_shape=(input_data.shape[1], input_data.shape[2])))
model.add(Dropout(dropout))
model.add(Dense(units=output_size))
model.add(Activation(activ_func))
model.compile(loss=loss, optimizer=optimizer)
return model
接下来,我设置了一些稍后要使用的参数。这些参数是——随机数种子、窗口长度、测试集大小、LSTM 层中的神经元数量、时期、批量大小、丢失、漏失和优化器。
np.random.seed(42)
window_len = 5
test_size = 0.2
zero_base = True
lstm_neurons = 100
epochs = 20
batch_size = 32
loss = 'mse'
dropout = 0.2
optimizer = 'adam'
现在让我们使用输入x_train
和标签y_train
来训练模型。
train, test, X_train, X_test, y_train, y_test = prepare_data(
hist, target_col, window_len=window_len, zero_base=zero_base, test_size=test_size)model = build_lstm_model(
X_train, output_size=1, neurons=lstm_neurons, dropout=dropout, loss=loss,
optimizer=optimizer)
history = model.fit(
X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=1, shuffle=True)
让我们看看 20 个时期的模型训练期间的快照。
Training of the neural network
我使用平均绝对误差(MAE)作为评估标准。选择 MAE 而不是均方根误差(RMSE)的原因是 MAE 更容易解释。RMSE 没有单独描述平均误差,因此更难理解。因为我们希望这个模型即使对非技术观众也能容易地解释,所以 MAE 看起来是一个更好的选择。
绝对平均误差
它测量一组预测中误差的平均大小,而不考虑它们的方向。它是实际观测值和预测观测值之间的绝对差异在测试样本上的平均值,其中所有个体差异都具有相同的权重。
targets = test[target_col][window_len:]
preds = model.predict(X_test).squeeze()
mean_absolute_error(preds, y_test)
**# 0.027955859325876943**
获得的 MAE 值看起来不错。最后,让我们使用下面的代码绘制实际价格和预测价格:
preds = test[target_col].values[:-window_len] * (preds + 1)
preds = pd.Series(index=targets.index, data=preds)
line_plot(targets, preds, 'actual', 'prediction', lw=3)
结论
在本文中,我演示了如何使用 LSTM 神经网络实时预测加密货币的价格。我经历了四个步骤:获取实时货币数据、为训练和测试准备数据、使用 LSTM 神经网络预测价格以及可视化预测结果。随意使用超参数或尝试不同的神经网络架构以获得更好的结果。
参考资料/进一步阅读
[## 用于比特币价格预测的机器学习模型比较- IEEE 会议出版物
近年来,比特币是加密货币市场中最有价值的。然而,比特币的价格已经非常…
ieeexplore.ieee.org](https://ieeexplore.ieee.org/document/8534911) [## 利用深度学习算法进行比特币价格预测
免责声明:本文中包括算法在内的所有信息都是为教育目的而提供和发布的…
medium.com](https://medium.com/activewizards-machine-learning-company/bitcoin-price-forecasting-with-deep-learning-algorithms-eb578a2387a3) [## 使用机器学习预测比特币的价格- IEEE 会议出版物
本文的目标是确定以美元为单位的比特币价格的走向可以预测到什么样的准确度。的…
ieeexplore.ieee.org](https://ieeexplore.ieee.org/abstract/document/8374483)
在你走之前
相应的源代码可以在这里找到:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/abhinavsagar/Cryptocurrency-Price-Prediction)
联系人
如果你想了解我最新的文章和项目,请关注我的媒体。以下是我的一些联系人详细信息:
快乐阅读,快乐学习,快乐编码!
黑客使用 LSTMs | TensorFlow 进行加密货币价格预测(第三部分)
在 TensorFlow 2 中使用 LSTM 深度神经网络预测比特币价格
Photo by David McBee
TL;DR 在 TensorFlow 2 中为时间序列预测建立并训练双向 LSTM 深度神经网络。利用模型预测未来比特币价格。
这次,您将构建一个基本的深度神经网络模型,根据历史数据预测比特币价格。你可以随心所欲地使用这个模型,但你要为自己的行为承担风险。
你可能会问自己这样的问题:
用加密货币还能发财吗?
当然,答案相当微妙。在这里,我们将看看你可能如何建立一个模型,以帮助你沿着疯狂的旅程。
或者你可能有经济困难?这里有一个可能的解决方案:
计划是这样的:
- 加密货币数据概述
- 时间序列
- 数据预处理
- 在 TensorFlow 2 中建立并训练 LSTM 模型
- 利用模型预测未来比特币价格
数据概述
我们的数据集来自雅虎!金融并涵盖所有可用的(在撰写本文时)比特币-美元价格数据。让我们把它载入熊猫数据框架:
注意,为了以防万一,我们按日期对数据进行排序。以下是我们感兴趣的数据示例:
我们总共有 3201 个数据点,代表 3201 天(~9 年)的比特币-美元价格。我们对预测未来日期的收盘价感兴趣。
当然,比特币让一些人变得非常富有,也让一些人变得非常贫穷。问题是,它会再次发生吗?让我们来看看一个可能的模型是怎么想的。我们走吧。
我们的数据集与之前的例子有些不同。数据按时间排序,并以相等的时间间隔(1 天)记录。这样的数据序列称为 时间序列 。
时间序列
时态数据集在实践中很常见。你的能量消耗和支出(卡路里输入,卡路里输出),天气变化,股票市场,从用户那里收集的对你的产品/应用的分析,甚至你(可能在恋爱中)的心产生时间序列。
你可能会对你的时间序列的许多属性感兴趣,比如平稳性、季节性和自相关性都是最著名的。
自相关是由某个间隔(称为滞后)分开的数据点的相关性。
季节性指的是在某个时间间隔出现某种循环模式(不,不一定是每个春天)。
如果一个时间序列具有恒定的均值和方差,则称其为平稳性。此外,协方差与时间无关。
在观察时间序列数据时,您可能会问自己一个明显的问题:“当前时间步长的值会影响下一个时间步长吗?”又名时间序列预测。
有许多方法可以用于此目的。但我们将建立一个深度神经网络,为我们做一些预测,并用它来预测未来的比特币价格。
建模
到目前为止,我们建立的所有模型都不允许对序列数据进行操作。幸运的是,我们可以使用一类特殊的神经网络模型,称为递归神经网络(RNNs) 来实现这个目的。 RNNs 允许使用模型的输出作为同一模型的新输入。该过程可以无限重复。
RNNs 的一个严重限制是无法捕捉序列中的长期相关性(例如,今天的价格和两周前的价格之间存在相关性吗?).处理这种情况的一种方法是使用**长短期记忆(LSTM)**RNN的变体。
LSTM 的默认行为是长时间记忆信息。让我们看看如何在 Keras 中使用 LSTM。
数据预处理
首先,我们将把价格数据压缩到[0,1]范围内。回想一下,这将帮助我们的优化算法更快地收敛:
source: Andrew Ng
我们将使用 scikit learn 中的最小最大缩放器:
缩放器期望数据的形状为(x,y ),因此我们在应用之前使用 reshape 添加一个虚拟尺寸。
让我们也去掉 nan,因为我们的模型不能很好地处理它们:
我们用 isnan 作为屏蔽,过滤掉 nan 值。在移除 nan 后,我们再次重塑数据。
制作序列
LSTMs 期望数据是三维的。我们需要将数据分割成预设长度的序列。我们想要获得的形状是:
[batch_size, sequence_length, n_features]
我们还想保存一些数据用于测试。让我们建立一些序列:
构建序列的过程通过在位置 0 创建指定长度的序列来进行。然后我们向右移动一个位置(例如 1)并创建另一个序列。重复该过程,直到使用了所有可能的位置。
我们保存 5%的数据用于测试。数据集看起来像这样:
(2945, 99, 1)
(156, 99, 1)
我们的模型将使用代表 99 天比特币价格变化的 2945 个序列进行训练。我们将预测未来 156 天的价格(从我们的模型视点)。
建立 LSTM 模型
我们正在创建一个 3 层 LSTM 递归神经网络。我们使用 20%的退出率来对抗培训期间的过度配合:
你可能想知道双向和 CuDNNLSTM 是怎么回事?
双向 RNNs 允许您对序列数据进行正向和反向(反向)训练。实际上,这种方法在 LSTMs 中运行良好。
CuDNNLSTM 是一个“由 cuDNN 支持的快速 LSTM 实现”。我个人认为这是一个很好的漏抽象的例子,但是它太快了!
我们的输出层有一个单神经元(预测比特币价格)。我们使用线性激活函数,其激活与输入成比例。
培养
注意,我们不想打乱训练数据,因为我们使用的是时间序列。
经过闪电般的训练(感谢谷歌免费的 T4 图形处理器),我们有以下训练损失:
预测比特币价格
让我们的模型预测比特币价格吧!
我们可以使用我们的缩放器来反转我们所做的转换,这样价格就不再在[0,1]范围内缩放。
我们相当简洁的模型似乎在测试数据上做得很好。想试试其他货币吗?
结论
恭喜你,你刚刚在 TensorFlow 2 中构建了一个双向 LSTM 递归神经网络。我们的模型(和预处理“管道”)非常通用,可以用于其他数据集。
未来研究的一个有趣方向可能是分析不同加密货币之间的相关性,以及这将如何影响我们模型的性能。
【https://www.curiousily.com】最初发表于。
受威胁者的密码学速成班
阅读/观看的概念概述和建议
Rotor Cipher Machine via Pixabay
在我的上一篇帖子中,我谈到了处理数据时保持专注的重要性。谁有权限?你如何保护这些信息?一些法律是如何改变的?学术界和工业界涵盖了什么和没有涵盖什么。
在这篇文章中,我决定给自己上一堂密码学速成课。密码学的概念可能听起来很吓人,数据的安全性和数据的安全传输肯定是需要认真对待的事情。但是我们每天都在创造数据。我认为现在对任何人来说,对什么是密码学有一个基本的了解是很重要的。
目标
- 尝试在一定程度上解除密码学的神秘性。
- 解释密码学的一些基本概念。
- 解释几个密码学在我们日常生活中应用的例子。
- 共享资源!
基本概念
为了开始理解密码学,我从基础开始。当你在网上查找密码学时,这里有一些反复出现的基本概念。我在下面链接了一个 YouTube 视频,如果你更喜欢视觉的话。
一、什么是密码学?密码学是一个专注于通信和数据存储的研究领域,旨在防止不必要的第三方窃取数据。例如,在手机出现之前,两个孩子可能会在课堂上互相传递一张纸条。他们不希望任何其他人(第三方),如老师,阅读笔记。因此,他们可能想出一种方法,用虚构的语言来写,或者对信息进行编码(加密信息),这样,即使老师可以“阅读”信息,他们也无法理解。
对信息进行加密(加扰)和解密(解扰)有不同的方式。它们通常分为两类:
- 对称:加密和解密的密钥是一样的,都使用私钥
- 不对称:加密和解密密钥不同,使用一个私钥(隐喻密钥),和一个公钥(隐喻锁),每个公钥只有一个私钥
为了进行实际的加密和解密,发送方和接收方需要密钥。密钥本质上是字符序列,允许用户随机打乱消息、文件、文件夹、数据、硬盘驱动器等。你试图保护和/或传递的任何信息。需要一个匹配的密钥来解密信息,无论该密钥是相同的(对称加密/解密)还是不同的(非对称加密/解密)。
你试图加密的信息可以叫做明文。一旦用密钥和加密程序对其进行加密,它就可以被称为密文,这就是存储和/或传输的内容。只有当数据处于静止状态(存储)或传输中的时,它才能被修改或窃取。当密文被一个密钥和解密程序解密时,你希望它是你发送的同一个明文**。**
我要介绍的最后一个概念是加密散列函数**。有些人可能熟悉哈希函数的概念。我们可以把散列函数想成任何一种函数(想想 machine,你放入 x,你得到 y)。哈希函数专门输出预先指定长度的值。例如,一个流行的加密散列函数是 SHA 256——SHA 代表安全散列算法——它给定一个输入,输出一个 256 位散列值。常规哈希函数和加密哈希函数之间的区别在于,当两个输入产生相同的输出时,加密哈希函数会尝试最大限度地减少冲突。我们可以看到,如果你有加密数据,冲突会是一个巨大的问题。**
现实生活中的例子,你可能甚至没有注意到
既然我们已经讨论了一些基本的加密概念,我想看看我们每天都会遇到的几个加密/解密的例子。
- ****HTTPS(超文本传输协议安全)**是您的本地设备与网络浏览器或远程站点安全通信的方式。当你访问 HTTPS 安全服务器(一个以 https 而不是 http 开头的安全网站)时,网络浏览器会检查一个证书,让浏览器知道该网站是合法的,而不是试图伪装成另一个网站的危险网站。HTTPS 安全服务器防止信息在连接过程中泄露。该连接使用 **TLS(传输层安全)加密,不要与其过时的前身 SSL(安全套接字层)混淆。
- 我们非常习惯于注册、登录和使用密码。人们不擅长想出和记住密码的想法已经存在一段时间了。事实证明,加密是密码系统工作的重要组成部分。一般来说,大多数系统会加密你输入的密码,只保留密文。下次你登录时,它会对你输入的内容进行加密,然后看看是否与文件上的密文相匹配。如果没有,就不能登录。这也是为什么大部分账号和网站只能重置密码,而不能给你发送旧密码的原因。
进一步的考虑
- 如何安全地存储密码或密钥等敏感信息?
- 您使用的是安全连接吗?
- 如何将密钥传输给需要它们的各方?
- 你怎么知道发送数据的人就是他们所说的那个人?如何验证自己的身份? GPG 密钥签名,签名链
奖励:从凯撒密码到一次性密码本
在阅读这篇博文的过程中,我偶然发现了可汗学院的一系列有趣的课程,题为“密码学之旅”,可以在这里找到。
这一部分是为有历史头脑的人准备的。课程从凯撒密码开始,这可能是我们小时候读到的东西,而没有理解密码学的概念,甚至可能是我们自己想出来的。
凯撒密码
这种加密方法起源于几千年前。你只需将你信息中的字母移动一定数量的字母,并告诉对方你想解码信息,移动的数量。例如,假设移位是 7,消息是英文的(不清楚这种密码如何适用于基于字符的语言)。
A -> H
B -> I
C -> J
D -> K
E -> L
.
.
.
V -> C
W -> D
X -> E
Y -> F
Z -> G
所以如果你的信息是“密码学很酷”这就变成了“JYFWAVNYHWOF PZ JVVS”这种密码的弱点是,我们可以看到一些字母重复,我们知道所有这些字母都编码为同一个原始字母。事实证明,使用频率分析可以很容易地破解凯撒密码。例如,在英语中,某些字母出现得更频繁,如 s、a、I、e 等。根据频繁加密的信件,我们可以反推,以确定这种转变可能是什么。
多字母移位密码
对凯撒密码的一个改进是给你的朋友不是 1 次移位,而是 n 次移位,然后重复进行。例如,如果你给你的朋友 5,8,13,0,1,1,2,3(这不是一个随机的顺序)。然后第一个字母移动 5 个字母,第二个字母移动 8 个字母,下一个移动 13 个字母,下一个移动 0 个字母,…第八个字母移动 3 个字母,然后重复这个序列。所以第九个字母被移动了 5 个字母,等等。移位序列越长,破解密码就越难。但是这个密码仍然不能完善保密。
一次性密码本
然而,一次性密码本提供了完美的保密性,因为每个字母都被分配了一个随机移位。然而,这是有代价的——大量的数据——你需要转换每封邮件/文件/你所传达的任何信息中的每一个字母。产生随机移位基本上就是德国人在二战中设计的恩尼格玛机在做的事情。然而,有一些人为错误允许模式被确定,恩尼格玛机被破解。
参考资料和资源
2018 年 9 月 16 日教程 python 加密网络安全在这篇文章中,我演示了加密模块的用法…
nitratine.net](https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/) [## Python 中的加密和解密
2018 年 9 月 16 日 YouTube python encryption cyber-security 在这篇文章中,我将讨论如何在…
nitratine.net](https://nitratine.net/blog/post/encryption-and-decryption-in-python/) [## 加密您的数据
使用 Python 进行对称加密
towardsdatascience.com](/encrypting-your-data-9eac85364cb) [## PyNaCl
PyNaCl 是绑定到 lib 钠的 Python,lib 钠是网络和加密库的一个分支。这些库…
pypi.org](https://pypi.org/project/PyNaCl/) [## 欢迎使用 pyca/Cryptography-Cryptography 2.9 . de v1 文档
密码术包括高级配方和普通密码算法的低级接口,例如…
密码学. io](https://cryptography.io/en/latest/) [## 安全外壳
安全外壳(SSH)是一种加密网络协议,用于在不安全的…
en.wikipedia.org](https://en.wikipedia.org/wiki/Secure_Shell) [## 传输层安全性
传输层安全性(TLS)及其现已废弃的前身安全套接字层(SSL)是加密的…
en.wikipedia.org](https://en.wikipedia.org/wiki/Transport_Layer_Security) [## 密码学基础
R 中的应用程序
towardsdatascience.com](/the-basics-of-cryptography-80c7906ba2f7) [## 密码 101
提供了理解 SSL/TLS 等完整系统所需的一切:分组密码、流密码、哈希…
www.crypto101.io](https://www.crypto101.io/)**
我是一名文化数据科学家
我可能刚刚创造了一个新的工作头衔…?
我用这个头衔已经有几个月了。在我的网站上。在我的作品集里。在的会谈和介绍。甚至当我认识新朋友的时候。
问题是,“文化数据科学家”这个术语并不存在。我刚编的。
我是一名数据科学家,使用统计学、计量经济学、机器学习、城市分析、社交媒体分析和数据可视化来了解和衡量文化在城市中的经济和社会影响。
但这显然有点拗口,尤其是当我在酒吧和一个不知道这些行话术语定义的人聊天时。
所以,我想我应该写一篇关于它的博客。
什么是文化?
文化是其中一个很重要的术语。这个定义被分为“艺术”和“社会行为”两部分,但它是一个泛指我们的术语。
《牛津词典》对文化的定义是:
- 艺术和其他人类智力成就的表现形式的总称。
- 特定民族或社会的观念、习俗和社会行为。
维基百科将文化描述为“人类社会中的社会行为和规范”
英国政府数字、文化、媒体和体育部(DCMS)有一个完整的部门关注“文化和创意”产业,其中包括艺术;电影、电视和音乐;收音机;摄影;工艺品;博物馆和美术馆;图书馆和档案馆;文化教育;历史建筑和类似旅游景点的经营;广告和营销;建筑;工艺品;设计和设计师时尚。
令人恼火的是,商界最近似乎也在劫持这个词。
什么是数据科学?
数据科学是一门使用和分析数据来测试假设、回答问题和理解见解的学科。
数据科学是“统一统计学、数据分析、机器学习及其相关方法的概念”,以便用数据“理解和分析实际现象”。
文化数据科学家
因此,文化数据科学家这个头衔很好地概括了我的工作。
我是一名数据科学家,使用统计学、计量经济学、机器学习、城市分析、社交媒体分析和数据可视化来了解和衡量文化在城市中的经济和社会影响。
我对文化的研究始于艺术,但现在已经相当广泛,跨越了艺术到音乐、时尚和食物。
职称比*“我是文化部门的数据科学家”*好多了。
可比资产
就像你如何成为一名经济顾问、财务顾问、软件工程师、机器学习工程师、土木工程师或 T21 工程师一样
我是一名文化数据科学家。
也许我太迂腐了?
但事实是,我每天打交道的人——艺术和文化部门的人——甚至不知道什么是数据科学家!
将“文化”放在“数据科学家”的前面,这种区分不仅独特有趣,而且有助于将我的工作置于背景之中。
研究
为了证明职位名称文化数据科学家并不存在,我将链接几个流行且常用的搜索引擎。
根据 Google Trends — 此处 —该术语不存在(2019 年 2 月 11 日检索)。
LinkedIn — 这里 —没有其他人有这个职位(2019 年 2 月 11 日检索)。
天使名单上也没有那个职位的工作——此处此处(2019 年 2 月 11 日检索)。
甚至一个标准的谷歌搜索也不会产生这个词。
文化分析和文化数据科学
不可否认,有人在使用“文化分析”这个术语,也有一些大学在使用“文化数据科学”。
列夫·马诺维奇在 2007 年发明的术语文化分析,是“对视觉材料的海量文化数据集的探索和分析”。
另一方面,加拿大蒙特利尔的麦吉尔大学有一个社会和文化数据科学的 T4 中心。
伦敦帝国理工学院有一个社会和文化分析实验室,但是他们的推特账户自 2015 年 10 月 30 日以来就没有发过一次推特!严重努力差!
我目前就读的位于 UCL 的巴特利特学院将推出一个名为文化遗产数据科学的新硕士学位。
但有趣的是,没有人使用文化数据科学家的头衔。
我是不是创造了一个新的头衔…?
截至 2019 年 3 月,我未能找到任何积极使用职位名称“文化数据科学家”的人。
该术语是必需的。随着我们进入 2020 年,文化变得更加数字化,现在存在更大的数据集,并且有更复杂的方法来分析这些数据。
如果大学正在创建这些研究实验室,那么人们应该对使用文化数据科学家这个头衔来描述他们正在做的工作感到舒服。
在我看来,社会科学家这个词是不行的,数据科学家也太宽泛了。计算社会科学家是个东西,但你指的是哪门社会科学……地理学、经济学、人类学、社会学、心理学、政治学……全部?
无论如何,看起来我刚刚创造了一个新的工作头衔,而且我会坚持一段时间!如果你的工作符合要求,我鼓励你也使用它!
感谢阅读!
Vishal
本文首发于 2019 年 3 月 10 日vishalkumar . London。
Vishal 是一名文化数据科学家,也是伦敦 UCL 的一名研究生。他对城市文化的经济和社会影响感兴趣。你可以在Twitter或者LinkedIn上与他取得联系。在insta gram或他的 网站 上看到更多 Vishal 的作品。
当前使用 Python3.7 的 Google 搜索包:简单教程。
简介
本文总结了当前使用 Python 3.7 实现 Google 搜索查询的常用库和包。写这篇文章的动机来自于我收到或看到的关于这个主题的异常多的请求。这背后的原因是 Google 的 SOAP 和 AJAX API 的停止使用——这两者都是为此目的而设计的。围绕数据科学和 python 的许多领域都有很好的文档记录,但是我发现在 Python 中使用 Google 搜索并没有很好的文档记录,这也是我写这篇文章的动机。
谷歌搜索——现代的必需品
使用谷歌搜索已经成为我们时代的一种主要方式,可以在几毫秒内从互联网的各个角落释放信息。在过去的 20 年中,我们一直依靠这种常见的方法来查询从新闻文章到研究主题的各种信息。随着过去几年数据科学的兴起,搜索互联网的两个最常见的原因是(1)解决堆栈溢出问题,或(2)数据挖掘——第二个原因将是本文的重点。
无论是为了科学目的还是商业智能项目,Python 和数据挖掘都被证明是一对非常有效的工具。数据挖掘被定义为检查大量数据以提取新信息或见解的方法。就本文的目的而言,因为它与 web 有关,所以从 internet 挖掘数据的方法称为 web 挖掘,它可以分为三类:(1) Web 内容挖掘,(2) Web 使用挖掘,以及(3) Web 结构挖掘。
谷歌搜索——事物的大计划
在我最近看到的许多与 web 挖掘相关的项目中,检索数据的首选方法是使用 google search 来检索 URL,以便进行 web 抓取。大部分项目都遵循这种通用格式,在这种格式中,URL 被获取,每个 URL 被解析和抓取,最后所有的数据被组织起来。出于本文的目的,我们现在只关注 URL 检索过程(蓝色部分)。需要强调的是,根据您正在寻找的数据类型;使用 RSS 源可能更合适。这当然很大程度上取决于您考虑的数据源是否提供 RSS 提要。我们稍后将再次讨论这个问题。
The general flow of thought in this article begins with the retrieval of URLs, which are then parsed, and then set up for future analysis.
现在让我们检查一个具体的用例。我们希望识别和量化某个公司的新闻文章或感兴趣的话题。在这种情况下,我想找到所有与人们对苹果公司新款 iPhone 的评论相关的文章
我们开始吧——我们有 3 个选项可以通过 Python 进行搜索
在本文发表之日,有三个公共库允许通过 Python 进行谷歌搜索。我们将从最简单的开始,转到最复杂的,因为我想确保所有数据科学家和所有非技术读者能够跟上。也就是说,你会注意到我概述的代码并不完全是最“皮托尼卡”。在写这篇文章的时候,我试图在“简单”和“高效”之间保持一个健康的平衡,以确保所有的读者都从中受益。
选项 1——谷歌图书馆(免费,但有限制)
我们首先在终端命令行上使用 pip 安装谷歌库:
pip install google
在我们的 Jupyter 笔记本中,我们可以通过以下方式导入库:
from googlesearch import search
然后,我们概述我们想要查询的内容。在我们的案例中,我们希望监控一个特定的公司或话题。让我们以“苹果”公司和“苹果手机”为例,检索关于它们的新闻文章。
query = "apple iphone news 2019"
下一步是创建一个空列表,并使用“for 循环”迭代代码:
my_results_list = []for i in search(query, # The query you want to run
tld = 'com', # The top level domain
lang = 'en', # The language
num = 10, # Number of results per page
start = 0, # First result to retrieve
stop = None, # Last result to retrieve
pause = 2.0, # Lapse between HTTP requests
): my_results_list.append(i)
print(i)
就这样!结束了。
这个库运行良好,并可靠地返回结果(而且是免费的!).然而,有一个方面我们没有考虑。“暂停”参数每次都会将查询延迟 2 秒。如果您要查找更多的结果,这将大大增加您的搜索时间。删除这个参数通常会在几秒钟内导致 403 错误(也就是谷歌阻止你)。除了遵守第二条规则之外,没有任何好的方法来解决这个问题(至少对于这个特定的包来说)。
选项 2-谷歌搜索结果库(非免费,无限制)
这里的第二个选择是使用 SERP 的谷歌搜索功能。
from serpapi.google_search_results import GoogleSearchResultsclient = GoogleSearchResults(
{"q" : "apple iphone news 2019", # The query
"location" : "Boston,MA", # Location
"secret_api_key" : "secretKey"} # API Key from SERP
)
result = client.get_dict()
result
虽然这个库有相关的成本,但它值得研究,因为它允许您避开上面选项 1 中 google 库中 HTTP 请求的 2 秒暂停。总之,这是一个伟大的图书馆,但它不是免费的。
选项# 3——谷歌应用编程接口客户端(大部分免费,大部分无限制)
据我所知,谷歌 API 客户端,,是我们目前为止看到的唯一一个谷歌拥有的项目。当涉及到导航这个空间时,它们提供了广泛的能力。我把它们列在最后,因为对于一些人来说,建立一个完整的账户并准备好是一个困难的过程。但是,如果您正在开发一个严重依赖搜索查询的模型,我建议您优先选择这个选项。
在过去,我试图介绍注册的基本步骤,但是过程中的小步骤似乎经常改变。我建议你首先阅读最新的“入门”页面。一旦你建立了一个帐户,你将需要获得两个项目:(1)一个私人的 API 密钥,和(2)一个自定义搜索引擎 ID。
设置好帐户后,继续安装库:
*pip install google-api-python-client*
安装了库之后,您可以继续运行您的第一个查询:
*from googleapiclient.discovery import build #Import the libraryapi_key = "my-secret-api-key"
cse_id = "my-secret-custom-search-id "def google_query(query, api_key, cse_id, **kwargs):
query_service = build("customsearch",
"v1",
developerKey=api_key
)
query_results = query_service.cse().list(q=query, # Query
cx=cse_id, # CSE ID
**kwargs
).execute()
return query_results['items']my_results_list = []my_results = google_query("apple iphone news 2019",
api_key,
cse_id,
num = 10
) for result in my_results:
my_results_list.append(result['link'])
print(result['link'])*
我认为最后一个选项是检索 URL 列表的最佳方式(甚至是一些原始的 HTML 数据!)以一种可靠且免费的方式。
总结了这三种方法后,我们以一个 URL 列表结束,我们现在可以解析这个列表来检索感兴趣的信息。我想指出的一个方面是,我们运行了 google 搜索来检索关于感兴趣的公司或主题的信息。有人可能会说 RSS 提要更适合检索新闻——事实也的确如此。然而,从商业智能的角度来看,我们希望确保所有相关的结果都出现在我们的查询中,并且数据不会偏向一个新闻源而不是另一个。一种常见的方法是将查询结果和 RSS 提要结合在一起,不过,我们将在另一个时间讨论这个问题。
向前移动&下一步
既然已经设置好了 URL 列表,下一个目标就是解析 URL 并检索数据。抓取 web 是数据科学的一个记录良好的领域,近年来随着文章和教程的出现而蓬勃发展。也就是说,我不会在本文中涉及它。但是,我会提供一些后续步骤的指导。
回头看看前面提到的框架,下一步是从 web 上搜集数据,然后相应地组织内容,为要开发的模型做准备。有几个不同的库可以用于这个过程。Scrapy 是一个优秀的抓取框架,当涉及到网页抓取时,它被称为“一体化”包。另一方面,我们有 Selenium,这是一个为浏览器自动化设计的库,允许您在页面之间导航。最后,我们有 BeautifulSoup ,它是一个更加保守和用户友好的数据检索器。鉴于 BS4 更加直接,非常适合大多数数据科学家的需求,我建议继续使用它。
There are 3 main libraries commonly used for scraping websites. I find BeautifulSoup to be the easiest to learn and follow — therefore we will use this an example for this article and tutorial.
我希望这篇文章对 Python 3.7 中搜索查询的使用有所帮助。我鼓励任何有你希望我报道的话题或想法的人,给我发电子邮件到 salehesam@gmail.com。
使用自定义实体提取解析结构化文档
Let’s talk about parsing structured documents with entity extraction!
网上有很多很棒的教程,解释如何用机器学习对大量文本进行分类。但是,如果不仅仅是对文本进行分类,而是想要对单个单词进行分类,比如:
You can’t make me apologize for loving Comic Sans.
这被称为实体提取(或命名实体识别),它非常有用。例如,您可以使用这种技术来挑选新闻文章中提到的所有人和地点,并将它们用作文章标签(新闻编辑室有时会这样做)。
实体提取(EE)对于解析结构化文档也很有用,比如表单、w4、收据、名片和餐馆菜单(这就是我们今天要用的)。
对于今年的 Google I/O,我想建立一个应用程序,它可以拍摄餐厅菜单的照片并自动解析它——提取所有的食物、它们的价格等等。(你可以在这里看到我在舞台上演示。)
我希望能够上传一张这样的菜单图片:
Step one: upload a photo of a menu
然后使用机器学习从菜单中神奇地提取实体,如餐厅的地址、电话号码、所有的食物标题(“沙拉”、“主菜”)、所有的食物、它们的价格和它们的描述(即“在椒盐卷饼上”)。
这个想法是,如果你是一家想要在像 Seamless 或 Grubhub 这样的应用程序上上市的餐馆,你可以输入你的菜单,而不必手动输入整个菜单。
Step two: identify all the foods, plus the food headings (“Salads,” “Mains”) and their descriptions (“On a pretzel bun”).
那么它是如何工作的呢?
首先,我使用 Google Cloud Vision API 的文本检测功能将我的菜单图片转换成原始文本。
一旦我有了文本格式的菜单,我就使用实体提取来解析它。我用两种技术做到了这一点:
- 我使用 Google Cloud 自然语言 API 提取了餐馆的地址、电话号码和所有列出的价格。
- 为了识别食物项目、标题和食物描述,我必须建立一个定制的机器学习模型(稍后会详细介绍)。
自然语言 API 能够自动检测常见的实体。例如,如果我向它发送字符串:
戴尔想从加利福尼亚州山景城 ampi theatre Pkwy 1600 号的咖啡店购买一个 3.50 美元的羊角面包,该咖啡店的电话号码是(650)253–0000。
The NL API recognizes entities like people, consumer goods, addresses, price, phone numbers, and more.
接下来,我添加了一张餐馆照片、星级评定和一张地图,让我的应用程序变得更加时尚。这些信息都没有直接印在菜单上,但餐馆的电话号码是。使用这个电话号码,我可以查询 Google Places API 来获取照片、星级等。
The restaurant’s star rating, photo, and GPS location come from the Places API.
构建自定义实体提取模型
好的,但是现在是困难的(也是最关键的)部分:我们如何提取菜单上的所有食物?我们如何区分什么是食物(“素食汉堡”),什么是食物标题(“主菜”),什么是食物描述(“在椒盐卷饼上”)?
这些实体完全是特定领域的。在我们的例子中,我们希望认识到“主菜”是一个食物标题。但是如果我们转而解析报纸,我们可能想要识别标题和文章正文之间的区别。或者,如果我们在分析简历,我们会想确定“高级软件工程师”是一个职位,而“Python”是一种编程语言。
虽然我之前提到的自然语言 API 可以识别电话号码和地址等等,但是它没有经过训练来识别这些特定于领域的实体。
为此,我们必须构建一个定制的实体提取模型。有很多方法可以做到这一点,但是我将向你展示一个我认为最简单的方法(代码最少),使用 Google AutoML 自然语言。我们将使用它来训练自定义实体提取模型。
它是这样工作的:
- 上传带标签的菜单数据集
- 训练模特
- 使用您的模型通过 REST API 识别定制实体
标签数据
但是在哪里可以找到一个标签菜单的数据集呢?
方便的是,我找到了这个由托管的菜单扫描的数据集(并贴上了标签!)由纽约公共图书馆提供。太棒了。
首先,我再次使用 Vision API 将数据集中的所有菜单转换为文本。
为了训练一个定制的实体提取模型,我必须将我的数据及其标签转换成 jsonl 格式(AutoML 期望的格式)。看起来是这样的:
jsonl file format
我要诚实地警告你,实际上给这些菜单贴标签是一件痛苦的事情。我使用一些粗糙的 Python 脚本将数据集的标签与 OCR 提取的菜单文本配对,但它们经常不对齐。我不得不进入 AutoML 用户界面,手工标记这些菜单,就像这样:
Hand-labeling menus using the AutoML editor.
回想起来,我可能应该使用一个数据标签服务,这样我就不必浪费时间给自己(或者实习生,也许?).
我还抓取了维基百科的美食页面,生成了一些假菜单来帮助扩充我的数据集。
训练模型
使用 Google AutoML,构建模型最困难的部分是构建带标签的数据集。实际上训练一个有这些数据的模型非常简单——只要跳到“训练”标签,然后点击“开始训练”建立一个定制模型大约需要 4 个小时。
Behind the scenes, Google trains a neural network to extract your custom entities.
做预测
当我们的实体提取模型完成训练后,我们可以在 AutoML UI 中测试它:
The model tagged most of the entities, but missed “Potato Chips” and “Fish and Chips.”
如你所见,它并不完美。
但是你想要什么?!那就是机器学习。不是完美。
也就是说,考虑到我的数据集很小(不到 150 个菜单),这还不错。我也没有考虑到文本的大小或它在页面上的位置(标题通常比菜名大,菜名比它们的描述大)。
但是,如果我是一家餐馆,我可以使用这个工具来导入我的菜单,而不是手动输入每一种食物,我会节省很多时间(尽管我可能需要做一些编辑)。此外,越多假设的餐厅使用我的应用程序,我就能获得越多假设的数据点来改进我的模型。
与此同时,谷歌咖啡馆的午餐来电。再见。
P.S .如果训练自己的实体提取模型,在评论里说说或者 @dalequark 。
快乐造型!
如何使用 R 在 Power BI 中生成定制的视觉效果
在 Power BI 中轻松创建交互式 R powered HTML 视觉效果
您是否曾想通过 Power BI 显示自己定制的视觉效果?如果答案是肯定的,那么这篇文章将帮助您快速了解如何导入在 R 中创建的自定义视觉效果,并在您的常规 Power BI 报告中使用它们。
先决条件:
**安装 R and R 工作室:**假设已经安装了 Power BI 桌面应用,首先需要安装 R 语言和集成开发环境(IDE)来运行 R 脚本。写这篇文章的时候,我正在使用 R-3.5.1 和 R Studio 。
**在 Power BI 中启用 R 视觉功能:**从 Power BI 桌面,转到文件>选项和设置>选项,然后在 R 脚本选项卡中选择您的 R 主目录和 IDE。
Enabling R home directory and IDE in Power BI
安装 node.js: 访问这个网站并下载最新的特性安装程序。按照向导中的安装步骤完成该过程。完成后,重新启动计算机开始。
**安装包:**打开 node.js 命令提示符,执行以下命令:
*npm install -g powerbi-visuals-tools*
要检查安装是否成功,请运行以下命令:
*pbiviz*
您应该会看到如下所示的帮助屏幕。
Successful installation of Power BI visual tools
**数据:**我使用了来自 UCI 机器学习知识库的老爷车评估数据集。你可以从这里下载,保存成 CSV 格式。根据该数据集,客户对汽车的接受程度取决于 6 个主要标准——购买价格、维护成本、车门数量、载客量、行李箱尺寸和汽车的预计安全性。这是数据集的一瞥:
Car evaluation data set
在本文中,我将创建一个 HTML 100%堆积柱形图来显示汽车的可接受性如何随购买价格而变化。
使用 R 创建 HTML 视觉效果:
**连接到数据:**首先,使用 Get Data 从 Power BI 桌面应用程序连接到您的数据。数据导入后,在可视化窗格中单击 R script 可视化图标。将要使用的列拖放到值区域。这将自动生成您将要处理的数据集。单击 R script 编辑器角落的小箭头,重定向到 R Studio,这样您就可以尝试和测试您的代码来生成定制的视觉效果。
Step by step instruction on how to create R script visuals
你可以跳过以上所有步骤,直接在 R Studio 中编写 read.csv 代码,连接你保存在本地机器中的数据。
**创建常规的非 HTML 视觉效果:**一旦 R Studio 打开,您可以看到读取数据集的代码已经存在,您可以立即开始您的分析。写下你的 R 代码,运行到 R studio 中,生成你想要的视觉效果。我在 R 中使用了流行的 ggplot2 库来可视化汽车的购买价格与其可接受性之间的关系。
*library(ggplot2)
g <- ggplot(data=dataset, aes(x=dataset$buying,
fill=dataset$car_acceptibility)) +
geom_bar(stat=”count”) +
scale_x_discrete(name =”Buying Price”) +
scale_fill_discrete(name=”Acceptability”)
g*
Buying price vs. Car acceptability
如果您在 Power BI 的 R 脚本编辑器中直接使用上面这段代码,它会生成一个图表,表明购买价格非常高的汽车很可能不会被大多数客户接受。您可以创建自己的过滤器来分割这个交互式图表。
Filtered chart to display only accepted cars
例如,如果您只想查看各种购买价格类别中接受的汽车数量,您可以创建一个汽车可接受性切片器并过滤数据。请注意,这不是一个 HTML 输出。
**创建 rhtml 模板:**常规 R-powered 定制可视化将输出绘图显示为静态图像。要生成 HTML 视觉效果,您需要创建 rhtml 模板。在 node.js 命令提示符下,执行以下命令:
*pbiviz new demoCarEvaluation -t rhtml*
rhtml template creation
这个模板包括一个非常基本的可以运行的 R Visual,它可以创建 HTML 输出。
使用 rhtml 模板:导航到您的本地机器,找到创建democare evaluation**文件夹的位置。在我的例子中,很明显这个文件夹在 c 盘> Users > username 中。找到新创建的文件夹后,打开它并在 R Studio 中编辑 script.r 文件。将您写下的代码粘贴到 script.r 的“实际代码”部分,以生成静态 R 可视化。
在下图中,你可以看到我已经粘贴了之前用来生成上面的堆积柱形图的全部代码。
**运行 rhtml 模板:**转到 node.js 命令提示符,使用更改目录命令导航到存储 script.r 的文件夹。若要打包 visual,请执行以下命令:
Changing the directory
*pbiviz package*
Creating the package
打包完成后,返回 Power BI 桌面应用程序,点击可视化窗格中的 从文件 导入。浏览到内的 dist 文件夹,导入 pbiviz 文件在报告中使用。
在 Power BI 中创建自定义可视化:完成上述所有步骤后,您将在可视化窗格中获得一个新图标。点击democare evaluation图标,在 Values 字段下拖动您想要在视觉中使用的列,您将在报告中看到您的 HTML 图表。将鼠标指针悬停在图表上,您将看到图表每个部分的更多详细信息。HTML 视觉支持一系列活动,如放大/缩小、自动缩放等。
如果你想在相同的数据上创建其他的视觉效果,你只需要编辑 script.r 文件,再次运行pbi viz package命令,你将能够非常快速和容易地创建新的视觉效果。
HTML custom visual using R
探索和享受!
<<note: this=“” is=“” an=“” old=“” article=“” originally=“” published=“” in=“” march=“” as=“” power=“” bi=“” changes=“” rapidly=“” please=“” check=“” microsoft=“” documentation=“” site=“” for=“” the=“” latest=“” updates.=“”>></note:>
谷歌人工智能平台上的定制模型部署服务
Source: Google
我在 Wootric 部署定制机器学习模型、管道和预测例程的经验
R 最近,谷歌云人工智能平台服务(CAIP)增加了一个新功能,机器学习(ML)从业者现在可以使用他们喜欢的框架,通过定制的预处理管道和预测例程来部署模型,所有这些都在一个无服务器微服务下。在这篇博文中,我详细解释了我们 Wootric 如何利用这一功能,并提到了一些需要注意的细节,因为该产品仍处于测试阶段。
一点背景知识
https://engineering.wootric.com/all
在我们将焦点完全转移到模型部署之前,我将花一点时间向您介绍一下我们的模型试图解决的问题的背景。在 Wootric,我们使用 NLP 和深度学习来学习和标记不同行业的客户和员工反馈中的主题。一条反馈可以与一个或多个标签相关联,如上图所示。要了解我们产品的更多信息,请访问此链接。这可以看作是一个模型的多标签分类问题,或者是 n 模型的两类多类分类问题。出于这篇博客的目的,我们将把它视为一个多类分类问题,并为 n 个标签部署 n 个模型。
模型概述
当我开始研究这个问题时,我用传统的 ML 分类器进行了实验,这些分类器根据每个标签的数据的不同单词包表示进行训练,作为基线。在这些模型中,总体来说最好的是随机森林模型。在本文中,为了便于解释,我们将部署这些模型,这样我们就可以花更多的时间在 CAIP 上进行定制部署,而不会迷失在模型的复杂性中。在后面的帖子中,我们将在更高的层次上讨论基于 CNN 的模型和基于序列的多标签模型的部署,两者都是用 pytorch 编写的。
人工智能平台服务概述
https://cloud.google.com/ — — The blue boxes highlight where CAIP comes into play
我们将在上图下半部分的 4 个方框中快速谈论 CAIP 的优势。要了解如何使用 CAIP 来训练和评估模型,请访问此链接。
在 CAIP 上,我们可以部署使用直接兼容的框架(sklearn、XGBoost、tensorflow)中的管道训练的模型,或者部署具有所需依赖关系的自定义预测器类和任何自定义的状态相关的预处理和后处理类作为源分发包。这里一个很大的积极因素是原始数据预处理、预测和预测后处理的耦合,所有这些都在一个模型微服务下;一切都发生在服务器端!这有几个值得一提的好处。首先,由于客户端没有进行预处理,这就将客户端从模型中分离出来。因此,我们可以在不更新客户端的情况下更新预处理代码,或者为更新提供新的端点。其次,不存在训练-服务偏斜,因为预处理步骤中的任何变化都会迫使我们重新训练模型。
此外,CAIP 的自定义预测例程允许我们将基于规则的预测与模型预测相集成,还可以从存储在存储桶中的模型集合中聚合预测。
由于这篇博客完全专注于定制部署,如果你对从 CAIP 支持的库中部署预定义的模型管道感兴趣,请参考这篇教程。
进入状态…
在我们继续之前,您应该:
- 熟悉 Google Cloud SDK ,
- 在 GCP 上创建一个项目,启用计费并启用 AI 平台(“云机器学习引擎”)和计算引擎 API。
或者,您可以在谷歌云平台(GCP)控制台上重复这些步骤,或者使用 REST API。
让我们进入代码
我有 11 个随机的森林模型,为 11 个不同的标签训练。这些标签是消费者对 SAAS-y 公司反馈的常见主题。以下是标签:
["Alerts_Notification", "Bugs", "Customer_Support", "Documentation", "Feature_Request", "Onboarding", "Performance", "Price", "Reporting", "UX_UI", "Value_Prop"]
考虑到我们正在处理嘈杂的文本数据,拥有可以清理数据的自定义预处理帮助程序肯定是有用的,如下所示:
简而言之,清理步骤包括数据的小写、使用 wordnet pos 标签的词汇化以及删除标点符号。这里要注意的一个重要步骤就在 gist 的上面,我将所需的 NLTK 资源下载到tmp
文件夹中,我将它附加到 NLTK 可以查找资源的路径列表中。在运行时,这是此类资源的唯一可写文件夹。另一种方法是将这些资源保存在包含所有模型工件的源分发包 tarball 中作为序列化对象,并将它们直接加载到自定义预测器类中(我们将在后面讨论)。
下面是我用来训练每个模型的代码:
在上述要点中需要注意的重要一点是使用了来自 sklearn 的 FunctionTransformer 方法,该方法允许我们向管道添加自定义预处理例程,只要自定义例程的 I/O 与其相邻例程的 I/O 一致。本质上,上面的代码循环遍历数据帧中的每个标签,使用LabelEncoder
将标签列转换为标签。然后,使用反馈r_text
和转换后的标签为每个标签训练一个模型,最终导出为酸洗对象。可以认为,在这种情况下,具有包含clean_data_custom
和text_transform
*,*的公共预处理 sklearn 管道对象将是最佳的,因为每个模型都在相同的数据上被训练,具有相同的配置。然而,为了简单起见,我们允许每个模型都有自己的预处理管道。如果您最终得到了一个公共管道对象,这可以合并到自定义预测器类中,我们将在接下来讨论。
让我们快速回顾一下。到目前为止,我有 11 个酸洗的模型管道(每个标签一个),以及一个预处理模块,带有用于清理的辅助函数。
现在的主要问题是,CAIP 如何将预测的输入反馈导入这 11 个模型?另外,我该如何处理 preprocess.py 以便 CAIP 可以将其链接到模型管道对象,这样他们就可以使用clean
函数了?
为了解决第一个问题,自定义预测例程开始发挥作用。参考下面我写的 CustomPredictor 类:
在我们继续之前,要知道每次我们为一个定制的预测例程创建一个新的模型版本时,我们都会将信息传递给 CAIP,它可以使用这些信息在一个存储桶中寻找模型工件。稍后我们将在代码中看到如何做到这一点,但现在要理解这些信息是使用标志传递给 gcloud 的。因此,当我们创建一个新的模型版本时,我们设置prediction-class
gcloud 标志指向 multiTag 模块中的 CustomPredictor 类。GCP 现在所做的是在源代码发行包**、**中查找这个类,并调用带有模型目录的from_path
类方法作为参数,它从另一个名为origin
的标志中选取这个参数,这个标志也是在创建模型版本时传递的。确保 GCP 在这里传递正确的目录路径是至关重要的!该方法将所有加载的模型存储到一个列表中,并用这个列表实例化一个CustomPredictor
对象。
现在,在创建自定义预测器类时,必须遵循以下模板:
基本上,总是让from_path
方法返回一个带有相关参数的自定义预测器类的实例,在本例中只是一个模型列表。这也是我们可以加载自定义预处理管道对象并将其传递给自定义预测器的地方,我们在前面简单地讨论过。现在,所有的神奇都发生在 predict 函数中。这将 JSON 反序列化的输入字符串列表作为输入。如代码所示,我简单地循环每个实例,循环每个模型,并将预测结果作为 python 中的 dictionary 对象追加。返回的results
必须是 JSON 可序列化的。
现在回到第二个问题(你记得是什么吗?).我如何告诉 CAIP 将 preprocess.py 链接到模型管道对象,以便它们可以使用clean
函数?另外,我如何上传 multiTag.py 模块?
这两个问题的答案都是一样的:作为一个源码分发包 (SDP)!如果您没有记错的话,我曾经提到过几次,所有的工件都必须包含在 SDP 中,并且这两个文件都算作模型工件。
下面是创建 SDP 的模块 setup.py :
scripts 参数应该是每个相关脚本的本地路径的 iterable。要创建 SDP,请运行以下命令:
python setup.py dist --formats=gztar
这里,dist
是 SDP 的目标目录。
现在我们已经准备好了所有的脚本和模型,剩下的就是运行几个 gcloud 命令,将模型和 SDP 复制到一个存储桶,创建一个模型资源并将其链接到这个桶,最后创建一个模型版本并进行在线预测!
首先,创建一个具有有效存储段名称和区域的存储段:
$BUCKET_NAME="multiTag_bucket"
gsutil mb -l $REGION gs://$BUCKET_NAME
为了复制模型和 SDP,我使用了gsutil cp
命令:
gsutil -m cp *.pkl gs://$BUCKET_NAME
gsutil cp dist/multiTag_custom_package-0.1.tar.gz gs://$BUCKET_NAME/multiTag_custom_package-0.1.tar.gz
更容易将 bucket 放在注册到 AI 平台的同一个项目中,否则 bucket 将需要 显式访问 到 AI 平台服务帐户。
现在我们已经将所有的工件都放在了一个存储桶中,让我们创建一个模型:
gcloud ai-platform models create "multiTag_model"
让我们也设置以下变量
MODEL_DIR="gs://multiTag_bucket"
VERSION_NAME="v0"
MODEL_NAME="multiTag_model"
CUSTOM_CODE_PATH="gs://multiTag_bucket/multiTag_custom_package-0.1.tar.gz"
PREDICTOR_CLASS="multiTag.CustomPredictor"
我将所有的模型和工件直接放入桶中,没有创建任何额外的目录,所以我的MODEL_DIR
只是桶 URI(通用资源标识符)。如果您的模型和相关的工件有不同的目录结构,确保您为 MODEL_DIR
和CUSTOM_CODE_PATH
给出了正确的绝对路径。
现在,创建如下面代码所示的版本。这就是我之前的意思,当我提到在创建一个模型版本时,将所有关于模型工件的位置元数据传递给 CAIP。
gcloud beta ai-platform versions create $VERSION_NAME \
--model $MODEL_NAME \
--origin $MODEL_DIR \
--runtime-version=1.13 \
--python-version=3.5 \
--package-uris=$CUSTOM_CODE_PATH \
--prediction-class=$PREDICTOR_CLASS
一旦创建了版本,您现在可以发送在线预测的输入。用这种格式的输入创建一个. txt 或 JSON 文件(推荐)。
现在,您可以通过运行以下代码获得在线预测:
gcloud ai-platform predict --model $MODEL_NAME --version $VERSION_NAME --json-instances $INPUT_FILE
并得到预测:
Predictions for a feedback
因此…
总的来说,我认为部署过程非常顺利,也很容易理解。然而,当我刚开始使用 CAIP 时,我面临的一个挑战是,对于部署期间或部署后(预测期间)的内部错误,回溯对调试没有太大帮助。我必须仔细检查每一点代码以了解问题,然后再次部署,这可能会让您有点紧张,因为部署过程本身需要几分钟,尤其是对于大型模型。所以调试这里或那里的小错误实际上会花费你很多时间!
等等,什么?你说用 CAIP local predict
测试我的模型?对于那些不知道的人,在部署之前,您可以使用 CAIP local predict
命令来测试您的模型在部署之前如何服务于预测。该命令使用本地环境中的依赖项来执行预测,并以与[gcloud ai-platform predict](https://cloud.google.com/sdk/gcloud/reference/ai-platform/predict)
执行在线预测时相同的格式返回结果。在本地测试预测有助于您在为在线预测请求支付费用之前发现错误。但是,但是…酪这个特性不适用于定制的预测例程,所以在部署之前要非常小心你的代码!
最后,需要注意的最后一点是,CAIP 上模型工件的限制是 250 MB 。你可以向谷歌申请更高的配额来部署更大的型号。
就这样,你成功了!我真的希望你喜欢阅读这篇文章,并发现它是有帮助的。如果您有任何问题,请留下您的评论!
部署愉快!
使用空间的自定义命名实体识别
Figure 1: Source
什么是命名实体识别(NER)?
命名实体识别(NER)是信息提取(IE)的一个子任务,在一个或多个文本主体中找出指定的实体并对其进行分类。NER 也简称为实体识别、实体分块和实体提取。NER 被用于人工智能的许多领域( AI ),包括自然语言处理( NLP )和机器学习。
NER 的空间
SpaCy 是 Python 中高级自然语言处理的开源库。它是专门为生产使用而设计的,有助于构建处理和“理解”大量文本的应用程序。它可以用于构建信息提取或自然语言理解系统,或者用于深度学习的文本预处理。spaCy 提供的一些功能包括标记化、词性(PoS)标记、文本分类和命名实体识别。
SpaCy 为 python 中的 NER 提供了一个非常有效的统计系统,它可以将标签分配给连续的标记组。它提供了一个默认模型,可以识别广泛的命名或数字实体,包括*个人、组织、语言、事件等。*除了这些默认实体之外,spaCy 还允许我们自由地向 NER 模型添加任意类别,方法是训练该模型,以便用更新的训练样本对其进行更新。
入门指南
装置
SpaCy 可以通过简单的pip
安装来安装。您还需要下载您希望使用 spaCy 的语言的语言模型。
pip install -U spacy
python -m spacy download en
我们开始吧!
数据集
我们将要处理的数据集可以从这里下载。我们将使用ner_dataset.csv
文件,只训练 260 个句子。
Figure 2: NER Dataset
数据集由以下标签组成-
- 地理=地理实体
- org =组织
- per =人
- 地缘政治实体
- tim =时间指示器
- 艺术=艺术品
- eve =事件
- 自然现象
数据集遵循生物类型标记。
数据预处理
SpaCy 要求训练数据采用以下格式-
Figure 3: spaCy Format Training Data (Source)
所以我们必须把我们的数据从.csv
格式转换成上面的格式。(spaCy 也接受其他形式的训练数据。更多细节请参考 文档 *。)*我们首先删除列Sentence #
和POS
,因为我们不需要它们,然后将.csv
文件转换为.tsv
文件。接下来,我们必须运行下面的脚本来获取.json
格式的训练数据。
现在数据应该是这样的,
Figure 4: Training Data in Json Format
下一步是将上述数据转换成 spaCy 需要的格式。可以使用以下脚本来完成-
现在我们已经为训练准备好了数据!让我们通过添加自定义实体来训练一个 NER 模型。
使用自定义实体培训空间 NER
SpaCy NER 已经支持像- PERSON
人这样的实体类型,包括虚构的。民族、宗教或政治团体。FAC
建筑、机场、公路、桥梁等。ORG
公司、机关、机构等。GPE
国家、城市、州等。
我们的目标是进一步训练这个模型,使其包含我们数据集中的自定义实体。要做到这一点,我们必须经历以下步骤-
- 加载模型,或使用带有所需语言 ID 的
[spacy.blank](https://spacy.io/api/top-level#spacy.blank)
创建一个空模型。如果正在使用空白模型,我们必须将实体识别器添加到管道中。如果使用现有模型,我们必须在训练期间使用[nlp.disable_pipes](https://spacy.io/api/language#disable_pipes)
禁用所有其他管道组件。这样,只有实体识别器得到训练。
# Setting up the pipeline and entity recognizer.if model is not None:
nlp = spacy.load(model) # load existing spacy model
print("Loaded model '%s'" % model)
else:
nlp = spacy.blank('en') # create blank Language class
print("Created blank 'en' model")if 'ner' not in nlp.pipe_names:
ner = nlp.create_pipe('ner')
nlp.add_pipe(ner)
else:
ner = nlp.get_pipe('ner')
2.使用[add_label](https://spacy.io/api/entityrecognizer#add_label)
方法将新的实体标签添加到实体识别器中。
# Add new entity labels to entity recognizerfor i in LABEL:
ner.add_label(i)# Inititalizing optimizerif model is None:
optimizer = nlp.begin_training()
else:
optimizer = nlp.entity.create_optimizer()
3.循环遍历示例,并调用[nlp.update](https://spacy.io/api/language#update)
,逐步遍历输入的单词。在每一个单词上,它都会做出一个预测。然后,它查阅注释,看看它是否正确。如果它错了,它会调整它的权重,这样下次正确的动作会得到更高的分数。
# Get names of other pipes to disable them during training to train # only NER and update the weightsother_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
with nlp.disable_pipes(*other_pipes): # only train NER
for itn in range(n_iter):
random.shuffle(TRAIN_DATA)
losses = {}
batches = minibatch(TRAIN_DATA,
size=compounding(4., 32., 1.001))
for batch in batches:
texts, annotations = zip(*batch)
# Updating the weights
nlp.update(texts, annotations, sgd=optimizer,
drop=0.35, losses=losses)
print('Losses', losses) nlp.update(texts, annotations, sgd=optimizer,
drop=0.35, losses=losses)
print('Losses', losses)
4.使用[nlp.to_disk](https://spacy.io/api/language#to_disk)
保存训练好的模型。
# Save model
if output_dir is not None:
output_dir = Path(output_dir)
if not output_dir.exists():
output_dir.mkdir()
nlp.meta['name'] = new_model_name # rename model
nlp.to_disk(output_dir)
print("Saved model to", output_dir)
5.测试模型,确保新实体被正确识别。
# Test the saved model
print("Loading from", output_dir)
nlp2 = spacy.load(output_dir)
doc2 = nlp2(test_text)
for ent in doc2.ents:
print(ent.label_, ent.text)
使用此脚本来训练和测试模型-
执行指令-
python spacy_ner_custom_entities.py \
-m=en \
-o=path/to/output/directory \
-n=1000
结果
当对查询- ['John Lee is the chief of CBSE', 'Americans suffered from H5N1']
进行测试时,模型识别出以下实体-
John Lee is the chief of CBSE.B-per JohnI-per LeeB-org CBSE Americans suffered from H5N1 virus in 2002.B-gpe AmericansB-nat H5N1B-tim 2002
结论
我希望你现在已经明白了如何在斯帕西 NER 模型的基础上训练你自己的 NER 模型。感谢阅读!😊
面向非数据科学家的自定义对象检测— Tensorflow
使用 Tensorflow 对象检测 API 用您自己的数据集训练模型。
在这篇文章的结尾你能做什么
总的来说,在本教程结束时,你基本上能够拿起你的数据集,将其加载到 jupyter 笔记本上,训练并使用你的模型:)
上面的图片是我们要在这里玩的例子的结果。
警告
这篇文章只是想让你了解一下 TF 物体检测 API,但是这个内容只是我的 jupyter 笔记本的拙劣翻版,如果你想看一些更有结构和更漂亮的东西,去我的 jupyter 笔记本那里有和这里一样的文本,但是在一个更漂亮和更容易理解的媒介中:)
首先,让我们安装依赖项
!pip install pillow
!pip install lxml
!pip install Cython
!pip install jupyter
!pip install matplotlib
!pip install pandas
!pip install opencv-python
!pip install tensorflow
下载 Tensorflow 对象检测 API
首先,让我们下载 tensorflow 模型存储库,这个存储库中的
有对象检测 api,我们将
用它来训练我们自己的对象检测模型。
我们要做的一切,都在路径 models/research/object _ detection 里面。
!git clone [https://github.com/tensorflow/models/](https://github.com/tensorflow/models/)
%cd models/research/object_detection
在这里,我们只是创建一些文件夹,我们稍后将使用它。
命令mkdir
创建目录
!mkdir training
!mkdir inference_graph
!mkdir -p images/train
!mkdir -p images/test
选择我们的预训练模型。
在 tensorflow zoo 模型中,我们可以选择一个预训练的
模型来下载并使用它来训练我们自己的数据集。
在 tensorlfow zoo 模型存储库的文件夹中,我们有一个表
,它解释了模型的精度(使用 mAP-mean Average Precision)
以及该模型的速度。
您可以选择您想要的任何型号,本教程中的过程对于其他
型号是相同的。
本教程我选了更快的 _ rcnn _ inception _ v2 _ coco _ 2018 _ 01 _ 28,只是
因为我要:)
!wget [http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_v2_coco_2018_01_28.tar.gz](http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_v2_coco_2018_01_28.tar.gz)
!tar -xvzf faster_rcnn_inception_v2_coco_2018_01_28.tar.gz
!rm -rf faster_rcnn_inception_v2_coco_2018_01_28.tar.gz
根据文档,将 PYTHONPATH 环境变量与模型、reasearch 和 slim path 一起导出是很重要的
import os
os.environ['PYTHONPATH'] = "{}/content/obj_detect_api/models:/content/obj_detect_api/models/research:/content/obj_detect_api/models/research/slim".format(os.environ['PYTHONPATH'])
汇编一些东西
这里我们有一些需要编译的原型缓冲区,记住
它是编译的,所以如果你切换机器,你不能只是复制和粘贴
这个家伙生成的文件。
老实说,我无法从“/research/object _ detection”
文件夹中执行这些原型,我尝试了 N 种方法都没用,所以我只是从
“/research”文件夹中编译它们。
理解什么是 proto buffers 对于本教程来说并不是必须的,但是如果你想让
了解更多,我建议你看一下文档,基本上它是包含消息结构的文本
结构(比如 json,xml ),你可以把它转换成一些语言
,比这多一点,但是现在对于你阅读那篇文章已经足够了
。
%cd ..!protoc ./object_detection/protos/*.proto --python_out=.
我不记得 Tensroflow 异议检测 API
要求的确切版本,但我从版本> = 3.0 中得知效果很好。
!protoc --version
所以只要安装它
!python3 setup.py build
!python3 setup.py install
测试安装是否正常。
一旦我们安装了所有东西,我们就可以从
Tensorflow 对象检测 API 运行一些示例脚本来验证一切是否正确。这个代码不是我的,我从 object_detection 文件夹中复制了它,只是为了在 jupyter 笔记本上运行它而做了一些修改。
我不会解释这段代码,因为它只是为了测试安装,我们稍后会看到类似的代码。
只是执行这些细胞。
警告:只需证明你使用的张量流> =1.12.0
Obs:记住你可以离开这篇文章,去 jupyter 笔记本,哪个更好:)
如果在你执行下面的单元格后,你可以看到一只狗的图像和一个海滩的图像,那么一切都正常!
用我们自己的数据集训练模型。
首先,让我们下载数据集。
关于数据集
在这篇文章中,我们将使用 kaggle 的数据集,但是不要担心,在这篇教程中,我将把你引向另一篇教你如何创建自己的分类数据集的文章。
帕斯卡-VOC
在谈论数据集之前,我想提醒大家,在本教程中,我们将使用 Pascal-VOC 格式的
数据集,这是一种著名的格式,其中有:
- jpg、jpeg、png 格式的图像…
- 注释:。以下格式的 xml 文件:
<annotation>
<folder>GeneratedData_Train</folder>
<filename>000001.png</filename>
<path>/my/path/GeneratedData_Train/000001.png</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>224</width>
<height>224</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>21</name>
<pose>Frontal</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<occluded>0</occluded>
<bndbox>
<xmin>82</xmin>
<xmax>172</xmax>
<ymin>88</ymin>
<ymax>146</ymax>
</bndbox>
</object>
</annotation>
对于每个图像,我们都有一个。同名 xml,例子:image001.png-> image 001 . XML
注意这里面。xml 我们有关于图像的其他信息,比如位置、大小、对象以及它们在图像中的位置…
我们在本文中使用的数据集是从 kaggle 中提取的 LISA 交通灯数据集,该
数据集包含交通灯的图像和分类,分类如下:
- 去;
- 停止;
- 警告;
- goLeft
- goForward
- stopLeft
- warningLeft
但是为了使本教程更简单,我修改了类,所以我们只有:
- 去;
- 停止;
- 警告;
下载后,请注意,我们将所有内容都移动到文件夹… / images 中
%cd object_detection
!wget --load-cookies /tmp/cookies.txt "[https://docs.google.com/uc?export=download&confirm=$(wget](https://docs.google.com/uc?export=download&confirm=$(wget) --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate '[https://docs.google.com/uc?export=download&id=15WlpBbq4EpxUxZeKEAbfI_YJABASpmFs'](https://docs.google.com/uc?export=download&id=15WlpBbq4EpxUxZeKEAbfI_YJABASpmFs') -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=15WlpBbq4EpxUxZeKEAbfI_YJABASpmFs" -O lisa608.zip
!unzip -qq ./lisa608.zip!mv images_output/* images/
!mv annotations_output/* images/
对于这个简单的教程,我不想处理太多的类,你可以这样做,但是为了简化这个过程,我将重命名所有最后有“Left”和“Forward”的类
在这里,我只是在训练和测试中拆分了我的数据集
如果你的注释是 Pascal-VOC 格式的(就像我们的例子),你需要把它们转换成 csv 格式。
我知道,我们的原始数据集之前已经是 csv 格式的了,但是我已经把它转换成了 xml,只是为了向您展示这个场景。
在这里,我们迭代每个文件夹、训练、测试和验证(如果我们有用于验证的数据),因此我们提取数据:
- 文件名
- 宽度
- 高度
- 班级
- xmin
- ymin
- xmax
- ymax
放在我们的 csv 上。
生成 TFRecords
要使用 TF 对象检测 API,我们需要遵循 TFRecord 输入格式。
当我们处理大量数据时,使用轻便快速的格式很重要,一个
选项是处理文档的二进制文件,这正是 TFRecords 所做的,但此外
针对 Tensorflow 进行了优化,因为它是为 Tensorflow 创建的,例如当
处理非常大的数据集并试图将其加载到内存中时, 显然你不会得到它
,因为你没有足够的内存 RAM 来做这件事,所以你必须处理批处理,但是
如果你使用你不需要的 TFRecords 来处理批处理,它为你抽象出如何将数据加载到内存中
,而不需要你自己编程。
这里有一篇文章详细解释了 TFRecords 的工作原理。
对于每个项目,必须在class_text_to_int ()
方法中进行一些更改,注意
有一个非常简单的逻辑结构,我们必须根据这个类返回一个整数
Obs:你可以从 jupyter 笔记本上看到完整的代码。
我们还需要在 TF 中输入我们的类。为此,我们将创建一个具有以下结构的. pbtxt 文件:
item {
id: 1
name: 'stop'
}
对于每个类,我们都有一个条目,每个条目都有一个 id 和一个名称,id 指的是我们在 TFRecords 中使用的 Id:
def class_text_to_int(row_label):
if row_label == 'stop':
return 1
elif row_label == 'warning':
return 2
elif row_label == 'go':
return 3
else:
None
记得使用相同的 id。
%%writefile training/labelmap.pbtxt
item {
id: 1
name: 'stop'
}item {
id: 2
name: 'warning'
}item {
id: 3
name: 'go'
}
这里我们将打印图像文件夹的长度,以便以后使用这些信息…
import os
test_path = "images/test"
len_dir = len(os.listdir(test_path))
print("{} imagens inside the {}".format(len_dir, test_path))
下一个单元格有一个文件是神经网络的配置文件,这里我们有一些超参数
,我们必须对其进行修改。
我从 faster _ rcnn _ inception _ v2 _ pets . config 复制了这个配置文件,并根据我各自的
修改进行了编辑,对于您将使用的每个深度学习架构,您需要一个不同的配置文件,
您可以在这里找到所有这些文件[...]/research/object_detection/samples/configs
,或者如果您喜欢的话,
通过 github 访问。
在这些文件中,有些东西应该被改变,比如: num_classes
faster_rcnn {
num_classes: 3
微调检查点
fine_tune_checkpoint: "/home/<full_path>/research/object_detection/faster_rcnn_inception_v2_coco_2018_01_28/model.ckpt"
在属性 train_input_reader 中,将 input_path 和 label_map_path 修改为:
tf_record_input_reader {
input_path: "/<full_path>/research/object_detection/train.record"
}
label_map_path: "/<full_path>/research/object_detection/training/labelmap.pbtxt"
}
请记住,train_input_reader 必须是 train.record 文件。
在 eval_config 属性中,在 num_examples 属性中更改您必须测试的实例(图像)数量(在…/images/test 文件夹中)
:
eval_input_reader: {
tf_record_input_reader {
input_path: "/full_path/research/object_detection/test.record"
}
label_map_path: "/full_path/research/object_detection/training/labelmap.pbtxt"
请注意,我使用的是测试记录而不是训练记录
Obs:记住你可以看到代码,并且已经通过 google colabotory 运行过了
%cd ..
!protoc ./object_detection/protos/*.proto --python_out=.%cd object_detection
对此我很抱歉,但我得到了一个非常恼人的错误,它说没有找到 slim lib,
许多人说问题出在我的 PYTHONPATH 环境变量中,但我验证了一千次
并没有发现问题,所以我通过将所有/research/slim 代码复制到/object_detection
文件夹中来解决它,如果任何人发现什么做错了,请在下面评论。
!cp -a ../slim/. .
让我们训练它!
%run legacy/train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/faster_rcnn_inception_v2.config
训练您的模型后,请注意在/training 文件夹中我们有一个 model . ckpt-22230 . data-00000-of-00001 文件,可能在您的
机器上会有另一个编号,该文件是您保存的训练模型!
!ls training
因为我们已经将整个/slim 文件夹复制到/object_detection,我们已经覆盖了
inference_graph.py
文件,所以我们在这里重新创建了该文件。
想了解更多关于推论的知识,我推荐这几篇非常好的文章。第一条 第二条
让我们运行我们的推论!记得更改 trained_checkpoint_prefix 属性,以使用/ training 文件夹中的 model.ckpt-XXX
!python3 my_inference_graph.py \
--input_type image_tensor \
--pipeline_config_path training/faster_rcnn_inception_v2_pets.config \
--trained_checkpoint_prefix training/model.ckpt-22230 \
--output_directory ./inference_graph
我们将在这里下载一些测试图像,以查看我们的模型的一些结果。
!wget '[http://marcusquintella.sigonline.com.br/openged/conteudos/1306/001306_59bc593899b85_Semaforos_out_2017.jpg'](http://marcusquintella.sigonline.com.br/openged/conteudos/1306/001306_59bc593899b85_Semaforos_out_2017.jpg') -O semaforo.png
这段代码和测试代码很像!
import os
import cv2
import numpy as np
import tensorflow as tf
import sys# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
让我们定义一些常量和路径,模型的检查点,标签等等。
# Import utilites
from utils import label_map_util
from utils import visualization_utils as vis_util# Name of the directory containing the object detection module we're using
MODEL_NAME = 'inference_graph'
IMAGE_NAME = 'semaforo.png'# Grab path to current working directory
CWD_PATH = os.getcwd()# Path to frozen detection graph .pb file, which contains the model that is used
# for object detection.
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')# Path to label map file
PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')# Path to image
PATH_TO_IMAGE = os.path.join(CWD_PATH,IMAGE_NAME)# Number of classes the object detector can identify
NUM_CLASSES = 3
在这里,我们加载我们的 label_maps,这样我们就可以进行模型预测,例如,
知道数字 3 对应于类别“go”
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
让我们加载我们的模型,并从模型中选择一些层
# Load the Tensorflow model into memory.
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')sess = tf.Session(graph=detection_graph)# Define input and output tensors (i.e. data) for the object detection classifier# Input tensor is the image
image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')# Output tensors are the detection boxes, scores, and classes
# Each box represents a part of the image where a particular object was detected
detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')# Each score represents level of confidence for each of the objects.
# The score is shown on the result image, together with the class label.
detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')# Number of objects detected
num_detections = detection_graph.get_tensor_by_name('num_detections:0')
下面我们加载图像并运行我们的模型,如果你对 Tensorflow 一无所知,我建议你
阅读这篇文章(这是一篇快速文章)并阅读文档,如果你想了解 tensorflow 中
如何工作的更多细节。
一些参数在这里是可配置的,例如定义线条宽度的 line_thickness 和对应于您希望 Tensoflow 的置信度百分比的
min_score_thresh:嘿,
在这里有一个对象具有超过 X%的置信度。(在我们的例子中,我们将使用 0.6)
Load image using OpenCV and
# expand image dimensions to have shape: [1, None, None, 3]
# i.e. a single-column array, where each item in the column has the pixel RGB value
image = cv2.imread(PATH_TO_IMAGE)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_expanded = np.expand_dims(image, axis=0)# Perform the actual detection by running the model with the image as input
(boxes, scores, classes, num) = sess.run(
[detection_boxes, detection_scores, detection_classes, num_detections],
feed_dict={image_tensor: image_expanded})# Draw the results of the detection (aka 'visulaize the results')vis_util.visualize_boxes_and_labels_on_image_array(
image,
np.squeeze(boxes),
np.squeeze(classes).astype(np.int32),
np.squeeze(scores),
category_index,
use_normalized_coordinates=True,
line_thickness=8,
min_score_thresh=0.6)
让我们用各自的分类打印我们的图像。在实际应用中,没有必要使用 visualize _ boxes _ and _ labels _ on _ image _ array(),可以分别使用盒子、类和分数。
%matplotlib inlineplt.figure(figsize=(20,10))
plt.imshow(image)
这是原始图像
image = cv2.imread(PATH_TO_IMAGE)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)plt.figure(figsize=(20,10))
plt.imshow(image)
现在你可以下载这个推论并在你的机器上,服务器上,任何你想要的地方使用它
!zip -r inference_graph.zip /content/obj_detect_api/models/research/object_detection/inference_graph
所以发到 google drive 上。
!pip install -U -q PyDrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials# 1\. Authenticate and create the PyDrive client.
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)model_file = drive.CreateFile({'title' : 'inference_graph.zip'})
model_file.SetContentFile('./inference_graph.zip')
model_file.Upload()# download to google drive
drive.CreateFile({'id': model_file.get('id')})
从头开始使用 TensorFlow 进行自定义对象检测
内部 AI
基于自定义数据集的 TensorFlow 对象检测训练
Custom Object Detection source: https://github.com/bourdakos1/Custom-Object-Detection
在本教程中,我们将尝试使用预先训练好的 SSD MobileNet V2 模型来训练我们自己的狗(corgi)检测器。
您无需从头开始训练自己的模型,而是可以在现有模型的基础上进行构建,并根据自己的目的对其进行微调,而不需要太多的计算能力。
1.装置
1.1 张量流
使用以下命令安装 Tensorflow:
$ pip install tensorflow
如果您有可以与 Tensorflow 一起使用的 GPU:
$ pip install tensorflow-gpu
1.2 其他依赖关系
$ pip install pillow Cython lxml jupyter matplotlib
使用自制软件安装 protobuf(你可以在这里了解更多关于自制软件的信息)
$ brew install protobuf
对于在其他操作系统上安装 protobuf,请遵循此处的说明。
1.3 克隆 Tensorflow 模型库
在本教程中,我们将使用 Tensorflow 模型存储库中的资源。因为 Tensorflow 安装没有附带它,所以我们需要从他们的 Github repo 中克隆它:
首先进入张量流目录:
# *For example: ~/anaconda/envs/<your_env_name>/lib/python3.6/site-packages/tensorflow*$ cd <path_to_your_tensorflow_installation>
克隆 Tensorflow 模型库:
$ git clone [https://github.com/tensorflow/models.git](https://github.com/tensorflow/models.git)
从此时起,该目录将被称为 **models**
目录
1.4 设置环境
每当您启动一个新的终端窗口来处理预训练的模型时,编译 Protobuf 并更改您的PYTHONPATH
是非常重要的。
从终端运行以下命令:
$ cd <path_to_your_tensorflow_installation>/models/research/$ protoc object_detection/protos/*.proto --python_out=.$ export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
运行快速测试以确认对象检测 API 工作正常:
$ python object_detection/builders/model_builder_test.py
如果结果如下所示,您就可以继续下一步了!
...............
----------------------------------------------------------------------
Ran 15 tests in 0.123sOK
1.5 推荐的文件夹结构
为了使本教程更容易理解,在刚刚克隆的models
目录中创建以下文件夹结构:
models
├── annotations
| └── xmls
├── images
├── checkpoints
├── tf_record
├── research
...
这些文件夹将用于存储我们的模型所需的组件。
2.收集图像
您可以收集图像或视频格式的数据。这里我提到了收集数据的两种方法。
2.1 从互联网上收集图像(谷歌搜索)
数据准备是训练自己模型最重要的部分。既然要训练一只柯基探测器,就必须收集柯基的图片!大约 200 个就足够了。
我推荐使用 google-images-download 下载图片。它搜索谷歌图片,然后根据你提供的输入下载图片。在输入中,您可以指定搜索参数,如关键字、图像数量、图像格式、图像大小和使用权。
因为我们一次下载 100 多张图片,所以我们需要在models
目录中有一个chromedriver
(在这里下载)。一旦您准备好了chromedriver
,您就可以使用这个示例命令来下载图像。确保您所有的图像都是 jpg 格式:
*# From the models directory*$ googleimagesdownload --keywords 'welsh corgi dog' \
--limit 200 \
--size medium \
--chromedriver ./chromedriver \
--format jpg
下载后,将所有图像保存到models/images/
。为了使后续过程更容易,让我们通过运行以下脚本将图像重命名为数字(例如1.jpg
、2.jpg
):
import ospath = 'models/images/'
counter = 1
for f in os.listdir(path):
suffix = f.split('.')[-1]
if suffix == 'jpg' or suffix == 'png':
new = '{}.{}'.format(str(counter), suffix)
os.rename(path + f, path + new)
counter = int(counter) + 1
2.2 从视频中收集图像
[## 使用 OpenCV (Python)将视频转换为图像以及将图像转换为视频
使用 Python 中的 OpenCV 库从视频生成图像(帧)和从图像(帧)生成视频
medium.com](https://medium.com/@iKhushPatel/convert-video-to-images-images-to-video-using-opencv-python-db27a128a481)
3.标记您的数据集
一旦你收集了所有你需要的图片,你需要手动标记它们。有许多服务于此目的的软件包。标签是一个受欢迎的选择。
labelImg 提供了一个用户友好的 GUI。另外,它以流行的 Pascal VOC 格式保存标签文件(.xml
)。如果你想用这些图片来训练 YOLO(你只看一次),那就用 YOLO。只需设置当前目录,并按照我们的结构保存目录。
以下是标签图像在 labelImg 中的样子:
Example of a labeled corgi in labelImg
仔细检查每个图像是否有相应的.xml
文件,并将其保存在models/annotations/xmls/
中。
对于大量注释,您可以使用下面提到的不同快捷键:
Ctrl + u - Load all of the images from a directory
Ctrl + r - Change the default annotation target dir
Ctrl + s - Save
w - Create a rect box
d - Next image
a - Previous image
del - Delete the selected rect box
Ctrl++ - Zoom in
Ctrl-- - Zoom out
Ctrl + d - Copy the current label and rect box
Space - Flag the current image as verified
↑→↓←Keyboard arrows to move selected rect box
4.创建标签地图(.pbtxt
)
类别需要在标签映射中列出。由于我们只检测地理信息系统,标签地图应该只包含一个项目,如下所示:
item {
id: 1
name: 'corgi'
}
注意id
必须从 1 开始,因为 0 是保留 id。
将该文件另存为models/annotations/
中的label_map.pbtxt
5.创建trainval.txt
trainval.txt
是没有文件扩展名的图像名称列表。因为我们有图像名称的序列号,所以列表应该是这样的:
1
2
3
...
198
199
200
将该文件保存为models/annotations/
中的trainval.txt
6.将 XML 转换为 CSV 文件(.csv
)
您可以使用这个链接来创建 CSV 格式的 XML 文件。我们有所有的图像和它们的边界框都是 XML 格式。此外,所有的图像都有单独的 XML 文件,所以使用这个代码,我们正在创建一个 CSV 文件,其中包含所有的 XML 文件和他们的边界框坐标到一个 CSV 文件,这是创建 TFrecords 的输入。
7.创建 TFRecord ( .record
)
TFRecord 是为 Tensorflow 设计的重要数据格式。(点击了解更多信息)。在训练自定义对象检测器之前,必须将数据转换为 TFRecord 格式。
由于我们需要训练和验证我们的模型,数据集将被分成训练集(train.record
)和验证集(val.record
)。训练集的目的很简单——它是模型学习的样本集。验证集是在训练期间使用的一组示例,用于反复评估模型准确性。
我们将使用create_tf_record.py
将我们的数据集转换成train.record
和val.record
。在这里下载并保存到models/research/object_detection/dataset_tools/
。
根据您的分类,只需更改 if row_label == ‘Label1’:
中的标签名称即可。
该脚本预先配置为进行 70–30 列车阀分割。通过运行以下命令来执行它:
# *From the models directory*$ python research/object_detection/dataset_tools/create_tf_record.py
如果脚本执行成功,train.record
和val.record
应该会出现在您的models/research/
目录中。将它们移动到models/tf_record/
目录。
8.下载预先训练的模型
在模型动物园中有很多预先训练好的物体检测模型可用。为了使用我们的定制数据集训练它们,模型需要使用它们的检查点(.ckpt
文件)在 Tensorflow 中恢复,这些检查点是以前模型状态的记录。
对于本教程,我们将在这里下载ssd_mobilenet_v2_coco
,并将其模型检查点文件(model.ckpt.meta, model.ckpt.index, model.ckpt.data-00000-of-00001
)保存到我们的models/checkpoints/
目录中。
9.修改配置(.config
)文件
每个预训练的模型都有一个包含模型细节的配置文件。为了检测我们的自定义类,需要相应地修改配置文件。
配置文件包含在您一开始克隆的models
目录中。您可以在以下位置找到它们:
models/research/object_detection/samples/configs
在我们的例子中,我们将修改ssd_mobilenet_v2_coco
的配置文件。先复制一份,保存在models/
目录下。
以下是我们需要更改的项目:
- 因为我们只试图检测柯基,所以将
num_classes
改为 1 fine_tune_checkpoint
告诉模型使用哪个检查点文件。将此设置为checkpoints/model.ckpt
- 模型还需要知道训练集和验证集的 TFRecord 文件和标签映射在哪里。由于我们的
train.record
和val.record
保存在tf_record
文件夹中,我们的配置应该反映出:
train_input_reader: {
tf_record_input_reader {
input_path: "tf_record/train.record"
}
label_map_path: "annotations/label_map.pbtxt"
}eval_input_reader: {
tf_record_input_reader {
input_path: "tf_record/val.record"
}
label_map_path: "annotations/label_map.pbtxt"
shuffle: false
num_readers: 1
}
10.火车
此时,您的models
目录应该如下所示:
models
├── annotations
| ├── label_map.pbtxt
| ├── trainval.txt
| └── xmls
| ├── 1.xml
| ├── 2.xml
| ├── ...
|
├── images
| ├── 1.jpg
| ├── 2.jpg
| ├── ...
|
├── checkpoints
| ├── model.ckpt.data-00000-of-00001
| ├── model.ckpt.index
| └── model.ckpt.meta
|
├── tf_record
| ├── train.record
| └── val.record
|
├── research
| ├── ...
...
如果您成功完成了之前的所有步骤,您就可以开始训练了!
请遵循以下步骤:
# *Change into the models directory*
$ cd tensorflow/models# *Make directory for storing training progress*
$ mkdir train# *Make directory for storing validation results*
$ mkdir eval# *Begin training*
$ python research/object_detection/train.py \
--logtostderr \
--train_dir=train \
--pipeline_config_path=ssd_mobilenet_v2_coco.config
训练时间因机器的计算能力而异。
11.估价
评估可以与培训同时进行。eval.py
脚本检查train
目录的进度,并根据最近的检查点评估模型。
*# From the models directory*$ python research/object_detection/eval.py \
--logtostderr \
--pipeline_config_path=ssd_mobilenet_v2_coco.config \
--checkpoint_dir=train \
--eval_dir=eval
您可以使用 Tensorboard 可视化模型训练进度:
*# From the models directory*$ tensorboard --logdir=./
根据 Tensorboard 输出的图表,您可以决定何时停止训练。通常,当损失函数逐渐减少并且不再显著减少时,你可以停止这个过程。在我的例子中,我停止在步骤 3258。
12.模型导出
一旦完成模型的训练,就可以导出模型用于推理。如果您一直遵循文件夹结构,请使用以下命令:
*# From the models directory*$ mkdir fine_tuned_model$ python research/object_detection/export_inference_graph.py \
--input_type image_tensor \
--pipeline_config_path ssd_mobilenet_v2_coco.config \
--trained_checkpoint_prefix train/model.ckpt-<the_highest_checkpoint_number> \
--output_directory fine_tuned_model
13.分类图像
现在你有了一个模型,你可以用它来检测图片和视频中的柯基犬!出于演示的目的,我们将检测图像中的 CORBA。在继续之前,选择一个您想要用来测试模型的图像。
models
目录附带了一个笔记本文件(.ipynb
),我们可以使用它进行一些调整来获得推论。它位于models/research/object_detection/object_detection_tutorial.ipynb
。按照以下步骤调整笔记本:
MODEL_NAME = 'ssd_mobilenet_v2_coco_2018_03_29'
PATH_TO_CKPT = 'path/to/your/frozen_inference_graph.pb'
PATH_TO_LABELS = 'models/annotations/label_map.pbtxt'
NUM_CLASSES = 1
- 完全注释掉单元格#5(就在
Download Model
下面) - 因为我们只对一个图像进行测试,注释掉单元格#9 中的
PATH_TO_TEST_IMAGES_DIR
和TEST_IMAGE_PATHS
(就在Detection
下面) - 在单元格#11(最后一个单元格)中,删除 for 循环,取消其内容,并添加测试图像的路径:
imagepath = 'path/to/image_you_want_to_test.jpg
完成这些步骤后,运行笔记本,您应该会看到测试图像中的 corgi 被一个边界框高亮显示!
Corgi found by our custom object detector
那里你有你的自定义柯基探测器!
你可能想知道,在训练完你的第一个模型后,我想改进我的模型并跟踪我的实验细节,什么是好工具?
然后就可以结账 https://neptune.ai 了,它提供了清晰简洁的模型追踪。您可以跟踪所有的超参数,并将模型保存在模型注册表中,并实时比较您的模型。Neptune 支持在一个地方记录、存储、查询、显示、组织和比较所有的模型元数据。更多信息,你可以参考下面的博客来训练物体检测模型。
https://Neptune . ai/blog/tensor flow-object-detection-API-最佳实践-培训-评估-部署
更多细节
请访问我的网站:【http://www.khushpatel.com】
基于 Android 和 TensorFlow 的图像分类箱包识别
问题是:
最近,当我在印度东北部旅行时,我不得不等了很长时间,我的包才出现在机场的行李传送带上。旋转木马周围挤满了通勤者。很难把我的包和其他包区分开来,因为大约有一半的包看起来很相似。我不得不亲自检查六个包,以确保没有一个是我的。
我想有人会建立一些东西来解决这个问题。我开始寻找现有的解决方案,但是什么也找不到。我偶然发现了一些使用 TensorFlow 演示自定义对象检测的博客。后来我发现了这个非常有用的资源,并以此为基础开始着手解决问题。
数据:
我首先需要的是数据。我本可以点击我的包的一些图片,但是我决定捕捉对象的所有侧面和边缘的视频。我从视频中提取单独的帧,并手工挑选视觉上不连续的帧。我将选定的帧转换为灰度图像。我用的是 ffmpeg。在命令行或终端上,键入,
ffmpeg -i video.mp4 -qscale:v 2 image_%03d.jpg
video.mp4 是我的包的视频,输出图像以 image_ 为前缀。然后我需要不属于我包的照片。我发现了一个有用的谷歌
Chrome 扩展,名为 Fatkun 。该扩展使我能够下载大量图像。我在谷歌图片上搜索包包,下载了一堆这样的图片。就像我包包的照片一样,我把后来下载的图片转换成了灰度。
我执行了一个 Python 脚本来将图像转换成灰度。下面的 Python 脚本有一个函数 rescale,它获取一个目录并将该目录中的所有图像转换为灰度。该脚本有一个依赖,PIL。
Python script to convert images inside a folder to grayscale
当我编排我的数据时,没有不平衡数据集的风险。我的包和我的包有相同数量的图像。
食谱:
一旦我有了图像,我就从这里下载tensor flow-for-Poets。您需要在计算机上安装 TensorFlow。此外,你需要下载枕头。您可以通过键入以下命令来完成这两项工作。
pip install --upgrade "tensorflow==1.7.*"
pip install PILLOW
在 Tensorflow-for-poets 的根目录中,我执行了,
python3 -m scripts.retrain --bottleneck_dir=tf_files/bottlenecks --how_many_training_steps=500 --model_dir=tf_files/models/ --summaries_dir=tf_files/training_summaries/mobilenet_v2_1.4_224 --output_graph=tf_files/retrained_graph_bags.pb --output_labels=tf_files/retrained_labels.txt --architecture="mobilenet_0.50_224" --image_dir=/Users/sumit/Desktop/carousel/Baggage-Carousel/Labs/data/
scripts.retrain 将一个目录作为输入。对我来说,这是命令的最后一部分。
image_dir=/Users/sumit/Desktop/carousel/Baggage-Carousel/Labs/data/
该文件夹如下所示:
名为 bag 的文件夹保存了我的包的灰度图像。另一个文件夹里有我能拿到的所有其他包的灰度照片。*‘架构’*论点是我想要重新训练的模型。我鼓励每个人都和模特一起玩耍。型号列表可以在这里找到。
*‘重新训练 _ 标签’是一个生成的文本文件,带有两个文件夹的名称。这两个文件夹的行为就像两个类。同样,’ rettrained _ graph _ bags . Pb '*是该过程的结果。这两个文件都可以在以下位置找到:
tensorflow-for-poets-2/tf_files
该命令应该从 tensorflow-for-poets 的根目录执行。当命令被执行时,它将启动学习过程。
接下来,我必须将生成的图形转换成 tflite。Tflite 或 TensorFlowLite 用于将机器学习模型部署到移动设备上。转换是通过执行以下命令完成的
toco — graph_def_file=tf_files/retrained_graph_bags.pb — output_file=tf_files/bagdroid_graph.tflite — output_format=TFLITE — input_shape=1,224,224,3 — input_array=input — output_array=final_result — inference_type=FLOAT — input_data_type=FLOAT
上面的命令将*’ rettrained _ graph _ bags . Pb '*作为输入,生成一个移动友好的 tflite 文件,命名为 'bagdroid_graph.tflite '。
Android 应用程序:
Android 应用程序只需要一些改动。除了外观上的变化,
- 我必须将*’ rettrained _ labels . txt ‘和’ bag droid _ graph . TF lite '*复制到应用程序的 assets 文件夹中。
- 在 ImageClassifier.java,我必须将模型路径和标签路径指向正确的值。
- 我不得不在检测上添加音频和触觉反馈。
Changes made in ImageClassifer.java
结果是:
完成后的应用程序应该看起来更好,并且能够检测它被训练检测的包。
The final application
最后,应用程序能够检测到我的包,给我声音和触觉反馈。
Detecting bag.
问题是:
一个非常明显的问题是,如果两个包是相同的,应用程序将识别这两个包。这个问题可以通过使用 NFC 芯片来缓解。
但是,实际问题是应用程序经常将随机的东西标记为我的包。我很想知道我能做些什么来减少误报。
用于高级机器学习的定制张量流损失函数
和少量迁移学习示例
在这篇文章中,我们将看看:
- 在高级 ML 应用中使用自定义损失函数
- 定义自定义损失函数并集成到基本张量流神经网络模型
- 知识提炼学习的一个简单示例,使用高斯过程参考应用于少量学习问题
链接到我的其他文章:
【注:tensor flow 2.0现已发布,与本文所基于的 the 1.x 版本有较大不同。我仍在研究 TF 2.0 w.r.t 自定义损失和张量操作,如本文所述,可能会写一篇新文章或更新这篇文章。请记住这一点。】
简介
机器学习的老路包括旅行到熟悉的地标和风景点。一组熟悉的界标是预定义的损失函数,为您试图优化的问题提供合适的损失值。我们熟悉分类的交叉熵损失和回归问题的均方误差(MSE)或均方根误差(RMSE)。包括前端(如 Keras)和后端(如 Tensorflow)的流行 ML 包包括一组用于大多数分类和回归任务的基本损失函数。但是,在常规方法之外,还存在自定义的损失函数,您可能需要使用它们来解决某个问题,这些损失函数只受有效张量运算的约束。
在 Keras 中,技术上你可以创建自己的损失函数,但是损失函数的形式仅限于 some_loss ( y_true,y_pred )并且仅此而已。如果您试图以 some_loss_1 ( *y_true,y_pred,*kwargs )的形式向损失中添加额外的参数,Keras 将会抛出一个运行时异常,并且您会丢失用于聚合数据集的计算时间。有一些方法可以解决这个问题,但一般来说,我们希望有一种可伸缩的方式来编写一个损失函数,接受我们传递给它的任何有效参数,并以标准和预期的方式对张量进行操作。我们将看到如何直接使用 Tensorflow 从头开始编写一个神经网络,并构建一个自定义的损失函数来训练它。
张量流
Tensorflow (TF)是一个符号和数字计算引擎,它允许我们将张量*串成计算图形,并对它们进行反向传播。Keras 是一个运行在 Tensorflow 之上的 API 或前端,它可以方便地打包使用 Tensorflow 构建的标准结构(如各种预定义的神经网络层),并从程序员那里抽象出许多 TF 的低级机制(Keras 也可以运行在 Theano 之上,同样的概念也适用)。然而,在使这些构造‘现成’的过程中,粒度级控制和做非常具体的事情的能力丧失了。
*为了简单起见,张量是具有类似(feature_dim,n_features)的形状元组的多维数组
一个例子是定义接受任意数量参数的定制损失函数的能力,并且可以使用网络内部的任意张量和网络外部的输入张量来计算损失。严格来说,TF 中的一个损失函数甚至不需要是 python 函数,只需要对 TF 张量对象进行有效的运算组合即可。前一点很重要,因为自定义损失的能力来自于计算任意张量上的损失的能力,而不仅仅是严格意义上的监督目标张量和网络输出张量,其形式为( y_true,y_pred )。
在我们讨论客户损失之前,让我们简要回顾一个基本的 2 层密集网络(MLP ),看看它是如何在 TF 中定义和训练的。虽然有预定义的 TF 层,但让我们从权重和偏差张量开始定义这些层。我们想熟悉 TF 中的占位符和变量张量。
那真是太酷了。通过用 soft max _ cross _ entropy _ with _ logits 替换损失,并用 tf.nn.softmax 替换最终 sigmoid 激活,可以修改上面的代码以用于多类分类。
接下来,为了演示如何使用具有任意张量的自定义损失函数,让我们实现一个知识提取模型,该模型对二进制分类损失以及正在训练的模型和参考模型之间的损失进行优化。知识提炼是迁移学习的一种形式,我们用目标模型(我们想要训练的模型)学习,但也间接从参考模型迁移知识表示。我们将使用来自 sklearn 的高斯过程分类器 (GPC)作为我们的参考模型。我们还将通过将我们的训练数据减少到 sklearn 乳腺癌数据集… 中 569 个样本的 1%来使问题变得更有趣,无论是参考还是目标,并从头开始训练它们。 这就是所谓的少数镜头学习问题。*
*在传统迁移学习中,参考模型通常是一个广泛和/或深入的网络,在许多示例/类上进行了预训练,而目标是一个较窄/较浅的网络,在少数可用的特定示例/类上进行了训练。
这个知识提炼方案的损失看起来像
*二元交叉熵损失只是常规的二元分类损失,第二项涉及目标 f(x) 和参考 *g(x)的输出之间的另一个损失 D 。我们设 D 为 f(x) 和g(x)之间的 Kullback-Leibler 散度 (DKL)
*DKL 简单地量化了一个分布 f 与 g、在信息(大致信息与确定性成反比)方面的差异;可以认为是分布之间的交叉熵,是可以取负值的不对称损失。通过最小化 f 和 g 之间的 DKL,我们基本上想要增加 f 相对于 g 的信息含量。当 f 和 g 的信息量相同时,上面的对数项为 0,DKL 损失也为 0。当使用 GPC 作为参考模型时,使用 DKL 作为损失是有意义的,因为当从 GPC 进行预测时,我们从它的后验分布(softmax)进行采样,尽管我们的神经网络是这个后验分布的粗略近似,但它也是一个分布。
*在下面的实现中,我们在组合损失中采用 abs( D_KL( f(x),g(x))。理论上,由于对数和不等式,D_KL 将总是非负的,但是在实际计算机上用舍入误差计算 D_KL 会导致负值。
请注意,我们现在需要将外部输入 g(x) 反馈到我们的损耗中。在 Keras 中,这个过程是人为的,不可扩展的。但在 TF 中,它就像创建一个新的占位张量、向组合损失添加必要的项,以及在运行训练或预测会话时输入一样简单。
*由于只有 5 个训练样本,上述示例比 DKL 损失被设置为零(即没有迁移学习)的网络收敛得更快,并且给出更好的原始测试准确度。**注意,测试集不平衡未被考虑!精明的读者应该在准确度读数上加上 F1 分数。*谢天谢地,我们数据集的伪随机样本给出了正类与负类的 2:3 比例。
同样值得注意的是,迁移学习模型的 softmax 输出在来自维持者的 100 个示例上进行了测试:
*[0.5134167 ]
[0.5767678 ]
[0.5299671 ]
[0.529941 ]
[0.51807505]
[0.4615707 ]
[0.61761355]
[0.5744497 ]
[0.6092696 ]
[0.55092424]
[0.5866923 ]
[0.5522269 ]
[0.5679551 ]*
相对于非迁移学习模式
*[0.44836044]
[0.99457294]
[0.47165167]
[0.573235 ]
[0.94637066]
[0.00909297]
[0.99778605]
[0.99487936]
[0.99742365]
[0.96588767]
[0.99646676]
[0.9843067 ]
[0.99225134]*
迁移学习模型的预测反映了的不确定性*,给出了它被训练的有限信息。选择 GPC 作为参考模型有一个很好的理由,毕竟,当我们只从零开始训练 5 个样本的分类器时,我们怎么能如此确定一个新患者患有癌症?*
结论
我们看到了如何在 TF 中从零开始实现神经网络,如何将张量运算结合到损失函数中,并触及了迁移学习的一个有趣应用。总的来说,在高级或特殊的监督学习应用中,TF 对于数据科学家来说要灵活得多。如果你喜欢阅读这篇文章和使用代码,请查看我的其他文章!
在 Python 中使用自定义转换器的 ML 数据管道
如何使用继承和 sklearn 为机器学习预处理编写自己的定制转换器和管道
大多数数据科学项目花费的总时间的 80%花费在清理和预处理数据上。我们都听说过,对吧?因此,我们必须找到尽可能自动化预处理和清理的方法。
Scikit-Learn 管道由多个步骤组成,每个步骤都必须是某种转换器,除了最后一个步骤,它可以是转换器或估计器,如机器学习模型。当我说变压器时,我指的是变压器,例如规格化器、标准定标器或单热编码器等等。但是,假设在我使用其中任何一个之前,我想编写 Scikit-Learn 没有提供的我自己的自定义转换器,它将使用我提供的权重向量作为参数,获取我的数据集中第 3、第 7 和第 11 列的加权平均值,用结果创建一个新列并删除原始列,该怎么办?除此之外,最重要的是,如果我还想让我的定制转换器与我现有的 Scikit-Learn 管道及其其他转换器无缝集成,该怎么办?听起来很棒,对我们来说很幸运,Scikit-Learn 允许我们这样做。
Python 中的继承
为了理解我们如何用 scikit-learn 编写我们自己的定制转换器,我们首先必须稍微熟悉一下 Python 中的继承概念。scikit-learn 中的所有转换器和估算器都是作为 Python 类实现的,每个类都有自己的属性和方法。所以每次你写像这样的 Python 语句-
您实际上是在使用类“OneHotEncoder”的类构造函数创建一个名为“one_hot_enc”的实例,并为其参数“sparse”传递参数“False”。OneHotEncoder 类具有诸如“fit”、“transform”和“fit_transform”等方法,现在可以在我们的实例上使用适当的参数调用这些方法,如下所示。
为了让我们的自定义转换器与 scikit-learn 管道兼容,它必须作为具有 fit、transform、fit_transform、get_params、set_params 等方法的类来实现,因此我们要编写所有这些方法……或者我们可以简单地编写我们希望我们的转换器应用的转换类型,然后从某个其他类继承所有其他内容!
要理解 Python 中继承的概念,请看下面这个波巴·费特的乐高进化。
比如我想写一个看起来像右边乐高积木的类。我完全可以从最左边开始,通过写我自己的方法来建立自己的路。然而,如果我能从我正在努力做的那个后面的那个开始呢?我不需要从头开始,我已经有了我需要的大部分方法,而不需要自己编写它们。我可以对它进行添加或修改,直到完成我需要它做的事情。那不是很好吗?这正是遗传允许我们做的。
当我们在下面写出自己的变形金刚时,这个概念会变得更加清晰。如果您想在继续学习之前对 Python 中的类和继承有更多的了解,请查看下面的链接。
Python 是一种面向对象的编程语言。与面向过程的编程不同,面向过程的编程主要强调…
www.programiz.com](https://www.programiz.com/python-programming/class) [## Python 继承
继承是面向对象编程中的一个强大特性。它指的是定义一个新的类,很少或没有…
www.programiz.com](https://www.programiz.com/python-programming/inheritance)
所以现在你可能在想,那太好了!但是我在哪里可以找到这些基类呢?这些基类包含了我需要用来编写 transformer 类的大多数方法。不要担心。Scikit-Learn 为我们提供了两个很棒的基类, TransformerMixin 和 BaseEstimator 。从 TransformerMixin 继承确保了我们所需要做的就是编写我们的 fit 和 transform 方法,并且我们可以免费获得 fit_transform。从 BaseEstimator 继承确保我们免费获得 get_params 和 set_params。由于 fit 方法除了返回对象本身之外不需要做任何事情,所以在从这些类继承之后,我们真正需要做的是为我们的自定义转换器定义转换方法,这样我们就获得了一个功能完整的自定义转换器,它可以与 scikit-learn 管道无缝集成!简单。
说明
我将在这个插图中使用的数据集可以通过这个链接在 Kaggle 上找到。
用回归法预测房价
www.kaggle.com](https://www.kaggle.com/harlfoxem/housesalesprediction)
此图的目标是通过编写我们自己的自定义转换器和管道所涉及的步骤,对数据进行预处理,直到数据被输入到机器学习算法中,以训练模型或进行预测。对于这个特殊的问题,可能有比在这个例子中描述的更好的方法来设计特性,因为我不关注这些特殊特性的有效性。此图的目的是让读者熟悉可用于创建转换器和管线的工具,以便尽可能高效地针对任何数据集以任何方式设计和预处理要素。
那我们开始吧。
该数据集包含分类和数字独立变量的混合,我们知道这些变量需要以不同的方式分别进行预处理。这意味着最初它们必须通过单独的管道进行适当的预处理,然后我们将它们组合在一起。因此,两个管道的第一步都必须提取需要下推进行预处理的适当列。
编写一个类并让 Python 知道它继承自一个或多个类的语法如下图所示,因为对于我们编写的任何类,我们都可以从 TransformerMixin 和 BaseEstimator 基类继承大部分内容。
下面是我们第一个名为 FeatureSelector 的自定义转换器的代码。这个构造函数的 transform 方法只是提取并返回 pandas 数据集,其中只包含那些在初始化过程中作为参数传递给它的列名。
如您所见,我们在声明类时将 BaseEstimator 和 TransformerMixin 放在括号中,让 Python 知道我们的类将从它们继承。像我们要写的所有构造函数一样,fit 方法只需要返回 self。transform 方法是我们真正要写的,让转换器做我们需要它做的事情。在这种情况下,它仅仅意味着返回一个只包含所选列的 pandas 数据框。
既然已经编写了将在两个管道中处理第一步的构造函数,我们就可以编写将在相应管道中处理其他步骤的转换器,从处理分类特性的管道开始。
分类管道
下面是我们的定制转换器将处理的功能列表,以及在我们的分类管道中如何处理。
- date :此列中的日期格式为‘yyyymmddt 000000’,必须进行清理和处理才能以任何有意义的方式使用。这个转换器的构造函数将允许我们为参数“use_dates”指定一个值列表,这取决于我们是想为年、月、日或这些值的某种组合创建一个单独的列,还是简单地通过传入一个空列表来完全忽略该列。通过不对该特性的规范进行硬编码,我们可以随时尝试不同的值组合,而不必重写代码。
- 滨水:房屋是否为滨水物业。转换为二进制—是或否
- 查看:房子被查看了多少次。大部分值都是 0。其余的非常稀疏地分布在 1 到 4 之间。转换为二进制—是或否
- yr _ recruited:房子装修的年份。大多数值都是 0,可能永远不会,而其余的值在几年之间分布得很稀疏。转换为二进制—是或否
一旦我们的定制转换器以上述方式处理了所有这些特性,它们将被转换成一个 Numpy 数组,并被推送到分类管道中的下一个也是最后一个转换器。一个简单的 sci kit-了解一个热编码器,它返回我们预处理数据的密集表示。下面是我们定制的转换器的代码。
数字流水线
下面是我们的自定义数值转换器将处理的特性列表,以及如何在我们的数值管道中处理。
- 卧室:房子里卧室的数量。照原样通过。
- 卫生间:房屋内卫生间数量。这个转换器的构造函数将有一个参数“bath_per_bead ”,它接受一个布尔值。如果为真,那么构造函数将通过计算浴室/卧室来创建一个新列,以计算每个卧室的浴室数量,并删除原始的浴室列。如果为 False,那么它将原样通过浴室列。
- sqft_living :房屋居住面积大小,平方英尺。照原样通过。
- sqft_lot :以平方英尺为单位的总批量。照原样通过。
- 楼层:房屋的层数。照原样通过。
- 条件:描述房屋条件的离散变量,取值范围为 1-5。照原样通过。
- 等级:根据 King County 等级系统给出的住房单元的总体等级,值为 1-13。照原样通过。
- sqft_basement :房屋内的地下室面积,以平方英尺为单位(如有)。没有地下室的房屋为 0。照原样通过。
- yr _ build:房子建造的年份。这个转换器的构造函数将有另一个参数‘years _ old ’,它也接受一个布尔值。如果为真,则构造函数将通过从 2019 年减去房屋建造年份来计算 2019 年的房屋年龄,从而创建一个新列,并将删除原始的 yr _ built 列。如果为 False,那么它将直接传递 yr _ built 列。
一旦所有这些特性都由我们的自定义数值转换器在上述数值管道中处理,数据将被转换为 Numpy 数组,并传递到数值管道的下一步,即另一种 scikit-learn 转换器。估算器将计算列中值,并用适当的中值填充任何 Nan 值。从那里,数据将被推送到数字管道中的最终转换器,一个简单的 scikit-learn 标准定标器。下面是自定义数值转换器的代码。
将管道组合在一起
现在,我们已经编写了数字和分类转换器,并定义了我们的管道,我们需要一种方法来横向组合它们。我们可以使用 scikit-learn 中的 FeatureUnion 类来实现。我们可以在 Python 中创建一个特征联合类对象,方法是给它两个或更多由转换器组成的管道对象。为要素联合对象调用 fit_transform 方法会将数据分别推入管道,然后将结果合并并返回。在我们的例子中,因为我们的两个管道的第一步是为每个管道提取适当的列,所以使用特征联合将它们组合起来,并在整个数据集上拟合特征联合对象,这意味着适当的列集将被下推到适当的管道集,并在它们被转换后组合在一起!是不是很牛逼?
我还没告诉你最精彩的部分呢。它将为我们并行计算!没错,它会并行转换数据,并将其重新组合在一起!因此,它很可能比任何处理这种线性预处理的脚本都要快,因为它很可能需要更多的并行工作。我们再也不用担心手动操作了。我们的 FeatureUnion 对象将尽可能多次地处理这个问题。我们所要做的就是在我们的完整特性联合对象上调用 fit_transform。下面是使用我们的自定义转换器和其他工具创建两个管道,然后将它们组合在一起的代码。
现在你可能已经注意到,我没有在完整的管道中包括任何机器学习模型。原因是我不能。FeatureUnion 对象接受仅包含转换器的管道对象。机器学习模型是一个估计器。解决方法是,我可以创建另一个管道对象,第一步传递完整的管道对象,最后一步添加一个机器学习模型。完整的预处理数据集将是第一步的输出,它将简单地传递到我的模型中,使它像您可能编写的任何其他 scikit-learn 管道一样工作!这是代码。
我们只需在未处理的数据集上拟合管道,它会使用我们构建的工具自动进行所有预处理和拟合。适当的柱子被分开,然后它们被推下适当的管道,在那里它们各自通过 3 或 4 个不同的变压器(总共 7 个!)使用我们决定的参数,将预处理的数据放回一起,并向下推至模型进行训练!调用 predict 对未处理的测试数据帧做同样的事情,并返回预测!这是我做的一个简单的图表,展示了我们机器学习管道的流程。
Simple flow diagram for our pipeline
除了因为我们的 transformer 类继承了 TransformerMixin 类而免费获得的 fit_transform 之外,我们还为我们的 transformer 提供了 get_params 和 set_params 方法,而无需编写它们,因为我们的 transformer 类也继承了 BaseEstimator 类。
这些方法会派上用场,因为我们编写转换器的方式允许我们通过为参数(如 use_dates、bath_per_bed 和 years_old)提供不同的参数来操纵数据的预处理方式。仅仅使用简单的乘积规则,我就可以为预处理部分的数据尝试大约 108 个参数组合!我可以使用 set_params 来设置它,而无需重新编写一行代码。由于这个管道的功能类似于任何其他管道,所以我也可以使用 GridSearch 来调优我打算与之一起使用的任何模型的超参数!
这就是了。现在,您知道了如何在自己的机器上编写自己的全功能定制转换器和管道来自动处理任何类型的数据,使用一点 Python 魔法和 Scikit-Learn 就可以实现这一点。显然还有改进的空间,比如验证数据是否是您期望的形式,在数据到达管道之前来自数据源,并让转换器能够处理和报告意外错误。然而,仅仅使用本文中的工具应该会使您的下一个数据科学项目更有效率,并允许您自动化和并行化一些繁琐的计算。
如果我遗漏了什么,或者有什么不准确的地方,或者如果你有任何反馈,请在评论中告诉我。我将非常感激。谢谢你。