plainify

【译】数据库是如何分片的?

本文翻译自 How does database sharding work?,如有疑问,请联系译者 了解什么是数据库分片,分片如何工作的,以及一些常见的分片框架和工具。 如果你使用过 Google 或 YouTube,那么你很可能已经访问过分片数据。分片通过将数据分区存储在多个服务器上,而不是将所有内容放在一个巨大的服务器上,以实现扩展数据库的目的。这篇文章将介绍数据库分片的工作原理、思考如何给你自己的数据库分片,以及其他一些有用的、可以提供帮助的工具,尤其是针对 MySQL 和 Postgres。 分片是扩展关系数据库的重要方式 试想以下场景:本季度你第三次扩大了 MySQL 版本 RDS 的实例规模,而 CFO 刚刚在会上上花了 30 分钟来“讨论预算”。也许是时候横向扩展而不是纵向扩展了! [1] RDS 中的读取副本似乎很简单,但读取数据只是问题的一半。一个心力憔悴的开发者该怎么办? 分片——这个术语可能最初来自视频游戏——一种扩展关系数据库的方式。你可能以前看过这张表格,这张表描述的是如何通过横向扩展来帮助你处理存储在单个服务器上的用户表: user_id first_name last_name email … ZpaDr20TTD4ZL7Wma Peter Gibbons peter@initech.net … bI32htQ1PsEQioC7G Bill Lumbergh bill@initech.net … 99J3x257SGP7J4IkF Milton Waddams stapler@initech.net … 0SH0pyi9bO5RM4I03 Lawrence two@onetime.com … … … … … 并将其转换为存储在 2 个(或 1,000 个)服务器上的用户表:...

plainify

【译】如何创建一个可复用的网页爬虫

原文地址:How to Create a Reusable Web Scraper 网页爬虫是个非常有趣的玩具。不过不好玩的是,我们需要根据不同网页上的元素不断的调整自己的代码。这就是为什么我要着手实现一个更好的网页爬虫项目——通过该项目可以以最少的更改实现对新网页的爬取。 第一步是将网页爬虫按照逻辑分成每个独立的部分: 页面请求器 页面验证器 模板页面处理器 页面请求器 页面请求器的实现有一些技巧。下载网页时要考虑很多因素。你需要确保你可以随机的使用用户代理,并且不要过于频繁地从同一域中请求。 此外,停下手头的工作去分析为什么网页无法下载是一件出力不讨好的事。尤其是当你的爬虫已经在多个站点运行了好几个小时的情况下。因此,我们会处理一些请求,并将它们保存为文件。 将请求保存到文件中还有另外一个好处。你不必担心一个标签的消失会影响到你的爬虫。如果页面处理器是独立的,并且你已经完成了页面的下载,你还可以根据需要快速且频繁的对其进行处理。如果发现有另一个要抓取的数据元素怎么办?别担心。只需添加一个标签,然后在你已下载的页面上重新运行处理器即可。 以下是一些实际情况下的示例代码: import requests import pickle from random import randint from urllib.parse import urlparse def _random_ua(): ua_list = ["user agent1, user agent2", "user agent3"] random_num = randint(0, len(ua_list)) return ua_list[random_num] def _headers(): return { 'user-agent': _random_ua() } def _save_page(response): uri = urlparse(response.url) filename = uri.netloc + ".pickle" with open(filename, 'wb+') as pickle_file: pickle....

plainify

【译】一种有关艺术风格迁移的神经网络算法

在艺术领域, 尤其是绘画创作上, 人们已经掌握了一种可以创造独一无二视觉体验的能力, 那就是通过将一张图片的内容和风格之间构成某种复杂的关系。 到目前为止, 该过程的算法基础是未知的, 并且不存在具有类似能力的人工系统。 然而, 受到一种名为深度神经网络的视觉模型的启发, 在视觉感知的其他关键领域, 例如物体和人脸识别, 仿生学的效果已经可以接近人类的表现。 这里我们将会介绍一个基于深度神经网络的人工系统, 它可以生成具有高感知品质的艺术图片。 该系统使用神经表示来分离和重组任意图像的内容和风格, 提供了一种创建艺术图像的神经算法。 而且, 按照要去表现最优的人工神经网络和生物视觉中找到相同. 我们的工作提供了人类是怎样创作和认知艺术图像的算法理解。 此外, 鉴于性能优化的人工神经网络与生物视觉之间惊人的相似性, 我们的工作为算法理解人类如何创造和感知艺术形象提供了一条前进的道路。 处理图像任务最有效的深度神经网络是卷积神经网络。 卷积神经网络由小型计算单元层组成, 以前馈方式分层处理视觉信息(图 1)。 每层单元可以理解为图像过滤器的集合(a collection of image filters), 每个图像过滤器从输入图像中提取特定特征。 因此, 一个给定层的输出包括所谓的特征映射(feature maps): 它们是对输入的图像进行不同类型的过滤得到的。 当卷积神经网络被训练用于物体识别时, 会生成一个图像的表征(representations) , 随着处理层级的上升, 物体的信息越来越明确。 因此, 随着神经网络中的层级一级一级地被处理, 输入的图像会被转换成一种表征, 与图片的像素细节相比, 这种表征会越来越关注图片的实际内容。 通过对某一层的提取出来的 feaure map 的重塑, 我们可以直接看到该层包含的图片信息。 层级越高, 那么获取的图像中物体内容就越高质量, 并且没有确切的像素值的约束(层级越高, 像素丢失越多)。 相反, 在低层级中重塑的话, 其实像素丢失地很少。 所以我们参考的是神经网络高层的特征, 用它来作为图片内容的表征。 为了获取输入图像的风格表征, 我们用一个特征空间去捕获纹理的信息。 这个特征空间建立在每层神经网络的过滤响应之上(也就是上面提到的 feature map)。 在 feature map 的空间范围上(也就是同一层上的 feature map), 过滤响应各有不同(feature map 关注的特征不同), 而这个特征空间就是由这些差异构成。 通过对每一层 featute map 两两求相关性, 我们会获得一个静态的, 多尺度的图像表征, 这也就捕获到了图像的纹理信息, 但这纹理信息并非全局的。...

【译】Effective TensorFlow Chapter13——在TensorFlow中利用learn API构建神经网络框架

本文翻译自: 《Building a neural network training framework with learn API》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 为了简单起见, 在之前的大多数示例中, 我们都是手动创建一个会话(session), 并不关心保存和加载检查点, 但在实践中通常不是这样做的。 在这我推荐你使用 learn API 来进行会话管理和日志记录(session management and logging)。 我们使用 TensorFlow 提供了一个简单而实用的框架来训练神经网络。 在这一节中, 我们将解释这个框架是如何工作的。 当利用神经网络训练模型进行实验时, 通常需要分割训练集和测试集。 你需要利用训练集训练你的模型, 并在测试集中计算一些指标来评估模型的好坏。 你还需要将模型参数存储为一个检查点(checkpoint), 因为你需要可以随时停止并重启训练过程。 TensorFlow 的 learn API 旨在简化这项工作, 使我们能够专注于开发实际模型。 使用 tf.learn API 的最简单的方式是直接使用 tf.Estimator 对象。 你需要定义一个模型函数, 该模型函数包含一个损失函数(loss function)、 一个训练操作(train op)、 一个或一组预测, 以及一组可选的用于评估的度量操作: import tensorflow as tf def model_fn(features, labels, mode, params): predictions = ....

【译】Effective TensorFlow Chapter12——TensorFlow中的数值稳定性

本文翻译自: 《Numerical stability in TensorFlow》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 当使用任何数值计算库(如 NumPy 或 TensorFlow)时, 值得注意的是, 编写出正确的数学计算代码对于计算出正确结果并不是必须的。 你同样需要确保整个计算过程是稳定的。 让我们从一个例子入手。 小学的时候我们就知道, 对于任意一个非 0 的数 x, 都有 x*y/y=x 。 但是让我们在实践中看看是否如此: import numpy as np x = np.float32(1) y = np.float32(1e-50) # y would be stored as zero z = x * y / y print(z) # prints nan 错误的原因是: y 是 float32 类型的数字, 所能表示的数值太小。 当 y 太大时会出现类似的问题: y = np.float32(1e39) # y would be stored as inf z = x * y / y print(z) # prints 0 float32 类型可以表示的最小正值是 1....

【译】Effective TensorFlow Chapter11——在TensorFlow中调试模型

本文翻译自: 《Debugging TensorFlow models》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 与常规 python 代码相比, TensorFlow 的符号特性使的 TensorFlow 的代码调试变得相对困难。 这里我介绍一些 TensorFlow 附带的工具, 使调试更容易。 使用 TensorFlow 时最常见的错误可能是传递形状错误的张量。 许多 TensorFlow 操作可以在不同秩(rank)和形状(shape)的张量上操作。 这在使用 API 时很方便, 但在出现问题时可能会导致额外的麻烦。 例如, 考虑下面这个 tf.matmul 操作, 它可以使两个矩阵相乘: a = tf.random_uniform([2, 3]) b = tf.random_uniform([3, 4]) c = tf.matmul(a, b) # c is a tensor of shape [2, 4] 但是下面这个函数也可以实现矩阵乘法: a = tf.random_uniform([10, 2, 3]) b = tf.random_uniform([10, 3, 4]) tf....

【译】Effective TensorFlow Chapter10——在TensorFlow中利用多GPU处理并行数据

本文翻译自: 《Multi-GPU processing with data parallelism》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 如果你使用类似 C++这样的语言在单核 CPU 上编写你的软件, 为使其能够在多个 GPU 上并行运行, 你可能需要从头开始重写你的软件。 但是在 TensorFlow 中并非如此。 由于其符号性质, tensorflow 可以隐藏所有这些复杂的过程, 使你无需在多个 CPU 和 GPU 上扩展程序。 让我们从在 CPU 上添加两个向量开始: import tensorflow as tf with tf.device(tf.DeviceSpec(device_type="CPU", device_index=0)): a = tf.random_uniform([1000, 100]) b = tf.random_uniform([1000, 100]) c = a + b tf.Session().run(c) 同样的事情在 GPU 上也可以简单地完成: with tf.device(tf.DeviceSpec(device_type="GPU", device_index=0)): a = tf.random_uniform([1000, 100]) b = tf.random_uniform([1000, 100]) c = a + b 但是, 如果我们有两个 GPU 并希望同时使用它们呢? 为此, 我们可以把数据分成两份, 并让每个 GPU 单独处理一个部分:...

【译】Effective TensorFlow Chapter9——使用Python ops进行原型内核和高级可视化

本文翻译自: 《Prototyping kernels and advanced visualization with Python ops》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 TensorFlow 中的内核操作完全用 C ++编写, 以提高效率。 但是用 C++编写 TensorFlow 内核的话可能会非常痛苦。 因此, 在花费数小时实现属于自己的内核之前, 你也许需要先实现一个操作的原型, 尽管这样的效率会很低。 通过 tf.py_func() 你可以将任何一个 python 源代码转换为 TensorFlow 的操作。 举个例子而言, 这里有一个用 python 自己实现的 ReLU 非线性激活函数, 通过 tf.py_func() 转换为 TensorFlow 操作的例子: import numpy as np import tensorflow as tf import uuid def relu(inputs): # Define the op in python def _relu(x): return np.maximum(x, 0....

【译】Effective TensorFlow Chapter8——控制流操作: 条件和循环

本文翻译自: 《Control flow operations: conditionals and loops》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 当我们在构建一个复杂模型如 RNN(循环神经网络)的时候, 你可能需要通过条件和循环来控制操作流程。 在这一节, 我们介绍一些在 TensorFlow 中常用的控制流。 假设我们现在需要通过一个条件判断来决定我们是否相加还是相乘两个变量。 这个可以通过调用 tf.cond() 简单实现, 它表现出像 python 中 if...else... 相似的功能。 a = tf.constant(1) b = tf.constant(2) p = tf.constant(True) x = tf.cond(p, lambda: a + b, lambda: a * b) print(tf.Session().run(x)) 因为这个条件判断为 True, 所以这个输出应该是加法输出, 也就是输出 3。 在使用 TensorFlow 的过程中, 大部分时间你都会使用大型的张量, 并且在一个批次(a batch)中进行操作。 一个与之相关的条件操作符是 tf.where() , 它需要提供一个条件判断, 就和 tf.cond() 一样, 但是 tf....

【译】Effective TensorFlow Chapter7——理解执行顺序和控制依赖

本文翻译自: 《Understanding order of execution and control dependencies》, 如有侵权请联系删除, 仅限于学术交流, 请勿商用。 如有谬误, 请联系指出。 正如我们刚开始提到的, TensorFlow 不会立刻运行定义了的操作, 而是在计算图中创造一个相关的节点, 这个节点可以用 Session.run() 进行执行。 这个使得 TensorFlow 可以在运行时进行优化, 以此确定最佳执行顺序, 并且在运算中剔除一些不需要使用的节点。 如果你只是在计算图中使用 tf.Tensors , 你就不需要担心依赖问题, 但是你更可能会使用 tf.Variable() , 这个操作使得问题变得更加困难。 我的建议是如果张量不能满足这个工作需求, 那么仅仅使用 Variables 就足够了。 这个可能不够直观, 我们不妨先观察一个例子: import tensorflow as tf a = tf.constant(1) b = tf.constant(2) a = a + b tf.Session().run(a) 正如我们期待的那样, “a”的计算结果是 3。 注意下, 我们创建了 3 个张量, 其中包含两个常数张量和一个储存加法结果的张量。 务必注意我们不能重写一个张量的值, 如果我们想要改变张量的值, 我们就必须要创建一个新的张量, 就像我们刚才做的那样。...