TowardsDataScience 博客中文翻译 2016~2018(一百二十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

马尔可夫决策过程入门:强化学习

原文:https://towardsdatascience.com/getting-started-with-markov-decision-processes-reinforcement-learning-ada7b4572ffb?source=collection_archive---------2-----------------------

第二部分:解释 马尔可夫决策过程、 贝尔曼方程和政策的概念

在这篇博文中,我将解释理解如何解决强化学习问题所需的概念。这一系列的博客文章包含了大卫·西尔弗在关于强化学习的介绍中解释的概念总结。

零件:1234

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

到目前为止,我们已经在很高的层次上学习了设置强化学习问题所需的组件。现在,我们将更详细地正式描述强化学习的环境。在本帖中,我们将看看一个完全可观测的 环境以及如何将环境正式描述为 马尔可夫决策过程 (MDPs)。

如果我们能解决马尔可夫决策过程,那么我们就能解决一大堆强化学习问题。

MDPs 需要满足 马尔可夫性质

马尔可夫性质: 要求“未来独立于过去给定的现在”。

性质 :麟州 Sₜ 是马氏当且仅当:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

简单地说,这意味着状态 Sₜ 从历史中获取所有相关信息。 S₁,S₂,…,Sₜ₋₁ 可以丢弃,我们仍然得到相同的 状态转移概率 到下一个状态 Sₜ₊₁

状态转移概率 : 状态转移概率告诉我们,给定我们处于状态 s 下一个状态s’会发生的概率是多少。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

P without the double lines represents the state transitions. The above equation has the transition from state s to state s’. P with the double lines represents the probability from going from state s to s’.

我们也可以根据一个状态转移矩阵 P 来定义所有的状态转移,其中每一行都告诉我们从一个状态到所有可能的后续状态的转移概率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

State transition matrix.

马尔可夫过程/马尔可夫链

第一个也是最简单的 MDP 是一个 马尔可夫过程

马尔可夫过程/马尔可夫链 : 具有马尔可夫性质的随机状态序列 S₁、S₂、…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是一个马尔可夫链的图示,其中每个节点代表一个状态,有可能从一个状态转移到下一个状态,其中 Stop 代表一个终止状态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Markov Chain

我们可以拿一个 样本 集来遍历这个链,最后到达终点状态。一个示例情节是从阶段 1阶段 2赢得到*停止。*以下是几个样本集的代表:

  • *S1 S2 赢停
  • S1 S2 瞬移 S2 赢停
  • S1 暂停 S1 S2 赢停*

上述马尔可夫链具有以下转移概率矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于每个状态,该状态的转移概率之和等于 1。

马尔可夫奖励过程

在上面的马尔可夫链中,我们没有与达到目标的状态相关联的值。一个 马尔可夫奖励过程 是一个带有奖励值的马尔可夫链。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的目标是最大化 回报 。回报 Gₜ 是从时步 t 开始的总折扣奖励。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Equation to calculate return

折现因子 γ 是介于 0 和 1 之间的一个值(可以选择)。如果γ接近 0,则导致近视评估,而接近 1 的值有利于远视评估。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Markov Reward Process

:由于在马尔可夫奖励过程中我们没有采取行动,Gₜ是通过遍历随机样本序列来计算的。

MRP 的价值函数

状态值函数 v(s) :给出状态 s 的长期值。它是从状态 s 开始的预期收益

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

state-value function

我们可以这样看,从状态 s 开始,通过状态 s 的各种样本,我们的预期收益是多少。我们更喜欢给予更多总回报的州。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

state-values for MRP with γ=1

MRPs 的贝尔曼方程

价值函数可以分解为两部分:

  • 即时奖励: Rₜ₊₁
  • 继承国贴现值:γ(sₜ₊₁*)*

我们可以使用上面的状态值函数和返回函数定义一个新的等式来计算状态值函数:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

updated bellman state-value equation

或者,这可以写成矩阵形式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用这个等式,我们可以计算每个状态的状态值。由于我们在上面有一个简单的模型,带有γ=1 的 MRP 的*“状态值”*,我们可以使用一个联立方程,使用更新的状态值函数来计算状态值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于较小的 MRPs,求解上面的方程很简单,但是对于较大的数目,就变得非常复杂。为了解决大型 MRP,我们需要其他技术,如动态规划蒙特卡洛评估时差学习,这些将在后面的博客中讨论。

马尔可夫决策过程

一个 马尔可夫决策过程 是一个马尔可夫回报过程的扩展,因为它包含了一个代理必须做出的决策。环境中的所有状态都是马尔可夫的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在马尔可夫决策过程中,我们现在对进入哪个状态有了更多的控制。在下面的 MDP 的例子中,如果我们选择进行传送动作,我们将在 40%的时间里回到状态阶段 2 中,在 60%的时间里回到状态阶段 1 中。当选择相应的动作时,其他状态转换以 100%的概率发生,例如采取动作前进 2阶段 2 将把我们带到胜利。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

政策

一个策略 π 是给定状态下动作的分布。它完全定义了一个代理的行为。MDP 政策取决于现状,而不是历史。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Policy function

策略给出了从一个状态到下一个状态的映射。如果我在状态 s,它从那个状态映射出采取每一个行动的概率。示例如果我们有策略 π(杂务|阶段 1)=100%,这意味着代理将在处于状态阶段 1 时采取动作杂务 100%

MDP 的价值函数

因为我们采取行动,所以根据我们的行为会有不同的期望。

MDP 的 状态值函数v _π(s)是从状态 s 开始,然后遵循策略π的期望收益。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

状态值函数告诉我们通过遵循策略 π 处于状态 s 有多好。

动作值函数 q_π(s,a) 是从状态 s 开始,采取动作 a ,然后跟随策略 π的期望收益。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

行动价值函数告诉我们从特定状态采取特定行动有多好。让我们知道我们应该在各州采取什么行动

贝尔曼期望方程

价值函数也可以以 的形式写成贝尔曼期望方程 如下:

状态值函数:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

动作值功能:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最优值函数

在上述所有等式中,我们使用给定的策略来遵循,这可能不是要采取的最佳行动。强化学习的关键目标是找到能使我们的回报最大化的最优策略。

最优状态值函数v∫(s)是所有策略的最大值函数。它告诉我们你能从系统中获得的最大回报。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最优动作值函数q∫(s,a) 是所有策略上的最大动作值函数。它告诉我们,从状态 s 开始并采取行动 a 时,你能从系统中获得的最大回报是什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你知道q∫,那么你就知道在 MDP 中应该采取的正确行动和最佳表现,从而解决 MDP 问题。

q∑(s,a)表示采取哪些行动来获得最佳表现。

寻找最佳策略

通过最大化超过q∫(s,a) 可以找到最优策略:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

贝尔曼最优方程 是非线性的,很难求解。在后面的博客中,我将讨论使用各种技术来解决这个方程的迭代解决方案,例如值迭代、策略迭代、Q-LearningSarsa。

参考

如果你喜欢这篇文章,并想看到更多,不要忘记关注和/或留下掌声。

mlFlow 入门

原文:https://towardsdatascience.com/getting-started-with-mlflow-52eff8c09c61?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

什么是 mlFlow?

mlFlow 是一个支持机器学习生命周期的框架。这意味着它具有在训练和运行期间监控模型的组件,能够存储模型,在生产代码中加载模型并创建管道。

该框架引入了 3 个不同的特性,每个特性都有自己的功能。

物流跟踪

跟踪可能是该框架最有趣的特性。它允许您围绕您的模型创建一个广泛的日志框架。您可以定义自定义指标,以便在运行后可以将输出与之前的运行进行比较。

我们将主要关注这一部分,但也给你一窥其他功能。

MlFlow 项目

此功能允许您根据需要创建管线。该特性使用自己的模板来定义您希望如何在云环境中运行模型。由于大多数公司都有在生产中运行代码的方法,所以您可能对这个特性不太感兴趣。

ml 流程模型

最后,我们有模型功能。mlFlow 模型是包装机器学习模型的标准格式,可用于各种下游工具,例如,通过 REST API 或 Apache Spark 上的批处理推理进行实时服务。

理论完成:是时候开始了

理论总是好的,但现在是时候采取更实际的方法了。首先,在我们真正开始之前,我们需要启动一个 mlFlow 服务器。为了正确地做到这一点,我创建了一个 docker 容器以便于部署。

在展示代码之前,配置存储后端也很重要。因为我们希望我们的模型存储在某个地方,所以我选择了 Azure blob 存储(请注意,AWS S3 也是受支持的)。

所以创建一个 blob 存储帐户,并在里面创建一个容器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Blob storage account Azure

一旦它被创建,你将需要写下 wasb 链接,因为你将需要这个值来启动 docker。url 通常定义如下:“wabss://@<storage_account_name>. blob . core . windows . net”</storage_account_name>

接下来,我们可以开始构建 docker。因为 mlFlow 需要 python,所以我从 python 图像开始,让我的生活变得简单了一些。基本上,只要确保 Python 在容器中可用,就可以从任何图像开始。对于本例,您只需安装以下两个软件包:

  • mlflow 版本 0.8.0
  • azure 存储 0.36.0

完整的 docker 解决方案只需看看我的 Github 账户:【https://github.com/Ycallaer/mlflowdocker

接下来你需要构建容器,如果你不知道怎么做,看看自述文件。

一旦您在本地机器上启动了 docker 映像,它应该可以通过以下 url 获得: http://localhost:5000/

如果一切顺利,你的主页可能会像这样。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Homepage mlFlow

调整模型以使用 mlFlow

一旦服务器部分准备好了,是时候修改我们的代码了。我创建了一个小的 ARIMA 模型实现来展示这个框架。

在开始之前,我们需要定义运行服务器的 URL。您可以通过调用方法“set_tracking_uri”来实现这一点。这已经为这个演示进行了硬编码,但理想情况下,这将指向一个公共端点。

接下来,我们需要创建一个实验。这应该是一个唯一的标识符。确保它唯一的一种方法是在每次调用实验方法时生成一个 uuid。在我的例子中,我硬编码它以加速演示。

通过调用“start_run()”方法,我们告诉 mlFlow 这是运行的起点,这将为您的运行设置开始日期。不要忘记将实验 id 传递给方法,这样所有的日志记录都保留在实验中。

省略实验 id 将导致所有日志被写入默认实验。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Start point mlFlow Tracking

接下来,我们需要指定在运行过程中要监控的值。一方面,您有“log_param()”,它为字符串值记录一个键值对。另一方面,我们有“log_metric()”,它只允许您将值定义为整数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example of log_param and log_metric

视觉效果

现在让我们回到 UI,看看我们运行的视觉结果是什么。在主页上,你会发现你的实验列在左侧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Homepage with experiment

如果你点击日期,你会看到那次跑步的概况。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Detailed info of an experiment

在指标旁边,您会看到一个图形符号,如果您单击它,您可以看到在运行过程中该指标是如何变化的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Detailed graph of a metric

保存模型

我们还希望能够使用框架保存模型。该框架允许您以与大多数流行框架兼容的格式加载和保存模型(例如:Scikit、Pytorch、Tensorflow 等)。完整的名单请看这里的。

将模型保存为工件的代码相当简单:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example of log_model call in mlFlow

拟合的结果将作为第一个参数传递给函数,第二部分是目录。如果您导航到 UI 并单击 run,您将在页面底部找到工件信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Model saved on Azure from mlFlow

如果你是偏执狂类型的,你现在可以看看 blob 存储帐户,以验证模型确实被保存了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Model on blob store

不错吧?如果你愿意,你可以看看加载特性,然后开始围绕这个模型构建应用程序。

用于该演示的完整回购可以在 Github 上找到。

问题

我发现这个框架更大的问题是,所有的日志都只存储在 docker 容器中,即使你已经定义了一个存储后端。这意味着,如果您重新启动容器,您的所有记录都将丢失。我记录了一个问题(https://github.com/mlflow/mlflow/issues/613),得到的回应是当前团队正在重新设计日志功能。所以祈祷吧。

OpenAI 健身房入门

原文:https://towardsdatascience.com/getting-started-with-openai-gym-932c7311d26c?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

OpenAI 健身房环境是了解更多机器学习的最有趣的方式之一。特别是强化学习和神经网络可以完美地应用到基准和雅达利游戏集合中。每个环境都有多种特色解决方案,并且您经常可以找到关于如何获得相同分数的文章。通过观察别人的方法和想法,你可以以一种有趣的方式快速提高自己。我注意到开始健身有点困难。虽然网上有很多算法教程,但第一步是理解你正在工作的编程环境。为了让新人更容易适应这个环境,我决定用 docker 容器和 jupyter 笔记本制作一个小教程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你需要什么

开始之前,安装 Docker 。Docker 是一个让你在电脑上运行虚拟机的工具。我创建了一个“图像”,其中包含了几个你想要的东西:tensorflow、健身房环境、numpy、opencv 和一些其他有用的工具。

安装 docker 后,运行以下命令下载我准备好的 Docker 映像:

docker run -p 8888:8888 rmeertens/tensorflowgym

在浏览器中,导航到:localhost:8888,并打开 TRADR 文件夹中的 OpenAI Universe 笔记本。

自己玩个游戏

让我们从自己玩翻筋斗游戏开始。你控制一个上面有杆子的酒吧。“游戏”的目标是尽可能长时间地保持横杠直立。在这个游戏中,你可以做两个动作:向左用力,或者向右用力。要手动玩这个游戏,请执行代码的第一部分。

通过左右点击你施加一个力,你会看到新的状态。请注意,我将游戏编程为当您“丢失”游戏时自动重置。

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt

from ipywidgets import widgets
from IPython.display import display

import gym

from matplotlib import animation
from JSAnimation.IPython_display import display_animation

def leftclicked(something):
    """ Apply a force to the left of the cart"""
    onclick(0)

def rightclicked(something):
    """ Apply a force to the right of the cart"""
    onclick(1)

def display_buttons():
    """ Display the buttons you can use to apply a force to the cart """
    left = widgets.Button(description="<")
    right = widgets.Button(description=">")
    display(left, right)

    left.on_click(leftclicked)
    right.on_click(rightclicked)

# Create the environment and display the initial state
env = gym.make('CartPole-v0')
observation = env.reset()
firstframe = env.render(mode = 'rgb_array')
fig,ax = plt.subplots()
im = ax.imshow(firstframe) 

# Show the buttons to control the cart
display_buttons()

# Function that defines what happens when you click one of the buttons
frames = []
def onclick(action):
    global frames
    observation, reward, done, info = env.step(action)
    frame = env.render(mode = 'rgb_array')
    im.set_data(frame)
    frames.append(frame)
    if done:
        env.reset()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重播

既然你已经玩过了,你可能想看重播。我们保存了游戏的每一次按钮点击状态,你可以在你的浏览器中显示出来:

def display_frames_as_gif(frames, filename_gif = None):
    """
    Displays a list of frames as a gif, with controls
    """
    plt.figure(figsize=(frames[0].shape[1] / 72.0, frames[0].shape[0] / 72.0), dpi = 72)
    patch = plt.imshow(frames[0])
    plt.axis('off')

    def animate(i):
        patch.set_data(frames[i])

    anim = animation.FuncAnimation(plt.gcf(), animate, frames = len(frames), interval=50)
    if filename_gif: 
        anim.save(filename_gif, writer = 'imagemagick', fps=20)
    display(display_animation(anim, default_mode='loop'))

display_frames_as_gif(frames, filename_gif="manualplay.gif")

表现

OpenAI 网站上描述了弹球环境。观察参数中的值显示位置(x)、速度(x_dot)、角度(theta)和角速度(theta_dot)。如果杆的角度超过 15 度,或者手推车从中心移动超过 2.4 个单位,游戏“结束”。然后可以通过调用 env.reset()来重置环境。

开始学习

如果没有简单的“学习”机制,这篇博文将是不完整的。凯文·弗朗斯写了一篇关于简单算法的博文,你可以应用在这个问题上:【http://kvfrans.com/simple-algoritms-for-solving-cartpole/

实现起来最简单的就是他的随机搜索算法。通过将参数与观察参数相乘,推车决定向左或向右施力。现在的问题是:什么是最好的参数?随机搜索随机定义它们,查看购物车在这些参数下可以持续多长时间,并记住找到的最佳参数。

def run_episode(env, parameters):  
    """Runs the env for a certain amount of steps with the given parameters. Returns the reward obtained"""
    observation = env.reset()
    totalreward = 0
    for _ in xrange(200):
        action = 0 if np.matmul(parameters,observation) < 0 else 1
        observation, reward, done, info = env.step(action)
        totalreward += reward
        if done:
            break
    return totalreward

# Random search: try random parameters between -1 and 1, see how long the game lasts with those parameters
bestparams = None  
bestreward = 0  
for _ in xrange(10000):  
    parameters = np.random.rand(4) * 2 - 1
    reward = run_episode(env,parameters)
    if reward > bestreward:
        bestreward = reward
        bestparams = parameters
        # considered solved if the agent lasts 200 timesteps
        if reward == 200:
            break

def show_episode(env, parameters):  
    """ Records the frames of the environment obtained using the given parameters... Returns RGB frames"""
    observation = env.reset()
    firstframe = env.render(mode = 'rgb_array')
    frames = [firstframe]

    for _ in xrange(200):
        action = 0 if np.matmul(parameters,observation) < 0 else 1
        observation, reward, done, info = env.step(action)
        frame = env.render(mode = 'rgb_array')
        frames.append(frame)
        if done:
            break
    return frames

frames = show_episode(env, bestparams)
display_frames_as_gif(frames, filename_gif="bestresultrandom.gif")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

练习以了解更多关于 OpenAI 健身房的信息

接下来就是自己玩自己学了。以下是一些建议:

  • 继续凯文·弗兰斯的教程:http://kvfrans.com/simple-algoritms-for-solving-cartpole/
  • 上传并分享您的结果。比较随机算法的效果,或者你自己实现的算法与其他人相比的效果。如何做到这一点可以在这个页面找到:【https://gym.openai.com/docs#recording-and-uploading-results】T2 标题下的“记录和上传结果”
  • 看看其他环境:【https://gym.openai.com/envs】T4。如果你能解决 cartpole 环境,你当然也能解决钟摆问题(注意,你必须调整你的算法,因为这个只有 3 个变量在观察中)。

结论

恭喜你!你在开放的健身房里制作了你的第一个自动平衡杆。既然这样做了,是时候要么改进你的算法,要么开始尝试不同的环境了。这个 Jupyter 笔记本跳过了很多关于你实际在做什么的基础知识,在 OpenAI 网站上有一篇关于这个的很棒的文章。

下一步

除非你决定把自己的算法作为练习,否则你不会在本教程中做很多机器学习(我不认为寻找随机参数是“学习”)。请看看:

感谢

这篇博客是我的 TRADR summerschool 关于在强化学习算法中使用人类输入的研讨会的第一部分。更多信息可以在他们的主页上找到。

OpenAI 健身房入门

原文:https://towardsdatascience.com/getting-started-with-openai-gym-d2ac911f5cbc?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

OpenAI gym 是一个开发和测试学习代理的环境。它是集中的,最适合强化学习代理,但不限制人们尝试其他方法,如硬编码游戏求解器/其他深度学习方法。

我为什么要使用 OpenAI 健身房环境?

  1. 你想学习强化学习算法——有各种各样的环境供你使用和尝试不同的强化学习算法。
  2. 你对学习代理有一个新的想法,并想测试一下——这个环境最适合在模拟中尝试新的算法,并与现有的算法进行比较。
  3. 想要在我们不想在现实中建模的情况下训练代理-深度学习需要大量的正面和负面的训练示例,并且很难提供这样的示例,例如训练自动驾驶汽车了解事故,自动驾驶汽车知道事故会发生什么以及如何发生是很重要的,并且在现实世界中建模既昂贵又有风险。模拟可以帮助我们。
  4. 将学习-做活动的速度提高 10 倍,在模拟中更好还是在现实生活中更好?当然是模拟,在这里我们的代理可以学得更快。

设置

开放式健身房很容易设置

要求

  1. Python 3.5±我还没试过用 Python 2.7 安装。请随时尝试,并让我知道你所面临的问题。
  2. 无论是从源代码安装还是直接安装,都需要 pip- pip。

安装

  1. 使用 pip 安装

pip 安装健身房

2.从源安装

git 克隆https://github.com/openai/gym&&CD 馆

pip 安装-e。

示例

首先,进口健身房

进口健身房

创造试验环境

env = gym.make('MountainCar-v0 ')

等等,这是什么环境?健身房就是在这种环境下的这种互动。

有大量的环境供我们玩——到目前为止,有 797 个环境。使用下面的代码片段找出所有

随机代理

请在此处找到源代码

在上述示例中,我们使用了以下环境 APIs

  1. action_space: 该状态下的一组有效动作
  2. 步骤:采取指定的行动并返回从环境中收集的更新信息,如观察奖励、是否达到目标以及对调试有用的其他信息

观察针对环境;例如,在山地车中,它将返回速度,速度是建立动量以实现目标所需要的。在某些情况下,它将是原始像素数据。

奖励是上一次行动获得的金额。默认情况下,目标是报酬最大化(当然!)

搞定这个真的很有用。这告诉我们什么时候完成,代理人什么时候达到目标。

当出错时,它会发出有用的调试信息,你必须弄清楚代理到底在做什么。

现在,我们的上述随机代理只是为了实现目标一次。在训练其他深度学习算法时,添加外部循环,就像历元数一样。在这里,人们把时代称为插曲。

基本模板

持续 n 次
而目标未实现
take _ action()
take _ step()
结束而
结束

阅读更多并参考

OpenCV 入门:在 Windows +图像混合上安装 OpenCV

原文:https://towardsdatascience.com/getting-started-with-opencv-installing-opencv-on-windows-using-anaconda-6d88d02f141f?source=collection_archive---------14-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Author-generated.

这个简短的教程包括以下说明:

  • 为 Windows 安装 Anaconda
  • 安装 Jupyter 笔记本、OpenCV 和其他软件包
  • 使用 OpenCV 实现图像混合

1.下载和设置 Anaconda

Anaconda 发行版的主要好处是它使得软件包的安装和维护变得方便快捷;此外,它还包含了 150 多个自动安装的软件包。

在继续学习本教程之前,请确保您的系统具备以下条件,以便确认可以安装 Anaconda 发行版:Windows、macOS 或 Linux x86 或 POWER8,32 位或 64 位,3GB HD 可用。

导航到 https://www.anaconda.com/download/的,点击 Windows 选项,下载 Windows 的 Python 3.6 版本。如果您有 64 位计算机,请单击 64 位图形安装程序(631 MB);如果您有 32 位计算机,请单击 32 位图形安装程序。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Screenshot from https://www.anaconda.com/download/

打开。然后在“欢迎使用 Anaconda3”GUI 上单击 Next 继续安装。同意许可协议,选择您的首选安装类型(推荐“仅我”选项),并选择您的目标文件夹。我建议使用“C:\Users\User_Name\Anaconda3”目录路径,因为它使其他包/库更容易访问 Anaconda,也更容易被 Anaconda 访问。因此,在“高级选项”页面上,将 Anaconda 注册为您的默认 Python 3.6 这一步假设您之前没有在系统上安装 Python。现在,您将能够在您的系统上安装 Anaconda。

2.安装所需的软件包(包括 Jupyter 笔记本和 OpenCV)

安装 Anaconda 之后,在您的系统上搜索并打开 Anaconda 提示符。

您需要创建一个环境,在这个环境中您可以安装必要的包并使用 OpenCV。您可以通过在 Anaconda 提示符下输入以下命令来实现这一点;您可以用自己选择的环境名替换 env :

conda create -n env pip python=3.6

在这一步之后,Anaconda 提示符将显示一组需要下载、解压缩和安装的包;要继续安装,请按键盘上的 y 键。

然后,您需要通过键入以下内容来激活环境:

conda activate env

每次您想要使用为本教程安装的包,包括 Jupyter Notebook 和 OpenCV,您都需要使用上面的命令激活环境。

在本教程中,我将使用 Jupyter Notebook,这是一个开源的 web 应用程序,它允许用户创建包含实时代码和可视化效果的文档,还有许多其他好处。如果您愿意,也可以使用 Spyder IDE 或您选择的 IDE 来运行本教程的代码。

您需要使用以下命令安装 Jupyter Notebook:

pip install jupyter notebook

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Author

您还需要使用以下命令安装 matplotlib(这是一个常用的 Python 绘图库):

pip install matplotlib

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Author

现在,让我们安装 OpenCV,它代表开源计算机视觉库;该库的目的是支持实时计算机视觉应用。我们可以使用以下命令来执行安装:

pip install opencv-python

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Here, I’m installing the OpenCV library release 3.4.2.17. Source: Author

请注意,如果您希望能够通过 OpenCV 操作/使用 JPEGs(专门用于图像混合任务),您将需要安装 Pillow 库,它使我们能够通过使用以下命令打开、操作和保存许多不同的图像文件格式:

pip install pillow

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Author

初步测试:熟悉 Jupyter 笔记本电脑

您可以在默认的 web 浏览器中打开 Jupyter Notebook,方法是在 Anaconda 提示符下输入以下命令:

jupyter notebook

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Author

在您的笔记本仪表盘(打开笔记本的 web 浏览器)中,单击“新建”按钮并选择一个 Python 3 笔记本。注意:如果你想看到完整的代码和结果,你可以访问这个链接:https://github . com/riacheruvu/DemystifyMLCode/blob/master/OpenCV _ Example/OpenCV _ Example . ipynb。您还可以下载位于https://github.com/riacheruvu/DemystifyMLCode的这个博客的主存储库的 zip 文件,提取 zip 文件的内容,导航到 OpenCV_Example 文件夹,然后上传。ipynb 文件和图像到 Jupyter 笔记本上,以便跟踪和运行代码。

如果您使用的是新的 Python 3 笔记本:您可以通过在笔记本中的一个“代码单元”或空框中输入print("Hello, world")5+5来测试安装是否正常进行,然后单击 Run 按钮。如果你以前用 Python 编程过,你会注意到你可以得到一个等式的输出,比如 5+5,而不需要使用 print()语句。如果你想了解更多,请看 Jupyter 笔记本文档(https://jupyter-notebook.readthedocs.io/en/stable/)。

为了快速测试是否安装了 numpy 包,在其中一个单元格中键入以下内容,以创建一个 numpy 数组,将其分配给一个变量,并打印变量的类型:

import numpy as npa = np.array([0, 1, 2])print(type(a))

a的类型应该是<class‘numpy . ndarray’>。

OpenCV 入门:混合图像

为了开始并测试 OpenCV 是否已经正确安装,让我们实现图像混合,这涉及到对图像执行算术运算,并允许我们执行时间交叉融合,类似于电影、摄影幻灯片等中流行的特殊效果。

首先我们需要导入所需的包;在 Python 中,注释通过#符号后跟文本来描述。

import numpy as npimport cv2%matplotlib inline#Comment: The purpose of the above line is to display matplotlib plots inlineimport matplotlib.pyplot as pltimport matplotlib.image as mpimg

如果在这一步出现任何问题,请返回并检查您是否正确安装了软件包。如果你对软件包安装有任何疑问,请在下面的评论中分享。

接下来,从互联网上下载两张您选择的图像(您可以使用。JPG 或者。本教程图像的 PNG 文件格式)。对于这个例子,我使用的是以下照片,分别由 Josiah WeissUnsplashGül KurtaranUnsplash 拍摄。您可以下载。JPG 图片文件在下面提供的链接,或者右键单击这篇文章中的图片,并保存它们。确保将图片放在与您正在处理的笔记本文件相同的目录中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Josiah Weiss on Unsplash

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Gül Kurtaran on Unsplash

下载完图片后,下一步就是从文件名中读取图片。对于这一步,我们将使用 matplotlib 的 image.imread 函数,该函数将图像从文件读入 Numpy 数组,如该函数的文档中所述(【https://matplotlib.org/api/image_api.html】)。从每个图像输出的阵列需要具有相同的大小/尺寸;否则,我们将收到一条错误消息,指出:

error: OpenCV(3.4.2) C:\projects\opencv-python\opencv\modules\core\src\arithm.cpp:659: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'cv::arithm_op'

我们可以通过使用 cv2.resize 命令将两个图像的高度和宽度调整为(300,300)来避免这个错误;如果您愿意尝试,可以更改高度和宽度的值。接下来,使用 matplotlib,我们可以绘制图像,给它一个标题,并在笔记本中显示它。

img_water = mpimg.imread(‘photo.jpg’)resized = cv2.resize(img_water, (300, 300))plt.imshow(resized)plt.title(‘Image’)plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

img_horse = mpimg.imread(‘photo2.jpg’)resized2 = cv2.resize(img_horse, (300, 300))plt.imshow(resized2)plt.title(‘Image’)plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

OpenCV 让我们能够使用 cv2.addWeighted 函数轻松地混合这些图像(类似于图像相加),该函数对图像应用以下等式,如 OpenCV 3.0.0-dev 文档中的“图像算术运算”一文所述:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 cv2.addWeighted 函数的下一行代码中,每个图像名称后面的数字是权重(在上面的等式中定义),它可以在 0 到 1 之间变化,以混合图像并使它们更透明/不透明。例如,下面我对水的图像使用了 0.5 的权重,对骑马的女人的图像使用了 0.6 的权重。作为一个快速练习,尝试用 addWeighted 代码行的权重来观察交叉叠化的变化。代码行末尾的附加 0 表示 gamma 或,出于本教程的目的,我们将把它设置为零。

blend = cv2.addWeighted(resized,0.5,resized2,0.6,0)plt.imshow(blend)plt.title(‘Blended Image’)plt.show()

显示混合图像会产生以下令人惊叹的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本教程到此结束;感谢您的阅读!如果你有任何反馈或问题,请在下面的评论中分享。

原载于 2018 年 8 月 30 日demystifymachinelearning.wordpress.com

Python 环境入门(使用 Conda)

原文:https://towardsdatascience.com/getting-started-with-python-environments-using-conda-32e9f2779307?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无论你想要一个还是不知道它是什么,你最终都必须用 Python 来处理
环境。如果你像我一样是 Python 的新手
或者是为任何编程语言设置工作空间的新手,那么你可能已经第一次经历了设置环境的痛苦。

我不知道自己在做什么,也不知道为什么有必要这么做,许多不同的在线指南可能没有完全相同的说明,还有许多帮助解决特定情况的堆栈溢出帖子,我发现很难理解到底什么是环境,什么时候需要它们,以及如何设置自己的环境。本指南旨在帮助建立对环境的直觉,并提供一些处理环境的例子,特别是使用 Anaconda 的包管理器 conda

你的代码是你的环境的产物

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Python 和很多其他编程语言一样,有不同的版本。有时,当我们创建软件时,软件需要在特定版本的语言上运行,因为我们的软件期望在旧版本中出现某种行为,但在新版本中会发生变化。同样,出于类似的原因,我们可能需要使用特定版本的库。但是我们的电脑上可能有很多项目,可能是一个运行在 0.11 版本上的 Flask 应用(你做的第一个!)和 Python 2.7 甚至更现代的 Flask app,运行在版本 0.12 和 Python 3.4 上。如果我尝试在 Python 2Python 3 上同时运行两个,其中一个可能会中断,因为在 Python 2 上运行的一些代码在 Python 3 上不能运行,反之亦然。这就是虚拟环境变得有用的地方。

虚拟环境将这些依赖关系保存在单独的“沙箱”中,因此您可以在两个应用程序之间轻松切换,并让它们运行。对于那些更熟悉编程的人来说,虚拟环境类似于 Docker 容器。此外,其他语言的包管理器,比如 JavaScript 的 NPM ( 节点包管理器),会帮你处理大部分细节,但是你必须亲自动手处理 Python 的环境。

创建你玩的沙盒

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建环境有多种方式,包括使用 virtualenv、venv(内置于 Python 3 标准库中)和 conda,
Anaconda 关联的包管理器。关于你为什么应该选择 conda 而不是 virtualenv 有一些争论,正如这篇博客文章中的神话#5 所概述的,但我将在本指南中重点关注如何使用 conda ,因为它是数据科学的一个流行工具,这也是我现在关注的重点。
本指南假设您已经安装了 Anacondaminiconda;所有的指令都在 bash 命令行上。
作为参考,我在 Mac OS X 的终端上运行我的命令。

要使用 conda 快速创建环境,您可以键入以下命令:

conda create --name your_env_name python=3.7 -y

在这个命令中,‘python = 3.7’部分指定了我想要在哪个版本的 python
中设置环境;您可以根据自己的需要更改版本。在你在网上看到的其他片段中,你可能会看到’ -n ‘而不是’-name’;它们的意思完全一样。’ -y '标志实际上是告诉命令行对随后出现的所有提示说“是”;这不是绝对必要的,但它确实为您节省了一点麻烦。

conda create --name your_env_name python=3.7 scipy=0.15.0 astroid babel

命令将有效地一次加载所有的包,这比一次加载一个包要好,因为这会导致依赖冲突。所以你可以手动添加所有你需要的包,但是如果你有很多包,这可能会很乏味;
除此之外,在命令行
上会有大量的输入,手指滑动可能会导致你重新输入命令。更糟糕的是,该命令可能不会保留在您的 shell 历史中,如果您想要在将来重新创建完全相同的环境,即使不困难,也会非常繁琐。

如果出于这些或其他原因,您不想从命令行创建环境,您可以创建一个 YAML (YAML 不是标记语言)文件,它的作用就像一个配置文件。你的 YAML 文件可能是这样的:

name: your_env_name
channels:
 — defaults
dependencies:
 — ca-certificates=2018.03.07=0
prefix: /Users/your_username/anaconda3/envs/your_env_name

如果该文件名为’ environment.yml’ ,那么我可以使用下面的命令创建环境:

conda env create -f environment.yml

-f 标志代表文件, YAML 文件的文件名
应该紧跟在“ -f 标志之后。

如果你能很容易地创建一个 YAML 文件,并且知道你需要的所有包,那就太好了。但是,如果您有一个想要复制的现有环境,该怎么办呢?也许您希望将应用程序复制到另一台服务器上,并希望有完全相同的设置来保持一致性。如果是这种情况,那么您可以运行下面的命令。

conda env export > my_environment.yml

大于号“>”表示输出正在将
写入名为“ my_environment.yml ”的文件。如果在此命令之前’ my_environment.yml’ 中有任何内容
,它们将被覆盖。

注意,对于 conda 你需要一个 YAML 文件;如果你决定使用 virtualenv
一个 txt 文件也能满足这里所做的一切,但是 conda 特别需要一个 YAML 文件。

掌控您的环境

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在您已经创建了一个环境,并假设您正在使用 conda,让我们使用以下命令快速验证它是否存在:

conda info --envs

该命令应该显示当前环境,可能如下所示:

practice /Users/your_username/anaconda3/envs/practice
base /Users/your_username/anaconda3
your_env_name /Users/your_username/anaconda3/envs/your_env_name

在确认您创建了环境之后,您现在可以实际使用它了。我们可以通过键入以下命令来实现这一点(假设您的环境在您的基础之下):

conda activate your_env_name

此时,您的终端提示符应该如下所示:

(your_env_name) Your_Machine:your_directory username$

如果该命令由于某种原因没有产生类似的输出,
您可以通过键入类似以下命令的内容来指定完整路径:

conda activate /Users/your_username/anaconda3/envs/your_env_name

如果像我一样,您想知道当您键入单词“activate”时会发生什么,它会运行一个 bash 脚本,该脚本存在于环境的一个子目录中。在我的例子中,脚本的文件路径看起来像这样:

/Users/my_username/anaconda3/envs/my_env_name/lib/python3.6/venv/scripts/common/activate

要停止使用环境,请键入

conda deactivate

与 activate 命令类似,deactivate 命令运行 activate bash 脚本中的一个函数。

如果您想要更新环境,请键入:

conda env update –f environment.yml –n your_env_name

如果您想摆脱整个环境,只需键入:

conda remove --name your_env_name --all

—所有”标志用于从环境中移除所有软件包,并且
是彻底清洁环境所必需的。

结论

作为一个快速总结,本指南介绍了如何通过在命令行以及从 YAML 文件中指定包来创建您的虚拟环境,如何进入和退出虚拟环境,如何更新它,以及如何在您不再需要它时将其删除。

在这一点上,您应该知道足够的信息来独立地配置您认为合适的环境,并且有足够的背景来解释为什么您应该创建一个虚拟环境。虽然本指南没有深入探讨 virtualenvvenvconda 虚拟环境之间的区别,但我在下面提供了几个链接让你开始。

请让我知道,如果你有任何问题或建议如何做得更好。

https://jakevdp . github . io/blog/2016/08/25/conda-myths-and-misconcepts/
https://real python . com/python-virtual-environments-a-primer/
https://medium . freecodecamp . org/why-you-need-python-environments-and-how-to-management-them-with-conda-85f 155 f 4353 c【中

开始使用 Python 进行数据分析

原文:https://towardsdatascience.com/getting-started-with-python-for-data-analysis-64d6f6c256b2?source=collection_archive---------4-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此文最初出现在blog.zakjost.com

最近有个朋友问了这个问题,我觉得在这里发表可能会对别人有好处。这是给刚接触 Python 的人的,他们想要从 0 到 1 的最简单的路径。

  1. 下载 Python 3。适用于您的操作系统的 x 版 Anaconda 发行版此处为。通过选择这个预捆绑的发行版,您将避免许多与安装相关的麻烦。它附带了大多数预先安装的重要数据分析软件包。
  2. 一旦你安装了它,测试以确保默认的 python 解释器就是你刚刚安装的那个。这一点很重要,因为您的系统可能已经安装了 Python 版本,但是它不具备 Anaconda 捆绑包中的所有优点,所以您需要确保新版本是默认版本。在苹果/Linux 上,这可能意味着在终端上输入which python。或者您可以运行 Python 解释器,确保版本与您下载的内容相匹配。如果一切顺利,应该通过安装来完成。如果没有,你需要在这里停下来修理它。
  3. 在你的外壳中发出jupyter notebook命令。这将打开一个浏览器窗口。如果没有,打开浏览器,导航到[http://localhost:8888](http://localhost:8888)。一到那里,就创建一个新的 Python 笔记本。
  4. 转至www.kaggle.com果仁部分,过滤至 Python 果仁。这些大多是其他人在数据集上进行分析或建模的 jupyter 笔记本,可在 Kaggle 的网站上免费获取。寻找像 EDA(探索性数据分析)这样的标题,而不是那些构建预测模型的标题。找到一个有趣的,并开始在你的笔记本中重新创建它。

注意:您会发现当您尝试重新创建这些分析时,您会得到导入错误。这可能是因为他们安装了 Anaconda 发行版中没有捆绑的包。你最终需要学习如何与 conda 包管理器交互,这将是你最终会陷入的许多兔子洞之一。通常就像conda install <package_name>一样简单,但是你需要找到正确的包名,有时你需要指定其他细节。其他时候你需要使用pip install <other_package_name>,但是你会在以后学到这些。

高级库摘要

这里有一个您将经常与之交互的重要库的快速总结。

  • NumPy:拥有许多科学计算的核心功能。在引擎盖下调用 C 编译的代码,所以比用 Python 写的相同函数要快得多。不是最用户友好的。
  • SciPy:类似于 NumPy,但是有更多的方法从分布中取样,计算测试统计…等等。
  • MatPlotLib:主绘图框架。不可避免的邪恶。
  • Seaborn:在 MatPlotLib 之后导入它,默认情况下它会让你的绘图漂亮很多。也有自己的功能,但我发现最酷的东西运行太慢。
  • 熊猫:主要是一个薄薄的包装,让用户更加友好。非常适合与数据表交互,他们称之为数据框架。也有关于绘图功能的包装器,以支持快速绘图,同时避免 MPL 的复杂性。我最喜欢用熊猫来处理数据。
  • Scikit-learn:有很多监督和非监督的机器学习算法。也有许多用于模型选择的度量标准和一个很好的预处理库,用于像主成分分析或编码分类变量这样的事情。

快速提示

  1. 在 jupyter 笔记本中,在运行单元格之前,在任何对象前面打一个问号,它将打开该对象的文档。当你忘记了你试图调用的函数期望你传递的细节时,这真的很方便。例如,?my_dataframe.apply将解释pandas.DataFrame对象的apply方法,这里用my_dataframe表示。
  2. 你可能总是需要参考你正在使用的库的文档,所以只要在你的浏览器中打开它。有太多可选的论点和细微差别。
  3. 当谈到不可避免的故障排除任务时,s tackoverflow 可能有答案。
  4. 接受这样一个事实,你会做一些你暂时还不完全理解的事情,否则你会被那些不重要的细节所困扰。有一天,你可能需要了解虚拟环境,这真的不是很难,但有许多类似的弯路会给初学者增加不必要的痛苦。
  5. 看别人的代码。这是学习惯例和最佳实践的最佳方式。这就是 Kaggle 内核真正发挥作用的地方。GitHub 还支持在浏览器中显示 jupyter 笔记本,因此互联网上有大量的例子。

PyTorch 入门第 1 部分:了解自动微分的工作原理

原文:https://towardsdatascience.com/getting-started-with-pytorch-part-1-understanding-how-automatic-differentiation-works-5008282073ec?source=collection_archive---------1-----------------------

更新:这个帖子是 2018 年初写回来的。PyTorch 已经走过了漫长的道路,更新版本的帖子可以在这里找到。

当我开始编写神经网络代码时,我最终使用了我周围所有人都在使用的东西。张量流。

但是最近,PyTorch 已经成为深度学习框架之王的主要竞争者。真正吸引人的是它的动态计算图范例。如果最后一行对你来说没有意义,也不要担心。在这篇文章的结尾,它会的。但请相信我的话,它使调试神经网络的方式更容易。

If you’re wondering why your energy has been low lately, switch to PyTorch!

先决条件

在我们开始之前,我必须指出,你至少应该有这样的基本概念:

  • 与神经网络训练相关的概念,特别是反向传播和梯度下降。
  • 应用链式法则计算导数。
  • Python 中类的工作原理。(或者关于面向对象编程的一般概念)

如果你错过了以上任何一个,我在文章的最后提供了链接来指导你。

所以,是时候开始使用 PyTorch 了。这是 PyTorch 系列教程的第一篇。

这是第 1 部分,我将描述基本的构建模块,以及亲笔签名的

****注意:需要注意的一点是,本教程是为 PyTorch 0.3 及更低版本制作的。提供的最新版本是 0.4。我决定坚持使用 0.3,因为到目前为止,0.3 是在 Conda 和 pip 渠道中发布的版本。此外,开源中使用的大部分 PyTorch 代码还没有更新到包含 0.4 中提出的一些更改。然而,我会指出,在某些地方,事情在 0.3 和 0.4 不同。

积木#1:张量

如果你曾经用 python 做过机器学习,你很可能遇到过 NumPy。我们使用 Numpy 的原因是因为它在做矩阵运算时比 Python 列表快得多。为什么?因为它完成了 c 语言中的大部分繁重工作。

但是,在训练深度神经网络的情况下,NumPy 阵列根本不能满足它。我懒得在这里做实际的计算(Google for“FLOPS in a iteration of ResNet to get a idea”),但是仅使用 NumPy 数组的代码就需要几个月的时间来训练一些最先进的网络。

这就是张量**发挥作用的地方。PyTorch 为我们提供了一种叫做张量的数据结构,与 NumPy 的 ndarray 非常相似。但与后者不同的是,张量可以利用 GPU 的资源来显著加快矩阵运算的速度。

这是你做张量的方法。

In [1]: import torch In [2]: import numpy as npIn [3]: arr = np.random.randn((3,5))In [4]: arr
Out[4]:array([[-1.00034281, -0.07042071,  0.81870386],
       [-0.86401346, -1.4290267 , -1.12398822],
       [-1.14619856,  0.39963316, -1.11038695],
       [ 0.00215314,  0.68790149, -0.55967659]])In [5]: tens = torch.from_numpy(arr)In [6]: tens
Out[6]:

-1.0003 -0.0704  0.8187
-0.8640 -1.4290 -1.1240
-1.1462  0.3996 -1.1104
0.0022  0.6879 -0.5597
[torch.DoubleTensor of size 4x3]In [7]: another_tensor = torch.LongTensor([[2,4],[5,6]])In [7]: another_tensor
Out[13]:  2  4
 5  6
[torch.LongTensor of size 2x2]In [8]: random_tensor = torch.randn((4,3))In [9]: random_tensor
Out[9]:1.0070 -0.6404  1.2707
-0.7767  0.1075  0.4539
-0.1782 -0.0091 -1.0463
 0.4164 -1.1172 -0.2888
[torch.FloatTensor of size 4x3]

构建模块#2:计算图

现在,我们在商业方面的事情。当训练神经网络时,我们需要计算损失函数相对于每个权重和偏差的梯度,然后使用梯度下降来更新这些权重。

随着神经网络达到数十亿个权重,高效地执行上述步骤可以决定训练的可行性。

构建模块#2.1:计算图表

计算图是现代深度学习网络工作方式的核心,PyTorch 也不例外。让我们先了解一下它们是什么。

假设,你的模型是这样描述的:

*b = w1 * a
c = w2 * a 
d = (w3 * b) + (w4 * c)
L = f(d)*

如果我真的画出计算图,它可能会像这样。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Computation Graph for our Model

现在,你必须注意到,上图并不完全是 PyTorch 在引擎盖下的图表的准确表示。然而,就目前而言,这足以证明我们的观点。

当我们可以顺序执行计算输出所需的操作时,为什么要创建这样的图形呢?

想象一下,如果你不仅要计算输出,还要训练网络,会发生什么。你必须计算所有紫色节点标记的权重的梯度。这将需要你找到自己的方式,然后更新权重。

计算图是一种简单的数据结构,允许您有效地应用链规则来计算所有参数的梯度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Applying the chain rule using computation graphs

这里有一些需要注意的事情。首先,图中箭头的方向现在颠倒了。那是因为我们是反向传播,箭头标记的是梯度反向流动。

第二,为了这些例子,你可以把我写的渐变想象成边缘权重。注意,这些梯度不需要计算链式法则。

现在,为了计算任意节点的梯度,比如 L,相对于任意其他节点,比如 c ( dL / dc) 我们要做的就是。

  1. 追踪从 L 到 c 的路径。这将是L→d→c**
  2. 沿着这条路径遍历时,将所有的边权重相乘。你最终得到的数量是:(*dL/DD)*(DD/DC)=(dL/DC)***
  3. 如果有多条路径,将它们的结果相加。例如,在 dL/da 的情况下,我们有两条路径。 L → d → c → a 和 L→d→b→a我们将它们的贡献相加得到L w r t a的梯度

(dL/DD)(*DD/DC)(DC/da)】+[(dL/DD)(*DD/db)(db/da)】

原则上,可以从 L 开始,开始向后遍历图形,计算沿途每个节点的梯度。

构建块#3:变量和亲笔签名

PyTorch 使用亲笔签名的包完成了我们上面描述的任务。**

现在,关于亲笔签名的是如何工作的,基本上有三件重要的事情需要理解。**

构建模块#3.1:变量

****变量,就像张量一样,是一个用来保存数据的类。然而,它的不同之处在于它的使用方式。 变量专门用于保存在神经网络训练期间变化的值,即我们网络的可学习参数。另一方面,张量用于存储不需要学习的值。例如,张量可用于存储每个示例产生的损失值。

**from torch.autograd import Variablevar_ex = Variable(torch.randn((4,3))   #creating a Variable**

一个变量类包装了一个张量。你可以通过调用 来访问这个张量。数据变量的属性。**

**变量也存储标量(比如说损耗)相对于它所保存的参数的梯度。这个渐变可以通过调用 来访问。grad 属性。这基本上是直到这个特定节点计算的梯度,并且每个后续节点的梯度可以通过将边权重乘以在它之前的节点计算的梯度来计算。

一个变量持有的第三个属性是一个 grad_fn ,一个函数对象,它创建了这个变量。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注: PyTorch 0.4 将变量和张量类合二为一,张量可以通过一个开关做成一个“变量”而不是实例化一个新的对象。但是既然,我们在本教程中做的是 v 0.3,我们就继续吧。

构建模块#3.2:功能

我上面说功能了吗?它基本上是一个函数的抽象。接受输入并返回输出的东西。比如我们有两个变量, ab ,那么如果,**

c = a + b

然后 c 是一个新变量,它的 grad_fn 是一个叫做 AddBackward (PyTorch 内置的两个变量相加的函数)这个函数以 ab 为输入,创建了 c

那么,你可能会问,既然 python 确实提供了定义函数的方法,为什么还需要一个全新的类呢?

训练神经网络时,有两个步骤:前向传递和后向传递。通常,如果您使用 python 函数来实现它,您将必须定义两个函数。一个是计算正向传递期间的输出,另一个是计算要传播的梯度。

PyTorch 将编写两个独立函数(用于向前传递和向后传递)的需求抽象成一个名为torch . autograded . function .的类的两个函数成员

PyTorch 结合了变量函数来创建一个计算图。****

积木#3.3:亲笔签名

现在让我们深入研究 PyTorch 如何创建计算图。首先,我们定义变量。

上面几行代码的结果是,

现在,让我们分析一下刚刚到底发生了什么。如果您查看源代码,事情是这样的。

  • 定义图形的变量(第 5-9 行)。我们从定义一堆“变量”开始(正常的,python 语言的用法,不是 pytorch 变量)。如果您注意到,我们定义的值是我们的计算图中的叶节点。只有我们必须定义它们才有意义,因为这些节点不是任何计算的结果。现在,这些家伙占用了我们 Python 名称空间中的内存。意味着,它们是百分之百真实的。我们必须requires _ grad***属性设置为 True,否则,这些变量将不会包含在计算图形中,并且不会为它们计算任何梯度(以及依赖于这些特定变量进行梯度流的其他变量)。*****
  • 创建图表(第 12-15 行)。到目前为止,我们的记忆中还没有计算图之类的东西。只有叶节点,但是只要您写下第 12–15 行,一个图就会被动态生成。确定这个细节非常重要。在飞行中。*当你写 b =w1a 时,就是图形创建开始的时候,一直持续到第 15 行。当从输入中计算输出时,这正是我们模型的正向传递。每个变量的正向函数可以缓存一些输入值,以便在计算反向传递的梯度时使用。(例如,如果我们的 forward 函数计算出 Wx ,那么 d(Wx)/d(W) 就是 x ,需要缓存的输入)**
  • 现在,我告诉你我之前画的图不准确的原因?因为 PyTorch 做图的时候,并不是变量对象才是图的节点。它是一个函数对象,确切地说,是构成图形节点的每个变量grad_fn 。PyTorch 图应该是这样的。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Each Function is a node in the PyTorch computation graph.

  • 我用名字表示了叶节点,但是它们也有自己的grad _ fn’(返回 None 值。这是有意义的,因为您不能反向传播到叶节点之外)。剩下的节点现在被它们的grad _ fn’所代替,我们看到单个节点 d 被三个函数代替,两个乘法,一个加法,而 loss 被一个函数代替。****
  • 计算梯度(第 18 行)。**我们现在通过调用来计算梯度。 L 上的 backward() 功能。这到底是怎么回事?首先,L 处的梯度就是 1 ( dL / dL )。**然后,我们调用它的向后函数,它的基本工作是计算函数对象的输出到函数对象的输入的梯度。这里 L 是 10 — d 的结果,也就是说,逆向函数会将梯度( dL/dd) 计算为-1。**
  • 现在,这个计算的梯度乘以累积的梯度(存储在当前节点对应的变量grad 属性中,在我们的例子中是 dL/dL = 1 ),然后发送到输入节点,存储在输入节点对应的变量 grad 属性中。**技术上,我们所做的是应用链式法则(dL/dL)(dL/DD)=dL/DD。*
  • 现在,让我们了解梯度是如何传播给变量 d 的。d 是从它的输入(w3,w4,b,c)计算出来的。在我们的图中,它由 3 个节点、2 个乘法和 1 个加法组成。**
  • 首先,函数 AddBackward ( 在我们的图中表示节点 d 的加法运算)计算它的输出( w3b + w4c )相对于它的输入( w3b 和 w4c* )的梯度,这是(两者都是 1)。现在,这些局部梯度乘以累积梯度(两者都是 dL/dd x 1 = -1),结果保存在各自输入节点的 grad 属性中。***
  • 然后,函数 MulBackward ( 代表 w4c 的乘法运算)分别计算其输入输出 w.r.t 到其输入( w4 和 c) a s (cw4) 的梯度。局部梯度乘以累积梯度( dL/d(w4c) = -1)。结果值( -1 x c 和-1 x w4 )然后分别存储在变量* w4cgrad 属性中。***
  • 所有节点的梯度以相似的方式计算。
  • L w.r.t 任何节点的梯度都可以通过调用来访问。 grad 在对应于那个节点的变量上,假设它是一个叶节点 (PyTorch 的默认行为不允许你访问非叶节点的渐变。稍后会有更多相关内容)。现在我们已经得到了梯度,我们可以使用 SGD 或任何你喜欢的优化算法来更新我们的权重。
*w1 = w1 — (learning_rate) * w1.grad    #update the wieghts using GD*

诸如此类。

亲笔签名的一些俏皮细节

所以,我不是告诉过你不能访问非叶子变量grad 属性吗。是啊,这是默认行为。您可以通过调用来重写它。 retain_grad()变量进行定义,然后你就可以访问它的 grad 属性。但是说真的,到底发生了什么事。**

动态计算图

PyTorch 创建了一个叫做的动态计算图*,这意味着这个图是动态生成的。在变量的 forward 函数被调用之前,图中不存在变量的节点(它是 grad_fn)该图是调用多个变量前进功能的结果。只有这样,缓冲区才会分配给图形和中间值(用于以后计算梯度)。当您调用 backward() 时,随着梯度的计算,这些缓冲区基本上被释放,图形被破坏。你可以尝试在一个图形上多次向后调用(),你会看到 PyTorch 会给你一个错误。这是因为图形在第一次调用 backward() 时被破坏,因此,第二次调用时没有图形可以向后调用。*

如果再次调用 forward ,会生成一个全新的图形。分配了新的内存。

****默认情况下,只保存叶节点的渐变( grad 属性),非叶节点的渐变被破坏。但是这种行为是可以改变的,如上所述。

这与 TensorFlow 使用的静态计算图形成对比,tensor flow 在运行程序的 之前声明了 。动态图范例允许您在运行时对网络架构进行更改,因为只有在运行一段代码时才会创建一个图。这意味着一个图可以在程序的生命周期中被重新定义。然而,这对于静态图形是不可能的,在静态图形中,图形是在运行程序之前创建的,只是在以后执行。动态图也使调试更容易,因为错误的来源很容易追踪。

一些贸易技巧

要求 _grad

这是变量类的一个属性。默认情况下,它是 False。当你不得不冻结一些层,并阻止他们在训练时更新参数时,这是很方便的。您可以简单地将 requires_grad 设置为 False,这些变量不会包含在计算图中。因此,没有梯度会传播到它们,或者传播到依赖这些层进行梯度流动的那些层。 requires_grad设置为 True 时 会传染,意思是即使一个运算的一个操作数 requires_grad 设置为 True,结果也会如此。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

b is not included in the graph. No gradient is backpropagated through b now. a only gets gradients from c now. Even if w1 has requires_grad = True, there is no way it can receive gradients.

不稳定的

这也是一个变量类的属性,当变量被设置为真时,它会导致变量被排除在计算图之外。这可能看起来与要求 _grad 非常相似,因为当设置为真时也会传染。但是比要求 _ grad优先级高。带有 requires_grad 等于真且 volatile 等于真的变量将不包括在计算图中。****

你可能会想,当我们可以简单地将 requires_grad 设置为 False 时,为什么还需要另一个开关来覆盖 requires_grad ?我暂时跑题一下。

当我们进行推理时,不创建图形是非常有用的,并且不需要梯度。首先,消除了创建计算图的开销,提高了速度。第二,如果我们创建一个图形,由于没有向后被调用,用于缓存值的缓冲区永远不会被释放,这可能会导致内存耗尽。**

通常,我们在神经网络中有许多层,我们可能在训练时将 requires_grad 设置为 True。为了防止在推断时制作图表,我们可以做两件事中的任何一件。设置 r equires_grad False 在所有层上(也许,152 层?).或者,只在输入端设置 volatile 为真,我们保证没有任何结果操作会产生一个图形。你的选择。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

No graph is created for b or any node that depends on b.

注意: PyTorch 0.4 没有组合张量/变量类的可变参数。相反,推理代码应该放在 torch.no_grad()上下文管理器中。

**with torch.no_grad():
    -----  your inference code goes here ----**

结论

所以,那是给你的签名。理解签名是如何工作的,可以在你被困在某个地方时,或者在你开始时处理错误时,帮你省去很多头痛。感谢阅读到目前为止。我打算在 PyTorch 上写更多的教程,讨论如何使用内置函数快速创建复杂的架构(或者,可能没有这么快,但比一个块一个块地编码要快)。所以,敬请期待!****

进一步阅读

  1. 理解反向传播
  2. 理解链式法则
  3. Python 中的类第一部分第二部分
  4. PyTorch 官方教程

开始阅读深度学习研究论文:为什么和如何

原文:https://towardsdatascience.com/getting-started-with-reading-deep-learning-research-papers-the-why-and-the-how-dfd1ac15dbc0?source=collection_archive---------3-----------------------

在你读完那本书或完成那门令人惊叹的关于深度学习的在线课程后,你是如何继续学习的?你如何变得“自给自足”,这样你就不必依赖别人来分解该领域的最新突破?

你阅读研究论文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Emma Frances Logan on Unsplash

开始前的一个小提示*——我不是深度学习方面的专家。我最近才开始阅读研究论文。在这篇文章中,我将写下我开始时发现的所有有用的东西。*

为什么

在 Quora 上的一个问题的回答中,问到如何测试一个人是否有资格从事机器学习的职业,吴恩达(Google Brain 创始人,百度 AI 集团前负责人)表示,任何人都有资格从事机器学习的职业。他说,在你完成了一些与 ML 相关的课程之后,“为了更进一步,阅读研究论文。更好的是,尝试在研究论文中复制这些结果。”

Dario amo dei(open AI 的研究员)说“为了测试你是否适合在 AI safety 或 ML 中工作,只需尝试非常快速地实现许多模型。从最近的一篇论文中找到一个 ML 模型,实现它,尝试让它快速工作。”

这表明阅读研究论文对加深一个人对该领域的理解至关重要。

每个月都有数百篇论文发表,任何认真研究这一领域的人都不能仅仅依靠导师式的文章或课程,在这些文章或课程中,其他人会为他/她分解最新的研究。当你阅读这篇文章时,新的、突破性的研究正在进行。该领域的研究步伐从未如此之快。你能希望跟上这种步伐的唯一方法是养成一种习惯,在研究论文发布时阅读它们。

在这篇文章中,我将尝试给你一些可行的建议,告诉你如何开始自己阅读论文。然后,最后,我会试着分解一份实际的文件,这样你就可以开始了。

怎么做

首先,阅读一篇科研论文是困难的。事实上—
“没有什么比阅读科学期刊文章更让你感到愚蠢的了。”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我只是想把它放在第一位,这样如果你觉得你不能真正理解一篇论文的内容,你就不会气馁。你不太可能在前几遍就理解它。所以,勇敢一点,再试一次!

现在,让我们来谈谈一些有价值的资源,它们将在你的阅读之旅中对你有所帮助…

arXiv.org

把它想象成互联网上的一个地方,研究人员在他们的论文真正发表在那些著名的科学杂志或会议(如果有的话)之前,在那里发表它们。

他们为什么要这么做?

嗯,事实证明做研究和实际写论文并不是它的结束。).从提交论文到在一些科学杂志上发表是一个相当长的过程。在一篇论文被提交到这些期刊之后,会有一个相当缓慢的同行评审过程,有时甚至会持续数年!)现在,对于机器学习这样一个快速发展的领域来说,这确实是不可取的。

这就是为什么, arXiv

研究人员将他们的论文发布在 arXiv 这样的预印库上,以便快速传播他们的研究并获得快速反馈。

Arxiv 理智保护者

好吧,所以允许研究人员容易地预印他们的研究论文是好的。但是读这些报纸的人呢?如果你去 arXiv 网站,很容易感到害怕和渺小和失落。绝对不是新人的地方(只是我的看法,欢迎你来试试虽然☺ )。

进入, Arxiv 理智保护者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Built by Andrej Karpathy, director of AI at Tesla and a personal favourite AI guy of mine

Arxiv Sanity 对 Arxiv 的作用,就像 Twitter 的 newsfeed 对 Twitter 的作用一样*(显然,除了它是完全开源和无广告的)*。正如 newsfeed 可以让你从 Twitter 的汪洋大海中看到最有趣的推文,个性化到你自己的口味,类似地,Arxiv Sanity 为你带来了发表在 Arxiv 上的关于 ML 的论文,这可能是你最感兴趣的。它可以让你根据流行趋势,根据你过去的喜好和你关注的人的喜好对报纸进行分类。(只是那些我们在社交媒体上已经习以为常的个性化推荐功能。)

Check out this short introductory video of the website to know more about it

机器学习 Reddit 上的 WAYR 线程

WAYR 是你在读什么的简称。这是子编辑机器 learningg 上的一个线程,人们在这里发布他们本周阅读的 ML 论文,并讨论他们从中发现的有趣内容。

我说过,arXiv 上每周发表的机器学习领域的研究论文数量极其庞大。这意味着一个人几乎不可能每周读完所有的书,并做一些常规的事情,如上大学、去工作或与他人交流。此外,并不是所有的报纸都值得一读。

因此,你需要把精力放在阅读最有前途的论文上,我上面提到的思路就是一种方法。

时事通讯,时事通讯,时事通讯!

时事通讯是我个人了解人工智能领域最新进展的最佳来源。你只需订阅它们,每周一免费将它们发送到你的收件箱。就这样,你可以了解到本周与 AI 相关的最有趣的新闻、文章和研究论文

以下是我订阅的内容:

  • 杰克·克拉克这是我最喜欢的,因为除了提供我上面提到的所有信息外,它还有一个叫做“科技故事”的部分。本部分包含一个基于上周事件的新的人工智能相关的科幻短篇故事!
    …坦白说:即使在我对人工智能的新事物不感兴趣的那几周,我也会浏览一下这份时事通讯,仅仅是因为科技故事)
  • Sam DeBrule他还经营着一家同名的媒体刊物。它包含了一些真正有趣的文章。一定要检查他们了。
  • Nathan . ai by Nathan bena ich虽然以上两篇简讯都是周刊,这是季刊。因此,你每三个月就会收到一封长长的电子邮件,总结了过去三个月该领域最有趣的进展。
  • 丹尼·布里兹的《AI 中的狂野一周》我很喜欢这本书,因为它干净、简洁,但似乎在过去的两个月里它变得不活跃了。无论如何,我在这里提一下,以防丹尼又开始发那些邮件。

推特上的“AI 人”

另一个好方法是关注 Twitter 上著名的研究人员和开发人员的账户,这样你就可以跟上这个领域最好的和最新的信息。这是我关注的人的名单:

  • 迈克尔·尼尔森
  • 安德烈·卡帕西
  • 弗朗索瓦·乔莱
  • 扬·勒村
  • 克里斯·奥拉赫
  • 杰克·克拉克
  • 伊恩·古德费勒
  • 杰夫·迪恩
  • 我知道这不是“人”,但是是的…)

“那很好,但是我该怎么开始呢??"

是的,这是更紧迫的问题。

好的,首先要确保你理解机器学习的基础知识,比如回归和其他类似的算法,深度学习的基础知识——普通的神经网络,反向传播,正则化,以及比康涅茨,RNN 和 LSTM 的工作原理多一点的基础知识。我真的不认为阅读研究论文是明确你对这些主题的基础知识的最佳方式。为此,您可以参考大量其他资源。

一旦你做到了这一点,你应该开始阅读一篇最初介绍上述观点的论文。这样,你就可以专注于习惯一篇研究论文的样子。你不必太担心如何理解你的第一篇研究论文,因为你已经非常熟悉这个想法了。

我推荐你从Alex net 论文 入手。

为什么要这篇论文?

请看这张图表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看看Computer Vision and Patter Recognition曲线是如何在 2012 年直线上升的?这很大程度上是因为这篇论文。

T44!!!

就是这篇论文重新点燃了所有人对深度学习的兴趣。

由 *Alex Krizhevsky、Ilya Sutskever、Geoffrey Hinton、*和撰写,标题为**ImageNet class ification with Deep convolution Networks,**这篇论文被认为是该领域最有影响力的论文之一。它描述了作者如何使用 CNN (名为 AlexNet) 赢得 2012 年 ImageNet 大规模视觉识别挑战赛(ILSVRC)。

对于那些不知道的人来说,使计算机能够看到和识别物体(又称计算机视觉)是计算机科学的最早目标之一。ILSVRC 就像这种“视觉计算机”的奥运会,参与者(计算机算法)试图正确识别属于 1000 个类别之一的图像。而且,在 2012 年,AlexNet 能够以巨大的优势赢得这项挑战: 它取得了 15.3%的前五名错误率,而第二名的错误率为 26.2%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不用说,整个计算机视觉社区都肃然起敬,该领域的研究以前所未有的速度发展。人们开始意识到深度神经网络的力量,那么,在这里你试图理解你如何才能得到一块馅饼!

也就是说,如果您通过一些课程或教程对 CNN 有了基本的了解,那么掌握本文的内容将会相当容易。所以,给你更多的力量!

一旦你完成了这篇论文,你可能会查阅其他与 CNN 相关的开创性论文,或者转向你感兴趣的其他架构(RNNs、LSTMs、GANs)。

Github 上也有很多仓库,里面收藏了深度学习方面的重要研究论文(这里有一个很酷的)。当你开始的时候,一定要检查它们。他们会帮助你建立自己的阅读清单。

如果我不提及这另一个来源,那将是非常不负责任的

  • Distill . pub:* 关于这一点,我只有一句话要说——
    如果所有的研究论文都发表在 distilt 期刊上,那么很可能,我就不会写这篇文章了,你也不需要阅读一篇文章来指导你阅读研究论文,互联网上也将需要更少(如果有的话)的课程和教程来试图用可理解的术语解释那些开创性的研究观点。 我会让迈克尔·尼尔森给你一个更恰当的《蒸馏日志》背后的动机:
    *

** [## 蒸馏:机器学习研究的交互式可视化期刊

《蒸馏》杂志今天发行。简而言之,Distill 是一个用于机器学习的交互式可视化杂志…

blog.ycombinator.com](https://blog.ycombinator.com/distill-an-interactive-visual-journal-for-machine-learning-research/)

因此,请务必查看中的篇文章。这真的是下一代的东西!**

感谢您从头到尾的阅读!我希望这篇文章能帮助你跟上最新的 ML 研究。记住,阅读科学论文是困难的。所以,没有必要气馁。如果你不理解,就再读一遍。

编辑:发表这篇文章帮助我与世界各地令人惊叹的专业人士建立了数百种联系。

你想像我一样写作吗?

我开设了一门写作课程,教你如何在互联网上开始写作之旅。这就叫——清晰写作,清晰思考 而我 免费赠送

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Clear Writing, Clear Thinking — a free 5-week email course that’ll teach you how to write well

你可以在 Twitter 上关注我,或者在 LinkedIn 上联系我,我不会给你发垃圾信息。;-)

强化 Q 学习入门

原文:https://towardsdatascience.com/getting-started-with-reinforcement-q-learning-77499b1766b6?source=collection_archive---------2-----------------------

简介

当 DeepMind 的 AlphaGo 击败围棋世界冠军李·塞多尔(Lee Sedol)时,人工智能(AI)真正崛起。人工智能代理的基本构建模块是 Q 学习,所以让我们直接进入它。正如著名作家安德鲁·特拉斯克所说的那样,“我用可以玩的玩具代码学得最好”。所以下面你会发现我们的玩具代码只使用了 Numpy,我们将在本文的其余部分更详细地讨论它。

什么是强化学习?

强化学习有一个“环境”和一个“代理”,前者是我们试图解决的问题集,后者是我们的人工智能算法。环境和代理之间的关系非常简单。代理将执行某些动作(像我们的玩具代码中的出租车上、下、右、左等移动),作为该动作的结果,他的状态将改变(出租车的新位置),这将导致代理获得奖励(到达其目的地的正奖励,或者如果您错误地搭载或放下乘客,则为负奖励)。通过行动和奖励过程的迭代,代理学习环境。它开始明白在哪个状态下,哪个动作给他最大的奖励,哪个动作给他负的奖励。这个执行一个动作并从奖励中学习的过程叫做强化学习。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

贝尔曼方程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们假设我们的代理在相邻 gif 的“开始”图像所示的环境中开始。最初,它只是做一些随机的运动,比如向右、向左、向上、向下等,最终在某个时候,它会到达目的地。现在只要它到达目的地,它就会得到奖励,比如说+1 分。这触发算法意识到这个地方(绿色方块)是它需要的地方。然后代理开始问问题,我是怎么到这个方块的,我之前是什么状态,我做了什么让我得到奖励。因此,它回顾和回溯其先前的状态,如下图所示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它首先用虚拟奖励“1”标记绿色方块左边的方块,告诉自己他只需要到达前面的方块,然后它需要做的只是向右移动,他就会到达目的地。这个过程继续,直到他回溯他的完整路径。这种路由回溯,代理执行多次迭代。

现在,如果我们永远不重置代理,一切都可以工作了,它会一直保持在 ON 状态,并在内存中记忆他刚才绘制的地图。但是,如果代理重置,并且下次被调用时从不同的状态启动,会发生什么呢?现在他很困惑,不知道该做什么,这就是为什么这种方法没有真正发挥作用。

这就是贝尔曼方程发挥作用的地方。

贝尔曼方程-> **V(s) = max(R (s,a)+γV(s′))**其中 V(s)是任意给定状态下的一个值

s —状态,a —行动,R —奖励,γ —折扣,s’ —采取行动‘a’后的下一个状态

贝尔曼方程说的是,一个国家的价值。V(s ),等于通过执行任何允许的动作 R(s,a)你可以从该状态获得的不同奖励的最大值,以及通过采取特定动作“a”你将到达的新状态的“贴现”值。参考下面的 gif 图可以更好的理解上面的公式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

目的地绿色方块左边的方块的值是 1,因为如果我们向右移动,我们可以得到 1 的奖励。回溯,现在不是像前面的情况一样将下一个左边的方块也指定为 1,而是使用伽玛值为 0.9 的贝尔曼方程,并将下一个方块的值指定为 0.9,对于路线的其余部分以此类推。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

同样,我们可以原路返回,填满我们的地图。现在我们已经创建了我们的地图,对于我们的代理来说,无论它从哪个位置开始,它应该走哪条路都变得非常明显。

有了对强化学习和贝尔曼方程的清晰理解,让我们来看看我们的玩具代码,看看它是如何实现上述概念的。为了更好的理解,我将逐行解释完整的代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题陈述:有 4 个地点(用不同的字母标注),你的工作是在一个地点接乘客,在另一个地点让他下车。你成功脱手可获得+20 分,每完成一个时间步长将失去 1 分。非法上下车行为还会被扣 10 分。在此环境中,实心正方形代表出租车,(" | ")代表墙壁,蓝色字母代表上车地点,紫色字母代表下车地点。出租车上有乘客时会变绿

代码走查

第 1–3 行:导入所需的库

#Importing Libararies
import gym
import numpy as np

第 5–8 行:设置开放的健身房环境。这只是建立任何健身房环境的标准方式

#Environment Setup
env = gym.make("Taxi-v2")
env.reset()
env.render()

第 10–17 行:首先,让我们看看我们的代理在随机选择要执行的动作时表现如何。

第 11 行:获取当前状态,即阻塞代理所处的状态。对于此特定环境,该值可以在 0–499 之间。

# Random Moments
state = env.reset()

第 12 行和第 13 行:初始化计数器和奖励。在这一点上,我会建议你手动玩环境,只是为了感受一下。在你的代码中使用下面两个例子来将代理置于特定的状态,或者使它向你喜欢的方向移动。

counter = 0
reward = None# Change state
env.env.s = 114
env.render()# Take an action
env.step(3)
env.render()

第 14 行:直到我们得到 20 英镑的奖励,这是我们正确放下乘客的奖励。

while reward != 20:

第 15 行:env.action_space.sample()是一个 gym 函数,它返回从允许的动作中选择的一个随机动作。我们调用 env.step()来执行这个随机选择的动作。env.step()总是返回新的状态、对前一个动作的奖励、挑战是否完成,以及一些对调试有用的附加信息。我们将所有这些值存储在各自的变量中,仅供参考。

state, reward, done, info = env.step(env.action_space.sample())

第 16 行:由于我们已经走了一步,我们将计数器加 1

counter += 1

第 17 行:每当我们最终将乘客送到正确的位置时,我们将退出 while 循环(因为收到的奖励将是 20)。打印计数器值,指示该特定迭代完成任务所用的步骤数。玩几次 while 循环,了解在随机采取行动的情况下完成挑战需要多少步。我们将把这个值与我们通过实现强化学习算法得到的值进行比较。

print(counter)

第 20 行:我们通过创建一个“可能状态的数量”到“可能动作的数量”维度的矩阵来开始 Q(强化)学习。记住,从我们的学习中,我们需要为每个状态和该状态下允许的每个动作保持一个 Q 值(贝尔曼方程中的 V(s))。正如在解释贝尔曼方程时所说的,最初代理不知道任何 Q 值,所以我们用全零初始化它。

Q = np.zeros([env.observation_space.n, env.action_space.n])

第 21 行:初始化奖励变量 G(因为变量‘reward’用于存储 env.step()给出的返回值,这里使用其他变量名 G)

G = 0

第 22 行:使用伽玛值 0.618。这纯粹是实验出来的。你可以试试你的价值观,在这里分享你的结果,只是为了比较。

gamma = 0.618

第 23 行:对于上千次迭代

for episode in range(1,1001):

第 24 行:初始化“done”值,我们将使用它在完成任务后退出 while 循环。

done = False

第 25 行:每次迭代各自的值初始化

G, reward, counter = 0,0,0

第 26 行:重置环境并获取其状态

state = env.reset()

第 27 行:虽然我们还没有“完成”

while done != True:

第 28 行:现在当创建 Q 矩阵时,记住我们已经创建了维度行= '可能状态的数量’和列= ‘可能动作的数量’。np.argmax(Q[state])从 Q 矩阵的行“state”中挑选出最大值。换句话说,它获取当前状态,在 Q 矩阵中查找,找到该状态的特定行,并返回沿着该行的最大值的索引(这将是“动作”号)

action = np.argmax(Q[state])

第 29 行:使用上面获得的“动作”来执行一个步骤并存储其结果。

state2, reward, done, info = env.step(action)

第 30 行:根据贝尔曼方程和上一步得到的结果更新我们的 Q 表。如果你遵循了本教程,你应该能够清楚地将这条线与上一节描述的贝尔曼方程对应起来。

Q[state,action] = (reward + gamma * np.max(Q[state2]))

第 31–33 行:更新了相应的变量

G += reward
counter += 1
state = state2

第 35 行:打印迭代,每 50 次迭代的奖励和计数器值。检查这些值,并将其与我们通过随机实现获得的“计数器”值进行比较。还要检查代理如何在初始迭代期间以负回报和高计数器值结束,以及它们如何随着它执行更多迭代而显著改善,从它的动作中学习并根据贝尔曼方程更新 Q 矩阵。

if episode % 50 == 0:
        print('Episode {} Total Reward: {} counter: {}'.format(episode,G,counter))

这是完整的代码

#Importing Libararies
import gym
import numpy as np#Environment Setup
env = gym.make("Taxi-v2")
env.reset()
env.render()# Random Moments
state = env.reset()
counter = 0
reward = None
while reward != 20:
    state, reward, done, info = env.step(env.action_space.sample())
    counter += 1
print(counter)# Q table implementation
Q = np.zeros([env.observation_space.n, env.action_space.n])
G = 0
gamma = 0.618
for episode in range(1,1001):
    done = False
    G, reward, counter = 0,0,0
    state = env.reset()
    while done != True:
            action = np.argmax(Q[state])
            state2, reward, done, info = env.step(action)
            Q[state,action] = (reward + gamma * np.max(Q[state2]))
            G += reward
            counter += 1
            state = state2   
    if episode % 50 == 0:
        print('Episode {} Total Reward: {} counter: {}'.format(episode,G,counter))

唷!!就是这样伙计们。深呼吸,祝贺你自己学会了一个 Q 学习人工智能代理的基本概念。高端 Atari 游戏中使用的 AI 代理的概念与本教程中解释的非常相似。不同的是,在这些游戏中,环境的状态数量变得非常多,所以不可能用 Q 矩阵表来实现,因为它的维数非常非常大。所以他们用神经网络来实现同样的功能。遵循 OpenAI 的文档来了解如何安装 openai 健身房环境。

如果你喜欢这篇文章,推特上关注、转发将鼓励我开始我的博客世界之旅。

下次见。干杯!!

SAS 入门:初学者

原文:https://towardsdatascience.com/getting-started-with-sas-beginner-354a94a48f08?source=collection_archive---------1-----------------------

这本快速入门指南是为新的 SAS 用户准备的。我已经包括了 SAS 的基本要素,以帮助您尽快使用 SAS。

什么是 SAS?

SAS 是分析统计数据的工具。SAS 是统计分析软件的缩写。SAS 的主要目的是检索、报告和分析统计数据。SAS 环境中的每个语句都以分号结束,否则该语句将给出错误消息。它是一个强大的工具,用于运行 SQL 查询和通过宏自动执行用户的任务。

除此之外,SAS 通过图形提供描述性的可视化,还有各种 SAS 版本提供机器学习、数据挖掘、时间序列等报告。SAS 支持两种类型的语句来运行程序。广义地说,SAS 程序中的语句分为:数据步骤和过程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这篇文章中,我试图解释使用 SAS 的数据分析。为了解释这个问题,我创建了数据汽车,其中包含以美元为单位的价格、汽车的长度、汽车的维修等级(这是一个分类值)、国外价值(显示汽车是国外的还是国内的)、重量以及最终的 mpg(汽车的里程)。

SAS Essentials 入门:

数据步:

数据步骤由所有 SAS 语句组成,以行数据开始,以行数据行结束。它描述和修改你数据。在数据步骤中,您告诉 SAS 如何读取数据以及生成或删除变量和观察值。数据步骤将原始数据转换成 SAS 数据集。SAS 可以互换使用卡和数据线语句。数据导入、报告变量和描述性分析是数据步骤流程的一部分。在数据步骤中有四种常用的语句。

  • 数据语句命名数据集
  • 输入语句列出了变量的名称
  • CARDS 语句表示数据行紧随其后。
  • INFILE 语句表示数据在一个文件中,以及该文件的名称。
data newdata;
input name $ price mpg rep78 wgt len foreign;
datalines;AMC     4099 22  3     2930   186    0
AMC     4749 17  3     3350   173    0 
AMC     3799 22  3     2640   168    0 
Audi    9690 17  5     2830   189    1 
Audi    6295 23  3     2070   174    1 
BMW     9735 25  4     2650   177    1 
Buick   4816 20  3     3250   196    0 
Buick   4453 26  3     2230   170    0 
Buick   5189 20  3     3280   200    0 
Buick  10372 16  3     3880   207    0 
Buick   4082 19  3     3400   200    0 
Cad.   11385 14  3     4330   221    0 
Cad.   14500 14  2     3900   204    0 
Cad.   15906 21  3     4290   204    0 
; run;

解释:在上面的代码中,我们创建了一个新的数据集 newdata,它包含变量 name、price、mpg、rep78(维修等级)、wgt、len 和 foreign。数据集 newdata 的维度包含 14 条记录和 7 个变量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PROC 步骤:

PROC 步骤告诉 SAS 对数据执行了什么分析,比如回归、方差分析、均值计算等。每个 PROC 语句都以 PROC 关键字开始。

proc print data=newdata(obs=10);
run;

上述语句将以如下方式运行并输出数据:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SAS 编程:

1)导入 SAS 数据:

SAS 中的 PROC 导入功能用于从 excel 文件中导入数据集。除了将数据加载到 SAS 环境之外,SAS 还有内置的库,其中存储了数据集以供用户帮助。

  • **临时数据:**数据仅持续到当前 SAS 会话。这意味着当会话结束时,生命周期短的文件也会被删除。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • **永久数据:**SAS 存储的终身数据,会话结束后不能删除。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2)统计描述性分析:

缺失值:

用句号()表示的缺失值函数。)标识数据中缺失记录的数量。在我们的数据集中,没有缺失值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PROC 意思是:

SAS 有计算平均值的基本程序。

proc means data=newdata;                 
 run;

解释:给定汽车数据的平均价格为$7790.71,其中最低价格为$3799,最高价格为$15906。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PROC FREQ:

SAS 有一个叫做 PROC FREQ 的程序来计算数据集中数据点的频率分布。频率分布是显示数据集中数据点频率的表格。表中的每个条目都有值在特定组或间隔内出现的频率或计数,这样,就可以使用表汇总值的分布。

proc freq data=newdata;
tables rep78; 
run;

解释:评级为 3 的列修复评级在数据中频繁出现,这意味着比其余值出现的几率高 78.5%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PROC CORR

两个变量 x 和 y 之间的关系可以使用 SAS 中的 CORR 函数来计算。相关性取-1 到+1 之间值,值 1 表示非常强的正相关性,而值-1 表示强的负相关性。

解释:在下面的输出中,汽车的长度和重量显示出 0.864 的正相关性,这意味着如果汽车的长度增加,那么它的重量可能会增加,也就是说,如果我们在这两个变量之间绘制一个图形,那么我们会得到一条直向上的对角线,可以看出-0.74 的值表示 len 和 mpg 之间的负关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3)图表和可视化

SAS 工具具有强大的图形功能,有助于分析和报告数据。

简单条形图:

条形图是最常用的表示分类数据的图表之一。在这种情况下,由值 1 表示的外国汽车相对多于国内汽车值 0。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

直方图:

直方图解释了连续值的分布。长度值稍微向左倾斜,这意味着向左的长尾表明长度数据不是正态分布的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

散点图:

散点图表示的两个变量之间的关系。两个连续变量之间的图表。在这里,我们可以看到一个强劲的上升趋势,这表明长度和重量之间有很强的相关性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方框图:

下图是箱线图的一个特例,其中我们通过分类变量来显示连续变量。如果数据集有异常值(极端值),盒须图可能不仅显示最小值或最大值。相反,胡须的末端代表四分位数范围(1.5*IQR),这是计算异常值的一个很好的属性。该变量的平均值为 7790.71,中位数更接近第一个四分位数。价格变量很少有极端值,在建模前需要进一步处理。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

阅读:

第 1 课:SAS | STAT 480 入门—在线统计

【SAS.pdf 入门

Google 联合实验室 TensorFlow 入门

原文:https://towardsdatascience.com/getting-started-with-tensorflow-in-google-colaboratory-9a97458e1014?source=collection_archive---------5-----------------------

10 分钟学会两项激动人心的技术!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Franck V. on Unsplash

TensorFlow 是数据科学家的主导深度学习框架,Jupyter Notebook 是数据科学家的首选工具。如果您可以在任何地方使用 TensorFlow,而无需设置环境,那会怎么样?更好的是,如果你可以免费使用 GPU 来训练你的深度学习模型呢?

谷歌合作实验室(Colab)就是答案!这是一项非常令人兴奋的技术,它允许数据科学家专注于建立机器学习模型,而不是物流!

在本文中,我们不仅将介绍使用 Colab 的基础知识,还将通过易于理解的示例帮助您开始使用 TensorFlow。

开始了。

打开 Colab 笔记本

首次使用 Colab 时,您可以在此处启动新笔记本:

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/)

创建笔记本后,它将保存在您的 Google Drive (Colab 笔记本文件夹)中。您可以通过访问您的 Google Drive 页面来访问它,然后双击文件名,或者右键单击,然后选择“用 Colab 打开”。

与 GitHub 连接

Colab 的构建者考虑得非常周到,他们甚至在 Github 中加入了承诺的功能。

要连接 GitHub,首先需要在 GitHub 上创建一个带有主分支的 repo。然后,从下拉菜单中选择“文件—在 GitHub 中保存副本”。您将仅在第一次被要求授权。方便的是,它甚至允许你在笔记本中包含一个“在 Colab 中打开”按钮,就像这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

启用 GPU 支持

要为深度学习项目打开 GPU,只需进入下拉菜单,选择“运行时—更改运行时类型—硬件加速器”,然后选择 GPU:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用单元格

在大多数情况下,这与本地 Jupyter 笔记本完全相同。例如,要运行代码单元格,只需按“Shift + Enter”即可。查看以下常用键盘快捷键(在使用 Chrome 的 Windows 上):

  • 运行单元格:“Shift + Enter”
  • 删除单元格:“Ctrl + M,然后 D”
  • 撤消:“Ctrl + Shift + Z”
  • 转换为代码单元格:“Ctrl + M,然后 Y”
  • 转换为 markdown 单元格:“Ctrl + M,然后 M”
  • 保存笔记本:“Ctrl + S”
  • 打开快捷方式屏幕:“Ctrl + M,然后 H”

使用文件

您也可以将数据上传到您的 Colab 文件夹。见下图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

张量

TensorFlow 的名字基于“张量”一词。张量到底是什么?简而言之,多维数组。让我们看看这意味着什么!

  • 我们有一个单一的数字,例如 6,我们称之为“标量”;
  • 我们有三个数字,例如[ 6,8,9],我们称之为“向量”;
  • 我们有一个数字表,例如[[6,8,9],[2,5,7]],我们称之为“矩阵”(有两行三列);
  • 我们有一个数表的表格,例如[[[6,8,9],[2,5,7]],[[6,8,9],[2,5,7]]],还有……我们这里用词不多了:(朋友,那是一个张量张量是数组的广义形式,可以有任意维数

在张量流术语中,标量是秩为 0 的张量,向量是秩为 1 的,矩阵是秩为 2 的,等等。有三种常用的张量类型:常量、变量和占位符,解释如下。

张量的类型

常量顾名思义。它们是你等式中的固定数字。要定义一个常数,我们可以这样做:

a = tf.constant(1, name='a_var')
b = tf.constant(2, name='b_bar')

除了值 1,我们还可以为张量提供一个名称,比如“a_var ”,它独立于 Python 变量名“a”。这是可选的,但将有助于以后的操作和故障排除。

定义之后,如果我们打印变量 a,我们会得到:

<tf.Tensor 'a_var:0' shape=() dtype=int32>

变量是要优化的模型参数,例如,神经网络中的权重和偏差。同样,我们也可以定义一个变量,并像这样显示它的内容:

c = tf.Variable(a + b)
c

并且有这样的输出:

<tf.Variable 'Variable:0' shape=() dtype=int32_ref>

但是需要注意的是,所有变量在使用前都需要初始化,如下所示:

init = tf.global_variables_initializer()

你可能已经注意到 a 和 b 的值,也就是整数 1 和 2,没有出现在任何地方,为什么?

这是 TensorFlow 的一个重要特征——“惰性执行”,意思是首先定义事物,但不运行。它只有在我们告诉它去做的时候才会被执行,这是通过运行一个会话来完成的!(注意 TensorFlow 也有急切执行。查看此处的了解更多信息)

会话和计算图

现在让我们定义一个会话并运行它:

with tf.Session() as session:                    
    session.run(init)                            
    print(session.run(c))

请注意,在会话中,我们运行变量的初始化和 c 的计算。我们将 c 定义为 a 和 b 的和:

c = tf.Variable(a + b)

用 TensorFlow 和深度学习的话说,这就是“计算图”。听起来很复杂,对吧?但它实际上只是我们想要进行的计算的一种表达方式!

占位符

另一个重要的张量类型是占位符。它的用例是保存要提供的数据的位置。例如,我们定义了一个计算图,我们有大量的训练数据,然后我们可以使用占位符来表示我们将在以后输入这些数据。

让我们看一个例子。假设我们有这样一个等式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们有一个 x 的向量,而不是一个单一的 x 输入。所以我们可以用一个占位符来定义 x:

x = tf.placeholder(dtype=tf.float32)

我们还需要系数。让我们使用常数:

a = tf.constant(1, dtype=tf.float32)
b = tf.constant(-20, dtype=tf.float32)
c = tf.constant(-100, dtype=tf.float32)

现在让我们制作计算图,并提供 x 的输入值:

y = a * (x ** 2) + b * x + c
x_feed = np.linspace(-10, 30, num=10)

最后,我们可以运行它:

with tf.Session() as sess:
  results = sess.run(y, feed_dict={x: x_feed})
print(results)

这给了我们:

[ 200\.         41.975304  -76.54321  -155.55554  -195.06174  -195.06174  -155.55554   -76.54324    41.97534   200\.      ]

综合考虑

现在我们有了 TensorFlow 的基础知识,让我们做一个迷你项目来构建一个线性回归模型,也就是神经网络:)(代码改编自 TensorFlow 指南中的示例这里

假设我们有一堆 x,y 值对,我们需要找到最佳拟合线。首先,由于 x 和 y 都有值要输入到模型中,我们将它们定义为占位符:

x = tf.placeholder(dtype=tf.float32, shape=(None, 1))
y_true = tf.placeholder(dtype=tf.float32, shape=(None, 1))

行数被定义为 None,以便灵活地输入我们想要的任意行数。

接下来,我们需要定义一个模型。在这种情况下,我们的模型只有一个层,只有一个权重和一个偏差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

TensorFlow 允许我们非常容易地定义神经网络层:

linear_model = tf.layers.Dense(
                   units=1, 
                   bias_initializer=tf.constant_initializer(1))
y_pred = linear_model(x)

单元的数量被设置为 1,因为我们在隐藏层中只有一个节点。

此外,我们需要有一个损失函数,并建立优化方法。损失函数基本上是一种使用训练数据来衡量我们的模型有多差的方法,所以当然,我们希望它最小化。我们将使用梯度下降算法来优化这个损失函数(我将在以后的文章中解释梯度下降)。

optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

然后我们可以初始化所有的变量。在这种情况下,我们所有的变量包括权重和偏差都是我们上面定义的层的一部分。

init = tf.global_variables_initializer()

最后,我们可以为占位符提供培训数据并开始培训:

x_values = np.array([[1], [2], [3], [4]])
y_values = np.array([[0], [-1], [-2], [-3]])with tf.Session() as sess:
  sess.run(init)
  for i in range(1000):
    _, loss_value = sess.run((train, loss),
                             feed_dict={x: x_values, y_true: y_values})

我们可以得到权重,并做出这样的预测:

weights = sess.run(linear_model.weights)
bias = sess.run(linear_model.bias)
preds = sess.run(y_pred, 
                 feed_dict={x: x_values})

由此产生了这些预测:

[[-0.00847495]  [-1.0041066 ]  [-1.9997383 ]  [-2.99537   ]]

如果你像我一样好奇,你可以通过以下方式验证模型是否使用其训练的权重和偏差进行预测:

w = weights[0].tolist()[0][0]
b = weights[1].tolist()[0]
x_values * w + b

这给了我们完全相同的结果!

array([[-0.00847495],        [-1.00410664],        [-1.99973834],        [-2.99537003]])

瞧啊。Google Colab 中使用 TensorFlow 搭建的一个简单的神经网络!希望你觉得这个教程有趣和丰富。

包含所有代码的笔记本可以在这里找到。一定要试一试!

最后的想法

云计算绝对是深度学习计算的未来。谷歌 Colab 显然是一款面向未来的产品。当我们可以在云上启动笔记本电脑并开始构建模型时,很难想象人们还想花时间建立深度学习环境!

如何开始使用宇宙魔方

原文:https://towardsdatascience.com/getting-started-with-tesseract-part-i-2a6a6b1cf75e?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Pierre Châtel-Innocenti.

从头开始设置您的开源 OCR 堆栈

众所周知,Tesseract 不是一个可以识别各种文本和图形的一体化 OCR 工具。事实上,这与事实相去甚远。如果这是一个秘密,我已经破坏了它,无论如何已经太晚了。所以,为什么不深入研究宇宙魔方,并分享一些可以改善你的结果的技巧和诀窍呢?

我喜欢免费的东西!

不过,真的。我真的很感谢那些为开源项目做出贡献而不期望任何回报的开发人员。毕竟,它们为我们提供了个人相对难以实现的能力,例如通过 TensorFlow 创建深度神经网络,而没有太多的麻烦。谁能想到机器学习会像今天这样触手可及?

宇宙魔方也帮助我们完成简单的 OCR 任务,成功率很高,并且是完全开源的。在这篇文章中,我将试着让你继续使用宇宙魔方,并希望帮助你清除在使用它时可能会遇到的一些障碍。

即使该领域有相当多的选择,例如, OCRopus ,宇宙魔方似乎仍然是大多数免费骑手的首选。嗯,如果你考虑到宇宙魔方仍在由谷歌社区开发,并随着时间的推移不断增长,这一切加在一起。然而,如果你以前有过使用 Tesseract 的经验,你可能会注意到,在图像预处理或自定义字体训练方面,Tesseract 很可能会让你失望。

自定义字体的训练留待以后讨论,现在,我将主要集中在复习基础知识,让你开始使用 Tesseract。首先,让我们快速检查一下安装。

装置

马科斯

我将使用家酿,一个软件包管理器,来安装宇宙魔方库。安装 HomeBrew 后,您应该提示以下命令。

$ brew install tesseract

或者,如果你愿意,你也可以用 MacPorts 做同样的事情。

$ sudo port install tesseract

人的本质

在 Ubuntu 上,这也很简单。

$ sudo apt-get install tesseract-ocr

Windows 操作系统

对于 Windows,可以从官方 GitHub 库下载非官方安装程序。多好的句子,嗯?

我如何知道安装是否正确?

要验证 Tesseract 是否安装成功,您可以点击您的终端并键入以下内容。

$ tesseract -v

如果您收到类似下面的几行提示,您的宇宙魔方安装正确。否则,您可能希望从系统中的 PATH 变量开始检查出了什么问题。

tesseract 3.05.01
 leptonica-1.74.4
  libjpeg 9c : libpng 1.6.34 : libtiff 4.0.9 : zlib 1.2.11

安装更多的库

首先,Tesseract 不是一个 Python 库。它也没有 Python 的官方包装器。这就是那些热心的开发者来为我们创造这个令人敬畏的 Python 包装器 pytesseract 的地方。我们还需要安装 OpenCV 和 PIL 来操作图像。

$ pip install pillow
$ pip install pytesseract
$ pip install opencv-python

就是这样!

图像预处理

现在,您已经将您的宇宙魔方安装在您的计算机上,准备好使用 Python 了。你还在等什么?嗯,没有人阻止你;请继续尝试。不过,这里有一个“但是”。正如许多文章(包括官方文档)所述,如果没有图像预处理,Tesseract 很可能会失败。

什么是图像预处理?

很长一段时间以来,我一直是 TensorFlow 知识库中提高质量页面的常客,在那里他们列出了一些你可以尝试提高准确度的方法。虽然它声称内部有各种图像处理操作,但这往往是不够的。在这里,我将尝试应用一些我们可以通过使用 OpenCV 完成的事情。

让我们定义一个简单的函数,它将图像路径作为输入,并将字符串作为输出返回。我要发挥超级创造力,把这个函数命名为“get_string”

def get_string(img_path):
    # Read image using opencv
    img = cv2.imread(img_path)

    # Extract the file name without the file extension
    file_name = os.path.basename(img_path).split('.')[0]
    file_name = file_name.split()[0]

    # Create a directory for outputs
    output_path = os.path.join(output_dir, file_name)
    if not os.path.exists(output_path):
        os.makedirs(output_path)

重定比例:镶嵌立方体最适合 300 dpi 或更高的图像。如果您处理的图像的 DPI 小于 300 dpi,您可以考虑重新缩放。否则,重新调整可能不会产生你认为会产生的影响。

就我个人而言,我更倾向于确保图像至少为 300 dpi,而不是在后期重新缩放。但是,每个人都有自己的喜好。你做你的。

 # Rescale the image, if needed.
    img = cv2.resize(img, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)

**去噪:**大多数打印文档都可能在某种程度上受到噪声的影响。虽然这种噪音的主要原因可能各不相同,但很明显,它使计算机更难识别字符。结合使用几种不同的技术可以去除图像上的噪声。这些包括但不限于将图像转换为灰度、膨胀、腐蚀和模糊。

膨胀、侵蚀和模糊需要一个内核矩阵来处理。简单地说,你的内核越大,你的方法工作的区域就越广。同样,没有一个内核大小值适合所有情况。你需要玩数字游戏,最终为你的图像找到正确的值。

然而,一个好的经验法则是从小字体的小内核值开始。同样,对于较大的字体,您可以尝试使用较大的内核。

 # Convert to gray
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Apply dilation and erosion to remove some noise
    kernel = np.ones((1, 1), np.uint8)
    img = cv2.dilate(img, kernel, iterations=1)
    img = cv2.erode(img, kernel, iterations=1) # Apply blur to smooth out the edges
    img = cv2.GaussianBlur(img, (5, 5), 0)

正如您在上面的代码中可能注意到的,我们可以用两种类似的方式创建内核:使用 NumPy 数组或者直接将内核传递给函数。

**二值化:**这绝对是必须的。让我们试着像电脑一样思考一下。在这个一切最终归结为 1 和 0 的网络现实中,将图像转换为黑白极大地帮助宇宙魔方识别字符。但是,如果输入文档缺乏对比度或背景稍暗,这可能会失败。

 # Apply threshold to get image with only b&w (binarization)
    img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

在输出目录中保存过滤后的图像后,我们可以通过将处理后的图像传递给 Tesseract 来完成 get_string 函数的编写,如下所示。

 # Save the filtered image in the output directory
    save_path = os.path.join(output_path, file_name + "_filter_" + str(method) + ".jpg")
    cv2.imwrite(save_path, img)

    # Recognize text with tesseract for python
    result = pytesseract.image_to_string(img, lang="eng")
    return result

临终遗言

现在,你可能认为你已经准备好了一切——但是总有改进的空间。如果我们有更多的过滤选项不是更好吗?实际上,有很多!我将在我的下一个故事中解释其中的一些。

对于那些想在进入下一个故事之前看看我的源代码的人来说,这里是我在 GitHubGist 上的完整代码。你可能注意到了,它实际上不仅仅是文本识别。事实上,它在图像的给定区域查找正则表达式并返回值。

我们很快就会到达那里,别担心!同时,最好继续你的一天,寻找更好的机会。

如何利用图像预处理提高立方体的精度

原文:https://towardsdatascience.com/getting-started-with-tesseract-part-ii-f7f9a0899b3f?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Pierre Châtel-Innocenti.

应用计算机视觉技术提高精确度

在之前的如何开始使用宇宙魔方中,我给了你一个关于使用 Python 使用宇宙魔方的实用快速入门教程。这是一个非常简单的概述,但它应该可以帮助您开始使用 Tesseract,并清除我在您的位置时所面临的一些障碍。现在,我热衷于向您展示更多的技巧和东西,您可以使用 Tesseract 和 OpenCV 来提高您的整体准确性。

我们上次讲到哪里了?

之前的故事中,大部分内容我都懒得赘述。但是如果你喜欢第一个故事,续集来了!那么,我们在哪里停下来的?

啊,我们对重缩放、去噪和二值化做了一个简单的概述。现在,是时候进入细节并向您展示一些您可以使用的设置了。

改比例

被重新缩放的图像或者缩小或者放大。如果你对缩小你的形象感兴趣, INTER_AREA 是适合你的选择。(顺便说一下,参数 fxfy 表示下面函数中的比例因子。)

img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

另一方面,在大多数情况下,您可能需要将图像放大以识别小字符。在这种情况下, INTER_CUBIC 通常比其他替代方法执行得更好,尽管它比其他方法慢。

img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

如果您想牺牲一些图像质量来获得更快的性能,您可能想尝试使用 INTER_LINEAR 来放大图像。

img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)

模糊

值得一提的是, OpenCV 库中有一些模糊滤镜可用。图像模糊通常通过将图像与低通滤波器核进行卷积来实现。虽然滤镜通常用于模糊图像或减少噪点,但它们之间还是有一些差异。

1.求平均值

在使用归一化的盒状滤波器对图像进行卷积之后,这将取核心区域下所有像素的平均值,并替换中心元素。我想这是不言自明的。

img = cv.blur(img,(5,5))

2.高斯模糊

这类似于求平均值,但它使用高斯核,而不是归一化的盒式滤波器进行卷积。这里,核的维数和两个方向上的标准偏差可以独立确定。高斯模糊对于去除非常有用——你猜怎么着?—图像中的高斯噪声。相反,高斯模糊不会保留输入中的边缘。

img = cv2.GaussianBlur(img, (5, 5), 0)

3.中间模糊

内核区域中的中心元素被替换为内核下所有像素的中值。特别是,在去除图像中的椒盐噪声方面,这优于其他模糊方法。

中值模糊是一种非线性滤波器。与线性过滤器不同,中值模糊用邻域值中的中值替换像素值。因此,中值模糊保留了边缘,因为中值必须是相邻像素之一的值。

img = cv2.medianBlur(img, 3)

4.双边过滤

说到锐边,双边滤波对于去除噪声而不平滑边缘是非常有用的。与高斯模糊类似,双边滤波也使用高斯滤波器来寻找邻域中的高斯加权平均值。但是,在模糊附近的像素时,它也考虑了像素差异。

因此,它确保只有那些与中心像素具有相似强度的像素被模糊,而具有不同像素值的像素不被模糊。这样,具有较大强度变化的边缘,即所谓的边缘,被保留下来。

img = cv.bilateralFilter(img,9,75,75)

总的来说,如果你对保留边缘感兴趣,选择中值模糊或双边滤波。相反,高斯模糊很可能比中值模糊更快。由于计算复杂,双边滤波是所有方法中最慢的。

再说一次,你做你的。

图像阈值处理

没有一种图像阈值方法适合所有类型的文档。实际上,所有的滤镜对不同的图像都有不同的表现。例如,虽然一些滤波器成功地将一些图像二值化,但是它们可能无法将其他图像二值化。同样地,有些滤镜可以很好地处理其他滤镜无法很好地二值化的图像。

我将尝试在这里涵盖基础知识,尽管我建议您阅读官方文档 OpenCV 关于图像阈值处理以获得更多信息及其背后的理论。

1.简单阈值

你可能记得你的一个朋友给你的生活提了一些建议,他说,“事情并不总是非黑即白的。”嗯,对于一个简单的门槛来说,事情相当简单。

cv.threshold(img,127,255,cv.THRESH_BINARY)

首先,你选择一个阈值,比如 127。如果像素值大于阈值,它会变成黑色。少的话就变成白色了。OpenCV 为我们提供了不同类型的阈值方法,可以作为第四个参数传递。我经常在大多数任务中使用二进制阈值,但是你可以访问的官方文档了解其他阈值方法。

2.自适应阈值

我们让算法为图像的小区域计算阈值,而不是设置一个全局阈值。因此,我们最终为不同的图像区域设置了不同的阈值,这太棒了!

cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)

有两种计算阈值的自适应方法。自适应阈值均值返回邻域面积的均值,自适应高斯均值计算邻域值的加权和。

我们还有两个参数来决定邻域的大小和从结果中减去的常量值:分别是第五个和第六个参数。

3.大津的门槛

这种方法特别适用于双峰图像,这种图像的直方图有两个峰值。如果是这种情况,我们可能会热衷于在这些峰值之间选择一个阈值。不过,这就是 Otsu 的二值化实际做的事情。

cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

这在某些情况下非常有用。但是它可能无法对非双峰图像进行二值化。所以,请大家对这个滤镜半信半疑。

阈值处理的类型

您可能已经注意到有一个参数,或者在某些情况下是几个参数的组合,作为参数传递以确定阈值的类型,比如 THRESH_BINARY。我现在就不在这里赘述了,因为在官方文档里已经解释的很清楚了。

接下来呢?

到目前为止,我们已经讨论了一些图像预处理技术。你可能想知道你什么时候会弄脏你的手。好吧,时候到了。在你回到你最喜欢的 Python IDE——我的是 PyCharm ,顺便说一句——之前,我将向你展示几行代码,这将节省你一些时间,同时试图找到哪种过滤器和图像操作的组合适合你的文档。

让我们从定义一个带有一些阈值过滤器和模糊方法组合的开关函数开始。一旦你有了这个想法,你也可以添加更多的过滤器,结合其他图像预处理方法,如重新调整你的过滤器集。

在这里,我创建了 20 种不同的图像阈值方法、模糊方法和内核大小的组合。switcher 函数 apply_threshold 有两个参数:OpenCV image 和一个表示过滤器的整数。同样,由于这个函数返回 OpenCV 图像,它可以很容易地集成到我们上一篇文章中的 get_string 函数中。

def apply_threshold(img, argument):
    switcher = {
        1: cv2.threshold(cv2.GaussianBlur(img, (9, 9), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1],
        2: cv2.threshold(cv2.GaussianBlur(img, (7, 7), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1],
        3: cv2.threshold(cv2.GaussianBlur(img, (5, 5), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1], **    ...  **        18: cv2.adaptiveThreshold(cv2.medianBlur(img, 7), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2),
        19: cv2.adaptiveThreshold(cv2.medianBlur(img, 5), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2),
        20: cv2.adaptiveThreshold(cv2.medianBlur(img, 3), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    }
    return switcher.get(argument, "Invalid method")

它来了。

def get_string(img_path, method):
    # Read image using opencv
    img = cv2.imread(img_path)

    # Extract the file name without the file extension
    file_name = os.path.basename(img_path).split('.')[0]
    file_name = file_name.split()[0]

    # Create a directory for outputs
    output_path = os.path.join(output_dir, file_name)
    if not os.path.exists(output_path):
        os.makedirs(output_path) # Rescale the image, if needed.
    img = cv2.resize(img, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC) # Convert to gray
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Apply dilation and erosion to remove some noise
    kernel = np.ones((1, 1), np.uint8)
    img = cv2.dilate(img, kernel, iterations=1)
    img = cv2.erode(img, kernel, iterations=1) **# Apply threshold to get image with only black and white
    img = apply_threshold(img, method)** # Save the filtered image in the output directory
    save_path = os.path.join(output_path, file_name + "_filter_" + str(method) + ".jpg")
    cv2.imwrite(save_path, img)

    # Recognize text with tesseract for python
    result = pytesseract.image_to_string(img, lang="eng") return result

临终遗言

现在,我们需要编写一个简单的 for 循环,遍历输入目录来收集图像,并对收集的图像应用每个过滤器。我更喜欢使用 globos 从目录中收集图像,使用 argparse 通过终端传递参数,就像任何其他正常人会做的那样。

如果你想看的话,我在这里做了和我的要点差不多的事情。然而,请随意使用您觉得舒服的工具。

到目前为止,我已经尝试介绍了一些有用的图像预处理概念和实现,尽管这可能只是冰山一角。我不知道在接下来的几周里我会有多少“闲暇时间”,所以我不能给你一个发表下一篇文章的具体时间框架。然而,我正在考虑在这个系列中至少增加一个部分来解释我遗漏的一些东西,比如图像的旋转和去歪斜。

在那之前,最好的办法是保持警惕,继续寻找迹象。 *

Vue.js for Data Science 入门

原文:https://towardsdatascience.com/getting-started-with-vue-js-for-data-science-f3c34d22cd38?source=collection_archive---------5-----------------------

Vue.js 是一个轻量级、易于使用的 JavaScript 框架,用于构建更复杂的前端网站。在这篇博客中,我将分享我作为一个从事数据科学项目的人对学习 Vue.js 的看法。我以前尝试过学习 jQuery 来做 JavaScript 工作,我发现它非常不直观并且难以使用。Vue.js 是一股新鲜空气,是与 jQuery — esp 完全不同的体验。对于主要生活在 HTML/CSS 世界中进行前端开发的人来说。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Vue.js is a light-weight JavaScript framework to build dynamic websites

I .我的数据科学工作流程与 web 开发:

  1. 像许多数据科学家一样,我通常使用像 Python 这样的脚本语言来构建模型。这些模型通常经过训练并存储在磁盘上的某个地方,通常用 Python 或另一种语言部署到生产中。(我曾经写过关于使用 Go 进行数据科学的文章——这是一种非常棒的语言,可以用于许多数据科学任务。)
  2. 对于我来说,构建网站的常见用例是从访问网站、登录并为您标记或分类数据的用户那里获取训练数据。
    对于这个工作流程,我使用了 Flask 作为 web 框架,以及 BootstrapJinja 前端模板引擎来构建小型网站。(这些可以通过 AWSHeroku 部署)
  3. 网站需要交互性怎么办?如果需要键盘快捷键怎么办?如果你希望需要动态图表来展示模型的不同状态呢?这些任务需要 JavaScript。通常人们使用 Angular、React 或 Vue 这样的框架来帮助编写代码。

二。Vue.js 入门:

Vue。JS 是轻量级的,有更温和的学习曲线,更直观,有很好的文档,在单页应用程序(spa)中越来越受欢迎。SPAs 允许大部分工作在客户端完成,不需要持续的页面重载。

Youtube 上的网络忍者视频的大呼小叫,他们是学习 Vue 的绝佳选择。让我们从一些 Vue 代码开始:

a)调用函数和动态访问数据:

在 HTML 代码中:添加带有idvue-appdiv,这将让 Vue 实例控制应用程序。HTML 使用{{}}与 Javascript 数据交互——这让 Vue 知道动态加载这些数据。在<script>标签中,添加到托管在 CDN 上的 Vue Javascript 文件和本地 Javascript 文件的链接。

JavaScript 文件内部:

Vue 实例使用el与 DOM 连接,data有键值对来保存所有可以动态更新的数据——这个名称是固定的。methods拥有所有可以使用{{}}在 HTML 内部调用的函数。在methods内部,可以使用this访问data。要得到name,就会是this.name : Vue 自动理解this是指这个对象。

关于这个过程,我发现的最好的事情之一是,我们可以将所有逻辑保留在纯 JavaScript 代码中,并将所有数据保留在一个 JavaScript 对象中。这对我来说感觉比什么都合并干净。

b)事件处理: vue . js 的另一个伟大之处是它如何无缝地处理像clickkeyup这样的事件。假设您希望用户使用两个按钮来编辑年龄。

在 JavaScript 文件中,编写了方法addsubtract:

上面的代码将在点击时增加或减少年龄,并在不重新加载页面的情况下动态显示给用户。其他事件可以是@keyup@dblclick, @mousemove等。
如果你想通过使用n在不同的divs之间切换,你可以使用@keyup.78来捕获这个事件,并引导用户使用你的 JavaScript 函数。

对循环和条件句使用 v-for 和 v-if:

比方说,用户在数据对象中有另一个名为favorites的属性。它有一个数据数组[“Batman”, “Spider-Man”, “Iron-Man”, “Black Panther”]。我们可以用<div v-for="(fav, index) in favorites"><h4>{{ fav }} </h4><div>。这将允许 HTML 代码逐个呈现项目列表。类似地,v-if可以用来检查条件和data对象中值的存在。

d)基于逻辑操纵类: 类绑定是 Vue 中我最喜欢的特性之一。比方说,您正在显示一个项目列表,并且希望在用户按下向上或向下按钮时突出显示该项目。这在使用类绑定的 Vue 中是可能的。下面是代码的完整示例

<li v-for=’item in items’ :class=’{“active-item”: currentItem === item.id}’>

currentItem可以在data对象中操作,当 currentItem 匹配当前项目的 id 时,它会使用类active-item高亮显示。

我已经非常简要地介绍了这些概念,这些例子只是 Vue.js 可以做什么的预告片,Vue.js 实际上有一些令人惊讶的文档,你可以在这里找到

三。数据科学的要点:

在最后一部分,我们将讨论关于 Vue.js 的数据科学关键要点。

  1. Vue.js 非常适合为全栈数据科学编写客户端代码:
    虽然了解用于开发模型的服务器端语言很好,但了解客户端框架也很好。这使得全栈数据科学。通过服务器端和客户端代码之间的交互,数据科学模型可以成为网站的一部分。Vue.js 在客户端代码开发上确实大放异彩。
  2. Vue.js 允许快速 XHR 请求将数据发送回服务器: 在浏览器中收集了用户的数据后,Vue 允许快速 XHR 请求使用 POST 请求将数据发送回服务器。在 Vue 实例的方法中,您可以使用this.$http.post(‘/post_url’, JSON.stringify(this.data))将数据发送回服务器,您只需要在 HTML 脚本标签中添加vue-resource库——您可以使用 CDN 链接来完成。
  3. Vue.js 对于已经熟悉 HTML 的人来说很棒: Vue 让你用 HTML 编辑网页,很多数据科学家已经很熟悉了。Vue 小巧、可扩展、直观。

已经在使用 Vue.js 的网站有阿里巴巴、小米、Gitlab、路透社和 Adobe。围绕 Vue 有很多真正令人兴奋的事情,学习了它并在项目中使用,很容易理解为什么。

学习 Vue 的优秀资源:

  1. Net Ninja 的 Youtube 视频系列是互联网上最好的视频系列之一
  2. Vue.js 文档非常干净,写得很好
    3)awesome-VueGithub 页面,链接到世界各地的多个项目、资源和社区

希望你喜欢 Vue 和数据科学的世界!

PS,看看我的新播客!我开始了一个名为“数据生活播客”的新播客。如果你已经在工作中处理数据,并且想听听在数据科学中处理数据、工具和技术的真实生活经历,这是为你准备的播客。在最近的一期节目中,我谈到了使用 Flask 和 Vue.js 构建一个单页面 web 应用程序。你可以在这里或者任何你听播客的地方听播客。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

My new podcast: The Data Life Podcast

如果你有任何问题,给我的 LinkedIn 个人资料留言,或者发邮件到 sanket@omnilence.com。感谢阅读!

为项目实施开绿灯

原文:https://towardsdatascience.com/getting-the-green-light-on-project-implementation-c400feae9eb?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我之前的博文中,我讨论了如何更好地销售数据科学项目。该职位虽然适用于整个流程,但在初始阶段尤其有用,尤其是在需求收集阶段。在这篇文章中,我想把天平向过程的下一个阶段倾斜,在这个阶段,你提出一个要实现的项目。

我想解释一下,我在这里的动机是,尽管至少在某些时候认为是数据科学固有的,但统计学与销售艺术相遇的地方并没有被谈论或书写。至少,如果有,我很难找到它。除非我错了,否则目前没有关于它的 MOOC,尽管可以说数据科学 MOOC 供过于求,如果它被博客讨论,它很少被博客讨论。我正试图填补这个空白——毕竟,当哈斯蒂等人免费发布机器学习算法的最终指南时,再写一篇关于核心机器学习算法之一如何工作的博文几乎没有意义。不过,在这种情况下,我最大的希望是有人在我的一篇帖子上写一条评论,把我带到商业统计的 TukeyBreimanCleveland ,我就可以挂上键盘了。

这篇文章将重点介绍在实施前会议上向客户展示什么样的模型,您希望客户同意实施,从而投入更多的时间和金钱。这一阶段可能是最难克服的障碍,因为这是时间和金钱承诺从少量增加到潜在的更大承诺的阶段。在内部销售的情况下,这可能意味着高管正在决定是否将项目从一个小型数据科学团队转移到一个更大的团队,该团队需要实施项目并允许项目在整个组织中广泛使用。

显然,在这种情况下,能够将您的模型的实现与解决您的客户正在经历的真实世界的问题联系起来是至关重要的,并且真实世界的问题应该对客户很重要。在可能的情况下,你应该能够将解决特定问题与节省一定数量的钱联系起来。当你在内部展示一个模型时,你更有可能找到一个合理的价格。同时,如果您在早期的发现会议中取得了成功,您将会意识到您正在解决的问题对您的客户有多么重要。

购买模型可信度的关键是结果对客户有意义。这意味着,不仅你的模型需要显示出很好的结果,而且你的客户需要了解你是如何评估你的模型的,将你的评估与她的业务联系起来,并相信结果。

有许多可用的评估方法,它们的使用会在统计和数据挖掘社区中引发争议。经常使用的评估方法,如接收器工作特性可以在统计的基础上受到批评,提出了更为稳健但细致入微的(因此更难理解),然而即使这些简单但错误的方法对商业受众来说也很难理解。

还有一些方法,如提升或增益,与客户试图解决的业务问题紧密相关。在销售你的结果的演示中,这种类型的评估是理想的,其中数据和问题是合适的。例如,lift 与增加销售的营销目标明确相关。

如果不合适,开发一个适合问题的度量标准可能是一个前进的方向。在这两种情况下,最好的做法仍然是使用统计上稳健的方法进行评估,以确保正确评估模型的性能,而不必使用该方法来传达结果(我希望在接下来的几周内,在我的博客中比较两种分类器评估方法)。

现在,尽管在几分钟的闪光中,在不知道如何得出结论的情况下,产生一个非常精确的模型是可以的。当然,你仍然可以用这种模型赢得 Kaggle。然而,不幸的是,说服用户只相信一个有准确性分数的模型是非常困难的。一方面,许多用于评估模型的指标对于本身不是机器学习用户的人来说是不可访问的。另一方面,对许多人来说,准确性分数本身并不令人信服——这些人想知道,“它对下一批数据有用吗?”和“好得不像真的吗?”

为展示的模型选择一个客户能够理解的解释是确保客户相信你的模型的关键。它太重要了,不能在这里作为脚注,所以我把它留到下一期。

见我的 博客登陆页 本系列其他故事详情

了解黑盒模型:

原文:https://towardsdatascience.com/getting-to-know-a-black-box-model-374e180589ce?source=collection_archive---------4-----------------------

基于雅可比的对抗性攻击和基于雅可比的数据增强的二维示例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mirror Lake and Lone Eagle Peak in Colorado 7/2018

随着对人工智能的大肆宣传,围绕对立例子的讨论也越来越多。一个对抗性的例子,也称为攻击,是一个被机器学习模型错误分类的输入。这些输入通常是高维输入,例如照片音频样本文本串,甚至是软件代码

有几个精彩的博客从理论上和初级水平介绍了对抗性攻击防御 。理解对立例子的关键之一是首先理解:

  1. 机器学习模型如何决策
  2. “数据流形”和高维空间
  3. 敌对的噪音或干扰

由于这些概念很难在高维空间中可视化,我们将通过一个简单的二维示例来演示对抗性攻击中使用的一些核心技术。这将有助于我们在更高的维度上更好地理解这些概念。

我们将构建一个逻辑回归分类器,它将充当我们打算攻击或欺骗的模型,或者我们的“受害者”模型。然后,我们将通过如何使用基于梯度的方法来攻击我们的受害者和我们的受害者的黑盒版本。(所有用来产生这篇文章的代码可以在这里看到)

建立受害者模型

让我们借用马丁·佩拉罗洛的例子从 iris 数据集的子集构建逻辑回归。为了简单起见,我们将把两个输入变量 X1 和 X2 以及类 0 和类 1 称为。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Subset of iris data set

我们在训练机器学习模型时的目标是确定这个二维空间中最好地分隔两个类别的线。幸运的是,这是一个简单的任务,因为这两个类是明显分开的,没有太多的重叠。为此,我们将拟合一个逻辑回归,该回归将创建属于类别 1 的数据点的概率分布。使用 sigmoid 函数(表示为 g)和一些参数θ,我们将使这个概率分布符合我们的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sigmoid function with parameters θ

通过改变矩阵θ中的参数,我们可以调整函数 g 以最佳地拟合我们的数据 x。

def sigmoid(X, theta):
    return 1 / (1 + np.exp(-np.dot(X, theta[0])))

我们将使用二元交叉熵损失作为损失函数来确定模型的预测有多接近真实情况。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Binary Cross-entropy Loss

def loss(X, theta, y):
    h = sigmoid(X, theta)
    return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()

损失函数对(w.r.t.) θ的偏导数告诉我们需要改变θ值的方向,以改变损失。在这种情况下,我们想尽量减少损失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Partial derivative of the loss function w.r.t. θ

h = sigmoid(X, theta)
gradient_wrt_theta = np.dot(X.T, (h - y)) / y.shape[0]

一旦我们通过对θ进行定向更新来最小化损失函数,我们的受害者模型就被训练好了!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Victim model’s probability distribution for class 1

上图显示了该空间中属于类别 1 的任意点的模型概率分布,与类别 0 相反(1- P(y=1))。它还以我们的模型的概率阈值为 0.5 的决策边界为特征,如果一个点在线上,则它属于类别 1 的概率将低于 50%。由于模型“决定”在这个阈值,它将分配 0 作为它的标签预测。

攻击受害者模型

基于雅可比或梯度的攻击的目标,在 Goodfellow 等人的解释和利用对抗的例子中有描述。艾尔。就是在受害者模型的决策边界上移动一个点。在我们的例子中,我们将把一个通常分类为 0 类的点“推”过受害者模型的决策边界,分类为 1 类。当使用高维数据时,对原始点的这种改变也被称为扰动,因为我们对输入进行了非常小的改变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

‘Pushing’ a data point over the victim model’s decision boundary

您可能还记得,在训练逻辑回归时,我们使用了损失函数和损失函数 w.r.t. θ的导数来确定θ需要如何变化才能使损失最小化。作为攻击者,在完全了解受害者模型如何工作的情况下,我们可以通过改变函数的其他输入来确定如何改变损失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Partial derivative of the loss function w.r.t. X

损失函数 w.r.t. X 的导数准确地告诉我们需要在哪个方向改变 X 的值来改变受害者模型的损失。

h = sigmoid(X, theta)
gradient_wrt_X = np.dot(np.expand_dims((h-y),1),theta)/y.shape[0]

既然要攻击模型,就要最大化它的损失。改变 X 的值实质上是在二维空间中移动 X。方向只是对抗性干扰中的一个组成部分。我们还需要考虑在该方向上移动多大的步长(表示为ε)才能越过决策边界。

#Normalizing gradient vectors to make sure step size is consistent
#necessary for our 2-d example, but not called for in the papergradient_magnitudes = np.expand_dims(np.asarray(list(map(lambda x: np.linalg.norm(x), gradient_wrt_X))),1)
grads_norm = gradient_wrt_X/gradient_magnitudes#Creating the adversarial perturbation
epsilon = 0.5 #The step size be adjusted 
X_advs = X+grads_norm*epsilon

对手必须考虑使用哪些数据点或输入,以及成功推动一个点越过决策边界所需的最小ε。如果对手从非常远离 0 级空间的点开始,他们将需要更大和更明显的扰动来将其转换为敌对的例子。让我们转换一些最接近决策边界和来自类 0 的点。(注意:其他技术允许从随机噪声中创建对立的例子- 论文 & 文章)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

‘Pushing’ several data points over the victim model’s decision boundary using epsilon = 0.5

我们已经成功地创造了一些对立的例子!

…嗯,你可能会想:

  1. “我们只是四处搬点东西。这些点只是现在的点不同而已……”
  2. “……我们之所以能够做到这一点,是因为我们对受害者模型了如指掌。如果我们不知道受害者模型是如何工作的呢?”

你是对的。我们会回到第一点,但是尼古拉斯·帕伯诺特等人的针对机器学习的实用黑盒攻击中的技术。艾尔。会帮助我们解决第二点。

攻击黑盒模型:

当我们了解一个模型的一切时,我们称它为“白盒”模型。相比之下,当我们对模型如何工作一无所知时,我们称之为“黑箱”。我们可以把黑盒模型想象成一个 API,我们通过发送输入和接收一些输出(标签、类号等)来 ping 它。理解黑盒攻击是至关重要的,因为它们证明隐藏在 API 后面的模型可能看起来是安全的,但实际上仍然容易受到攻击。

Papernot 的论文讨论了基于雅可比的数据集增强技术,该技术旨在训练另一个模型,称为替代模型,以共享与受害者模型非常相似的决策边界。一旦替代模型被训练成具有与受害者模型几乎相同的决策边界,被创建来将一个点移动到替代模型的决策边界上的对抗性扰动也将可能越过受害者模型的决策边界。他们通过探索受害者模型的决策空间周围的空间并确定受害者如何响应来实现这一点。

训练替代模型

这种技巧可以被描述为一个孩子在学习惹恼他们的父母。孩子一开始对什么会让他们的父母生气没有先入之见,但他们可以通过在一周内随机选择一组行为来测试他们的父母,并注意他们的父母对这些行为的反应。虽然父母可能会对其中的每一个表现出非二元反应,但让我们假设孩子的行为要么是坏的,要么是好的(两类)。在第一周之后,孩子已经了解了一些困扰他们父母的事情,并且有根据地猜测还有什么会困扰他们的父母。第二周,孩子记下成功的行动,并进一步采取不成功的行动。孩子每周重复这一过程,注意他们父母的反应,调整他们对什么会困扰父母的理解,直到他们确切知道什么会困扰他们,什么不会。

基于雅可比的数据集扩充的工作方式与获取初始数据的随机样本并用于训练非常差的替代模型的方式相同。对抗性示例是从数据集创建的(使用之前基于梯度的攻击)。这里,对立的例子是模型梯度方向上的一步,以确定黑盒模型是否会以与替代模型相同的方式对新数据点进行分类。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Substitute model’s decision boundary converges to that of the decision boundary

扩充的数据由黑盒模型标记,并用于训练更好的替代模型。就像孩子一样,替代模型对黑盒模型的决策边界在哪里有了更精确的理解。经过几次迭代后,替代模型与黑盒模型共享几乎完全相同的决策边界。

替代模型甚至不需要与黑盒模型是同一类型的 ML 模型。事实上,一个简单的多层感知器足以学习一个复杂的卷积神经网络足够接近的决策边界。最终,通过少量数据样本、几次数据扩充和标记迭代,可以成功攻击黑盒模型。

点积的诅咒:

现在,回到第一点:你是对的,我在二维空间中移动点。虽然这是为了保持示例的简单性,但对抗性攻击利用了神经网络放大信号的特性。安德烈·卡帕西在中解释了点积的效果,更多细节请点击

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The dot-product amplifies the signal from small adversarial perturbations

在我们的二维例子中,为了移动点穿过受害者模型的决策边界,我们需要以步长ε移动它。当神经网络的权重矩阵乘以正常输入时,每个权重和每个输入值的乘积被求和。然而,在对抗输入的情况下,对抗信号的附加求和放大了作为总输入维度的函数的信号。也就是说,为了实现跨越决策边界所需的步长,我们需要随着输入维度数量的增加,对每个 X 值进行较小的更改。输入维度越大,我们就越难注意到对抗性扰动——这种效应是为什么 MNIST 的对抗性例子比 ImageNet 的对抗性例子更明显的原因之一。

基于梯度的攻击已被证明是有效的技术,它们利用深度学习模型将高维输入处理成概率分布的方式。黑盒攻击表明,只要我们能够访问受害者模型的输入和输出,我们就可以创建一个足够好的模型副本用于攻击。然而,这些技术有弱点。要使用基于梯度的攻击,我们需要确切地知道输入是如何嵌入的(转换成机器可读的格式,如向量)。例如,图像通常表示为二维像素矩阵或三维矩阵,这是信息的一致表示。另一方面,可以使用一些秘密的预训练单词嵌入或学习嵌入来嵌入其他类型的非结构化数据,如文本。因为我们不能对一个单词求导,所以我们需要知道这个单词是如何表示的。训练替代模型需要一组可能可检测到的对黑盒模型的 pings。研究人员正在寻找越来越多的方法来保护他们的模型免受恶意攻击。无论如何,我们必须主动了解我们模型的弱点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值