通过快速思考构建句子嵌入
快速思考入门
在之前的故事中,我分享了skip-thinks来计算句子嵌入。今天,我们有另一种无监督学习方法来计算句子嵌入,这就是快速思维。
Logeswaran 等人(2018)引入了快速思考方法来检索下游应用的句子嵌入。看完这篇文章,你会明白:
- 思维敏捷的设计
- 估价
- 实验
- 参考
快速思维设计
快速思维和跳过思维非常相似。目标是分类候选句子是否属于相邻句子,而不是生成单词来构造句子(跳过思想方法)。与 skip-gram 相同,快速思考和 skip-gram 构建都利用分类器来学习向量。
#a skip-thoughts, #b quick-thoughts (Logeswaran et al., 2018)
给出一个目标句子,并使用负采样方法(Mikolov 等人,2013 年)为二元分类器构建一个有效的上下文句子和非上下文句子。
通过将有效的上下文句子标记为目标(例如 1),而将其他非上下文句子标记为非目标(例如 0),它可以建立一个分类器来找出哪个句子与目标句子相关。
该架构与使用编码器和解码器方法的跳跃思维相同,但是快速思维使用分类器而不是语言模型。你可以在这里查看来了解这个架构。
实验
Unsupervised Representation Learning Comparison (Logeswaran et al. 2018)
从上面的结果,你可以注意到 QT(快速思维)在不同的任务中得到了很好的结果。单 QT 和双 QT 意味着使用单向和双向 RNN 模型。
Supervised Representation Learning Comparison (Logeswaran et al. 2018)
在监督表征学习比较中,MC-QT(多通道快速思维)几乎在所有任务中都胜出。MC-QT 被定义为两个双向 rnn 的级联。第一个双向 RNN 使用一个预训练的字向量,它是手套。另一个双向 RNN 是可调字向量,这意味着从头开始训练向量。
Image Caption Retrieval (Logeswaran et al. 2018)
在图像到文本和文本到图像的下游任务中,MC-QT 也取得了不错的效果。
拿走
- 和跳跃思维一样,快速思维构建句子嵌入。
- 与 skip-gram 相同,Quick-thinks 利用分类器来学习嵌入。
- MC-QT 展示了从多个 NLP 下游任务中学习句子嵌入的能力。
关于我
我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客、 LinkedIn 或 Github 联系我。
参考
Logeswaran L .,Lee H .,2018,学习句子表征的高效框架
用流行的深度学习框架构建简单的人工神经网络
使用 TensorFlow、Keras、PyTorch 和 MXNet/Gluon
几周前,我完成了构建一个非常简单的神经网络的步骤,并在 go 中从头开始实现了它。然而,已经有许多深度学习框架可用,所以如果你想使用深度学习作为解决问题的工具,从头开始通常不是你要做的。
问题是,在众多深度学习框架中,我应该使用哪一个?比较深度学习框架的方法有很多。这是数据孵化器最近(2017 年 9 月)的排名,根据他们的 Github、Stack Overflow 和 Google 搜索结果得分,给出了一个有趣的人气排名。
Deep learning frameworks popularity (data from https://blog.thedataincubator.com/2017/10/ranking-popular-deep-learning-libraries-for-data-science/)
从结果来看,很明显 TensorFlow 无疑是最受欢迎的框架,随着 Keras 现在成为 TensorFlow 本身的一部分,事情在不久的将来不会有太大变化。此外,几乎所有流行的深度学习框架都有 Python APIs,因此 TensorFlow/Keras 与 Python 的结合似乎是正确的选择。
尽管如此,我对其他一些框架很好奇,所以我开始了一段小小的旅程,编写与我在这些框架中所做的相同(或几乎相同)的简单人工神经网络进行比较。
作为快速复习,我创建的神经网络是一个简单的前馈神经网络,通常也称为多级感知器(MLP)。使用这个简单的 MLP,我获得了 MNIST 6 万个手写数字的数据集,并用它来训练神经网络。之后,我使用 10,000 个手写数字的测试数据集来测试神经网络的准确性。
Our simple artificial neural network
神经网络有 3 层,第一(输入)层有 784 个神经元(28×28 像素),第二(隐藏)层有 200 个神经元,最后(输出)层有 10 个神经元。我用 sigmoid 函数作为激活函数,也用均方差作为损失函数。最后,我用 0.1 作为学习率,完全不使用任何偏向神经元。
以下所有实施都遵循相同的一般步骤:
- 设置参数并加载数据集(大多数框架都有加载标准数据集的方法,如 MNIST)
- 通过创建一个创建并返回神经网络的
mlp
函数来定义神经网络 - 定义
train
功能 - 定义
predict
功能 - 创建一个 main,允许用户首先使用训练数据集(60,000 个图像)进行训练,然后使用测试数据集(10,000 个图像)进行预测
这种用 MNIST 数据集对数字进行的手写识别在深度学习教程中经常使用,它几乎是编写深度学习程序的“hello world”。不过,作为免责声明,您在下面看到的实现没有经过任何方式的优化,也不是最终的实现方式。事实上,还有许多其他更好的方法,这只是几个例子。
现在我们开始,先看看如何在 TensorFlow 中实现这个。
张量流
TensorFlow 最初由从事谷歌大脑项目的研究人员和工程师开发,供内部使用,并于 2015 年开源。这是迄今为止最受欢迎的深度学习框架。
在 TensorFlow 上运行的更著名的项目包括 DeepMind (开发 AlphaGo 的谷歌公司),它在 2016 年从 Torch 转换为 TensorFlow。
这个实现使用 TensorFlow 1.6。我们开始吧。
设置参数并加载数据集
import TensorFlow as tf
import argparse
import numpy as np
from TensorFlow.examples.tutorials.mnist import input_data
# parameters
inputs, hiddens, outputs = 784, 200, 10
learning_rate = 0.01
epochs = 50
batch_size = 20
#loading the datasets
mnist = input_data.read_data_sets("./mnist/", one_hot=True)
相当简单,不言自明。请注意,我们将数据输出设置为单次触发。这仅仅意味着具有最高值的 ndarray 元素的位置是正确的。
定义神经网络
# a random generator using uniform
def random(r, c, v):
return tf.random_uniform([r,c], minval=-1/tf.sqrt(float(v)), maxval=1/tf.sqrt(float(v)))
# the neural network
def mlp(x, hidden_weights=None, output_weights=None):
if hidden_weights == None:
hidden_weights = tf.Variable(random(inputs, hiddens, inputs), name="hidden_weights")
if output_weights == None:
output_weights = tf.Variable(random(hiddens, outputs, hiddens), name="output_weights")
hidden_outputs = tf.matmul(x, hidden_weights)
hidden_outputs = tf.nn.sigmoid(hidden_outputs)
final_outputs = tf.matmul(hidden_outputs, output_weights)
final_outputs = tf.nn.sigmoid(final_outputs)
return final_outputs
这是我们定义神经网络的地方。相对来说比较直接。如果没有传入隐藏和输出权重,则使用tf.random_uniform
函数随机生成权重。这发生在我们训练神经网络的时候。
How a neuron works
正如在我之前创建的神经网络一样,我们首先将输入x
与隐藏权重相乘(使用tf.matmul
)以获得隐藏输出。请记住,我们正在处理矩阵,因此tf.matmul
实际上是一个点积函数,隐藏权重和输入都是矩阵。
隐藏的输出然后通过一个激活函数,在这个例子中,是一个sigmoid
函数。然后将输出乘以输出权重,得到最终输出。
最终输出在再次通过 sigmoid 激活函数后返回。
定义列车功能
# training with the train dataset
def train(x, y):
final_outputs = mlp(x)
errors = tf.reduce_mean(tf.squared_difference(final_outputs, y))
optimiser = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(errors)
init_op = tf.global_variables_initializer()
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init_op)
total_batch = int(len(mnist.train.labels) / batch_size)
for epoch in range(epochs):
avg_error = 0
for i in range(total_batch):
batch_x, batch_y = mnist.train.next_batch(batch_size=batch_size)
_, c = sess.run([optimiser, errors], feed_dict={x: batch_x, y: batch_y})
avg_error += c / total_batch
print("Epoch [%d/%d], error: %.4f" %(epoch+1, epochs, avg_error))
print("\nTraining complete!")
saver.save(sess, "./model")
让我们看看我们如何训练我们的神经网络模型。首先,我们使用mlp
函数创建它,向它传递输入。我们还将我们的误差函数恰当地定义为目标和输出之间的平方差(均方误差)。
接下来,我们定义优化器,我们在这里使用 Adam 优化器,向它传递学习率和我们的误差函数。当我第一次尝试这个的时候,我使用了梯度下降优化器,但是这些值需要很长时间才能收敛。当我切换到 Adam 优化器时,它收敛得很好,所以我改用 Adam 优化器。
现在我们有了优化器,我们初始化所有的变量并定义一个保护程序,这样我们就可以保存模型了。我们启动一个会话,并按时期运行小批量,将我们之前加载的训练数据集传递给它。
一旦我们完成训练,我们保存模型。张量流模型由两部分组成。第一个是元图,它保存了张量流图上的信息。这被保存到一个扩展名为.meta
的文件中,在这种情况下,它将是model.meta
。
第二个是一堆检查点文件。model.index
存储变量名称和形状的列表,而model.data-00000-of-00001
存储变量的实际值。
稍后,当我们想要加载模型进行预测时,我们将重用这些文件。
定义预测函数
# predicting with the test dataset
def predict(x):
saver = tf.train.import_meta_graph("./model.meta")
with tf.Session() as sess:
saver.restore(sess, tf.train.latest_checkpoint("./"))
graph = tf.get_default_graph()
hidden_weights = graph.get_tensor_by_name("hidden_weights:0")
output_weights = graph.get_tensor_by_name("output_weights:0")
final_outputs = mlp(x, hidden_weights, output_weights)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(final_outputs, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.summary.scalar('accuracy', accuracy)
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))
在我们训练好模型之后,我们会想要一些可以用来预测值的东西。在这种情况下,我们实际上想要的是对测试数据集中的 10,000 张图像运行我们的predict
函数,看看我们的训练模型正确地得到了多少张图像。
我们从导入来自model.meta
文件的元图开始。接下来,我们恢复检查点,并使用默认的图来获得隐藏的权重和输出权重各自的名称。
最后,我们通过调用mlp
函数并向其传递保存的权重来恢复训练好的模型。
有了训练好的模型,当我们通过测试数据集时,我们试图预测输出,并获得模型的准确性。predict
功能打印出所有测试图像的预测精度。
训练然后预测
if __name__ == "__main__":
x = tf.placeholder(tf.float32, [None, inputs])
y = tf.placeholder(tf.float32, [None, outputs])
parser = argparse.ArgumentParser()
parser.add_argument("--action", type=str, default="predict" )
FLAGS, unparsed = parser.parse_known_args()
if FLAGS.action == "predict":
predict(x)
if FLAGS.action == "train":
train(x, y)
最后一点很简单,它只是一个主要的功能,允许用户进行预测或训练。这一部分在其他实现中实际上是相同的,所以我以后不会再展示这段代码了。
这是结果。
模型预测正确率为 97.25%,不算太好但还可以。现在我们接下来看看 Keras。
Keras(在张量流上)
Keras 不是一个独立的框架,而是一个建立在 TensorFlow、Theano 和 CNTK 之上的接口。Keras 设计用于快速原型制作,易于使用和用户友好。
2017 年,TensorFlow 决定在 TensorFlow 的核心库中支持 Keras,尽管 Keras 本身没有任何变化。
让我们看看 Keras 的情况有什么不同。
设置参数并加载数据集
import argparse
from keras.models import Sequential
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import load_model
from keras import optimizers
from keras import utils
# parameters
inputs, hiddens, outputs = 784, 100, 10
learning_rate = 0.01
epochs = 50
batch_size = 20
# loading datasets
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape(60000, 784).astype('float32')/255
train_labels = utils.to_categorical(train_labels, outputs)
test_images = test_images.reshape(10000, 784).astype('float32')/255
test_labels = utils.to_categorical(test_labels, outputs)
设置数据集似乎比以前更加复杂,但这没什么大不了的,事实上,更清楚的是,我们正在将训练和测试数据集重塑为正确的形状和大小。
定义列车功能
# training with the train dataset
def train():
model = Sequential()
model.add(Dense(hiddens, activation='sigmoid', input_shape=(inputs,)))
model.add(Dense(outputs, activation='sigmoid'))
sgd = optimizers.Adam(lr=learning_rate)
model.compile(optimizer=sgd, loss='mean_squared_error')
model.fit(train_images, train_labels, batch_size=batch_size, epochs=epochs)
model.save('mlp_model.h5')
你可能会注意到,我没有在这里定义神经网络。我本来可以创建一个单独的mlp
函数来完成这项工作,但这并不是真正必要的,因为我使用了一个内置的 Keras 模型,名为Sequential
,并简单地在它上面堆叠层来构建网络。
前两行添加了隐藏层和输出层(根据给定的隐藏层的输入形状,默认情况下会采用后面的输入)。这包括激活功能sigmoid
。
接下来,我们使用内置的 Adam 优化器optimizers.Adam
来定义优化器。
该模型由优化器编译,并被赋予一个误差(或损失)函数mean_squared_error
,该函数也是内置的。
最后,我们使用fit
方法,使用图像和标签训练模型,具有给定的批量大小和时期数。
和以前一样,我们在训练模型之后保存它。
定义预测函数
# predicting the test dataset
def predict():
model = load_model("mlp_model.h5")
error = model.evaluate(test_images, test_labels)
print("accuracy:", 1 - error)
如果您认为训练函数相当简单,请查看预测函数!您只需要加载模型,然后用它来评估测试图像和标签!
训练然后预测
以下是你训练时看到的。
这是预测的结果。
这里的准确性要好得多,我们在检测正确的图像时有 99.42%的准确性。
PyTorch
PyTorch 顾名思义,就是 Torch 框架的 Python 版本。Torch 最初是用 C 开发的,有一个使用 Lua 编程语言的包装器。PyTorch 主要是由脸书的人工智能研究小组开发的,而是用 Python 包装了 Torch 二进制文件。
PyTorch 的一个关键特性是能够使用动态计算图修改现有的神经网络,而不必从头开始重建。PyTorch 将其描述为使用和重放录音机,它的灵感来自其他作品,如亲笔签名和 Chainer 。
在实现简单的神经网络的过程中,我没有机会正确地使用这个特性,但这似乎是一个建立神经网络的有趣方法,我想在以后进行更多的探索。
让我们看看 PyTorch 如何为我们的简单神经网络工作。
设置参数并加载数据集
import torch
import argparse
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable
# parameters
inputs, hiddens, outputs = 784, 200, 10
learning_rate = 0.01
epochs = 50
batch_size = 20
transformation = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])
train_dataset = datasets.MNIST('mnist/',train=True,transform=transformation, download=False)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = datasets.MNIST('mnist/',train=False,transform=transformation, download=False)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
加载数据集需要几个步骤,但它们相当简单。值得注意的是,变换的平均值为 0.1307,标准差为 0.3081,这是 MNIST 数据集的平均值和标准差。
定义神经网络
class mlp(nn.Module):
def __init__(self):
super(MLP, self).__init__()
self.sigmoid = nn.Sigmoid()
self.hidden_layer = nn.Linear(inputs, hiddens)
self.output_layer = nn.Linear(hiddens, outputs)
def forward(self, x):
out = self.sigmoid(self.hidden_layer(x))
out = self.sigmoid(self.output_layer(out))
return out
def name(self):
return "mlp"
定义神经网络很简单。我们在类中定义了一些方法,sigmoid
是nn.Sigmoid
,hidden_layer
和output_layer
是适当大小的线性层。
然后,forward
方法将输入x
传递给隐藏层,然后传递给sigmoid
激活函数。之后,它进入输出层,并在返回输出之前再次调用sigmoid
激活函数。
定义列车功能
def train():
model = mlp()
loss = nn.MSELoss(size_average=False)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(epochs):
avg_error = 0
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, inputs))
# Convert class label to one hot vector
one_hot = torch.FloatTensor(labels.size(0), 10).zero_()
target = one_hot.scatter_(1, labels.view((labels.size(0),1)), 1)
target = Variable(target)
# Compute loss and gradient
optimizer.zero_grad()
out = model(images)
error = loss(out, target)
error.backward()
# Apply gradient
optimizer.step()
avg_error += error.data[0]
avg_error /= train_loader.dataset.train_data.shape[0]
print ('Epoch [%d/%d], error: %.4f' %(epoch+1, epochs, avg_error))
# Save model to file
torch.save(model.state_dict(), 'model.pkl')
与其他实现一样,我们首先创建神经网络模型、误差函数loss
(我们将其定义为均方误差损失函数)以及 Adam 优化器。
我们照常运行 50 个时期的训练。因为训练标签的格式不正确,所以我们需要将其转换为一个热点向量,target
。然后,我们使用loss
函数计算误差,将实际输出值和目标值传递给它,然后对其应用反向传播。
最后,我们在结束训练之前保存模型。有几种方法可以保存 PyTorch 模型。更通用的 Python 方式是将其保存为 pickle 文件,扩展名为.pkl
。这是我在这个实现中使用的。另一种方法是使用 PyTorch 自己的序列化机制,它保存到一个扩展名为.pth
的文件中。
定义预测函数
def predict():
model = mlp()
model.load_state_dict(torch.load('model.pkl'))
correct, total = 0, 0
for images, labels in test_loader:
images = Variable(images.view(-1, inputs))
out = model(images)
_, predicted = torch.max(out.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print('accuracy: %0.2f %%' % (100.0 * correct / total))
预测比训练简单。这里我们需要首先创建一个神经网络,并用保存的状态加载它,以重现训练好的模型。然后使用训练好的模型预测输出,然后使用标签检查它是否正确。最后,我们将所有正确预测的值加起来,并得到准确率的百分比。
训练然后预测
这是结果。
正如你所看到的,网络不能以相同的学习速率在 50 个时期内完全收敛。这里的预测准确率相当差,只有 95.17%。另一方面,当我切换到使用 SGD 优化器时,准确率提高到了 98.29%。
带有胶子的 MXNet
MXNet 是 Apache 基金会的一个项目,目前正在 Apache 中孵化。它支持多种语言,并得到了许多大型行业参与者的支持,主要包括亚马逊和微软。
亚马逊选择 MXNet 作为深度学习框架的首选,因为它声称 MXNet 比其他框架更好地扩展和运行。MXNet 模型是可移植的,也可以部署在设备上。2017 年 10 月,亚马逊和微软为 MXNet 推出了一个名为 Gluon 的新界面,以使深度学习更容易。
胶子相对容易使用,从我的角度来看,建立我们简单的神经网络看起来也差不多。诚然,我可能还没有使用它的最佳能力。
让我们看看它是如何工作的。
设置参数并加载数据集
import argparse
import numpy as np
import mxnet as mx
from mxnet import nd, autograd, gluon
from mxnet.gluon import nn
from mxnet.gluon.data import vision
# parameters
inputs, hiddens, outputs = 784, 200, 10
learning_rate = 0.01
epochs = 50
batch_size = 20
ctx = mx.cpu()
def transform(data, label):
return data.astype(np.float32)/255, label.astype(np.float32)
train_data = mx.gluon.data.DataLoader(vision.MNIST(train=True, transform=transform), batch_size, shuffle=True)
test_data = mx.gluon.data.DataLoader(vision.MNIST(train=False, transform=transform), batch_size, shuffle=False)
与其他框架不同,您必须更加明确您希望操作的上下文在哪里运行。在这种情况下,我只在 CPU 上运行,所以我创建了一个基于 CPU 的上下文ctx
。
加载数据集与其他框架没有太大区别。
定义神经网络
def mlp():
model = nn.Sequential()
with model.name_scope():
model.add(nn.Dense(hiddens, activation="sigmoid"))
model.add(nn.Dense(outputs, activation="sigmoid"))
dist = mx.init.Uniform(1/np.sqrt(float(inputs)))
model.collect_params().initialize(dist, ctx=ctx)
return model
定义神经网络相对简单,与 Keras 非常相似。我们简单地使用一个内置的模型,用适当的激活函数在它上面添加层,然后用从均匀分布中采样的随机值的上下文和权重初始化它。我在这里使用均匀分布是为了与早期的实现保持一致。我尝试了其他的发行版,但是结果有些相同,所以至少在这篇文章中我坚持使用这个发行版。
定义列车功能
def train():
model = mlp()
loss = gluon.loss.L2Loss()
optimizer = gluon.Trainer(model.collect_params(), "adam", {"learning_rate": learning_rate})
for e in range(epochs):
cumulative_error = 0
for i, (data, labels) in enumerate(train_data):
data = data.as_in_context(ctx).reshape((-1, inputs))
labels = nd.one_hot(labels, 10, 1, 0).as_in_context(ctx)
with autograd.record():
output = model(data)
error = loss(output, labels)
error.backward()
optimizer.step(data.shape[0])
cumulative_error += nd.sum(error).asscalar()
print("Epoch [%d/%d]: error: %.4f" % (e+1, epochs, cumulative_error/len(train_data)))
model.save_params("mxnet.model")
为了训练模型,我们首先用我们的mlp
函数创建它。我们使用L2Loss
定义一个误差函数loss
,它本质上是一个均方误差函数。
我们还定义了一个优化器(在 MXNet 中称为Trainer
),它使用 Adam 优化器算法。
接下来,我们枚举训练数据集,并将其整形为一个独热 n 数组。我们将训练数据集传递给经过训练的模型,以获得输出。输出和标签被传递给错误函数。
训练结束后,我们保存网络模型。MXNet 允许我们用简单的save_params
方法保存参数。对文件名没有太大的要求,所以我们可以使用任何我们喜欢的名字。
定义预测函数
def predict():
model = mlp()
model.load_params("mxnet.model", ctx)
acc = mx.metric.Accuracy()
for i, (data, label) in enumerate(test_data):
data = data.as_in_context(ctx).reshape((-1, inputs))
label = label.as_in_context(ctx)
output = model(data)
predictions = nd.argmax(output, axis=1)
acc.update(preds=predictions, labels=label)
print("accuracy: %.2f %%" % (acc.get()[1] * 100))
predict
函数通过从我们之前保存的文件中加载它来重新创建我们的训练模型。我们重塑测试数据集中的数据,并将其传递给已加载的训练模型,然后我们将预测作为输出。然后使用标签,我们发现预测的准确性。
训练然后预测
下面是使用 MXNet 框架和 Gluon 进行预测的结果。
准确率为 97.49%,与其他框架相当。
一些想法
显然这个帖子没有所有的深度学习框架。这更像是在我探索各种框架时,漫无边际地浏览了几个激发我想象力的选定框架。我错过了很多流行的,包括 Caffe 和 Caffe2,CNTK,Theano,Torch,Sonnet 等等。
我也没有做任何比较——这不是我的目的,任何比较都需要对这些框架有更深入的理解,也需要更多的时间。从某种意义上说,由于所有这些框架都在增长(当我在过去几周写这篇文章时,TensorFlow 连续发布了 1.7 和 1.8!)并且改变任何比较将会很快变得不准确。相反,我的目的是弄清楚实际编写深度学习软件有多容易,以及这些框架能在多大程度上帮助我做到这一点。
当我使用这些框架时,我意识到就目标而言,它们基本上是相同的。在每个框架中,目标总是有一个简单的方法来加载数据集,定义模型,训练模型,然后使用它来预测结果。实现的方式可能因框架而异,潜在的哲学可能不同,但目标是相同的。
从某种意义上说,它非常类似于我过去 20 年一直使用的所有 web 框架。虽然这些年来已经创建了令人惊叹的 web 应用程序,但是 web 框架基本上以相同的方式工作,具有相同的视图、控制器和服务,并且使用 HTTP。
毫无疑问,我把一切都过于简单化了,但在某种意义上,我同时也感到安慰。
源代码
您可以在这里找到所有源代码:
https://github.com/sausheong/pynn
使用开放堆栈构建语音识别
语音识别是新的用户界面,将带来我们与应用程序和机器交互方式的范式转变。说“关掉微波炉”,“订购我的每周用品”比使用触摸和点击界面以及(重新)学习应用程序界面要容易得多。事实上,语音是人类开发的原始通信协议。我们并没有进化到通过点击苹果/三星设备来交流。
我最近实现了一个语音识别系统。我对这个领域缺乏好的和简单的博客/帖子感到非常沮丧。希望这篇文章能消除人们的疑虑,引导试图首次创建语音识别系统的人朝着正确的方向前进。
首先,你创建自动语音识别系统的动机是什么?我可以想到一些创建自己的 ASR 的情况:
- 您的应用程序有一个语音识别用例,主要用于零/低带宽环境。因此,将 ASR 作为您的应用程序的一部分供离线使用是有意义的。
- 您所在的行业受到监管,如医疗或金融行业,个人身份信息不能发送到苹果/谷歌/微软服务器进行转录。
- 你想做一个 ASR 系统,在小词汇量上转录非母语外国口音。
在大多数其他情况下,将你的应用程序与苹果/谷歌/微软现有的语音 API 集成是完全有意义的。(注意,亚马逊 Alexa 不是一种语音转录技术)毕竟,这些科技巨头可以在庞大的语料库上训练他们的语音模型,你可以期待他们的转录中真的很低的 WER(单词错误率)。
我试过苹果的 ASR speech kit,还不错。我没有尝试过谷歌,但尝试过必应语音 API,对它的转录质量印象深刻。
好吧,如果谷歌/微软/苹果的语音 API 不能满足你的需求,那么你应该自己开发。
在这篇文章中,我将回顾使用传统的基于 GMM/DNN-HMM 模型的语音识别堆栈。高斯混合模型(GMM)/深度神经网络(DNN)用于模拟语音中的音素。音素是语音的原子单位,英语中大约有 40 个音素。隐马尔可夫模型(HMM)用于基于音素序列生成单词。ASR 的最新技术状态是使用递归神经网络实现的,其中通过使用允许预测字符级转录的目标函数来丢弃音素:连接主义者时间分类 (CTC)。
以下是开源 ASR 的主要竞争者:
- 卡尔迪
- CMU 狮身人面像
还有其他竞争者,如 HTK、Julius、ISIP,但我没有把他们包括在我的分析中,原因有很多->不是严格的开源,不容易实现,转录质量差等等。
易于实施
CMU 斯芬克斯轻而易举地击败了卡尔迪。CMU·斯芬克斯的教程很容易理解。另一方面,我发现 Kaldi 的实现又密集又困难。最初,我甚至很难在我的机器上实现一个简单的数字识别设置。有了 CMU·斯芬克斯,我在阅读的几个小时内就准备好了。
支持移动设备
CMU 狮身人面像再次击败了卡尔迪。CMU Sphinx 拥有易于实现的 iOS 和 Android SDK(pocket Sphinx)。卡尔迪实际上没有。原因是 Kaldi 创建了大约 5–7G 的巨大 FST 模型文件,这些文件在实时搜索和查询以生成转录时计算量非常大。
转录质量
卡尔迪打败了 CMU·斯芬克斯,这就是我坚持使用卡尔迪的原因。对于我的应用用例的一小部分词汇来说,卡尔迪一直胜过 CMU·斯芬克斯。
我知道这是一篇很长的文章,但是希望这篇文章能为你选择合适的栈来构建你自己的 ASR 系统提供一些指导。
用 Spark 打造 Spotify 的“发现周刊”
基于协同过滤算法的音频推荐系统的 MLlib & PySpark 实现
今天是我在 NBC Universal 实习的第三天,我受到鼓舞要实现一个新的目标:在今年夏天离开30 Rock&1221 Campus(我将在那里工作大部分时间)之前掌握 Spark 。
作为领先的媒体和娱乐行业,我们公司拥有数百 Pb 来自全国各地和通过国际有线电视的电视广播数据。虽然这听起来令人惊讶和不知所措,但毫无疑问,现在越来越多的公司依靠推荐系统的力量来满足各种个人品味和需求,从而提高客户的满意度和忠诚度。
在娱乐行业,Spotify 等音乐科技巨头将推荐引擎作为其产品的重要组成部分。涉及用户兴趣的模式检测和分析在提供个性化推荐方面发挥了关键作用。这是因为给用户体验添加另一个维度有助于推荐系统在识别我们不知道自己会喜欢的曲目方面做得非常出色。
用什么算法?
让我从我们可以用来构建音频推荐系统的两种主要方法开始。第一个是 内容过滤 ,利用产品和用户的已知信息进行推荐。使用这种方法,我们根据产品(例如电影信息、价格信息和产品描述)和用户(例如人口统计和问卷信息)创建档案。
实施内容过滤的一个广为人知的例子是在线电台 Pandora 的音乐基因组计划。在这里,一个专家根据上百个特征给一首歌打分。用户还提供关于他/她的音乐偏好的信息。基于这两个源的配对提出建议。
潘多拉使用内容过滤,Spotify 使用 协同过滤 用于他们的发现周刊推荐系统。后一种技术使用先前用户的输入/行为来做出未来的推荐。我们忽略任何先验的用户或对象信息。我们使用相似用户的评分来预测评分。
进一步理解 Spotify 技术的一种方式是通过一种基于邻居的方法,在这种方法中,你(1)首先根据我们的重叠评分的一致程度来定义你和其他用户之间的相似性评分,然后(2)让其他人根据这些评分来投票决定你喜欢什么。
与内容过滤相比,协作过滤的一个主要吸引力在于其不受领域限制的方法,这意味着它不需要知道什么被评级,只需要知道谁对什么进行了评级,以及评级是什么。
注意两种方法并不互相排斥。内容信息也可以内置到协同过滤系统中,提高性能。现在我们已经了解了算法是如何工作的,让我们来了解一下我们将用来构建推荐系统的技术— Spark。
为什么是火花?
Apache Spark 是一个快速通用的集群计算系统。随着行业开发出更具创意、基于客户的产品和服务,对机器学习算法的需求变得更加重要,以帮助开发个性化、推荐和预测性见解。
像 R 和 Python 这样的工具长期以来被用来执行各种机器学习活动。然而,随着信息的大量增长,计算效率对于帮助解决高时间和空间复杂性变得非常关键。
此外,Spark 为数据工程师和数据科学家提供了一个强大的统一引擎,它不仅速度快(比 Hadoop 快 100 倍,用于大规模数据处理)且易于使用,而且简单、高度可扩展,并可与其他工具有效集成,如 R、SQL、Python、Scala 和 Java。
Source: Infoworld Analytics
我最喜欢 Spark 的一点是,它能够帮助我们数据科学家解决高度复杂的机器学习问题,涉及图形计算、流和以互动方式在更大规模上进行实时互动查询处理。
使用 PySpark 的逐步实现
我们现在将使用 AudioScribbler 数据集实现协同过滤算法来构建音频推荐系统(在这里下载压缩档案)。
导入库和数据集
一旦数据集中有了三个文件,就可以启动spark-shell
。构建模型的第一步是理解您的数据,并将其解析成对 Spark 中的分析有用的形式。让我们从导入库和初始化您的SparkContext
开始用 PySpark 编码。
import findspark
import pyspark
from pyspark import SparkContext
from pyspark import SparkConf
from pyspark.mllib import recommendation
from pyspark.mllib.recommendation import ***'''initialize spark in VM'''**findspark.init('/usr/local/bin/spark-1.3.1-bin-hadoop2.6/')
try:
sc=SparkContext()
except:
None
接下来,将每个文件存储到一个变量中。 user_artist_data.txt 表示一个播放列表数据集,其中文件的每一行都包含一个用户 ID、一个艺术家 ID 和一个播放次数,用空格分隔。 artist_data.txt 包含与艺术家姓名相关联的不透明数字 id。 artist_alias.txt 将可能拼写错误或不标准的艺术家 ID 映射到艺术家规范名称的 ID。它每行包含两个 id,用制表符分隔。
**'''define variables'''**rawUserArtistData = sc.textFile("vagrant/user_artist_data.txt")
rawArtistData = sc.textFile("vagrant/artist_data.txt")
rawArtistAlias = sc.textFile("vagrant/artist_alias.txt")
预处理数据
我们希望获得原始艺术家数据的列表,每个 ID 和名称都存储在元组中。让我们使用 artist_data.txt 来创建这个列表。
def pairsplit(singlePair):
splitPair = singlePair.rsplit('\t')
if len(splitPair) != 2:
return []
else:
try:
return [(int(splitPair[0]), splitPair[1])]
except:
return []
artistByID = dict(rawArtistData.flatMap(lambda x: pairsplit(x)).collect())
我们还使用 artist_alias.txt 将“坏的”艺术家 id 映射到“好的”艺术家 id,而不仅仅是将其用作艺术家 id 的原始数据对。我们使用下面的代码将坏的 id 转换成好的 id。例如,第一个条目将 ID 6803336 映射到 1000010,这意味着它将“Aerosmith(不插电)”映射到“Aerosmith”。
def aliaslookup(alias):
splitPair = alias.rsplit('\t')
if len(splitPair) != 2:
return []
else:
try:
return [(int(splitPair[0]), int(splitPair[1]))]
except:
return []
artistAlias = rawArtistAlias.flatMap(lambda x: aliaslookup(x)).collectAsMap()
建立一个模型
然后,我们创建一个查找函数,将数据转换成评级对象。请注意,任何潜在的 MLlib 模型都需要产品作为客观的衡量标准。在我们的模型中,产品是艺术家。因此,我们将使用 user_artist_data.txt 来实现我们的火车数据。
def ratinglookup(x):
userID, artistID, count = map(lambda line: int(line), x.split())
finalArtistID = bArtistAlias.value.get(artistID)
if finalArtistID is None:
finalArtistID = artistID
return Rating(userID, finalArtistID, count)trainData = rawUserArtistData.map(lambda x: ratinglookup(x))
trainData.cache()
我们还为artistAlias
创建了一个名为bArtistAlias
的广播变量。这使得 Spark 只为集群中的每个执行器发送并在内存中保存一个副本。当有数千个任务,并且许多任务在每个执行器上并行执行时,这可以节省大量的网络流量和内存。
bArtistAlias = sc.broadcast(artistAlias)
最后,我们使用协同过滤算法建立我们的模型,如下所示。该操作可能需要几分钟或更长时间,具体取决于您的群集。我花了大约 15 分钟来运行这个模型。
**'''build model'''**model = ALS.trainImplicit(trainData, 10, 5)
我们应该首先通过检查一个用户、他或她的戏剧以及对该用户的推荐,来看看艺术家的推荐是否有任何直观的意义。以用户2093760
为例。提取这个用户听过的艺术家的 id 并打印他们的名字。这意味着在输入中搜索该用户的艺术家 id,然后根据这些 id 过滤艺术家集,以便您可以按顺序收集和打印姓名:
**'''test artist'''**spotcheckingID = 2093760
bArtistByID = sc.broadcast(artistByID)rawArtistsForUser = (trainData
.filter(lambda x: x.user == spotcheckingID)
.map(lambda x: bArtistByID.value.get(x.product))
.collect())
print(rawArtistsForUser)
获得您的推荐
我想根据我的数据模型选出前 10 首歌曲:
**'''output recommendations'''**recommendations = map(lambda x: artistByID.get(x.product), model.call("recommendProducts", spotcheckingID, **10**))
print(recommendations)
在我的 Spark VM 集群上运行这个程序,我得到了以下输出:
- Jay Z、50 Cent、Snoop Dogg、2Pac、Nas、Kanye West、Outkast、Eminem、德瑞医生和卢达克里斯。
A screenshot of my model output. Note that your top 10 listed songs can be in random order.
是的,这些艺术家看起来像说唱歌手的混合体!请记住,这组艺术家在 2005 年非常受欢迎,这是这个数据集被提取的年份。
**可能的下一步?**我们可以使用另一组可用的歌曲数据提取一组推荐的歌曲,并根据我们的顶级艺术家对它们进行查询。
希望你喜欢和快乐的黑客!
编码参考
你可以在这里找到我的原始代码:https://github.com/moorissa/audiorecommender
Moorissa 是一名研究生,目前在哥伦比亚大学学习机器学习,希望有一天她可以利用这些技能让世界变得更好,一次一天。
使用 USB 摄像头和无线连接的 Raspberry Pi 构建监控系统
本教程讨论使用插入 Raspberry Pi (RPi)的 USB 摄像头构建监控系统,该摄像头通过无线接口连接到 PC。PyGame 用于访问摄像机和捕捉存储在 RPisd 卡中的图像。为场景创建背景模型,以发现默认状态的变化。一个连接到 GPIO 引脚的简单电路点亮一个 led 来指示这种状态。
Cover image by Ahmed Fawzy Gad. Building Surveillance System using USB Camera and Wireless-Connected Raspberry Pi
该教程包含以下步骤:
- 使用无线接口将 RPi 连接到 PC。
- 将 USB 摄像头连接到 RPi。
- 使用 PyGame 捕捉图像。
- 建立背景模型。
- 检测背景模型的变化。
- 构建一个简单的电路,当发生变化时点亮 led。
本教程假设读者有一台连接到无线网络的 PC 和一台使用以太网接口连接到交换机的 RPi。要做这样的工作,请阅读题为“构建一个运行在 Raspberry Pi 上的图像分类器”的教程,该教程可从以下链接获得:
https://www . LinkedIn . com/pulse/building-image-classifier-running-raspberry-pi-Ahmed-gad
您应该能够使用“Advanced IP Scanner”等软件知道设备的 IP 地址,并熟悉使用 MobaXterm 软件建立 SSH 连接。之后,我们就可以开始讨论上面的每一个步骤了。
1.使用无线接口将 RPi 连接到 PC
在之前的教程“构建运行在 Raspberry Pi 上的图像分类器”中,我们构建了一个连接了三个设备的网络,这三个设备分别是 RPi、交换机和 PC。RPI 使用以太网接口连接到交换机,但 PC 使用无线接口连接到交换机。在本教程中,我们将通过使用 RPi 的无线接口连接到交换机来修改此类网络。这使得网络完全无线连接,避免了有线的限制。
RPi 的无线接口需要配置才能使用。因此,我们仍将使用通过以太网接口建立的连接来配置无线接口。通过在交换机中使用 DHCP,RPi 以太网接口将获得一个 IPv4 地址。这样的地址可以用于建立安全外壳(SSH)连接。关于建立连接的更多细节,可以参考前面的教程。
在使用 MobaXterm 创建的 SSH 会话中,我们可以使用终端命令或 Raspbian 操作系统的 GUI 开始配置无线接口。两种方法都很简单。
使用终端命令,我们将首先扫描可用的无线网络,找到它们的服务集标识符(SSIDs)。这是使用以下命令完成的:
**pi@raspberrypi:~ $ sudo iwlist wlan0 scan**
下图给出了该命令输出的前几行。目标无线网络的 SSID 为“ TEData_864A ”。请注意,您不必使用交换机将 PC 连接到 RPi。使用智能手机,我们可以创建一个接入点来连接它们。
知道目标网络的 SSID 后,我们可以使用它来配置无线接口。这种配置存在于一个文件中,可以使用以下命令访问该文件:
**pi@raspberrypi:~ $ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf**
文件将在终端中打开。使用向下箭头,返回到文件的末尾,写入网络配置。这是通过按如下方式写入网络的 SSID 和密码实现的:
**network={
ssid=”TEData_864A”
psk=”YOUR_NETWOK_PASSWORD”
}**
之后,按 CTRL+X 退出文件,然后按 Y 保存更改。对于我的例子,我配置了两个网络,因此文件内容有两个配置的网络,如下图所示。
您可能需要将无线接口的状态从“打开”更改为“关闭”,然后再次将其更改为“打开”,以应用此类配置。这是使用这两个命令完成的:
**pi@raspberry:~ $ sudo ifdown wlan0
pi@raspberry:~ $ sudo ifup wlan0**
要检查无线接口配置是否正确,输入“ ifconfig 命令检索接口的配置。
**pi@raspberry:~ $ ifconfig**
根据此命令的输出,无线接口的 IPv4 地址为 192.168.1.8。这就是如何使用终端命令配置无线连接。
我们可以使用操作系统的 GUI 做同样的事情,可以使用 startlxde 终端命令访问该 GUI。GUI 打开后,在操作系统栏的右侧会出现一个网络连接图标。点击它将打开一个可用无线网络的菜单,如下图所示。单击任何一项都会打开一个窗口,允许您输入密码。通过输入 SSID 为" TEData_864A 的网络密码,并输入" ifconfig "命令,结果将与上图所示相同。
此时,我们已经将 PC 和 RPi 无线连接到交换机。当前网络如下图所示。我们现在可以删除以太网连接,只使用 RPi 和交换机之间的无线连接。
2.将 USB 摄像头连接到 RPi
RPi 有自己的摄像头模块可以使用。与其买这个模块,对很多人来说可能很贵,我们可以只使用一个 USB 摄像头,它可能在任何地方都可以以更低的成本买到。这种相机的配置非常简单。只需将 USB 摄像头连接到 RPi 的一个 USB 端口。之后,我们可以通过使用“fswebcam”包捕捉图像来检查相机是否工作正常。首先,我们需要使用以下命令安装该软件包:
**pi@raspberry:~ $ sudo apt-get install fswebcam**
之后,我们可以用它来捕捉图像。一个非常基本的方法如下:
**pi@raspberry:~ $ sudo fswebcam test_image.jpg**
这将访问相机,捕捉图像,并以“test_image.jpg”的名称将其保存到 SD 卡的当前目录中。执行命令后的输出如下图所示。
以下是捕捉到的图像:
3.使用 PyGame 捕捉图像
“ fswebcam ”包对于快速测试相机是否工作正常很有用。在确保它运行良好之后,我们可以开始构建一个 Python 脚本,使用 PyGame 库访问相机以连续捕捉图像。下面的代码使用 PyGame 来捕捉一个图像,打开一个窗口来显示这个图像,最后保存这个图像。
**import** pygame
**import** pygame.camera
*# Captured image dimensions. It should be less than or equal to the maximum dimensions acceptable by the camera.* width = 320
height = 240
*# Initializing PyGame and the camera.* pygame.init()
pygame.camera.init()
*# Specifying the camera to be used for capturing images. If there is a single camera, then it have the index 0.* cam = pygame.camera.Camera(**"/dev/video0"**,(width,height))
*# Preparing a resizable window of the specified size for displaying the captured images.* window = pygame.display.set_mode((width,height),pygame.RESIZABLE)
*# Starting the camera for capturing images.* cam.start()
*# Capturing an image.* image = cam.get_image()
*# Stopping the camera.* cam.stop()
*# Displaying the image on the window starting from the top-left corner.* window.blit(image,(0,0))
*# Refreshing the window.* pygame.display.update()
*# Saving the captured image.* pygame.image.save(window,**'PyGame_image.jpg'**)
假设上面的代码保存在一个名为“ im_cap.py ”的 Python 文件中。要执行这样的代码,我们可以从终端发出以下命令:
**pi@raspberry:~ $ python3 im_cam.py**
这是执行该文件后显示的窗口。
我们可以修改前面的代码来捕获多个图像。例如,我们可以使用一个循环的来捕捉一些先前指定的图像。我们也可以使用一个 while 循环,它并不局限于一些图像。下面是使用 for 循环捕获 2000 张图像的修改代码。
**import** pygame
**import** pygame.camera
*# Captured image dimensions. It should be less than or equal to the maximum dimensions acceptable by the camera.* width = 320
height = 240
*# Initializing PyGame and the camera.* pygame.init()
pygame.camera.init()
*# Specifying the camera to be used for capturing images. If there is a single camera, then it has the index 0.* cam = pygame.camera.Camera(**"/dev/video0"**, (width, height))
*# Preparing a resizable window of the specified size for displaying the captured images.* window = pygame.display.set_mode((width, height), pygame.RESIZABLE)
*# Starting the camera for capturing images.* cam.start()
**for** im_num **in** range(0, 2000):
**print**(**"Image : "**, im_num)
*# Capturing an image.* image = cam.get_image()
*# Displaying the image on the window starting from the top-left corner.* window.blit(image, (0, 0))
*# Refreshing the window.* pygame.display.update()
*# Saving the captured image.* pygame.image.save(window, **'./pygame_images/image_'** + str(im_num) + **'.jpg'**)
*# Stopping the camera.* cam.stop()
这里有 8 张捕捉到的图像。请注意,相机的位置发生了一点变化。
4.构建背景模型
到目前为止,我们成功地构建了一个简单的监控系统,在该系统中,摄像机捕获图像并保存在 RPi 的 SD 卡中。我们可以扩展它来自动检测场景的变化。这是通过为场景建立背景模型来实现的。对这种模型的任何改变都将表明一种改变。例如,如果有人正在穿过场景,将导致背景发生变化。
背景模型可以简单地通过将多个捕获的图像平均到其中没有任何对象的场景背景来创建。因为我们对颜色信息感兴趣,所以图像将被转换成二进制。下面是用于构建背景模型的 Python 代码。
**import** skimage.io
**import** os
**import** numpy
dir_files = os.listdir(**'./pygame_images/'**)bg_image = skimage.io.imread(fname=dir_files[0], as_grey=True)
**for** k **in** range(1, len(dir_files)):
fname = dir_files[k]
im = skimage.io.imread(fname=fname, as_grey=True)
bg_image = bg_image + im
bg_image = bg_image/(len(dir_files))
bg_image_bin = bg_image > 0.5
skimage.io.imsave(fname=**'bg_model.jpg'**, arr=bg_image)
skimage.io.imsave(fname=**'bg_model_bin.jpg'**, arr=bg_image_bin*255)
这是平均 500 张图像后的背景模型,既有灰度也有二值。
5.检测背景模型的变化
在建立背景模型之后,我们可以测试一张新的图像来检查背景是否有变化。只需将新图像转换成二进制即可。然后比较两幅图像中白色像素的数量。如果该数字超过给定的阈值,这表明背景发生了变化。阈值随着场景的不同而变化。下面是用于测试新图像的代码。
bg_num_ones = numpy.sum(bg_image_bin)test = skimage.io.imread(fname=**"./pygame_images/image_800.jpg"**,
as_grey=True)
test_bin = test > 0.5
test_num_ones = numpy.sum(test_bin)
**print**(**"Num 1s in BG :"**, bg_num_ones)
**print**(**"Num 1s in Test :"**, test_num_ones)
**if**(abs(test_num_ones-bg_num_ones) < 5000):
**print**(**"Change."**)
这是一个彩色、灰度和二进制的测试图像,由于场景中出现了一个物体(人),因此背景发生了变化。
6.构建一个简单的电路,当发生变化时点亮 Led
作为对背景模型变化的指示,我们可以建立一个简单的电路,当发生变化时,led 就会发光。该电路将连接到 RPi 的 GPIO(通用输入输出)箱。该电路需要以下元件:
- 一块试验板。
- 一个 led。
- 一个电阻器(大于或等于 100 欧姆)。我使用 178.8 欧姆的电阻。
- 两根公/公跳线。
- 两根公/母跳线。
建议在将电路连接到 GPIO 引脚之前对其进行测试。这是因为如果电阻值选择不当,不仅会烧坏 led,还会损坏 GPIO 引脚。为了进行测试,我们需要一个电池为试验板供电。这是正确连接所有组件后的电路。
之后,我们可以取下电池,将试验板连接到 RPi 的 GPIO 引脚。根据 GPIO 引脚的试验板编号,接地连接到 20 号箱,高压连接到 22 号输出箱。下图说明了试验板和 RPi 之间的连接。RPi 还连接到充电器和 USB 摄像头。
使用下面给出的 Python 脚本控制输出 GPIO bin。其默认状态为低电平,表示 led 关闭。当背景发生变化时,状态将变为 HIGH,表示 led 打开。led 保持亮起 0.1 秒,然后其状态恢复为熄灭。当另一个输入图像不同于背景时,led 将重新打开 0.1 秒。
**import** time
**import** RPi.GPIO
**import** skimage.io
**import** numpy
**import** os
**import** pygame.camera
**import** pygame
*#####GPIO#####
# Initializing the GPIO pins. The numbering using is board.* RPi.GPIO.setmode(RPi.GPIO.BOARD)
*# Configuring the GPIO bin number 22 to be an output bin.* RPi.GPIO.setup(22, RPi.GPIO.OUT)
*#####PyGame#####
# Initializing PyGame and the camera.* pygame.init()
pygame.camera.init()
*# Captured image dimensions. It should be less than or equal to the maximum dimensions acceptable by the camera.* width = 320
height = 240
*# Preparing a resizable window of the specified size for displaying the captured images.* window = pygame.display.set_mode((width, height), pygame.RESIZABLE)
*# Specifying the camera source and the image dimensions.* cam = pygame.camera.Camera(**"/dev/video0"**,(width,height))
cam.start()
*#####Background Model#####
# Reading the background model.* bg_image = skimage.io.imread(fname=**'bg_model_bin.jpg'**, as_grey=True)
bg_image_bin = bg_image > 0.5
bg_num_ones = numpy.sum(bg_image_bin)
im_dir = **'/home/pi/pygame_images/'
for** im_num **in** range(0, 2000):
**print**(**"Image : "**, im_num)
im = cam.get_image()
*# Displaying the image on the window starting from the top-left corner.* window.blit(im, (0, 0))
*# Refreshing the window.* pygame.display.update()
pygame.image.save(window, im_dir+**'image'**+str(im_num)+**'.jpg'**)
im = pygame.surfarray.array3d(window)
test_bin = im > 0.5
test_num_ones = numpy.sum(test_bin)
*# Checking if there is a change in the test image.* **if** (abs(test_num_ones - bg_num_ones) < 5000):
**print**(**"Change."**)
**try**:
RPi.GPIO.output(22, RPi.GPIO.HIGH)
time.sleep(0.1)
RPi.GPIO.output(22, RPi.GPIO.LOW)
**except** KeyboardInterrupt: *# CTRL+C* **print**(**"Keyboard Interrupt."**)
**except**:
**print**(**"Error occurred."**)
*# Stopping the camera.* cam.stop()
*# cleanup all GPIO pins.* **print**(**"Clean Up GPIO."**)
RPi.GPIO.cleanup()
下图显示了由于人的存在而不同于背景图像的一个输入图像。因此,led 将打开 0.1 秒。
以下视频(https://youtu.be/WOUG-vjg3A4)显示了使用相机拍摄的多帧的 led 状态。根据所使用的阈值,当输入图像不同于背景模型时,led 被打开。
了解更多详情
Ahmed Fawzy Gad,《构建运行在 Raspberry Pi 上的图像分类器》,2018 年 9 月,https://www . LinkedIn . com/pulse/Building-Image-Classifier-Running-Raspberry-Pi-Ahmed-Gad
联系作者
- 电子邮件:【ahmed.f.gad@gmail.com
- 领英:https://linkedin.com/in/ahmedfgad/
- https://kdnuggets.com/author/ahmed-gad
- YouTube:http://youtube.com/AhmedGadFCIT
- 走向科学:https://towardsdatascience.com/@ahmedfgad
构建人工智能堆栈
随着机器学习的使用——特别是计算密集型深度学习技术——在研究和行业中蓬勃发展,构建机器学习堆栈的市场也出现了爆炸式增长。谷歌、亚马逊和微软等科技巨头发布旨在使 ML(机器学习)技术更容易开发并最终推动云销售的云产品,完美地说明了这一点。从数据准备(图像标记),到培训(模型优化),再到部署,这一趋势也在大量构建基础设施和工具的初创公司中得到了强调。
我在 Elaia 和大型云提供商那里看到的创业公司的 5 个痛点:
- 效率低下的 ML 团队机器学习科学家和工程师在管道和低价值任务上花费了太多时间,例如建立他们的基础设施和工具,围绕数据管道进行黑客攻击,以及建立基本的自动化,从而推迟了研发项目。
- 低硬件利用率计算基础设施未得到充分利用,导致成本不理想和/或 ML 团队争夺稀缺资源
- 技术不确定性随着新的硬件产品(谷歌 TPUs,最新的英伟达芯片)和软件产品(谷歌 AutoML)的推出,决策者很难就 ML 基础设施做出长期决策。
- 技能和堆栈的异构性传统数据科学家和 IT 经理正在慢慢迁移到新技术(高级 ML 和深度学习),并需要与新一代深度学习本地科学家一起工作。
- 监管和隐私数据要么至关重要,需要限制安全性,而新出现的监管带来了额外的挑战(HIPAA、GDPR 等)
市场仍然不成熟,尽管技术基础已经具备,可以构建一个全面的产品,最终实现快速的 ML 开发和广泛的现实影响
在这类文章中,很难使用正确的词汇。AI,ML,深度学习都被误用了。在某些方面,自第一台计算机制造出来,人工智能栈就已经永远存在了。在这里,我将重点关注能够开发当前一代产品的产品,通常是计算和数据密集型机器学习模型。我戏称它为人工智能栈。
认为谷歌的战略和产品将深刻影响市场,并从上一代技术(即 Map Reduce 范式和 Hadoop 生态系统)中汲取灵感,我将提出两种未来堆栈可能的情况。
1)谷歌的战略正在推动人工智能基础设施和工具市场
谷歌的战略
谷歌的商业模式过度依赖广告收入,投资者已经多次指出这个事实。随着新平台的出现,语音(如虚拟助手)等界面被广泛采用,我们现在知道的搜索格式的数量将慢慢减少。为了弥补这一点,谷歌推出了许多其他产品,这些产品在历史上对底线的影响有限,直到最近。
人工智能领域似乎出现了两个战略机遇:
通过人工智能附加服务创造收入人工智能的崛起为谷歌创造了巨大的市场机会,谷歌在该领域、文化和内部基础设施方面拥有丰富的专业知识,可以快速开发和推出人工智能驱动的产品。
征服云市场虽然 AWS 仍然是云基础设施服务的市场领导者,拥有 30%以上的市场份额,但世界的云化并没有结束,这为新一代云产品留下了空间。在本文的其余部分,我们将重点关注谷歌为抓住这一机遇而部署的战略。
Cloud Prodiver Growth vs Market Share
谷歌已经在人工智能堆栈中构建了产品
虽然很容易认为谷歌正在影响任何市场,但它特别是在人工智能基础设施和工具市场。事实上,谷歌已经发布了不同层次的产品。机器学习框架 TensorFlow 是目前最受欢迎的。谷歌云是机器学习科学家最喜欢的云,在收入方面历史上与 AWS 相比相形见绌。
Google’s Products Cover the Stack. Some are open source software (Kubernetes, TensorFlow), some are Hosted services (ML Engine) and some hardware (TPU)
为了赢得云战争,谷歌使用了两个杠杆:
- 产品差异化:增值的人工智能基础设施产品和服务可能会赢得迫切需要获得坚实堆栈(自下而上采用)的人工智能开发人员,以及寻求支持建立其人工智能战略(自上而下采用)的领导层——在这方面,谷歌的品牌是一项重要资产。TensorFlow 等免费开源框架已经迅速普及,这使得谷歌 ML 引擎(一个高价的机器学习云平台)的营销变得更加容易。谷歌还发布了 Kubeflow,这是一个运行在 Kubernetes 之上的开源机器学习平台,可能为内部用户提供谷歌 ML 引擎的替代选择。
- **更低的切换成本:**更好的产品可能不足以说服客户,尤其是在企业生产环境中,迁移工作负载成本高昂,并且可能需要大量的软件重新设计。应用程序的容器化创造了降低转换成本的机会。谷歌赢得了与 Kubernetes 的战争,实施了其容器工作负载协调系统。这样一来,它还通过提高工作负载的可移植性显著降低了切换成本,既简化了云服务之间的切换,也简化了从内部部署到云产品的切换。
这对那些寻求了解人工智能栈未来的人来说很重要:谷歌正在为栈的各个层开发产品。TensorFlow 已经成为领先的(但不是唯一的)机器学习框架。谷歌 ML 引擎因其用户友好性而广受赞誉,尽管其高昂的价格可能会成为重度用户的阻碍。开源平台 Kubeflow 虽然还不成熟,但正在慢慢获得牵引力。
在堆栈的最底层,Kubernetes 在扩展到人工智能之外的容器工作负载编排领域获得了明确的优势。生产工作负载采用 Kubernetes 为构建整个 Kubernetes-native AI 生态系统创造了合适的基础。
Google Open Source Products Adoption
结论
谷歌战略的后果之一是,人工智能堆栈的每一层都得到服务,取得了各种各样但越来越大的成功,由谷歌维护的开源产品(尽管 Kubernetes 现在由云原生基金会维护)。
我想回答的问题是,专有机器学习产品是否会有空间,以及在哪里会有空间。
为了理解动态,我将使用 Hadoop 生态系统(第 2 部分)的类比,并尝试推断两个场景。
2)与 Hadoop 生态系统的类比(希望是合理的)
Hadoop 堆栈可以分解为基础设施、平台和工具,与 AI 堆栈非常相似。
这种类比至少有一些局限性:
- Hadoop 是专为 map reduce 范式构建的,用于处理超大规模数据集。另一方面,Kubernetes 是为通用工作负载编排而开发的。除了技术上的影响,这意味着 Kubernetes 将在一个更大的市场上被采用。作为一个副作用,一个公司可能会采用 Kubernetes 来编排其主网站的容器——然后青睐能够利用其现有 Kubernetes 安装的 ML 产品。
- 深度学习模型的开发和训练从根本上来说比 ETL 操作(Hadoop 生态系统的原始用例)更复杂。他们经常利用 GPU 计算,这产生了另一种技术差异,并要求更复杂的堆栈。
- Hadoop 的采用始于市场存在之时,但规模相当小——它始于少数客户,包括雅虎,维护大型 Hadoop 客户,并逐渐购买服务来帮助管理他们。点击此处了解 Hadoop 的历史。至于人工智能堆栈,在任何解决方案可用之前,大规模存在对机器学习平台的需求。目前的产品仍相对不成熟,但市场已经爆炸式增长。
从这个类比中我们能学到什么?
- Hadoop 生态系统围绕着一系列开源产品和工具。
- Hadoop 堆栈的业务模型主要由服务和企业支持及工具驱动,就像 Red Hat 一样。
从长远来看,AI 也会这样吗?市场会广泛采用 Kubernetes+Kubeflow 作为基础设施和机器学习平台吗,在这种情况下,其他玩家会转而为 Kubeflow 构建企业版、工具和服务吗?还是企业平台会有市场?
3)两种场景
在开始预测之前,让我回到市场上来。它可以大致分为三个角色:
- 小玩家和个人开发者喜欢简单性,但是简化了 IT 需求。他们是现有云产品的典型客户,如 Google ML Engine 或 AWS Sagemaker。
- 企业云用户同样也是现有产品的良好目标,尽管高级用户的特定需求也需要云提供商无法满足的定制服务。
- 企业内部部署目标目前在平台和工具方面严重不足。主要的不确定性就在于此,并证明了下面两种情况的合理性。
The AI Stack Broken down by segment — Major uncertainty lays in the on-premise segment
场景 1:相互竞争的开源和企业产品共存
由于对企业产品的需求已经存在,而开源产品还远未成熟,一些公司已经开始构建闭源产品。
Clusterone 和 RiseML 等公司以及其他几家公司就是这种情况。
如果开源产品不能很快成熟,对内部部署企业级产品的需求将推动它们的采用。开源可能会在第二波产品中赶上来。
**商业模式:**专有企业软件
**剩余机会:**因此,堆栈将保持相当分散的状态。这可能会使构建工具的主流产品变得更加困难。这些市场条件也可能有利于端到端的垂直机器学习平台。
场景 2:开源占主导地位,企业生态系统出现
现有的 Kubernetes 采用和 Kubeflow 的更快成熟可能会引发广泛的采用,以及对开源代码库贡献的良性循环。
这将为基于 Kubeflow 的企业级产品、服务和支持模型带来机遇,与 Cloudera 和 Hortonworks(现在的 Cloudera-Hortonworks)以及 MapR 的 Hadoop 生态系统产品非常相似。
**商业模式:**服务、支持和企业-Kubeflow
**剩余的机会:**围绕 Kubeflow 的栈的标准化将赋予公司在栈顶构建工具的特权,以及围绕 Kubeflow 的工具和应用的生态系统模型。
结论
预测堆栈将如何发展是一项棘手的工作。无论如何,记住这两种情况可以帮助决策者识别机会,并针对不断变化的市场条件进行对冲。
尽管栈的一些标准化将有益于那些构建应用程序和工具的人,但一个成熟的标准产品的出现还需要时间。可能有第三种方式,开源和闭源玩家在定义标准上合作,最大化他们成功的机会和最终用户的价值。
感谢 Louisa Mesnard 在撰写本文时给予的帮助。
免责声明:观点仅代表我个人。我是 Clusterone 的联合创始人,持有该公司的股份。
从 HBO 的硅谷建立热狗/非热狗分类器
Photo by Fancycrave on Unsplash
自从我在 HBO 的硅谷看了由百搭应用开发者 Jian-Yang 创建的热狗/非热狗应用,我就想创建它。现在终于,我有了!但由于我缺乏应用程序开发技能,我只创建了应用程序将使用的机器学习分类器。尽管如此,创造这个应用程序的大脑还是很酷的。此外,这是一个非常酷的数据科学项目。所以,下面是我的经验。
注: 找到朱庇特笔记本 这里 。
“这不是魔法。是天赋和汗水。”吉尔福伊尔
没有数据学不了
任何数据科学或机器学习或深度学习或人工智能项目的第一步都是获取数据。你可以创建最复杂的算法,并在最疯狂的 GPU 或 TPU 上运行你的 ML 模型,但如果你的数据不够好,那么你将无法在 ML 任务上取得任何进展。所以,首先是获取数据。
ImageNet 来拯救我们了!
我用了 ImageNet 网站来获取数据。至于热狗,我搜索了“热狗”、“法兰克福香肠”和“辣热狗”。至于“不是热狗”部分,我搜索了“宠物”、“家具”、“人”和“食物”。选择这些照片的原因是,这些是人们在使用这种应用程序时最有可能拍摄的照片。
我使用了一个小脚本从 ImageNet 下载所有这些图像,并删除无效/损坏的图像。然后,我翻遍了所有的图片,手动删除了破碎的和不相关的图片。最后,我有 1822 张热狗的图片和 1822 张“不是热狗”的图片。
注意: 我有超过 3000 张“不是热狗”的图片,但我随机选择了其中的 1822 张,以平衡这两个类别。
现在,我有了创建这个分类器所需的所有数据。
让数据更好
下一步是让数据更好。首先,我编写了一个小脚本,将所有图像的大小调整为 299x299 分辨率,这样所有图像的大小都相同,我在加载这些图像时就不会遇到各种不兼容问题。
在目录中正确组织数据也很重要。我按照以下方式组织数据:
数据集— > (train — > (hotdog,nothotdog),测试— > (hotdog,nothotdog),有效— > (hotdog,nothotdog))
以这种方式构建数据集的原因是,当我们在 Keras 中加载数据时,Keras 要求数据是这种方式。
第一次迭代——创建一个基本的 ConV 模型
在第一次迭代中,我创建了一个简单的卷积模型,有两个 ConV 层和三个全连接层。我没有将整个图像数据集加载到内存(numpy 数组)中,而是使用 Keras 生成器在运行时批量加载图像。我还在 keras 中使用了ImageDataGenerator
类来批量扩充运行时的数据。
该模型用 50 个历元训练约 50 分钟,在测试集上给出了 71.09%的准确率。
对于如此简单的任务来说,这是相当低的精确度。我的意思是,人类完成这项任务的准确率必须达到 100%。
这引起了我的思考,我决定在迭代#2 中更进一步。
第二次迭代——迁移学习
我决定用迁移学习让这个分类器更好更快的训练。现在,我无法实时扩充数据,因为迁移学习在 Keras 中不支持。因此,我编写了一个脚本来扩充数据并创建一个更好的数据集。我应用了以下转换:
- 水平翻转
- 垂直翻转
- 以一定角度旋转图像
- 剪切和缩放图像
这种数据扩充导致了数据集版本 2.0,其具有 7822 个热狗图像和 7822 个“非热狗”图像。这是一个大得多的数据集,所以我预计分类器的准确性会有所提高。现在,实际上获得新数据比应用数据增强要好得多,正如deep learning . ai课程中吴恩达所教导的那样,但由于前者不是一个选择,数据增强至少可以使在分类器方面有所改进。
现在我有了一个相对更大更好的数据集,是时候开始 了!
不,不是克里斯托弗·诺兰写的那本。
我决定使用 InceptionNet V3,因为它提供了比 VGGNet 和 ResNet50 更好的结果。Keras 提供了一个Application
模块,可以很容易地使用这些预先训练好的架构。于是,我下载了预先训练好的 InceptionV3 模型和权重,然后在这个模型上训练数据集,得到数据集的瓶颈特征。这基本上是通过从 InceptionNet 中移除完全连接的层并仅在 ConV 层上训练数据来实现的。这个过程将我们的原始图像转换成矢量。
现在我们创建一个简单的 ConV 模型(与迭代#1 中的相同),并在这些瓶颈特性上训练它。该模型训练时间约为 5 分钟,在测试集上的准确率为 96.42%。对于如此少的数据来说,这是一个相当好的精度。由于准确性并不总是衡量模型性能的最佳指标,我创建了一个混淆矩阵。
Confusion Plot
看那些被错误分类的图片,很多被分类器错误分类为“不是热狗”的图片并没有很好的看到热狗。或者吃的不仅仅是热狗。虽然,为什么它把一群人归类为热狗是一个谜,我希望有一天能解决!
等等,我们刚刚做了什么?
- 我们从一个电视节目中获得了一个想法,并决定使用这个想法来完成整个 ML 流程。
- 首先,我们收集数据,因为这是我们 ML 模型的动力。在这种情况下,我们得到了热狗和其他一些不是热狗的东西的图像。
- 我们做了一些数据预处理,删除了破损/无用的图像,并将所有图像调整到相同的大小。
- 我们创建了一个简单的 ConV 模型,并使用实时数据增强。我们得到的结果并没有给我们留下太多印象。因此,为了追求快乐和更好的准确性,我们决定更进一步。
- 我们使用迁移学习来获得更好的结果。从预先训练好的网络花名册中,我们选择了 InceptionV3 网络,得到了瓶颈特征。
- 我们在这些瓶颈特征上训练了一个类似于第一个网络的网络,并且获得了更好的准确性。
- 我们绘制了一些指标,如损失、准确性和混淆矩阵,因为图表很酷,也很有用。
- 我们坐下来,对我们最近的成就微笑,并开始思考下一步要做什么。
原来如此。我创造了一个很好的分类器来告诉我某样东西是不是热狗。正如杨健认为的那样,这是下一个价值 10 亿美元的想法!
“真令人陶醉。别装得一点都不神奇。确实是!”—贾里德
这个项目是我正在进行的#100DaysofMLCode 挑战的一部分。关注我在 推特 上的更新。
为计算机视觉模型构建 Web 应用并在 10 分钟内部署到生产环境*:详细指南
result.html
下载入门包&为 Docker 托管的 web 应用程序提供商之一执行一次性设置后,您可以将 fast.ai 或 keras 库中创建的计算机视觉模型快速部署为响应性 web 应用程序,这一切只需不到 10 到 15 分钟。
**2020 年 8 月 23 日更新:**世界变化很大,自从我更新了这篇文章,fastai 和 keras 库也是如此, Fastai 已经发布了完全重写 Fastai 的版本 2 ,keras 也是如此,它现在是 tensorflow2 的一部分。我还为 fastai 和 keras 发布了更新的入门包,请在此下载:
Fastai 版本 2:
git clone [https://github.com/psmathur/fastai2-vision-app](https://github.com/psmathur/fastai2-vision-app)
Keras(在张量流 2 下)
git clone https://github.com/psmathur/keras-vision-app
**2019 年 1 月 4 日更新:**增加了一个部署选项:“呈现”一个新的最简单但功能强大的基于 Docker 的 web 服务托管提供商&更多。
**2018 年 12 月 4 日更新:**我我不确定,我想继续使用 Zeit 服务,因为 Zeit 最近做出了很多改变来限制 100 MB 的限制。我无法解决 100 MB 的限制问题,即使我有无限付费计划,甚至当我试图通过 CLI 用“now.json”显式使用平台的版本 1。依我看,他们用 100 MB 的限制来限制自己,肯定错过了巨大的商机!
**所以,你已经使用像 Fast 这样著名的深度学习库建立了**一个令人敬畏的图像分类模型。AI 或 Keras ,然后写了一篇关于它的文章,同时解释了你的模型如何可以对各种类型的蓝松鸦 s、植物病害、意大利美食、 薯条、瑞士手表进行分类,甚至可以预测出你身边播放的古典音乐的作曲者,使用音频文件的声谱图(而你认为图像分类是被夸大其词了)。
现在,接下来呢?
嗯,除了写一篇关于你如何建立一个令人惊叹的计算机视觉模型的技术博客帖子,你还想与你的同事、朋友、家人或任何拥有带网络浏览器的设备的人轻松分享你的工作。您希望与他们分享您的工作,因为他们都可以快速测试您基于深度学习的模型结果并提供有价值的反馈,这是评估您最终 DL 模型的重要一步。
你需要一个演示网络应用程序!
Source: https://gifsboom.net/post/141202971289/t-rex-vs-spiderman-in-real-life-superhero
假设您已经建立了一个图像分类算法,现在需要一个简单的 web 应用程序,它可以以异步方式处理从 web 浏览器上传的图像或图片,然后它还需要以异步方式下载您训练过的模型,托管在其他地方。
深度学习模型很重,你知道一个巨大的多维激活矩阵,所以它们需要在一些云存储服务上独立上传,另外你想有一个切换到更好升级的模型的选项,特别是基于你收到的反馈,而不改变和重新部署底层 web 应用。
然后,这个 web 应用程序还应该能够使用您首选的深度学习库将您的模型加载到机器的内存中,然后它可以预测您上传的图像上的标签。
最终,所有这些东西都需要在某个云托管提供商上进行配置、部署和托管。听起来很有趣,对吧…
我们都知道,如果你没有一个既定的流程,尤其是在 bug 修复或部署配置期间,上面提到的任何步骤都会花费大量时间。因此,为了将所有这些步骤减到最少,我写了这个指南。一旦你遵循了这篇文章,你将有一个 3(或 2)步的过程,通过它你可以快速地为你的计算机视觉模型构建一个 web 应用&可以在< 10 Minutes.
Here is the link of a sample web app: 将它们部署到生产中
index.html
为了构建和部署这种 web 应用程序,首先,我们将下载或克隆托管在我的 GitHub repo 上的启动包,目前,这些 web 应用程序启动包仅用于使用 Keras 和fast . ai构建的计算机视觉模型
这些初学者包包含一个简单的响应式 web 应用程序,它构建在 ASGI 服务器的基础上。下载其中一个入门包后,您只需更改几行代码,就可以在本地机器上运行您的深度学习模型。
其次,我们将使用 Docker 托管的服务之一。我们将把静态 web 应用程序目录与 docker 配置放在一起,然后将它部署到这些完全托管的 docker 托管服务之一的生产环境中。
**在这篇文章中,我正在覆盖, AWS 豆茎 , Azure Web App 和 现在版本 1 **。然而,你可以使用类似的步骤部署到任何其他 Docker 托管的服务。
那么,现在,事不宜迟,让我们从第一步开始。
步骤 1:下载 web 应用程序入门包
对于你的 keras 模型部署 去我的 Github 下载keras-vision-apprepo。
wget [https://github.com/pankymathur/keras-vision-app/archive/master.zip](https://github.com/pankymathur/fastai-vision-app/archive/master.zip)
为了你的 fast.ai 模型部署 去我的 Github 下载fastai-vision-apprepo。
wget [https://github.com/pankymathur/fastai-vision-app/archive/master.zip](https://github.com/pankymathur/fastai-vision-app/archive/master.zip)
解压缩 zip 文件,重命名目录,使其与您的应用程序名称相匹配
unzip *fastai-vision-app*.zipmv fastai-vision-app YOUR-APP-NAME-HEREcd YOUR-APP-NAME-HERE
注意:你也可以在 Keras 或者 Fast 的目录下,让一切都保持现在的样子。AI starter pack app,只需转到步骤 2 &步骤 3 进行快速试用部署,那样的话,你就要部署我的X-Finder App或者 寻衣 App 。如果您没有,并且想在部署之前完善一切,那么请继续阅读。
上传您的训练模型 将您的训练模型上传到任何公共云托管服务。通常训练好的模型在 keras 中的文件类型为“. H5***”*,可以使用 model.save() 方法和“ 文件类型创建。并且可以使用方法 learn.save() 创建。**
举个例子,对于我的文章和 fast.ai 项目 “打细纹服装分类基准” ,我最终的模型文件名是“stage-1 _ SZ-150 . PTH”。它的大小为< 100 MB,并公开托管在我的 public GitHub 项目回购上。
如果您的模型文件大于 100 MB,您可以使用任何其他云服务,如 Google Drive 或 Dropbox 来上传您的模型文件,然后复制该文件的原始下载链接。
****注:原始下载链接是直接开始文件下载的链接,通常不同于您看到的共享链接。例如,dropbox 原始下载链接如下所示:
'[https://www.dropbox.com/s/y4kl2gv1akv7y4i/stage-2.pth?raw=1'](https://www.dropbox.com/s/y4kl2gv1akv7y4i/stage-2.pth?raw=1')
- 为 Keras 车型定制的入门 Web 应用
打开“app”
目录中的文件"server.py”
,然后用托管模型文件的原始下载 URL 更新带有“model_file_url”
变量的行。例如:
model_file_url = 'https://github.com/pankymathur/Fine-Grained-Clothing-Classification/blob/master/data/cloth_categories/models/model.h5?raw=true'
保持其他一切不变,如果你像我一样使用一些东西,例如,我已经在 Keras 中使用迁移学习过程创建了一个简单的图像分类模型,具有 Resnet50 架构和 Imagenet 预训练的权重,用于 46 种不同类型的服装类别。当然,您可以完全定制代码来满足您的需求。
然后我已经上传了我训练好的 Keras 模型< 100 MB on my GitHub public repo, so here is how my final “ server.py" 的样子,就在步骤 2 之前。
server.py
- 针对 Fast 定制的 Starter Web 应用程序。人工智能模型
打开“app”
目录中的文件"server.py”
,然后用您的托管模型文件的原始下载 URL 更新带有“model_file_url”
变量的行。例如:
model_file_url = 'https://github.com/pankymathur/Fine-Grained-Clothing-Classification/blob/master/data/cloth_categories/models/stage-1_sz-150.pth?raw=true'
在同一个文件中,用您期望从模型中预测的标签类更新下面的行。
classes = ['Blouse', 'Blazer', 'Button-Down', 'Bomber', 'Anorak', 'Tee', 'Tank', 'Top', 'Sweater', 'Flannel', 'Hoodie', 'Cardigan', 'Jacket', 'Henley', 'Poncho', 'Jersey', 'Turtleneck', 'Parka', 'Peacoat', 'Halter', 'Skirt', 'Shorts', 'Jeans', 'Joggers', 'Sweatpants', 'Jeggings', 'Cutoffs', 'Sweatshorts', 'Leggings', 'Culottes', 'Chinos', 'Trunks', 'Sarong', 'Gauchos', 'Jodhpurs', 'Capris', 'Dress', 'Romper', 'Coat', 'Kimono', 'Jumpsuit', 'Robe', 'Caftan', 'Kaftan', 'Coverup', 'Onesie']
保持其他一切不变,您的应用程序就可以快速部署了(当然,您可以完全定制代码来满足您的需求)。对于一些部署选项,您需要将您的应用程序推送到 GitHub repo,这可能是公共的,也可能是私有的,具体取决于您的选择。
步骤 2(选项 1):渲染
Render 是一款简单而强大的云提供商服务,适用于您的所有应用和网站。点击此链接=>https://dashboard.render.com/register?i=fastai-v3注册,即可获得 25 美元的积分。渲染 web 服务的费用为每月 5 美元,按秒按比例分配。
**注册后,转到你的渲染面板,然后创建一个新的 **Web 服务。在这里使用 GitHub repo 为你在上面步骤 1 中创建的应用程序。
请注意,在这一步中,您需要授予 Render 权限来访问您的 GitHub repo。
之后,在部署屏幕上,为您的服务选择一个名称,并使用**Docker**
作为环境。此外,如果您在 GitHub repo 中有多个分支,请选择适当的分支,或者保留主分支选择。
只需点击保存 Web 服务即可!您基于 docker 的 web 应用程序服务将开始构建,并且应该在大约 10 分钟后上线。您可以在部署日志中跟踪它的进度。最后,您可以检查显示在渲染面板中的 web URL
【https://keras-vision.app.render.com/ 号
第二步(选项 2): AWS 弹性豆茎
AWS Elastic Beanstalk 是一个易于使用的 AWS 服务,用于为 Docker 应用程序部署 web 应用程序,此外 AWS 还为新帐户提供免费试用。特别是因为我们的应用不打算使用任何数据库实例,最终定价将只包括 EC2 实例、负载平衡器和 S3 定价。点击这里阅读更多关于 AWS Beanstalk 定价的信息。
首先,打开 AWS Dashboard,搜索 Elastic Beanstalk services,然后单击“开始使用”创建新应用程序。您将看到以下屏幕。
为您的演示应用程序名称和描述添加详细信息,然后单击“ ”创建“ ”。您将看到一个用于创建新环境的新屏幕。
选择 【立即创建一个】 ,将出现如下画面。
Create New Environment
在此选择 web 服务器环境,您将看到 创建 Web 服务器环境 详细信息屏幕。
添加你的“ 环境名“ ,选择你的“域名,看看是否可用,然后添加“ 描述”。
****重要提示:在基本配置部分,选择 预配置平台 ,然后选择“”通用选项。
在同一页上向下滚动,因为你需要添加更多的细节。
选择 【上传我们的代码】 选项,点击上传,会出现如下画面。在上传您的入门包之前,请阅读下面的说明!
****重要提示:出于某种奇怪的原因,你可以直接上传我们 web app 文件夹的压缩文件,你必须将内容直接压缩到你的 web app 文件夹下,我猜是因为 AWS Beanstalk 需要看到直接在压缩文件的根目录下找到的 Dockerfile,而不是在 web app 文件夹下。因此,要做到这一点,只需在您的本地机器上打开 web 应用程序并直接压缩内容。这就是我在 Mac OS X 中的做法。
******可选:**如果您已经在您的机器上本地运行了" server.py " ,那么您可能已经在目录 app>static>model>"model . H5 "或"model . PTH "下下载了模型文件,为了使这个压缩的压缩文件更小,您可以删除那些模型文件。但是,请注意,AWS Beanstalk 允许上传的文件大小不超过 512 MB。
上传你的一个 web app 的源码包后,“ 创建 web 服务器环境页面” 会是下面这个样子。
****重要:不要按 【创建环境】 现在,我们要用 配置更多的选项!
Don’t Click Create Environment Now! Use Configure More options
这些都是必要的步骤,为了让我们的 Web App 在 AWS Beanstalk 上顺利部署,点击 【配置更多选项】, 将会打开一个新的页面,在这里我们要将"配置预置部分改为" 自定义配置" 选项,如下图所示
然后下到第一节>软件】****点击 修改 会打开一个如下图的页面,将代理服务器从 Nginx 修改为 无。 保持其他一切不变,按保存。
“保存”后你会回到配置页面,在这里下去第二节>【实例】点击 【修改】 会打开一个如下图的页面,将实例类型从【t1.micro】改为【T3 . medium】。 保持其他一切不变,按保存。******
这就是自定义配置,现在按“ 【创建环境】 然后去喝杯咖啡什么的,AWS Beanstalk 需要 10-20 分钟来部署您的源代码以创建 docker 映像,然后将该 Docker 映像部署到您选择的 ec2 实例,创建应用程序负载平衡器,使用入站和出站网络设置创建适当的安全组以及许多其他事情,这些都超出了本指南的范围。您将看到一个屏幕,显示 AWS BeanStalk 部署的日志文件条目。
请耐心等待,8-10 分钟后,您会看到这样的仪表盘,它会显示健康状况,如每个阶段的 【绿色】 和详细日志。
点击仪表板上显示的 URL,您将被重定向到新的演示应用程序,并在 AWS 上运行。
**注:如果你在仪表盘上看到,健康不是“而是“”,请详细查看日志文件。您可以在左侧的“日志”部分找到详细日志,按下请求日志>完整日志或最后 100 行。阅读日志将向您显示健康状态“红色”的主要原因以及您的部署失败的原因。 通常,这是你选择的小型 ec2 实例类型,它们在运行你的应用程序或尝试应用其他自定义设置时无法处理部署或内存问题,我在上面没有提到这一点。
第 2 步(选项 3):带有自定义运行时的 Google 应用引擎
Google App Engine 自定义运行时让你构建在由 Dockerfile 定义的环境中运行的应用。此外,谷歌云确实为新账户提供 12 个月的免费试用,价值 300 美元。特别是因为我们的应用程序不打算使用任何数据库实例,最终定价将只包括谷歌计算实例、负载平衡器和谷歌云存储定价。点击此处阅读更多关于谷歌应用引擎定价的信息。
首先,打开 Google Cloud Dashboard,点击创建项目,然后命名您的新 GCP 项目。通过创建新的计费帐户或设置现有帐户,在您的新 GCP 项目中启用计费。您将看到以下屏幕。
创建新项目后,您将看到 GCP 仪表板页面,转到页面的最右上角,单击“ 【激活云壳】” 。终端窗口将在同一页面中打开。
此时,您可以继续使用同一个终端窗口,或者在新的浏览器页面中打开该终端窗口。
运行以下命令创建 App Engine 应用程序,并指定希望应用程序运行的地理区域。
**gcloud app create**
我选择 13 并按回车键,几分钟后,它会显示类似“成功!应用程序现已创建。”
现在,通过键入以下命令,下载 Github 或任何其他 git 存储库管理服务上托管的 starter pack 应用程序存储库。确保您的入门包与我的 repo 中的 app.yaml 和 Dockerfile 相同。
**git clone [https://github.com/pankymathur/fastai-vision-app](https://github.com/pankymathur/fastai-vision-app)**
下载存储库后,导航到您的应用程序目录。
**cd fastai-vision-app**
将您的应用部署到 Google 应用引擎
**gcloud app deploy**
您将看到一个屏幕,显示“要部署的服务”,输入 Y
然后去喝杯咖啡,因为 app engine 需要 8~10 分钟来部署基于 docker 的应用程序,并呈现到您的最终 URL。要查看您的应用在http://YOUR_PROJECT_ID.appspot.com
运行,运行以下命令启动您的浏览器:
**gcloud app browse**
这是我在 GCP 上运行的默认 fastai-vision-app starter pack 应用。
第二步(选项 4): Now.sh
现在版本 1 有一个免费计划,可以为你的静态网络应用程序无限部署&域,可以处理高达 1 GB 的存储&带宽,&许多其他功能,只要你的最大文件大小不超过 5 MB。
现在桌面应用程序
- 用于 Mac OSx 和 Windows
前往https://zeit.co/download下载 now.sh 桌面 app 进行快速拖拽&展开。
命令行安装
- 在 Mac OS X 上
**# *Intall* [*https://brew.sh*](https://brew.sh)*, if not already installed*
# a mac without brew is just another empty glass/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"*# Install npm, if not already installed*
brew install npm# *Install now.sh cli*
sudo npm i -g --unsafe-perm now**
- 在 Linux 上
***# if not already installed*
sudo apt install npm# *Install now.sh cli*
sudo npm i -g --unsafe-perm now**
- 在 Windows 上
下载 https://nodejs.org/en/download/的 NPM 视窗安装程序
使用 Powershell:
**# *Install now.sh cli*
sudo npm i -g --unsafe-perm now**
在 Windows 10 上使用 Linux 应用程序:
选择你选择的 Linux 应用:https://docs.microsoft.com/en-us/windows/wsl/install-win10安装好 Linux 应用后,进入终端,按照上面的 Linux 说明安装 now.sh CLI
部署
- 通过 Now 桌面
通过拖放或上传您的responsive-web-app
目录到“Now Desktop”进行部署。
它将在一个单独的浏览器窗口中显示所有的部署日志细节。您可能需要在部署开始前登录 zeit.co。
它将为您的静态应用程序创建一个唯一的部署 URL ,并在部署期间的前几行日志中显示出来。通常,它的格式为[https://YOUR-APP-NAME-HERE-xxxxxxxxxx.now.sh](https://YOUR-APP-NAME-HERE-xxxxxxxxxx.now.sh)
当部署完成时,它将显示"成功!浏览器窗口中的部署就绪。
可选:如果你像我一样,你想为你的应用程序使用一些漂亮的 URL 名称,而不是默认的名称,如 [https://YOURAPPNAMEHERE-xxxxxxxxxx.now.sh](https://YOUR-APP-NAME-HERE-xxxxxxxxxx.now.sh)
您可以转到zeit.co上的仪表盘,使用当前部署的创建别名选项,将别名添加到您的应用中
- 通过 Now CLI
在终端上,确保您在keras-vision-app
或fastai-vision-app
目录中,然后键入:
**now**
每次使用“Now CLI”进行部署时,它都会为您的静态应用程序创建一个唯一的部署 URL ,并且会在部署期间的前几行日志中显示出来。通常,它的格式为[https://YOURAPPNAMEHERE-xxxxxxxxxx.now.sh](https://YOURAPPNAMEHERE-xxxxxxxxxx.now.sh)
当部署完成时,它将显示"成功!终端上的部署就绪。
可选:如果你像我一样,你想为你的应用程序使用一些漂亮的 URL 名称,而不是默认的名称,如 [https://YOURAPPNAMEHERE-xxxxxxxxxx.now.sh](https://YOUR-APP-NAME-HERE-xxxxxxxxxx.now.sh)
您可以使用以下命令更改应用程序的别名:
now alias PRETTY_URL_NAME [YOURAPPNAMEHERE-xxxxxxxxxx.now.sh](https://YOUR-APP-NAME-HERE-xxxxxxxxxx.now.sh)
它会显示一些东西:
**> Success! YOUR-APP-NAME-HERE.now.sh now points to YOURAPPNAMEHERE-rhainypwfk.now.sh**
缩放比例
默认情况下,now.sh 上的 all now deployment 会在一段非活动时间后进入睡眠状态。如果你想让你的应用程序在分享或演示过程中处于活动状态,这并不好。因此,扩展您的应用实例:
**# You only need to do this once.
now scale YOUR-APP-NAME-HERE.now.sh sfo 1**
它会显示一些东西:
**> ✔ Scaled 1 instance in sfo1 [923ms]
> Success! Scale state verified**
现在,您可以与任何人分享[https://YOUR-APP-NAME-HERE.now.s](https://YOUR-APP-NAME-HERE.now.sh)h
,以获得快速反馈和演示。
例如,这里是我的默认演示应用程序的链接https://x-finder . now . sh
设置 Docker Hub 帐户并上传您的 docker repo(选项 5)
你需要一个免费 Docker hub 账户。docker Hub 是容器托管存储库,我们将使用它向 Docker 托管的应用程序服务提供商之一提供 Docker 映像,如“ Azure 网站 for Containers”这样这些服务就知道从哪里获取 Docker 映像。
有很多很多的容器托管服务,提供公开或私有托管你的 docker 镜像的选项,例如,这些是业界常见的容器注册表 Docker Hub 、 Azure Container Registry、Amazon Elastic Container Registry或 Google Container Registry 。对于我们的场景,Docker Hub 上的公共容器存储库是一个很好的选择。
有两种方法可以在 docker Hub 上创建 Docker 存储库,第一种是使用 Docker CLI,它与 Mac OSx 或 Windows 的 Docker 桌面应用程序打包在一起。
安装 Docker 桌面应用程序并登录 Docker Hub 帐户后,以下是构建 Docker 映像并将其上传到 Docker Hub 容器注册表的步骤:
- 创建一个 Docker 图像
****docker build -t <imageName> .*#For ex: docker build -t keras-vision-app .*****
- 在本地运行映像,查看您的应用程序运行情况
****docker run -p 5042:5042 <imageName>#*For ex: docker run -p 5042:5042 keras-vision-app*****
- 用你的 Docker Hub 用户名标记图片
****docker tag image username/repository:tag#*For ex: docker tag keras-vision-app pankajmathur/keras-vision-app*****
- 将图像推送到 Docker Hub
****docker push username/repository:tag#F*or ex: docker push pankajmathur/keras-vision-app*****
成功推送后,您可以在 docker Hub 帐户中看到您的本地 Docker 映像。
keras-vision-app docker repo
第二种方式是使用 GitHub 与Docker Hub 账户集成。这是从 0 到 Docker 容器注册表最快的方法。
- 将 Docker Hub 与您的 GitHub 个人资料相链接
登录 Docker Hub,然后导航至个人资料>设置>关联账户&服务然后点击 GitHub 服务。弹出窗口提示您输入 GitHub 凭据。授予对代码库的访问权限后。您的 DockerHub 链接账户&服务页面将如下所示:****
- 创建自动化构建
转到您的 DockerHub 仪表板,然后从右上方的下拉菜单中选择创建 > 创建自动化构建。它会要求您选择 GitHub 关联帐户:****
系统提示将显示您所有的 GitHub 存储库,键入以过滤存储库列表,然后选择要构建的项目。
系统提示将显示创建自动构建对话框。该对话框采用了一些您可以自定义的默认值。默认情况下,Docker Hub 会为存储库中的每个分支构建映像。它假设 docker 文件位于您的源存储库的根目录下。当它构建一个映像时,Docker Hub 用分支名称标记它。如果你想自定义默认选项,那么点击这里自定义这个行为链接。(对于我们的用例,保留默认值是好的)****
点击创建,系统显示你的自动化构建的主页。
就这样,你让你的 docker 托管容器注册中心复制你的存储库的名称,在我的例子中,它是pankajmathur/fastai-vision-App,现在你已经准备好步骤 2(选项 4):Azure Web App for Container Service。******
步骤 2(选项 4): Azure Web App for Containers 服务
Azure Web App for Containersone click docker App 提供了非常易于部署和托管的 docker 静态应用机制。有一篇好文章是同道 fast.ai 学员 日产 写的 https://redditech . blog/2018/11/04/hosting-fastai-app-in-azure-websites-for-containers/。
请阅读这篇文章,它展示了 Azure Portal App Services for Container Services 流程的一步一步的截图。我能够阅读这篇文章,并能够在< 10 minutes.***
中设置我的 web 应用程序 Azure 最初需要很长时间来部署整个容器并传播 DNS,几乎需要额外的 10 分钟。***
缩放比例
Nissan 没有涵盖这一部分,所以默认情况下,所有 azure web 应用程序部署在一段不活动时间后都会进入睡眠状态。如果你想让你的应用程序在分享或演示过程中处于活动状态,这并不好。因此,通过转到 Azure 应用服务设置>应用设置 并打开App Always =>并关闭ARR Affinity =>来扩展您的应用实例
目前 Azure 提供前 30 天 200 美元的免费试用积分来试用他们的服务,所以你可以很容易地注册一个新帐户并尝试所有步骤。
这是我们的 Azure Web App = >https://keras-vision-app.azurewebsites.net
入门包的罩下是什么?
嗯,我的两个 keras 和fast . aistarter packs 库都是 GitHub 上的开源,所以你可以在下载或克隆它之前检查所有代码。启动包的主体是" server.py" ,这是一个小型的 starlette . io&uvicon 驱动的 ASGI 服务器。
这个小小的服务器实际上一点也不小,而是一个强大的服务器,这个小小的服务器在Asyncio库的帮助下,使用“ 【上传(请求)】方法,以并发方式处理您的图像或图片上传,然后它有“【download _ file(URL,dest) 方法,优雅地将您的训练好的模型下载到本地驱动器,然后这个小小的 在事件循环、任务、和协同程序机制的帮助下,使用您的 keras 或 fast.ai 深度学习库将您下载的模型文件加载到主机内存中,最终这个微型服务器预测您上传的图像上的标签,并将其吐回到 prediction.txt 文件中。****
frontend statics 是一个简单的 HTML5 响应式 web 应用程序,带有几个整洁的 JS hacks 来处理大图像文件上传,特别是对那些令人敬畏的 raw 相机或自拍图片有用。
最后,微型 ASGI 服务器和 responsive statics 被放入一个 docker 中,使用 docker 配置安装正确的 python 版本,并在 requirement.txt 的帮助下安装 Keras 或 Fast.ai、starlette.io、uvicorn 和所有其他库依赖项,然后这个 docker 配置将暴露端口 5042 并启动服务器。所有这一切,让你可以轻松地在 docker 云机器上托管你的 Docker 映像…
注意:大多数现代浏览器都能很好地处理这些 JS hacks 和 HTML5 文件。如果你还停留在 21 世纪初,忽略这篇文章。
source: https://cheezburger.com/8348948736
就这样,希望你喜欢这个指南,并能够为你的计算机视觉模型构建你的 Web 应用程序&能够将它们部署到生产中,并在这样做的同时建立一个 3 步流程,因此你可以立即重复所有这些步骤。如果没有,请在评论区告诉我你的问题。如果是的话,我真的很希望得到一些关于这篇文章的反馈和改进意见。
同时,快乐深度学习…
使用 Python 中的 Keras 在流失建模数据集上从头开始构建您自己的人工神经网络
用神经网络的力量留住你的客户群!
众所周知,留住客户是许多公司的头等大事;获得新客户的成本可能是留住现有客户的好几倍。此外,了解客户流失的原因和估计与单个客户相关的风险都是设计数据驱动的保留策略的重要组成部分。流失模型可以是一种工具,它将这些元素整合在一起,并提供洞察和输出,推动整个组织的决策制定。因此,它被用来预测哪些客户将离开银行。
什么是流失率?
流失率(有时也称为损耗率),从最广泛的意义上来说,是对特定时期内从一个集体群体中移出的个人或物品数量的衡量。这是决定一个企业将支持的客户的稳态水平的两个主要因素之一。
那么这篇文章的读者是谁呢?
你可以是刚刚完成机器学习 MOOC 的人,也可以是正在寻找基于机器学习的更实用/动手项目的初露头角的数据科学家。
如果你是经济学专业的学生,试图将数据科学的各个方面与你所在领域相关的东西结合起来,这也可能是相关的。
我们还在等什么?我们开始吧!!
因此,在这个数据集中,我们将处理客户流失建模,也就是说,我们将编写一个人工神经网络来找出客户实际离开银行的原因以及他们之间的依赖关系。
这是一个分类问题,即 0-1 分类(如果客户离开,1;如果客户留下,0)
我们可能会使用 Theano 或 Tensorflow,但问题是这些库要求我们从头开始编写大部分 Ml 代码,因此我们使用 Keras,这使我们能够编写强大的神经网络,只需几行代码 Keras 在 Theano 和 Tensorflow 上运行,您可以将其视为深度学习的 Sklearn。
第 1 部分—数据预处理
# Importing the libraries
*import* numpy *as* np
*import* matplotlib.pyplot *as* plt
*import* pandas *as* pd
导入数据集
将它保存在 Pycharm 项目/项目名称中,并使用 pandas 加载它。
dataset = pd.read_csv('Churn_Modelling.csv')
从这些特征中我们可以看出,行号、姓名与客户离开银行没有关系。
所以我们从 X 中删除它们,X 包含从 3 到 12 的特征索引。
X = dataset.iloc[:, 3:13].values
我们通过在变量 y 中存储第 13 个索引来存储 y 中的相关值/预测值
y = dataset.iloc[:, 13].values
打印出…的值
包含特性的 x→y→包含目标变量
print(X)
print(y)
编码分类数据…
现在我们将特征中的字符串值编码为数值,因为 ML 算法只能处理数字,而不能处理字符串值。
仅有的两个值是性别和地区,需要转换成数字数据
*from* sklearn.preprocessing *import* LabelEncoder, OneHotEncoder
创建 1 号标签编码器对象以编码区域名称(功能中的索引 1)
labelencoder_X_1 = LabelEncoder()
编码区从字符串到 3 个编号分别为 0,1,2
X[:, 1] = labelencoder_X_1.fit_transform(X[:, 1])
创建 2 号标签编码器对象以编码性别名称(特征中的索引 2)
labelencoder_X_2 = LabelEncoder()
将性别从字符串分别编码为 2 个 no.s,1(男,女)
X[:, 2] = labelencoder_X_2.fit_transform(X[:, 2])
现在创建虚拟变量
onehotencoder = OneHotEncoder(categorical_features = [1])
X = onehotencoder.fit_transform(X).toarray()
X = X[:, 1:]
将数据集分为训练集和测试集
*from* sklearn.model_selection *import* train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
特征缩放
*from* sklearn.preprocessing *import* StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
第二部分——现在让我们制作人工神经网络!
列出了用随机梯度下降法训练 ANN 的步骤:-
1)随机地将权重初始化为接近 0(但不是 0)的小数字。
2)在输入层中输入数据集的第一个观察值,每个要素在一个输入节点中。
3)从左到右的前向传播,神经元被激活的方式影响每个神经元的激活。
受权重限制。传播激活,直到获得预测结果 y。
4)将预测结果与实际结果进行比较。测量产生的误差。
5)反向传播:从右到左,误差反向传播。根据权重对误差的影响程度来更新权重。学习率告诉我们更新权重的程度。
6)重复步骤 1 至 5,并在每次观察后更新权重(强化学习)。
或者:重复步骤 1 至 5,但仅在一批观察(批量学习)后更新权重。7)当整个训练集通过人工神经网络时。这完成了一个时代。重做更多的纪元。
导入 Keras 库和包
*import* keras
为了一层一层地建立神经网络
*from* keras.models *import* Sequential
将权重随机初始化为接近 0(但不是 0)的小数字
*from* keras.layers *import* Dense
正在初始化人工神经网络…
因此,实际上有两种方式来初始化深度学习模型
— — — 1)逐个定义每一层
— — — 2)定义一个图
我们没有在顺序对象中放入任何参数,因为我们将手动定义层
classifier = Sequential()
添加输入层和第一个隐藏层…
这仍然是一个没有答案的问题,直到今天,我们实际上需要多少隐藏层的节点?
没有经验法则,但是您可以将隐藏层中的节点数分别设置为输入和输出层中节点数的平均值。(在 90%的情况下有效!!)
——→此处 avg= (11+1)/2== > 6 因此设置输出 Dim = 6
——→Init 将统一初始化隐藏层权重
——→激活函数是整流器激活函数(Relu)
Input dim 告诉我们输入层中的节点数。这是只做一次,不会被指定在进一步的层。
classifier.add(Dense(output_dim = 6, init = 'uniform', activation = 'relu', input_dim = 11))
添加第二个隐藏层…
classifier.add(Dense(output_dim = 6, init = 'uniform', activation = 'relu'))
添加输出层…
classifier.add(Dense(output_dim = 1, init = 'uniform', activation = 'sigmoid'))
当我们需要 2 个或更少类别的概率时,使用 Sigmoid 激活函数(类似于逻辑回归)
当因变量超过 2 个类别时,切换到 Softmax。
正在编译人工神经网络…
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
将人工神经网络拟合到训练集
classifier.fit(X_train, y_train, batch_size = 10, nb_epoch = 100)
第 3 部分—进行预测和评估模型
预测测试集结果
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)
如果 y_pred 大于 0.5,则返回 true(1),否则返回 false(2)
print(y_pred)
**该模型在训练数据上训练和在测试数据上测试时,在两种情况下都给出了大约 86%的准确度。**这从我们的角度来看是伟大的!!!
制作混淆矩阵
*from* sklearn.metrics *import* confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)
从混淆矩阵中获得。您可以根据您的混淆矩阵中获得的内容来更改值。
print(accuracy)
恭喜你!你只是为给你这个任务的银行写了你自己的神经网络。您现在可以找出最有可能离开银行的前 10%的客户(这对银行来说非常重要)。该银行现在可能会采取纠正措施,以避免失去客户,如果没有你的帮助,它不会这样做:P
我希望你喜欢我的教程!我将 github(现在是 Gitlab 😛)链接附加到代码和数据集上。
[## sid-Darth Vader/基于人工神经网络的银行数据集建模
人工神经网络对流失建模数据集对银行人工神经网络对流失建模数据集…
github.com](https://github.com/Sid-darthvader/Artificial-Neural-Network-on-Churn-Modeling-Dataset-for-a-Bank)
参考文献-机器学习课程,作者:基里尔·叶列缅科和哈德琳·德·庞特维斯
打造自己的深度学习盒子
通往我的第一个深度学习平台的崎岖之路
Primary parts for building a deep learning machine
在完成杰瑞米·霍华德令人敬畏的深度学习课程的第一部分后,我看了看我的 AWS 账单,发现我每月花费近 200 美元运行 GPU。没必要花那么多钱来完成他的课程,但我开始平行研究一些课外数据集,我渴望得到结果。
在与同学交谈并阅读了一些博客帖子后,我决定尝试构建自己的盒子。技术和硬件变化如此之快,我担心 post 的大部分内容很快就会过时,但我希望我的一般方法至少在一段时间内仍然有用。
构建盒子的 6 个步骤
1.选择零件
2。组装五金件
3。安装操作系统
4。安装驱动器
5。安装库
6。设置远程访问
1.选择零件
我首先阅读了一些博客,以获得当前关于购买哪些部件的共识。由于硬件变化如此之快,到时候我会让你研究具体的部件,但一般来说你需要找到以下组件:主板,CPU,内存(RAM),硬盘(SSD),显卡(GPU),CPU 冷却器,电源和外壳。
我强烈建议在购买前在 pcpartpicker.com 上创建一个零件清单。它们有一个“兼容性检查”功能,可以告诉你你的组件是否不兼容。你可以在这里找到我的列表。
零件目录表
CPU*—英特尔 i7 7700k 4.2GHz 四核RAM***—海盗船复仇LPX 32GB(2x 16)DDR 4–3200276版主板 —微星 Z270-A PRO ATX LGA 1151
酷派 —酷派大师 Hyper 212 EVO 82.9 CFM**
我决定从一个显卡(单个 GPU)开始,但我确保 MSI 板有一个额外的 PCIe 插槽,以便我可以在未来添加另一个卡。更新(2017 年 5 月):原来微星 Z270-A PRO 有 1 个 x16e PCIe 插槽,不是 2 个。它可以在 x4e 插槽中容纳一个额外的 GPU,但性能会受到限制。如果你打算使用多个 GPU,就不要买这个!
一般来说,我会选择顾客评论最多的零件,即使这些评论并不完美。零件越受欢迎,用户生成操作指南和提示的可能性就越大。这将为您在接下来的两步中省去许多痛苦。
有用的帖子
打造个人深度学习钻机
优化入门 CUDA 打造
打造深度学习梦想机器
深度学习硬件指南
2.组装硬件
现在是有趣的部分。我能够找到大多数部件的教学视频,但有几个我不得不根据类似安装的视频进行修改。MSI 板、CoolMaster 和 NZXT 外壳的说明手册很不错,但我必须用其他材料补充它们。以下是一些我觉得有用的视频:
学习
- 买一把好的螺丝刀——我有一把不好的螺丝刀,它很快让我陷入困境。帮你自己一个忙,买一个长颈的,这样你就可以伸进狭小的空间。
- 再用力点 —免责声明:如果你弄坏了什么东西,不要怪我,但至少在两个场合(CPU 和内存)我浪费了时间,因为我对部件太温柔了。我害怕太用力,所以如果零件不容易到位,我就放弃了。在内存方面,我几乎在亚马逊上购买了一套全新的芯片。两种情况下的解决方法都是更用力。
- ***了解您的 BIOS—*BIOS 是预装在主板上的一个小软件,在您第一次启动机器时弹出。它基本上是一个控制面板,用于配置硬件和启动操作系统。了解您的主板在哪里寻找“引导驱动器”(保存您的操作系统的 USB 或 SSD)以及它如何选择要使用的显卡非常重要。令人遗憾的是,MSI 手册在这些问题上含糊不清,但有一些很好的视频深入到了细节中。
- 你的显示器没坏— 我花了一段时间才想出如何让显示器与我的新盒子配合使用。我在某处读到过,最初你需要将显示器连接到主板上,因为没有 Nvidia 驱动程序,显卡就无法工作。当我终于启动,但是我看不到任何东西在显示器上。我试着连接显卡,只是为了好玩,但也不起作用。最后,我尝试完全移除显卡,连接回主板并重启。成功了!问题是,微星主板默认使用自己的显卡,只有当它在 PCIe 插槽中找不到任何外部卡时。因为我第一次尝试启动时连接了显卡,所以主板尝试使用我的新卡。我没有看到任何东西,因为 Nvidia 驱动程序没有安装!
终于,我的杰作完成了!
**
3.安装操作系统
在您让显示器工作之后,您应该会看到类似这样的内容。这是你的简历。为了让一切正常运行,我需要做两个配置更改:更改引导优先级和交换默认显卡。
Pre-installed BIOS on MSI motherboards
我打算把我的机器主要用于编程和机器学习,所以我决定安装 Ubuntu 作为我的操作系统。我还希望从我的 Mac 电脑上远程工作,所以我不认为有必要安装 Windows,但你可以同时安装这两个系统。
创建可启动的 USB 驱动器
我按照这些用于 Mac 的指令下载了一个名为 UNetBootin 的客户端。
引导进入 Ubuntu
在一个完美的世界里,我应该能够插上我的 USB 驱动器,重新启动,回答几个问题,并且已经安装了一个完全可用的 Ubuntu 版本。相反,我得到了以下错误消息:
I pressed ESC a few times. Then DEL. Then F1, F10, and F12. Then #%^ and $&]&&&#^. Nothing worked.
问题在于 MSI 选择的默认“启动优先级”。再次登录 BIOS(开机后立即按 F11),我看到 BIOS 被配置为首先尝试从我的硬盘(三星 SSD)启动,硬盘是空的,但可能有足够的垃圾来混淆 BIOS。解决方案是将 USB 选项拖到优先级列表的顶部,然后重新启动。终于看到了友好的 Ubuntu 设置画面!
安装 Ubuntu 并重启后,我很自然地沮丧地发现我无法通过 Ubuntu 加载屏幕。它只是停滞不前,并最终超时。WTF!?!
问题原来是微星主板上的内置显卡(GTX 1080 还在我的茶几上)。它与 Ubuntu 图形用户界面不兼容!这是典型的先有鸡还是先有蛋。没有 Ubuntu 我不能安装 Nvidia 驱动,但是没有驱动我不能启动 Ubuntu!进入 GRUB 。
Ubuntu boot menu. You can get here by holding down ESC or Left Shift after powering on.
我最终找到了两个很棒的帖子在这里和在这里,它们帮助我摆脱了困境。解决方案是在引导命令中添加 nomodeset 参数。这帮助我启动了一个相当普通的 Ubuntu 版本,并继续我的道路。
4.安装驱动程序
NVIDIA 驱动程序是出了名的难相处,这个也不例外。在其他用户的带领下,我去了 NVIDIA 网站,下载了 GeForce 驱动程序,并开始使用 Ubuntu GUI 安装它。这是一个会给我带来巨大痛苦的错误。
检测不到兼容的 NVIDIA 卡
又一个鸡和蛋。我没有重新安装 GTX 1080,因为没有驱动程序它就无法工作。如果我重新连接它,MSI 板将再次开始使用它,我将回到我开始的地方。解决方案是重新启动 BIOS 并改变显卡的优先级。我没有默认选择新卡,而是更新了设置,让主板的内置卡优先。这让我可以重新安装 GTX 1080 并正常登录 Ubuntu。
你似乎正在运行 X 服务器
更好的方法
最终,我让一切都正常工作了(驱动程序、CUDA、深度学习库等),并为自己感到欣慰。但是没过多久,我又一次破坏了配置文件。
在 AskUbuntu 上花了几个小时后,我注意到新的 CUDA 8.0 工具箱预装了 NVIDIA 驱动程序,并允许您同时安装 CUDA 和驱动程序。
我清除了现有的 NVIDIA 库,运行了下面的代码,一切正常。你可以在这里看到完整的说明。
*wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.44-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1604_8.0.44-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda*
然后将以下内容添加到您的~/中。bash_profile:
*export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
export LIBRARY_PATH=/usr/local/cuda-8.0/lib64${LIBRARY_PATH:+:${LIBRARY_PATH}}*
哦,我提到过你可以在 Ubuntu 文本模式下从命令行完成所有这些吗?谁需要图形用户界面!
5.安装深度学习库
有很多很好的帖子描述了基本的深度学习库以及如何安装它们( 1 、 2 、 3 、 4 )。这里关键的一点是不要盲目地遵循说明,尤其是关于如何安装的部分。这些说明通常已经过时,图书馆网站上有更好的例子。以下是我安装的库:
CUDA —利用 GPU
的并行计算平台 cud nn—Nvidia library for accelerated deep learning
Anaconda—Python for data science(numpy、scikit、jupyter…)
open blas—快速线性代数方法
Tensorflow—Google 的机器学习库
Theano*—tensor flow
Keras的替代方案—简化使用 tensor flow 或 the ano 的工作*******
之后,我运行了一些测试,以确保一切正常,并开始使用 Jupyter 笔记本。
6.设置远程访问
这是一个可选的步骤,但是如果你打算从你的笔记本电脑远程工作,这里有一些方法可以做到这一点。
团队查看器
Teamviewer 是屏幕共享软件。如果你在两台机器上都安装并运行了它,你就可以从你的笔记本电脑上控制你的 Ubuntu 机器,反之亦然。虽然这使得某些事情更方便,但通过屏幕共享做任何事情都有点慢而且笨拙。
SSH 和端口转发
我希望能够远程 SSH 到我的新盒子,并与它交互,就好像它是我终端中的另一个选项卡一样。为此,我在 Ubuntu 上安装了 OpenSSH 。
*****sudo apt-get install openssh-server
sudo service ssh status*****
之后,我配置了我的 Comcast 路由器,将外部流量直接转发到我的主机。我按照康卡斯特的指示来到这里,令我惊讶的是,事情成功了!我通过检查 www.canyouseeme.org的 22 号端口验证了这一点。该过程的一部分包括计算出您的公共 IP 地址,您可以通过运行以下命令找到该地址:
*****dig +short myip.opendns.com @resolver1.opendns.com*****
远程笔记本
如果你是 Jupyter 的粉丝,另一个很酷的技巧是在深度学习桌面上运行笔记本,但在笔记本电脑上查看和编辑笔记本。这里有一个很棒的技术教程,所以我只转述一下命令:
*****$laptop: ssh -l bfortuner@DEEPLEARNINGIP
$server: jupyter notebook --no-browser --port=8888
$laptop: ssh -NL 8888:localhost:8888 bfortuner@DEEPLEARNINGIP*****
现在你可以在笔记本电脑的浏览器中访问 http://localhost:8888,并开始在深度学习机器上编辑笔记本!
这是所有的乡亲。有问题随时给我发信息!
一边训练 DL 模型一边烧 GPU?这些命令可以冷却它。
我们经常用 Geforce GPU 做个人研究的深度学习模型训练,但是满载运行时 GPU 温度会高达 84°C!那不仅仅是在烧 GPU,更是在烧我们的心!
受一个来自**(中文版 Quora)* 的朋友的启发,他修改了 gpu 风扇速度来冷却 gpu,那是因为默认的 nvidia gpu 设置将 GPU 风扇速度限制在 70%或更低,我们必须手动改变 GPU 风扇速度来冷却它。*
PS:本教程应用了 GTX GPU 的 Ubuntu OS,请注意。
中文版本:
I also write this article in Chinese, here is Chinese version: 深度学习训练时 GPU 温度过高?几个命令,为你的 GPU 迅速降温。
如果您连接了显示器。
步骤 1:修改/etc/X11/xorg.conf 文件:
*sudo nano /etc/X11/xorg.conf*
步骤 2:将以下命令放入“设备部分”术语中:
*Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA"
Option "Coolbits" "4"
EndSection*
第三步:重启你的机器。
步骤 4:输入以下命令:
*nvidia-settings -a “[gpu:0]/GPUFanControlState=1” -a “[fan:0]/GPUTargetFanSpeed=100”*
“gpuFanControlState=1”表示可以手动改变风扇转速,“[fan:0]”表示要设置哪个 GPU 风扇,“GPUTargetFanSpeed=100”表示将转速设置为 100%,但那样会很吵,可以选择 80%。
如果没有连接显示器。
我们经常使用 ssh 连接机器,所以机器不会连接显示器。但是上面的方法只有在你有显示器的时候才有效,所以我们必须做些什么来欺骗你的操作系统,让它认为你有显示器。
解决方案参考这篇文章:风扇转速无 X(无头):powermizer 掉卡到 p8 ,作者提供了一个改变风扇转速的脚本。下面是完整的步骤:
第一步:将这个 repo 克隆到这个目录:/opt
*cd /opt
git clone https://github.com/boris-dimitrov/set_gpu_fans_public*
这个回购包括这些文件,关键脚本是“cool_gpu”。
第二步:把文档的名字从“set_gpu_fans_public”改成“set-gpu-fans”,那是作者的小错别字。
sudo mv set_gpu_fans_public set-gpu-fans
步骤 3 : cd 到 set-gpu-fans 目录,并输入以下命令:
*cd /opt/set-gpu-fans
sudo tcsh
./cool_gpu >& controller.log &
tail -f controller.log*
它将启动冷却脚本,您可以看到以下过程:
测试时间:
在我们测试它是否可以冷却 gpu 之前,我们检查当前的温度。
现在大概是 37°C,好的,我们来运行一个模型,看看效果如何。
温度越来越高,当它变得稳定时,你可以看到最终温度:
哇,我们做到了!我们将 gpu 从 84°C 冷却到 67°C!那真的太牛逼了!
有一件事你应该知道,目前的 GPU 功率状态是 P2,这意味着它运行在高性能,最高的是 P0,最低的是 P12。这个冷却脚本工作得非常好,而且没有降低性能。
立正!冷却脚本的原始版本会降低 GPU 性能!
我们上面使用的脚本是原始脚本的改进版本,原始脚本在这里:设置风扇速度,不需要 X 服务器。
许多人使用原始脚本会导致性能下降的问题,它会将电源状态从 P2 下降到 P8,甚至 P12,所以我强烈建议不要使用原始的。但我们还是要对原剧本作者付出一定的尊重,没有他的作品我们无法改变粉丝速度。
如果你觉得这篇文章能帮到你,请点击心脏,分享给你的朋友!感谢阅读。
商业和数据科学——管理预期
数据科学家的角色非常多样化,需要承担不同的职责,并对分析技能和商业敏锐性有着天生的偏好。难怪熟练的数据科学家被比作像独角兽一样稀有。
他们可能与神话中的人物不相上下,但对于企业和数据科学家来说,如果即使是最有才华的数据科学家也要蓬勃发展,期望必须是现实的,结构必须到位。
数据科学经理的角色
数据科学领导者的角色需要的技能不同于在管理或分析角色中获得的技能。这类经理必须对数据科学的理解既有深度又有广度,其中深度来自完整数据科学产品生命周期的第一手经验,即从头开始参与项目的实践经验。广度来自对数据科学领域的全面了解,这可以证明合格的管理者和杰出的分析师之间的重要区别。
如何将数据科学与商业战略相结合
起点——选择要分析的数据
首先,企业应该避免变得数据贪婪。一般的公司可能会产生大量的数据,但是从大量的数据中形成可操作的见解通常是不必要的耗时。出于这个原因,数据战略需要一种灵活的方法——一种持续评估数据点的方法,由公司中每个相关的利益相关者确定数据需求的优先级,而不仅仅是由数据科学家确定。
拥抱现实——准备投入必要的预算
数据科学可以代表公司的未来,因此企业必须对他们需要的人才和所需的预算持现实态度。举个例子,如果一家公司的数据量很大,那么管理数据的角色和分析数据的角色可能需要单独招聘。
雇佣前:退后一步,体会数据科学家的重要性
现实主义还必须延伸到评估你正在招聘的角色——数据科学家不仅要揭示洞察力,还要识别和解决问题领域。他们的角色是复杂的、紧迫的和具有挑战性的——您必须为他们提供在其角色中茁壮成长所需的业务支持结构。
数据科学家和企业如何更好地合作
1。沟通:促进团队合作
数据科学项目的成功依赖于可靠的沟通,团队必须具有凝聚力和协调性,其中最重要的是我们之前提到的那种罕见的天生的数据科学领导者。
2。驾驭商业直觉
企业是商业直觉和大量商业人才的家园,数据科学家一定不要害怕寻找这些人并利用他们的知识,这可以揭示客户、产品和市场。公司可以通过开放沟通渠道和为这些部门提供合作时间来帮助实现这一目标。
3。测量结果
你为什么要做你正在做的事情,成功的定义是什么?这些是在查看单一数据集之前必须回答的关键问题。根据您对成功的衡量,必须有一些指标来定义您的数据科学工作是否达到了您设定的所有目标,是令人沮丧地失败了,还是达到了两者之间的某个程度。
4。敏捷地工作
业务直觉和输入应该不断地为数据科学项目提供支持,随着洞察力的获得,这必须影响项目的下一步,如果要满足流畅的项目交付,敏捷工作是必不可少的。最小可行产品和短交付周期是关键。
5。创建一个分享知识的社区和文化
一个成功的数据科学项目始于并止于正确的人和正确的部门之间开放、健康和富有成效的关系,但如果没有一致的努力,这一切都不会发生。为了创造一种协作文化,必须培养这种文化——会议必须让所有人受益,让所有人参与——为关键利益相关者提供分享知识的机会——而不是让领导者简单地发号施令。
商业+数据科学
数据科学家被正确地放在一个基座上,受到高度尊重,能够成为更明智决策的核心,通过数据洞察提高生产力和商业方向。然而,利用数据科学家的商业优势不仅取决于对他们的现实期望,还取决于其他人的现实期望,特别是高级管理人员和领导团队。除了这种共生关系,还有将数据科学与业务战略相结合的挑战——这需要对数据有适当谨慎的偏好,因为数据贪婪可能会迅速吞噬项目成功的前景。
任何数据科学工作的战略性准备工作都与数据科学项目的具体细节一样重要,包括方法、数据集和模型。确保数据科学家与业务部门和其他核心部门的人员协作,是从组织未来的重大投资中获得最佳投资回报的关键。
数据科学中的商业直觉
通常,当我们想到数据科学作业时,脑海中出现的主要内容是需要应用的算法技术。虽然这一点至关重要,但在典型的数据科学任务中,还有许多其他步骤需要同等关注。
典型的数据科学任务可分为以下几个阶段:
让我用一个简单的案例来解释一下:
有一个在线零售商,他在十一月,就在假期之前,举办一个购物节。它有一个 100 万种产品的目录和一个 1 亿名顾客的数据库,这些顾客过去都曾向它买过东西。
该零售商希望针对其客户群开展促销电子邮件活动。目标是运行一系列“成功的电子邮件活动”。
现在让我们来理解这项特殊任务的不同阶段:
1。 定义业务目标:
这是一个极其关键的阶段,因为对手头业务问题/目标的错误解释会导致错误的解决方案和不良结果。如果你仔细想想,数据科学的作用是使用数据和从中获得的见解来解决现实世界的问题。从这个角度来看,准确地识别问题和定义目标对于成功的结果至关重要。在本例中,营销人员希望向其每位客户发送定制的电子邮件,显示根据客户的偏好和品味整理的产品报价列表:
Source: https://www.remarkety.com/customer-segmentation-drives-better-product-recommendations
在这种情况下,为了定义业务目标,我们必须问几个问题:
a)我们是向 100 MM 客户的全部名单发送电子邮件,还是向一组精选的客户发送电子邮件?该零售商正在组织购物节,因此向所有 100 MM 客户发送电子邮件可能是有意义的,但仍需要考虑某些要点:
a.通过向所有客户发送大量电子邮件,会不会让一些客户不高兴,比如那些不主动向零售商购物的客户
b.由于我们希望向客户展示精选的产品列表(基于个人偏好),因此,如果将所有 100 MM 客户都考虑在内,我们可能最终会发现一组客户对任何产品都没有表现出很高的偏好(可能是因为他们没有在零售商那里购买足够多的产品,因此零售商没有足够的信息来了解他们的偏好)
c.有时,数据处理和存储成本也是一个考虑因素。处理 100 万客户及其特征,运行机器学习算法可能是相当时间和资源密集型的。虽然基础设施可以处理这种情况,但除了前两个考虑因素,排除一些客户可能是有意义的,特别是为了加快上市时间。
b)我们如何定义和量化成功指标?这是一个极其重要的决策,并且与业务目标直接相关。在上面的例子中,我们可以有一些可能的成功标准:
*a .活动的购买率(购买数量/发送的电子邮件数量):*该指标将给出活动在说服客户消费方面的效果。因此,如果零售商只关心整个活动带动了多少销售,那么这就是要追求的指标!
b.*活动的电子邮件打开率(打开的电子邮件数量/发送的电子邮件数量):*如果零售商想要了解其他因素,如电子邮件活动内容的有效性,具体来说,在这种情况下,电子邮件主题的“吸引人”程度,这可能很重要。同样,电子邮件点击率(打开电子邮件后,点击电子邮件中提供的网络链接,进入零售商的网站)显示了电子邮件内容的有效性。
c.*活动的盈利能力:*有时,零售商可能会对提高每位顾客的消费感兴趣,而不仅仅是让更多的顾客做出回应(即提高回应率)。请这样想——一项旨在推动越来越多的客户消费的活动,最终可能会吸引那些购买大量低价值产品的客户,而避开那些购买较少但购买高价值产品的客户。
**2。数据处理与分析:
这也是另一个非常重要的阶段,在这个阶段,我们详细了解我们可用的数据,以及我们如何使用这些数据来准确地解决手头的问题。
概括地说,这一阶段可以有以下步骤:
1.缺失值处理
2.异常值处理
3.数据分段
4.特征工程
让我们一个接一个地检查它们,以获得为什么需要这个步骤的直觉。在上述案例中,假设您从过去的促销电子邮件活动中获得了如下数据:
上面的数据是三个客户(这家在线零售商拥有 1 亿个客户)及其部分信息的快照。
可以看出,第二个顾客的性别是未知的。性别可能是强有力的信息,因此,如果很大比例的客户是“未知”或“失踪”的性别,那么我们将丢失一条非常重要的信息。有许多方法可以估算性别(通过称呼或姓名),因此可用于 缺失值处理。 同样,如果报告的年收入缺失(因为此信息仅由客户提供,他/她可能不愿意提供),我们可以使用过去 12 个月的支出来估算/预测年收入。
异常值处理 也很重要。例如,我们可以看到“过去 12 个月支出”或“年收入”的一些非常高的值。在支出的情况下,可能是因为某些客户的一次性高美元支出可能不会持续,并且可能会使整个数据产生偏差,因此将支出值限制在某个阈值(例如“过去 12 个月支出”的 99 或 95 百分位值)有助于减少这种偏差。
有时,我们可能会看到数据中有不同的客户群,他们的行为非常不同。例如,如果我们观察最近的客户(最近 6 个月成为在线零售商的会员),这些客户的行为方式可能与其他客户非常不同(他们可能非常好奇,因此电子邮件打开率可能非常高,但购买率可能很低)。因此,将这些客户与其他客户混合可能会使数据在某些参数上产生偏差,或者这些客户的特征可能会被其他客户所掩盖,从而降低他们在构建的任何预测算法中的代表性。在这种情况下,为这两个 【数据段】 (新客户和剩余客户)构建单独的算法可能是有意义的
特征工程: 特征或变量才是真正赋予算法预测能力的东西。因此,拥有正确的特征集是构建一个健壮算法的关键——因此关注特征工程。特征工程的类型:
- 特征选择:选择对问题最有用的特征子集。有许多特征选择算法,如基于相关性、信息值或其他特征重要性概念的评分算法。然而,随着越来越多的计算能力和机器学习技术,特征选择越来越多地在算法中处理。
- 特征构建:从原始数据手动构建新特征,例如,在上面的案例研究中,我们有一个特征“最后消费日期”,它本身可能不提供任何预测能力。但是,我们可以创建一个非常强大的功能“自上次消费后的天数”(最近消费过的客户可能有更高的再次消费意愿,因此可能对电子邮件报价更敏感)
- 特征提取:像图像、语音、文本这样的一些数据可以有多个特征,因此,通过特征提取,我们可以自动降低这些类型的特征的维数,并从数据中提取隐藏的特征。例如,在图像识别中,如下面的口袋妖怪图像,每个图像可以有数百个特征(像素)。因此,任何图像识别算法都必须处理来自多幅图像的大量特征。因此,该算法必须能够自动提取和减少这些大量的特征,以更小的一组有意义的特征。
3。建模与评估:
这是我们必须选择“正确的算法”来为我们的业务问题获得“正确的解决方案集”的步骤。如您所见,这是极其重要的一步,关键是找到最适合给定业务目标的算法。在上面的案例中,无需深入细节,我们有两组目标— (1)从 100 万个客户中找到响应度最高的一组客户—假设是 x (2)对于这 x 个客户列表中的每个客户,显示与他/她的偏好最相关的报价。对于第一个目标,我们需要一个响应预测算法(例如回归技术),该算法将给出每个客户的响应可能性分数/概率,然后可用于对客户进行排序,并为活动选择响应度最高的客户。对于目标(2)——发现客户的优惠偏好,我们需要能够帮助选择最有可能被客户偏好的产品优惠的算法(例如,推荐算法或分类技术)
一旦我们构建了算法,对它们的评估也是基于它们满足手头目标的程度。让我们通过上面的案例研究来理解这一点。假设我们已经建立了一个响应预测算法,该算法根据 1 亿名客户在看到电子邮件报价后购买产品的概率对他们进行排序:
现在,我们将这些 1 亿客户分成 10 个相等的桶,按照响应概率从高到低的降序排列。对于每一类客户,我们会查看他们对之前发送给所有 100 MM 客户的电子邮件促销活动的实际回复率:
Please note: the response here is product purchase after seeing the email offer
因此,为了实现目标 1,我们只需决定在哪个时段发送电子邮件报价。
现在,在上表中,您可以看到某些时段的“平均响应概率”和“实际响应率”之间存在差异,例如时段 3 和 4。因此,与实际值相比,预测值并不十分“准确”。但是,由于这里的目标是选择一组高响应可能性的客户,我们更关心该模型在响应方面对客户进行排序的情况。看一下实际的回复率,它似乎做得相当不错(过去活动的实际回复率也差不多是按降序排列的)。因此,在这里,模型结果评估更多地是围绕如何根据客户的响应概率而不是预测的准确性对客户进行排序。
然而,当我们评估第二个模型的结果时,预测准确性可能更重要,第二个模型给出了每个客户对每种产品的偏好得分。比方说,在上面的例子中,有 10 个产品报价。因此,我们建立了一个模型,为 10 种产品中的每一种给出每位顾客的偏好得分:
这里,客户 1 对报价 1、2 和 4 有更高的偏好。对于产品 3 和 5,由于偏好得分很低,我们可以假设他对这些产品没有任何偏好。类似地,我们可以说客户 2 没有表现出对任何特定产品的偏好。我们可以创建一个阈值分数,如果客户的分数高于该阈值,我们将考虑该偏好,否则不予考虑。因此,您可以在这里看到,我们正在根据分值进行此类评估,因此,获得反映客户真实偏好的准确分值非常重要。因此,在该模型评估中,预测精度非常重要。
**4。原型:
通过构建数据原型,我们的意思是创建必要的基础设施,以便在生产环境中实现解决方案。鉴于实施是一个时间和资源密集型过程,需要给予适当的考虑。在上述情况下,其中一些可能是:
- 这一电子邮件活动是一次性的营销活动还是更有规律的活动?如果是常规的,那么创建一个生产平台来执行这样的活动是有意义的。
- 对于这样一个平台,如何将来自不同来源的所有数据放在一起?需要从清理源数据所涉及的工作量和成本、更新频率、内部数据卫生检查和平衡等方面进行评估。
- 所有这些数据将如何存储和处理?这涉及到需要并行处理(如果数据量巨大)还是实时处理以及存储基础架构等决策。
- 电子邮件将如何发送?同样,需要做出的决策包括:是否需要第三方电子邮件交付供应商、客户数据隐私检查和平衡、上市速度(包括实时处理需求)等。
这是一些需要考虑的因素,但是根据任务的规模和复杂程度,可能还有许多其他需要评估和评价的事情。
因此,如您所见,数据科学任务是许多阶段的总和,需要领域专业知识、对业务目标的详细理解以及技术专业知识。二者缺一不可!!
想了解更多?参加由www.deeplearningtrack.com提供的为期 8 周的基于案例研究的数据科学课程