怎样让python深度学习模型在手机上跑

可以开发票么?
可以的,购买课程或者充值余额后都是可以开具发票的,具体详情点击:
购买的课程可以下载么?
目前PC端暂不支持下载课程视频,请手机或者平板电脑下载“51CTO学院”APP后再下载视频哦!
优惠券如何使用?
非折扣课程(不包含1元课程/套餐)可使用,一个订单(可包含多个课程)只可使用一张;优惠券一经使用,不再返还;若被冻结请在PC端删除订单即可返还。
更多问题查询点击
欢迎您提供宝贵意见,对于您的意见我们都会认真、慎重的讨论,每一个意见都是我们更好为您服务的鞭策和激励,感谢您帮助学院成长,后使用快捷导航没有帐号?
Keras 教程: Python 深度学习终极入门指南
查看: 29368|
评论: 0|原作者: kissg 译|来自: Python程序员
摘要: 深度学习是指具有多隐层的神经网络, 其可以学习输入数据的抽象表示. 这个定义显然太简单了, 但对于现在的我们来说, 却是最有实际意义的.比方说, 深度学习促进了计算机视觉的巨大进步. 现在, 我们能够对图片进行分类, ...
在这篇 Keras 教程中, 你将学到如何用 Python 建立一个卷积!事实上, 我们将利用著名的 MNIST 数据集, 训练一个准确度超过 99% 的手写数字分类器.开始之前, 请注意, 本指南是面向对应用感兴趣的初学者的.我们旨在向你介绍一个最流行的同时也是功能最强大的, 用于建立神经网络的 Python 库. 这意味着我们将跳过许多理论与数学知识, 但我们还是会向你推荐一些学习这些的极好的资源.开始之前推荐的预备知识本指南推荐的预备知识有:的基本概念Python 编程技能为了能快速开始, 我们假设你已经具备了这方面的知识.为什么要用 Keras?Keras 是我们推荐的 Python 深度学习库, 尤其是对于初学者而言. 它很简约, 模块化的方法使建立并运行神经网络变得轻巧. 你可以在这里读到更多关于 Keras 的内容:Keras, Python 的深度学习库深度学习究竟是什么?深度学习是指具有多隐层的神经网络, 其可以学习输入数据的抽象表示. 这个定义显然太简单了, 但对于现在的我们来说, 却是最有实际意义的.比方说, 深度学习促进了计算机视觉的巨大进步. 现在, 我们能够对图片进行分类, 识别图片中的物体, 甚至给图片打标签. 要实现这些, 多隐层的深度神经网络可以从原始输入图片中按序学习更复杂的特征:第一层隐层也许只能学习到局部边缘模式.之后, 每一个后续层 (或过滤器) 将学习更复杂的表示.最后, 最后一层可以对图片进行分类, 是猫还是袋鼠.这类深度神经网络就称为卷积神经网络.卷积神经网络究竟是什么?简而言之, 卷积神经网络 (CNN) 就是将输入数据假设成图的多层神经网络 (有些时候, 会有多达 17 甚至更多层).通过实现这个需求, CNN 可以大大减少需要调整的参数数量. 因此, CNN 可以高效处理高维原始图片.卷积神经网络的底层机制已经超过了本教程的范围, 更多请看这里.本教程不是什么:这不是一门深度学习的完整课程. 相反地, 本教程旨在带你从零到一, 尽量”无痛”地建立卷积神经网络!如果你有兴趣掌握深度学习背后的理论, 强烈推荐斯坦福大学的这门课:CS231n: Convolutional Neural Networks for Visual Recognition开始前的小提示:我们试着让教程尽可能流线化, 这意味着任何一个主题, 我们都不会太深究细节. 万一你想要学习关于一个函数或模块更多的知识, 同时打开 Keras 文档 很有帮助.Keras 教程目录下面是创建你的第一个卷积神经网络 (CNN) 的步骤:配置环境安装 Keras导入库和模块从 MNIST 导入图片数据预处理输入数据预处理类标签定义模型架构编译模型用训练数据拟合模型用测试数据评估模型第一步: 配置环境首先, 挂一张励志海报:可能没什么用- -.然后, 确保你的计算机上已经安装了以下软件:Python 2.7+ (Python 3 也可以, 但总体而言, Python 2.7 在数据科学领域依旧更受欢迎.)Scipy 和 NumPyMatplotlib (可选的, 推荐用于探索性分析)Theano* (安装指南)强烈建议使用 Anaconda 发行版 来安装 Python, NumPy, SciPy. 它自带所有这些包.注意: 用 TensorFlow 也可以 (作为 Theano 的替代), 但我们将坚持使用 Theano, 以保持程序足够简单. 使用 TensorFlow 和 Theano 的主要区别在于, 数据输入神经网络之前, 需要简单地重塑.你可以检查一下是否都正确安装了:第二步: 安装 Keras如果我们没有涵盖如何安装 Keras, 这就不是一篇 Keras 的教程.好消息是, 如果你使用的 Anaconda, 你已经安装好了一个超赞的包管理系统: pip.你可以在命令行输入 $ pip 确认安装. 这条命令将打印一个命令和选项的列表. 如果你还没有安装 pip, 参照这里进行安装.第三步: 导入库和模块第四步: 从 MNIST 加载图片数据MNIST 是深度学习和计算机视觉入门很好的数据集. 它很大, 这对于神经网络是一个巨大的挑战, 但它在单台计算机上又是可管理的. 我们将在另一个文章中对此进行更多的讨论: 6 Fun Machine Learning Projects for Beginners.输出的图片是这样的:总的来说, 做计算机视觉的, 在进行任何工作之前, 可视地绘制数据很有帮助. 这是一个快速明智的检查, 可以防止可避免的错误 (比如对数据维度的误解).第五步: 输入数据预处理在后端使用 Theano 时, 你必须显式地声明一个维度, 用于表示输入图片的深度. 举个例子, 一幅带有 RGB 3 个通道的全彩图片, 深度为 3.MNIST 图片的深度为 1, 因此必须显式地进行声明.换言之, 我们要将数据集从 (n, width, height) 转换成 (n, depth, width, height).第六步: 预处理类标签第七步: 定义模型架构现在, 我们就可以定义我们的模型架构了. 在实际研发工作中, 研究员会花大量的时间研究模型架构.在这里, 为了教程的继续, 我们不会讨论理论或数学. 这本身就是复杂的领域, 对于想要深入学习的同学, 建议看一下上文提到的 CS231n 课程.另外, 刚开始时, 你可以使用现成的例子或者实现紫黯学术论文中已经证明的架构. 这里有一个 Keras 实现样例.输的形状参数应为形状为 1 的样例. 本例中, 就是 (1, 28, 28), 与每张数字图片的 (depth, width, height) 相对应.但是前 3 个参数又代表什么呢? 它们分别对应于要使用的卷积过滤器的数量, 每个卷积内核的行数与列数.注意: 默认情况下, 步长为 (1, 1), 可以用 ‘subsample’ 参数进行调整.再次声明, 我们不会太深究理论的东西, 但有必要强调一下我们刚刚添加的 Dropout 层. 这是一个规范化模型的方法, 目的是防止过度拟合. 你可以在这里看到更多内容.MaxPooling2D 是一种减少模型参数数量的方式, 其通过在前一层上滑动一个 2*2 的滤波器, 再从这个 2*2 的滤波器的 4 个值中取最大值.现在, 我们唯一需要做的就是定义损失函数和优化器, 然后就可以对模型进行训练了.第八步: 编译模型现在可以轻松一点了, 最难的部分已经过去了.只需要编译模型, 然后我们就可以训练它了. 编译模型时, 我们需要声明损失函数和优化器 (SGD, Adam 等等).Keras 有各种各样的 损失函数和开箱即用的优化器.第九步: 用训练数据进行模型拟合要拟合模型, 我们需要做的就是声明训练的批次大小以及训练次数, 然后传入训练数据.简单吗?你也可以使用各种回调函数来设置提前结束的规则, 保存模型权重, 或记录每次训练的历史.第十步: 用测试数据评估模型最后, 可以用测试数据对模型进行评估:恭喜! 你已经完成了本 Keras 教程.我们刚刚体验了 Keras 的核心功能, 但也仅仅是体验. 希望通过本教程, 你已经获得了进一步探索 Keras 所有功能的基础.如果希望继续学习, 我们推荐学习其他的 Keras 样例模型 和斯坦福大学的计算机视觉课程.完整的代码以下就是本教程的所有代码, 保存为一个脚本:英文原文:/keras-tutorial-deep-learning-in-python&欢迎加入本站公开兴趣群软件开发技术群兴趣范围包括:,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流QQ群:源代码研究群兴趣范围包括:Hadoop源代码解读,改进,优化,场景定制,与Hadoop有关的各种开源项目,总之就是玩转HadoopQQ群:&
刚表态过的朋友 ()
上一篇:下一篇:深度学习(五)BP神经网络 in python
深度学习(五)BP神经网络 in python:将上一章节中的BP神经网络实现出来。代码并没有考虑效率,但是代码很容易理解整个BP过程,这里我将我的理解记录下来并分享出来。
BP神经网络回顾
我们先看一下单个神经元的结构:
我们在看一下一个这里需要构建的神经网络的结构:
再回顾一下BP误差传播算法:
用数学的形式表示就是:
z1a1z2a2=xW1+b1=tanh(z1)=a1W2+b2=y^=softmax(z2)
其中x表示输入向量,zi是i层的输入,ai是应用激活函数的输出。W1,b1,W2,b2是这个网络的模型参数。应用BP公式求导(这是是人工求导的,在theano中是可以自动求导)得:
&3=y^?y&2=(1?tanh2z1)&&3WT2?L?W2=aT1&3?L?b2=&3?L?W1=xT&2?L?b1=&2
BP算法代码in python
def generate_data():
np.random.seed(0)
X, y = datasets.make_moons(200,noise=0.20)
return X, y
这里面使用的是scikit-learn中的函数,产生200个数据,下图是这个图的可视化结果:
神经网络结构
class Config:
nn_input_dim = 2
# 输入的维度
nn_output_dim = 2
# 输出维度
# 梯度下降参数
epsilon = 0.01
reg_lambda = 0.01
# 正则化长度
如网络图所示,这里的网络有2维输入,2维输出,学习步长是0.01(如果这里不懂,可以看一下梯度下降法的原理),正则化长度。
神经网络模型
# 这个function是学习神经网络的参数以及建立模型
# - nn_hdim: 隐藏层的节点数
# - num_passes: 梯度下降法使用的样本数量
def build_model(X, y, nn_hdim, num_passes=20000):
# Initialize the parameters to random values. We need to learn these.
num_examples = len(X)
np.random.seed(0)
W1 = np.random.randn(Config.nn_input_dim, nn_hdim) / np.sqrt(Config.nn_input_dim)
b1 = np.zeros((1, nn_hdim))
W2 = np.random.randn(nn_hdim, Config.nn_output_dim) / np.sqrt(nn_hdim)
b2 = np.zeros((1, Config.nn_output_dim))
# 最后返回的模型,主要就是每一层的参数向量
model = {}
# 梯度下降法
for i in range(0, num_passes):
# 正向传播过程
z1 = X.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
# 误差反向传播过程
delta3 = probs
delta3[range(num_examples), y] -= 1
dW2 = (a1.T).dot(delta3)
db2 = np.sum(delta3, axis=0, keepdims=True)
delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
dW1 = np.dot(X.T, delta2)
db1 = np.sum(delta2, axis=0)
# 添加正则项 (b1 and b2 不需要做正则化)
dW2 += Config.reg_lambda * W2
dW1 += Config.reg_lambda * W1
# 梯度下降参数更新
W1 += -Config.epsilon * dW1
b1 += -Config.epsilon * db1
W2 += -Config.epsilon * dW2
b2 += -Config.epsilon * db2
# 更新模型参数
model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
return model
前向传播过程数学表达:
z1a1z2a2=xW1+b1=tanh(z1)=a1W2+b2=y^=softmax(z2)
误差反向传播数学表达:
&3=y^?y&2=(1?tanh2z1)&&3WT2?L?W2=aT1&3?L?b2=&3?L?W1=xT&2?L?b1=&2
梯度下降更新参数:
这里是整个神经网络的核心的地方,代码的解释我个人觉得使用数学公式表示的更加明了清晰。这段代码中还有将loss值打印出来的函数,我将这段代码删除了,方便代码更加紧凑,更加容易理解。
def predict(model, x):
W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
# Forward propagation
z1 = x.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
return np.argmax(probs, axis=1)
这里就是一个前向传播过程:
z1a1z2a2=xW1+b1=tanh(z1)=a1W2+b2=y^=softmax(z2)
结果可视化
def visualize(X, y, model):
# plt.scatter(X[:, 0], X[:, 1], s=40, c=y, cmap=plt.cm.Spectral)
# plt.show()
plot_decision_boundary(lambda x:predict(model,x), X, y)
plt.title(&Logistic Regression&)
def plot_decision_boundary(pred_func, X, y):
# 设置最小最大值并填充
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
# 生成数据网格
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# 预测整个数据网格上的数据
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制数据点以及边界
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.show()
将数据点以及边界绘制出来。
def main():
X, y = generate_data()
model = build_model(X, y, 3, print_loss=True)
visualize(X, y, model)
if __name__ == &__main__&:
这里使用到的所有代码
下面这是这里使用到的所有代码,为了紧凑,删除了一些代码,如果你想看源代码看。想看原文看
import numpy as np
from sklearn import datasets, linear_model
import matplotlib.pyplot as plt
class Config:
nn_input_dim = 2
nn_output_dim = 2
epsilon = 0.01
reg_lambda = 0.01
def generate_data():
np.random.seed(0)
X, y = datasets.make_moons(200, noise=0.20)
return X, y
def visualize(X, y, model):
plot_decision_boundary(lambda x:predict(model,x), X, y)
plt.title(&Logistic Regression&)
def plot_decision_boundary(pred_func, X, y):
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.show()
def predict(model, x):
W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
z1 = x.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
return np.argmax(probs, axis=1)
def build_model(X, y, nn_hdim, num_passes=20000, print_loss=False):
num_examples = len(X)
np.random.seed(0)
W1 = np.random.randn(Config.nn_input_dim, nn_hdim) / np.sqrt(Config.nn_input_dim)
b1 = np.zeros((1, nn_hdim))
W2 = np.random.randn(nn_hdim, Config.nn_output_dim) / np.sqrt(nn_hdim)
b2 = np.zeros((1, Config.nn_output_dim))
model = {}
for i in range(0, num_passes):
z1 = X.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
delta3 = probs
delta3[range(num_examples), y] -= 1
dW2 = (a1.T).dot(delta3)
db2 = np.sum(delta3, axis=0, keepdims=True)
delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
dW1 = np.dot(X.T, delta2)
db1 = np.sum(delta2, axis=0)
dW2 += Config.reg_lambda * W2
dW1 += Config.reg_lambda * W1
W1 += -Config.epsilon * dW1
b1 += -Config.epsilon * db1
W2 += -Config.epsilon * dW2
b2 += -Config.epsilon * db2
model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
return model
def main():
X, y = generate_data()
model = build_model(X, y, 3)
visualize(X, y, model)
if __name__ == &__main__&:《数据科学与大数据技术》训练营: 初级以统计分析为主,工具是R语言;中级是大数据处理+算法+python 课程以实战为主,50%的内容是案例和练习,学完就可以上手/Blog/archives/45839
> 如何用Python一门语言通吃高性能并发、GPU计算和深度学习
#大数据MOOC学院#为了帮助IT从业者职业之路拥有更多收获,在诸多C粉的殷切期待下,由&CTO俱乐部打造的CTO线上讲堂自登场以来获得大家好评。本期邀请极验验证CTO黄胜蓝带来&如何用Python一门语言通吃高性能并发、GPU计算和深度学习&&的主题分享。
分享嘉宾:极验验证CTO 黄胜蓝
嘉宾简介:黄胜蓝 ,现任武汉极意网络科技有限公司CTO。高中时期NOIP一等奖保送至武汉大学,大学期间曾指导团队获得世界数学建模大赛金奖,同时负责武汉大学学生校园门户网站的运维工作。于2013年加入武汉极意网络科技有限公司,带领团队实现&行为式验证&安全模型,同时构建了高效、稳定的服务架构承载每天数十亿请求。对于技术发展有深刻见解,善于将适合的新技术融入公司技术架构中。
公司简介:武汉极意网络科技有限公司是全球首家&行为式验证&安全技术服务提供商,开创了验证安全从1.0时代到2.0时代的变革,并始终致力于为各大网站、应用、企业提供&更安全、更便捷、更具智慧的验证&服务及解决方案。
极意拥有业内领先的自主知识产权与技术研发实力,其首创的&行为式验证&安全技术,彻底颠覆了传统&码式验证&安全技术的思想,完成了14年以来验证安全领域的第一次飞跃&&安全性提高44.78倍以上,平均用户验证时长仅不到以前的1/3,提高用户交互度达20%以上,全面支持移动终端的触屏验证体验。
极意拥有强大创新能力的核心团队,里面有第四届中国侨界贡献奖(创新团队)核心成员负责项目整体运营、有获得世界计算机性能大赛刷新世界纪录的雅虎黑客负责云服务器构架、有世界数学建模大赛冠军负责&多重行为判别算法&的研究。公司自成立以来,就受到国内外诸多投资机构的关注与投资,去年公司接受了来自IDG的数千万投资。目前我们的客户包括新浪博客、斗鱼、战旗、聚美优品、网金社等数万家网站,对于游戏领域更是实现了全行业覆盖。
以下是12月31日CTO讲堂现场完整速记:&
主持人:今天讲堂现在开始,欢迎极验验证CTO黄胜蓝,麻烦给大家介绍下自己吧。
黄胜蓝:大家好,我叫黄胜蓝,目前担任武汉极意网络科技有限公司CTO,在公司主要负责带领团队构建高性能的服务架构和行为式安全模型。
看了我的照片应该会有些人想知道我的年龄。我确实是比之前的嘉宾都会年轻很多,其实我今年上半年才刚刚踏出武汉大学的大门^_^。高中时期我通过计算机竞赛一等奖保送到了武汉大学,这个经历对我而言很重要,有了当时对于数据结构和算法较为深刻的学习使得现在在接触实际工程中的一些概念时可以非常快速地了解其中的原理。大学大一大二在学校的自强网做运维工作,这段经历也让我受益匪浅,对于互联网相关技术也有了更多的了解。大二的暑假机缘巧合加入了极验验证团队。
主持人:请介绍一下目前极验验证的情况以及技术团队构成。
黄胜蓝:极验验证今年已经三岁了,目前我们的用户几乎遍布了互联网各个领域,每天处理的验证突破一亿次,每秒数万的并发对我们而言已经是常态。典型的客户包括新浪博客、斗鱼TV、战旗TV、熊猫TV、宝宝树、聚美优品、东方航空等。去年公司收到了来自IDG的数千万A轮投资,目前正在进行B轮,也是一线的投资机构。
比较有意思的有一次我到西电请了一些学生社团的负责人吃饭,十多个人中只有一个人没见到过我们的产品。
这些是我们典型客户的一个集中展示,分别是web端和移动端的。
团队方面,目前员工将近五十人,其中技术团队三十人多有,大部分都来自于武汉这边的几所高校,是一个非常非常年轻的团队。虽然团队在经验层面相对欠缺,不过目前从成果来看,不论是技术的深度还是广度都还算是拿得出手的。
主持人:介绍下极验验证如何兼顾安全性与用户体验?
黄胜蓝:极验验证与传统验证码对于验证技术的理解是有着本质上的区别的。传统验证码本质是人类可以理解图片的内容而计算机程序没有办法理解,这样的想法放在十年前或者五年前还算是靠谱,但是放在现在这样一个计算机程序都可以实现无人驾驶汽车的年代指望通过几张模糊不清的图就想难倒计算机程序实在是太天真了,同时传统验证对于正常用户的上网体验影响极大。而极验验证的&行为式验证&的概念,不再出一个难题作为门槛来限制用户,而是跟用户做一个小小的游戏,在游戏中通过行为来判断用户是正常用户还是恶意的程序请求。
我们根据收集到的海量行为数据构建了人类行为的边界,同时我们还动态实时地监控每个验证一段时间的全部验证行为,当这些行为的特征分布发生变化时我们的验证也会将分布异常集中的验证行为挡住。所以极验验证可以在比对手更加安全的同时对于用户也更加友好,实现安全与用户体验的双重提升。
这个图是某一次有个网站受到了恶意请求,我们将收集到的数据与正常人的数据从三个维度用tsne画出来图,很明显可以看出区别。正是因为极验验证在产品的用户体验和安全性上都完胜了传统的字符验证码,所以在市场上也出现了这样一个现象,一个行业中一旦有一家网站上线了我们的产品,马上就会有很多相同行业的网站主导找到我们接入产品,这也反映了我们的产品确实解决了验证码长期的痛点。
我们在后期也会继续提升技术实力,优化体验,为业界奉献更安全、更便捷、更智慧的验证。
主持人:技术架构是怎样的?用到了哪些技术呢?
黄胜蓝:简单明了的一张图,左半边是提供验证服务的集群,右半边是存储和分析日志的集群。用到的技术都是业界主流的方案,但是为了更加稳定高效承载数万的验证请求并发,我们在一些地方做了修改。
主持人:极验验证采用基于协程的并发方案以及独特的缓存方案,可高效稳定承载每天数十亿次请求,能详细介绍一下该方案么?
黄胜蓝:我们在不断优化优化服务性能的过程中有三个最大的敌人:
第一个就是并发本身所带来的开销即新开处理线程、关闭处理线程、多个处理线程时间片轮转所带来的开销。
实际上对于一些逻辑不那么复杂的场景来说这些开销甚至比真正的处理逻辑部分代码的开销更大。所以我们决定采用基于协程的并发方式,即服务进程只有一个(单cpu)所有的请求数据都由这个服务进程内部来维护,同时服务进程自行调度不同请求的处理顺序,这样避免了传统多线程并发方式新建、销毁以及系统调度处理线程的开销。基于这样的考虑我们选择了基于Tornado框架实现api服务的开发。Tornado的实现非常简洁明了,使用python的生成器作为协程,利用IOLoop实现了调度队列。
第二个问题是数据库的性能,这里说的数据库包括MongoDB和Redis,我这里分开讲。
先讲MongoDB的问题,MongoDB主要存储不同的用户对于验证的不同设置,比如该显示什么样的图片。
一开始每次验证请求都会查询MongoDB,当时我们的MongoDB是纯内存的,同时三台机器组成一个复制集,这样的组合大概能稳定承载八九千的qps,后来随着我们验证量越来越大,这个承载能力逐渐就成为了我们的瓶颈。
为了彻底搞定这个问题,我们提出了最极端的解决方案,干脆直接把数据库中的数据完全缓存到服务进程里定期批量更新,这样查询的开销将大大降低。但是因为我们用的是Python,由于GIL的存在,在8核服务器上会fork出来8个服务进程,进程之间不像线程那么方便,所以我们基于mmap自己写了一套伙伴算法构建了一个跨进程共享缓存。自从这套缓存上线之后,Mongodb的负载几乎变成了零。
说完了MongoDB再说Redis的问题,Redis代码简洁、数据结构丰富、性能强大,唯一的问题是作为一个单进程程序,终究性能是有上限的。
虽然今年Redis发布了官方的集群版本,但是经过我们的测试,认为这套分布式方案的故障恢复时间不够优秀并且运维成本较高。在Redis官方集群方案面世之前,开源世界有不少proxy方案,比如Twtter的TwemProxy和豌豆荚的Codis。这两种方案测试完之后给我们的感觉TwemProxy运维还是比较麻烦,Codis使用起来让人非常心旷神怡,无论是修改配置还是扩容都可以在配置页面上完成,并且性能也还算不错,但无奈当时Codis还有比较严重的BUG只能放弃之。
几乎尝试过各种方案之后,我们还是下决心自己实现一套分布式方案,目的是高度贴合我们的需求并且运维成本要低、扩容要方便、故障切换要快最重要的是数据冗余一定要做好。
基于上面的考虑,我们确定基于客户端的分布式方案,通过zookeeper来同步状态保证高可用。具体来说,我们修改Redis源码,使其向zookeeper注册,客户端由zookeeper上获取Redis服务器集群信息并根据统一的一致性哈希算法来计算数据应该存储在哪台Redis上,并在哈希环的下一台Redis上写入一份冗余数据,当读取原始数据失败时可以立即尝试读取冗余数据而不会造成服务中断。
第三个问题是Python语言的性能问题,这个后面说。
主持人:您带领团队构建了&行为式验证&安全模型,能谈一下在这个过程中遇到了哪些困难以及大致的经历吗?(包括团队管理、技术攻坚等方面)
黄胜蓝:从产品第一版DEMO开发出来到现在我们遇到了数不清的问题,现在回头看可以大致分为三个阶段。
第一个阶段是在主要解决性能问题,最早DEMO是用PHP和MYSQL写出来的,每次验证的临时数据也会写入MySQL,可以说整套服务也就只能小范围玩一玩了。随后的几个月时间,我们围绕着提升性能对整套服务不断进行优化,最后形成了用Python语言,Tornado作为框架,Redis存储验证临时数据,MongoDB作为数据库的架构。
第二个阶段是解决数据统计与分析的问题,搞定了服务的性能问题之后,用户慢慢多了起来,相应产生的日志也就越来越多。根据日志准确快速统计相关数据、实时监控行为分布以及试验安全模型所需要大量计算能力的问题又出现在我们面前。为了解决这样的问题,我们用建立起自己的运算集群,由Flume收集日志,Spark与Storm分别进行批处理与流处理,HDFS永久存储,Ceph临时存储,Mesos进行调度。
第三个阶段是我们对于数据与模型的理解,在提供验证服务的同时我们也在不断根据收集到的数据来更新我们的模型使得验证更加安全,破解更加困难。
而在这个过程中最大的困难在于我们对于我们对于模型与特征的理解。机器学习的算法做的都是一件事情即根据训练样本在特征空间中寻找一个分类面来分割空间,然后利用这个分类面预测新样本。不同的方法采用不同的数学模型来构建这个分类面,不同数学模型有着不同的表达能力,绘制出来的分类面形状和特性就会不同,而如何在选择合适的模型或者合适的模型组合训练准确、有泛化性分类器就需要对数据有着深入的理解。
团队的管理方面我们也在不断探索如何构建一套科学合理的考核评价体系,从而使得项目按时完成的同时保持团队的激情与探索欲望。这方面等会大家可以多多交流。
主持人:请结合实际情况,谈谈Python的多种形式优化。
黄胜蓝:Python这个语言确实有点让人又爱又恨,Python的语法、Python无比成熟的生态环境都是Python的优点。可以说对于一个互联网公司Python几乎可以满足所有的业务需求,从web到自动化运维工具再到数据分析和机器学习,Python都可以搞定。但是Python的问题也很明显,也就是它的性能问题。
好在现在Python世界也涌现出来了适用各种各样情况下的性能优化手段,我在这里结合我们遇到的实际情况简单介绍几个我们用到的。
1)使用C编写Python扩展或者使用Cython。这两种方式我们都有采用,也是业界比较常用的优化Python性能的方式。这里面主要说一下Cython,优化程序性能的本质实际上是在平衡程序员时间和机器运算时间的成本,而利用Cython则可以非常灵活地寻找这中间的平衡。Cython可以使用介于Python和C之间的语法,当语法更接近Python时获得的性能提升也就越少,而语法越接近于C时,性能也更加接近C。
2)使用pypy。这是一个支持jit的Python解释器,其官方测试结果比较好看,就我们实际测试结果来看它的性能优势不是很稳定,大部分项目是领先的但是有的项目又会莫名其妙的很慢。并且它对于C的扩展支持不佳。
3)使用Numba。对于数据分析、机器学习有过了解的人一定会听说过Numpy,Numba就是专门用来优化基于Numpy程序的工具。利用它可以只加入一行代码就将性能提升数倍,而缺点就是这种方式不能作为通用的优化手段,并且Numba虽然使用起来比较简单,但其依赖相对复杂,部署起来会有点麻烦。
主持人:数据分析方面,请您谈一谈如何利用gpu加速数据分析。
黄胜蓝:很多人可能会觉得gpu编程是一件很困难的事情,其实当真正接触了之后就会了解到让你的程序在gpu上运行其实并不难,真正的难点在于理解gpu的特性从而将最合适的任务交给gpu来做,同时采用合适的优化手段。
以我们为例,我们利用PyOpenCl将日志中用户的验证行为进行特征计算。计算流程中上下文的创建、任务队列的创建以及缓冲区的控制都通过Python来控制,kernel部分由C写。
这里面相对麻烦一点的是缓冲区的问题,因为cpu和gpu是两套独立的内存,数据要拷贝才能进行计算,这部分代码PyOpenCl封装的比较好,借用了NumPy的数据类型,操作起来会比用C写方便很多。
其中最核心部分是kernel,也就是将会运行在GPU上的代码,其实这部分代码的编写也不需要掌握什么特殊技能,我们的做法就是几乎移植了在CPU上的版本,只是在GPU上多条数据同时一起计算而已。
所以就像前面说的,找到合适的任务用gpu进行计算其实并不是一件很困难的事情。那么什么样的任务比较适合gpu上进行计算呢?我简单归纳一下就是任务逻辑相对简单(因为第一kernel要用C写,太复杂的逻辑写起来还是有点麻烦。第二优化和调试起来相对麻烦),重复性高的任务。比如排序、统计、查找、过滤、简单的预处理等等。
主持人:深度学习技术方案的选择方面,有哪些思考?
黄胜蓝:深度学习是目前机器学习领域最大的热门,也是互联网巨头们争相角逐的战场。对于中小企业而言,虽然可能没有实力聘请顶尖的研发人员、没有能力获取顶尖的运算能力但是这并不意味着一定会无缘深度学习所带来的变革。
目前开源的深度学习框架非常多,利用这些开源的深度学习库可以非常方便的构建一个神经网络并进行实验。
Python也为我们提供了探索深度学习世界非常有用的工具,我们使用了两个东西,一个是Theano,另一个叫做Kares。
Theano是一个数学表达式编译器,对于普通程序员来说可能会对这个概念很奇怪,实际上很简单,它可以把一系列数学表达式以及相应的符号链接编译成可执行代码,而这个可执行代码还不仅仅是cpu,它同样可以编译出gpu可执行代码。所以基于这样的工具,我们就可以实现从数学表达式自动编译成gpu上的可执行代码,是不是很爽!
再来看Kares,它是一个深度学习库,它将大牛们提出的各种网络结构、激活函数、Cost Function、以及各种Trick做了统一的整理和封装,可以用及其简单的方式将各种方法组合成为一个神经网络进行实验,这个库的底层是基于Theano的,也就是利用Theano将表达式编译成了gpu代码,所以当你真正想去做深度学习的实验时你就会发现用这些工具其实可以非常非常快就构建一个实验项目。
当然,不是有了这些工具就意味着探索深度学习的道路会一帆风顺。理论方面,不仅要透彻了解神经网络背后的数学模型,更要紧跟业界动态,不断学习最新的理论与技巧;实践方面,训练出一个优秀的网络往往需要大量的试验,尝试不同的网络结构、trick与超参数,复杂的网络往往需要更大量的数据来反向传播更新权值,这些意味着对于运算能力、数据存储能力都是极大的考验。
探索深度学习的前提是一定要有一支高水平、全方面的团队!
主持人:如今互联网时代给各行各业带来了巨大的变革,同时也加剧了行业从业者浮躁的心态,该如何沉下心来做事,并不断提升技术能力?
黄胜蓝:的确,这两年行情比较火爆,行业对于技术人员的需求持续高涨,待遇也是水涨船高。带来的结果就是很多技术人员在这样环境下变得浮躁起来,不再深究代码的优化、常常把新技术挂在嘴边却不甚了解、哪些技术待遇高就学什么技术等等。
我认为作为技术人员一定要在互联网浪潮中保持危机感和广阔的技术视野。危机感可以督促自己不迷失在眼前取得的成绩而是继续努力力争上游。广阔的技术视野可以让你更加清楚认识到业界遇到了哪些问题,又是开发了哪些项目提出了哪些方法来解决这些问题的。看清楚了业界发展的方向就可以避免在提升技术能力的道路上走弯路。
主持人:请结合你的切身体会谈谈创业路上您都有哪些收获和思考,对于如今越来越多想要投身创业大海的年轻人,有什么建议?
黄胜蓝:创业是九死一生的事情,首先也确定是否有能力承受可能的失败,这个是最大的前提。第二就是选好方向,创业做一件事情的时候一定要保证你是这行里面对这个行业了解最深的,否则做出来的东西一定没什么意义。
主持人:推荐一些觉得非常不错的资料或者书籍吧。
黄胜蓝:推荐一些比较基础的吧学习Python建议可以看看《Python核心编程》这本书,讲的比较细致。有兴趣了解深度学习的话可以看看UFLDL,很经典的一个教程&
互动环节:&跟用户做一个小小的游戏,在游戏中通过行为来判断用户是正常用户还是恶意的程序请求&这里提的恶意程序的行为,能说一下吗?
黄胜蓝:我们的验证是利用一个拼图游戏来收集用户的行为,正常人类的行为由于受到肌肉结构、鼠标等等限制会符合一些特征,而攻击者在模拟行为时则很难完全模拟。我们通过这样的原理来区分正常用户还是程序。
互动环节:您好,谢谢分享。 我想请教一下,Python与PHP这两种语言相比,Python的主要优势是什么?对电商行业应用而言,您对技术选型的建议是什么?谢谢。
黄胜蓝:php是世界上最好的语言。&比较这两门语言,我们不谈论语言本身的优劣,因为这些仁者见仁智者见智。&
我从另一个方面讲一下我的理解,Python的社区整体用户层次相对较高,涉及的领域非常全面。而PHP的社区基本还局限在web开发方向。对于电商行业而言,最开始可能实现web逻辑也就够了,但是规模起来之后要做推荐系统、反欺诈系统的时候PHP就完全不能满足要求了。用Python的话则永远跟得上需求,各种问题都能搞定。
互动环节:您好,能说说做为一个cto,第一公司工作职责,第二如何能像bat这样的大公司技术看齐,谢谢。
黄胜蓝:cto这个职位可能在不同的公司职责都不太一样,甚至在一家创业公司不同时期都会发生很大的变化。团队小时候可能需要引领技术方向,大一点之后就要做好技术管理。&
第二个问题,像bat看齐我觉得毫无必要,业务不同规模不同。
互动环节:首先感谢黄总的分享& 看到黄总用了很多开源技术 大家知道现在谷歌的技术还有推特的技术可能要翻墙 黄总有没有好的翻墙工具 可以推荐。
黄胜蓝:翻墙工具我们一般用shadowsocks。
互动环节:我想请教一下,您用python做过什么有趣的项目来提高对高并发或是python的熟练度?我现在可以使用python实现一些简单的脚本,不知道现在我应该哪些方面来提高自己对python的认识和熟练?
黄胜蓝:我用python做的最有趣的项目就是写了极验验证的后台代码。对python的理解和认识其实多看看书就行了,更重要的是了解python的重量级项目。如果做数据挖掘就一定要熟悉numpy、scipy这样的项目。
互动环节:贵公司的产品我好像也用过 尤其是拖拽式模式感觉挺好!想提问下 验证一旦出问题玩不了& 对客户网站的整个业务流程影响很大& 会终止在那儿 请问是如何保证高可用的?& 比如有没有多区域部署。
黄胜蓝:高可用方面我们的有多区部署。同时我们也考虑到验证所处的关键地位,在我们的sdk中也包含了服务异常处理流程,会切换成一个本地版验证,保证正常用户不受影响。
互动环节:你们的验证码能更好的识别机器和人吗?可以简单说说你们判断机器和人的机制吗?
黄胜蓝:我们的验证是利用一个拼图游戏来收集用户的行为,正常人类的行为由于受到肌肉结构、鼠标等等限制会符合一些特征,而攻击者在模拟行为时则很难完全模拟。我们通过这样的原理来区分正常用户还是程序。
互动环节:tornado我们也有在用,作为游戏的login服务器时,有个问题,协程这种协作式工作流程会使得一次用户请求在yield之后,被其它协程占用cpu,最后导致该请求处理时间变长。这种场景你们有处理吗?
黄胜蓝:以前遇到过这样的问题。这样的问题一般是代码逻辑中存在阻塞时间较长的部分,如果是io或者网络导致的阻塞可以通过换成异步驱动搞定。如果是某些代码长期占用cpu计算,可以考虑把这部分代码通过celery或者其他任务队列扔给其他机器去处理。&
还有一种情况是,即使用了异步驱动,后端数据库处理不过来这么多请求导致挂起的协程越来越多,最后大量出现超时或者错误。
来源:CSDN
转载请注明: &
or分享 (0)

我要回帖

 

随机推荐