TowardsDataScience 博客中文翻译 2016~2018(六十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

关联规则完全指南(2/2)

原文:https://towardsdatascience.com/complete-guide-to-association-rules-2-2-c92072b56c84?source=collection_archive---------4-----------------------

帮助您更快、更智能购物的算法

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

在这篇博客中,我将讨论从交易列表中高效提取关联规则的算法。本博客的第 1 部分涵盖了构成关联规则挖掘基础的术语和概念。这整个概念背后的动机和一些基本术语的含义在那里得到了解释。以下是上一部分中一些术语的简要定义。

  1. 关联规则:例如。{X → Y}是在有 X 的篮子上寻找 Y 的表示
  2. 项目集:例如。{X,Y}是构成关联规则的所有项目的列表的表示
  3. Support:包含该项集的事务部分
  4. 置信度:给定{X},出现{Y}的概率存在
  5. lift:置信度与{Y}发生的基线概率之比

现在我们已经熟悉了这些术语,让我们继续从交易列表中提取规则。这个过程的第一步是获得在我们的事务集中至少出现一次的所有项目的列表。

挑战在于从大量的关联规则中挖掘出重要的规则,这些关联规则可以从项目列表中导出。

请记住,规则生成是一个两步过程。第一个是生成一个项目集,如{面包,鸡蛋,牛奶},第二个是从每个项目集生成一个规则,如{面包→鸡蛋,牛奶},{面包,鸡蛋→牛奶}等。下面将讨论这两个步骤。

1.从项目列表生成项目集

产生关联规则的第一步是获得所有的频繁项目集,在这些项目集上可以执行二进制划分以获得前件和后件。例如,如果所有交易组合起来有 6 个项目{面包、黄油、鸡蛋、牛奶、笔记本、牙刷},项目集将看起来像{面包}、{黄油}、{面包、笔记本}、{牛奶、牙刷}、{牛奶、鸡蛋、蔬菜}等。项目集的大小可以从一个项目到我们拥有的项目总数不等。现在,我们只从中寻找频繁项集,而不是全部,以便检查生成的总项集的数量。

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

频繁项集是那些在事务中至少出现最小次数的项集。从技术上讲,这些项目集的支持值(包含该项目集的事务部分)高于最小阈值 minsup

因此,如果{Bread,Notebook}在 100 个事务中只出现 2 次,并且(2/100) = 0.02 低于 minsup 的值,则它可能不是频繁项集。

寻找频繁项目集的强力方法是形成所有可能的项目集,并检查每个项目集的支持值。 先验原则 有助于使这种搜索高效 它表明

频繁项目集的所有子集也必须是频繁的。

这相当于说包含项目{面包,鸡蛋} 的交易数大于或等于包含{面包,鸡蛋,蔬菜} *的交易数。*如果后一种情况发生在 30 笔交易中,前一种情况在所有 30 笔交易中都发生,并且可能会在更多的交易中发生。所以如果{面包,鸡蛋,蔬菜}的支持值即(30/100) = 0.3 高于 minsup,那么我们可以确定{面包,鸡蛋}的支持值即(> 30/100) = > 0.3 也高于 minsup。这被称为支持度的反单调性质,其中如果我们从一个项目集中删除一个项目,生成的新项目集的支持度值要么相同,要么增加。

先验原则是支持度反单调性质的结果。

Apriori 原则允许我们删除不满足支持度最小阈值条件的项目集的所有超集。例如,如果{Milk,Notebook}不满足我们的 minsup 阈值,则添加了任何项的项集也不会超过该阈值。

产生的方法论被称为 apriori 算法。 涉及的步骤有:

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

Ref: https://annalyzin.files.wordpress.com/2016/04/association-rules-apriori-tutorial-explanation.gif

生成只有一个项目的所有频繁项目集(支持≥ minsup)。接下来,生成长度为 2 的项集,作为上述项集的所有可能组合。然后,删除那些支持值低于最小支持值的。

现在,将长度为 3 的项集生成为长度为 2 的项集的所有可能组合(修剪后保留下来),并对支持值执行相同的检查。

我们像这样不断增加项目集的长度,并在每一步检查阈值。

从图中可以看出,修剪非频繁项集可以将需要考虑的项集数量减少一半以上!随着项目数量的增加,计算能力降低的比例变得越来越显著。

这个比例还取决于我们选取的最小支持阈值(minsup ),它完全是对当前问题的主观判断,可以基于过去的经验。

2.从频繁项目集生成所有可能的规则

一旦产生了频繁项集,从中找出规则相对来说就不那么费力了。规则是通过对每个项目集进行二进制划分形成的。如果{面包,鸡蛋,牛奶,黄油}是频繁项目集,候选规则将如下所示:

(鸡蛋,牛奶,黄油→面包),(面包,牛奶,黄油→鸡蛋),(面包,鸡蛋→牛奶,黄油),(鸡蛋,牛奶→面包,黄油),(黄油→面包,鸡蛋,牛奶)

从所有可能的候选规则列表中,我们的目标是识别出低于最低置信水平 (minconf)的规则。和支持度的反单调性质一样,从同一个项目集 生成的规则 置信度也遵循一个反单调性质。它相对于结果项中的元素数是反单调的。

这意味着(A,B,C→ D) ≥ (B,C → A,D) ≥ (C → A,B,D)的置信度。提醒一下,对{X → Y}的信心=支持{X,Y }/支持{X}

正如我们所知,从相同项目集生成的所有规则的支持度保持不变,差异仅发生在置信度的分母计算中。随着 X 中项目数量的减少,支持度{X}增加(根据支持度的反单调性质),因此置信度值减少。

对上述内容的直观解释如下。考虑 F1 和 F2:

F1 =既有(黄油)又有(鸡蛋、牛奶、面包)的交易比例

将会有很多有黄油的交易,而鸡蛋、牛奶和面包这三者将只能在其中的一小部分中找到位置。

F2 =有(牛奶、黄油、面包)也有(鸡蛋)的交易的比例

牛奶、黄油和面包三者都有(相比之下只有黄油)的交易将会很少,而且很有可能会有鸡蛋。

所以会观察到 F1 < F2. Using this property of confidence, pruning is done in a similar way as was done while looking for frequent itemsets. It is illustrated in the figure below.

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

Ref: https://www-users.cs.umn.edu/~kumar001/dmbook/ch6.pdf

We start with a frequent itemset {a,b,c,d} and start forming rules with just one consequent. Remove the rules failing to satisfy the minconf condition. Now, start forming rules using a combination of consequents from the remaining ones. Keep repeating until only one item is left on antecedent. This process has to be done for all frequent itemsets.

Here again, minimum confidence threshold that we pick up is completely subjective to the problem at hand.

With these two steps, we have identified a set of association rules which satisfy both the minimum support and minimum confidence condition. The number of such rules obtained will vary with the values of minsupminconf 。现在,可以搜索这样生成的规则子集,以获得 lift 的最高值,从而做出业务决策。R 中有一些构建良好的库,通过将 minsup 和 minconf 作为参数放入事务中来获取关联规则。它们还提供了可视化的能力。本文这里用代码一步一步的讨论整个过程。

在结束之前,我将引入两个术语,最大频繁项集和闭频繁项集,它们是所有频繁项集的紧凑表示。

最大频繁项集: 它是一个其直接超集都不频繁的频繁项集。这就像一个频繁项集 X,其中不能添加任何项 y,因此{X,y}仍然高于 minsup 阈值。

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

Different cases for itemset {Bread, Butter}

闭频繁项集 : 它是一个不存在与项集具有相同支持度的超集的频繁项集。考虑一个项目集 X,如果 X 的所有出现都伴随着 Y 的出现,那么 X 不是闭集。(例如参考下图)

最大频繁项目集是有价值的,因为它们是频繁项目集的最紧凑的表示形式。

所有的频繁项集都可以导出为最大频繁项集的子集。然而,关于子集支持的信息丢失了。如果该值是必需的,则闭频繁项集是表示所有频繁项集的另一种方式。

封闭项集有助于删除一些冗余项集,同时不会丢失有关支持值的信息。

从封闭项集计算非封闭项集的支持值是另一种算法,其细节不在本文讨论范围之内。

我试图通过这篇博客涵盖所有与关联规则挖掘相关的重要术语和概念,并在必要时详细介绍。以下是该过程中引入几个术语一行摘要——

  1. 关联规则挖掘:(1)项目集生成,(2)规则生成
  2. 先验原则:频繁项目集的所有子集也必须是频繁的
  3. Apriori 算法:剪枝以有效获取所有频繁项集
  4. 最大频繁项目集:没有一个直接超集是频繁的
  5. 封闭频繁项集:没有一个直接超集具有相同的支持值

我希望你喜欢读这篇文章,并且比以前有更清晰的思路。如果您有兴趣阅读更多详细信息,请参考资源。通过评论让我知道你的想法/问题。

如果你还没有阅读第一篇博客中的介绍,请在这里阅读!

使用 TensorFlow 和 Flask RESTful Python API 构建基于 ConvNet HTTP 的应用程序的完整指南

原文:https://towardsdatascience.com/complete-guide-to-build-convnet-http-based-application-using-tensorflow-and-flask-restful-python-c6326b13878b?source=collection_archive---------10-----------------------

本教程将带您了解使用 TensorFlow 创建卷积神经网络(CNN/ConvNet)所需的步骤,并通过允许使用 Flask RESTful API 通过基于 HTTP 的应用程序进行远程访问,将其投入生产。

该教程在 2018 年 5 月 15 日至 20 日期间在 KDnuggets.com 最常分享的帖子中排名第二。它获得了银质徽章。

在本教程中,CNN 将使用 TensorFlow NN (tf.nn)模块构建。CNN 模型架构是针对 CIFAR10 数据集创建、训练和测试的。为了使模型可以远程访问,使用 Python 创建了一个 Flask Web 应用程序来接收上传的图像,并使用 HTTP 返回其分类标签。在有 CPU 支持的 Windows 上,除了 TensorFlow 之外,还使用 Anaconda3。本教程假设你对 CNN 有一个基本的了解,比如层、步幅和填充。还需要关于 Python 的知识。

本教程总结为以下步骤:

1.通过安装 Python、TensorFlow、PyCharm 和 Flask API 来准备环境。

2.下载和准备 CIFAR-10 数据集。

3.用张量流建立 CNN 计算图。

4.训练 CNN。

5.保存训练好的 CNN 模型。

6.准备测试数据并恢复训练好的 CNN 模型。

7.测试训练好的 CNN 模型。

8.构建 Flask Web 应用程序。

9.使用 HTML 表单上传图像。

10.创建辅助 HTML、JavaScript 和 CSS 文件。

11.基于 HTTP 远程访问训练好的模型进行预测。

1。安装 Python、TensorFlow、PyCharm 和 Flask API

在开始构建项目之前,需要准备它的环境。Python 是第一个开始安装的工具,因为环境完全依赖于它。如果您已经准备好了环境,可以跳过第一步。

1.1 Anaconda/Python 安装

可以安装原生 Python 发行版,但是建议使用一体化包,比如 Anaconda,因为它会为您做一些事情。在这个项目中,使用了 Anaconda 3。对于 Windows,可执行文件可以从 https://www.anaconda.com/download/#windows 的下载。它很容易安装。

为了确保 Anaconda3 安装正确,可以发出 CMD 命令(,其中 python ),如图 1 所示。如果 Anaconda3 安装正确,它的安装路径将出现在命令输出中。

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

Figure 1

1.2 张量流安装

使用 Anaconda3 安装 Python 后,接下来就是安装 TensorFlow (TF)。本教程在有 CPU 支持的 Windows 上使用 TF。安装说明见本页https://www.tensorflow.org/install/install_windows。这段 YouTube 视频可能会有所帮助(【https://youtu.be/MsONo20MRVU】T2)。

TF 安装步骤如下:

1)通过调用该命令为 TF 创建一个 conda 环境:

C:> conda create -n tensorflow pip python=3.5

这将创建一个空文件夹来存放 TF 安装的虚拟环境(venv)。venv 位于此位置的 Anaconda3 安装目录下(\Anaconda3\envs\tensorflow)。

使用此命令激活 TensorFlow 安装的 venv:

C:> activate tensorflow

上面的命令告诉我们,我们在 venv 内部,任何库安装都将在其中。在此命令之后,命令提示符应更改为(tensorflow)C:>。进入目录后,我们准备安装库。

3)激活 venv 后,可以通过发出以下命令安装 Windows TensorFlow 的纯 CPU 版本:

**(tensorflow)C:> pip install --ignore-installed --upgrade tensorflow**

为了测试 TF 是否安装正确,我们可以尝试如图 2 所示导入它。但是记住在导入 TF 之前,必须激活它的 venv。从 CMD 测试它,我们需要发出 python 命令,以便能够与 python 交互。因为导入行中没有出现错误,所以 TF 安装成功。

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

Figure 2

1.3 PyCharm Python IDE 安装

对于这个项目,建议使用 Python IDE,而不是在 CMD 中输入命令。本教程中使用的 IDE 是 PyCharm。它的 Windows 可执行文件可以从这个页面下载https://www.jetbrains.com/pycharm/download/#section=windows。它的安装说明非常简单。

下载安装 PyCharm Python IDE 后,接下来就是和 TF 链接了。这是通过将其 Python 解释器设置为 TF venv 下安装的 Python 来实现的,如图 3 所示。这是通过打开 IDE 的设置并选择安装在 TF venv 中的python.exe文件的项目解释器来完成的。

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

Figure 3

1.4 烧瓶安装

最后要安装的工具是 Flask RESTful API。它是一个要使用 pip/conda 安装程序在 TF venv 下使用以下 CMD 命令安装的库:

C:> pip install Flask-API

如果 NumPy 和 SciPy 尚未安装,应该安装在 venv 中,以便能够读取和操作图像。

通过安装 Anaconda (Python)、TensorFlow、PyCharm 和 Flask,我们已经准备好开始构建项目了。

2。下载和准备 CIFAR-10 数据集

10 类 CIFAR 数据集(CIFAR-10)的 Python 版本可以从 https://www.cs.toronto.edu/~kriz/cifar.html的这个页面下载。该数据集包含 60,000 幅图像,分为训练和测试数据。有五个保存训练数据的文件,其中每个文件有 10,000 个图像。这些图像是大小为 32x32x3 的 RGB。训练文件被命名为 data_batch_1data_batch_2 等等。有一个保存测试数据的文件,名为 test_batch ,包含 10,000 个图像。有一个名为 batches.meta 的元数据文件,保存着数据集类标签,分别是飞机汽车鹿青蛙卡车

因为数据集中的每个文件都是二进制文件,所以应该对其进行解码,以便检索实际的图像数据。为此,创建了一个名为 unpickle_patch 的函数来完成此类工作,定义如下:

def unpickle_patch(file):
"""
Decoding the binary file.
:param file:File to decode it data.
:return: Dictionary of the file holding details including input data and output labels.
"""
patch_bin_file = open(file, 'rb')#Reading the binary file.
patch_dict = pickle.load(patch_bin_file, encoding='bytes')#Loading the details of the binary file into a dictionary.
return patch_dict#Returning the dictionary.

该方法接受二进制文件名,并返回一个包含该文件详细信息的字典。除了标签之外,字典还保存文件中所有 10,000 个样本的数据。

为了解码整个训练数据,创建了一个名为 get_dataset_images 的新函数。该函数接受数据集路径,并且只对定型数据起作用。因此,它会过滤该路径下的文件,并仅返回以 data_batch_ 开头的文件。测试数据是在构建和训练 CNN 之后准备的。

对于每个训练文件,通过调用 unpickle_patch 函数对其进行解码。基于此类函数返回的字典,get_dataset_images 函数返回图像数据及其类标签。从**‘数据’键检索图像数据,从‘标签’**键检索图像的类别标签。

因为图像数据保存为 1D 矢量,它应该被整形为三维。这是因为张量流接受这种形状的图像。因此,get_dataset_images 函数除了接受每个图像中的通道数之外,还接受行数/列数作为参数。

该功能的实现如下:

def get_dataset_images(dataset_path, im_dim=32, num_channels=3):
    """
    This function accepts the dataset path, reads the data, and returns it after being reshaped to match the requierments of the CNN.
    :param dataset_path:Path of the CIFAR10 dataset binary files.
    :param im_dim:Number of rows and columns in each image. The image is expected to be rectangular.
    :param num_channels:Number of color channels in the image.
    :return:Returns the input data after being reshaped and output labels.
    """
    num_files = 5#Number of training binary files in the CIFAR10 dataset.
    images_per_file = 10000#Number of samples withing each binary file.
    files_names = os.listdir(patches_dir)#Listing the binary files in the dataset path.
    """
    Creating an empty array to hold the entire training data after being reshaped.
    The dataset has 5 binary files holding the data. Each binary file has 10,000 samples. Total number of samples in the dataset is 5*10,000=50,000.
    Each sample has a total of 3,072 pixels. These pixels are reshaped to form a RGB image of shape 32x32x3.
    Finally, the entire dataset has 50,000 samples and each sample of shape 32x32x3 (50,000x32x32x3).
    """
    dataset_array = numpy.zeros(shape=(num_files * images_per_file, im_dim, im_dim, num_channels))
    #Creating an empty array to hold the labels of each input sample. Its size is 50,000 to hold the label of each sample in the dataset.
    dataset_labels = numpy.zeros(shape=(num_files * images_per_file), dtype=numpy.uint8)
    index = 0#Index variable to count number of training binary files being processed.
    for file_name in files_names:
        """
        Because the CIFAR10 directory does not only contain the desired training files and has some  other files, it is required to filter the required files.
        Training files start by 'data_batch_' which is used to test whether the file is for training or not.
        """
        if file_name[0:len(file_name) - 1] == "data_batch_":
            print("Working on : ", file_name)
            """
            Appending the path of the binary files to the name of the current file.
            Then the complete path of the binary file is used to decoded the file and return the actual pixels values.
            """
            data_dict = unpickle_patch(dataset_path+file_name)
            """
            Returning the data using its key 'data' in the dictionary.
            Character b is used before the key to tell it is binary string.
            """
            images_data = data_dict[b"data"]
            #Reshaping all samples in the current binary file to be of 32x32x3 shape.
            images_data_reshaped = numpy.reshape(images_data, newshape=(len(images_data), im_dim, im_dim, num_channels))
            #Appending the data of the current file after being reshaped.
            dataset_array[index * images_per_file:(index + 1) * images_per_file, :, :, :] = images_data_reshaped
            #Appening the labels of the current file.
            dataset_labels[index * images_per_file:(index + 1) * images_per_file] = data_dict[b"labels"]
            index = index + 1#Incrementing the counter of the processed training files by 1 to accept new file.
    return dataset_array, dataset_labels#Returning the training input data and output labels.

通过准备训练数据,我们可以使用 TF 建立和训练 CNN 模型。

3。使用 TensorFlow 构建 CNN 计算图

CNN 的计算图是在一个名为 create_CNN 的函数中创建的。它创建卷积(conv)、ReLU、最大池化、下降和完全连接(FC)图层的堆栈,并返回最后一个完全连接图层的结果。每一层的输出都是下一层的输入。这要求相邻层的输出和输入的大小一致。请注意,对于每个 conv、ReLU 和 max 池层,有一些参数需要指定,如每个维度的跨度和填充。

def create_CNN(input_data, num_classes, keep_prop):
"""
Builds the CNN architecture by stacking conv, relu, pool, dropout, and fully connected layers.
:param input_data:patch data to be processed.
:param num_classes:Number of classes in the dataset. It helps determining the number of outputs in the last fully connected layer.
:param keep_prop:probability of dropping neurons in the dropout layer.
:return: last fully connected layer.
"""
#Preparing the first convolution layer.
filters1, conv_layer1 = create_conv_layer(input_data=input_data, filter_size=5, num_filters=4)
"""
Applying ReLU activation function over the conv layer output.
It returns a new array of the same shape as the input array.
"""
relu_layer1 = tensorflow.nn.relu(conv_layer1)
print("Size of relu1 result : ", relu_layer1.shape)
"""
Max pooling is applied to the ReLU layer result to achieve translation invariance.
It returns a new array of a different shape from the the input array relative to the strides and kernel size used.
"""
max_pooling_layer1 = tensorflow.nn.max_pool(value=relu_layer1, ksize=[1, 2, 2, 1], strides=[1, 1, 1, 1], padding="VALID")
print("Size of maxpool1 result : ", max_pooling_layer1.shape)#Similar to the previous conv-relu-pool layers, new layers are just stacked to complete the CNN architecture.
#Conv layer with 3 filters and each filter is of sisze of 5x5.
filters2, conv_layer2 = create_conv_layer(input_data=max_pooling_layer1, filter_size=7, num_filters=3)
relu_layer2 = tensorflow.nn.relu(conv_layer2)
print("Size of relu2 result : ", relu_layer2.shape)
max_pooling_layer2 = tensorflow.nn.max_pool(value=relu_layer2, ksize=[1, 2, 2, 1], strides=[1, 1, 1, 1], padding="VALID")
print("Size of maxpool2 result : ", max_pooling_layer2.shape)#Conv layer with 2 filters and a filter sisze of 5x5.
filters3, conv_layer3 = create_conv_layer(input_data=max_pooling_layer2, filter_size=5, num_filters=2)
relu_layer3 = tensorflow.nn.relu(conv_layer3)
print("Size of relu3 result : ", relu_layer3.shape)
max_pooling_layer3 = tensorflow.nn.max_pool(value=relu_layer3, ksize=[1, 2, 2, 1], strides=[1, 1, 1, 1], padding="VALID")
print("Size of maxpool3 result : ", max_pooling_layer3.shape)#Adding dropout layer before the fully connected layers to avoid overfitting.
flattened_layer = dropout_flatten_layer(previous_layer=max_pooling_layer3, keep_prop=keep_prop)#First fully connected (FC) layer. It accepts the result of the dropout layer after being flattened (1D).
fc_resultl = fc_layer(flattened_layer=flattened_layer, num_inputs=flattened_layer.get_shape()[1:].num_elements(),
num_outputs=200)
#Second fully connected layer accepting the output of the previous fully connected layer. Number of outputs is equal to the number of dataset classes.
fc_result2 = fc_layer(flattened_layer=fc_resultl, num_inputs=fc_resultl.get_shape()[1:].num_elements(), num_outputs=num_classes)
print("Fully connected layer results : ", fc_result2)
return fc_result2#Returning the result of the last FC layer.

因为卷积层在输入数据和所用的一组过滤器之间应用卷积运算,所以 create_CNN 函数接受输入数据作为输入参数。get_dataset_images 函数返回的就是这样的数据。卷积图层是使用创建 conv 图层函数创建的。create_conv_layer 函数接受输入数据、过滤器大小和过滤器数量,并返回输入数据与过滤器集合的卷积结果。这组滤波器根据输入图像的深度来设置它们的大小。创建 conv 层的定义如下:

def create_conv_layer(input_data, filter_size, num_filters):"""Builds the CNN convolution (conv) layer.:param input_data:patch data to be processed.:param filter_size:#Number of rows and columns of each filter. It is expected to have a rectangular filter.:param num_filters:Number of filters.:return:The last fully connected layer of the network.""""""Preparing the filters of the conv layer by specifiying its shape.Number of channels in both input image and each filter must match.Because number of channels is specified in the shape of the input image as the last value, index of -1 works fine."""filters = tensorflow.Variable(tensorflow.truncated_normal(shape=(filter_size, filter_size, tensorflow.cast(input_data.shape[-1], dtype=tensorflow.int32), num_filters),stddev=0.05))print("Size of conv filters bank : ", filters.shape)"""Building the convolution layer by specifying the input data, filters, strides along each of the 4 dimensions, and the padding.Padding value of 'VALID' means the some borders of the input image will be lost in the result based on the filter size."""conv_layer = tensorflow.nn.conv2d(input=input_data,filter=filters,strides=[1, 1, 1, 1],padding="VALID")print("Size of conv result : ", conv_layer.shape)return filters, conv_layer#Returing the filters and the convolution layer result.

另一个论点是神经元留在脱落层的概率。它指定有多少神经元被丢弃层丢弃。dropout 层是使用 dropout_flatten_layer 函数实现的,如下所示。该函数返回一个展平的数组,该数组将作为完全连接的层的输入。

def dropout_flatten_layer(previous_layer, keep_prop):"""Applying the dropout layer.:param previous_layer: Result of the previous layer to the dropout layer.:param keep_prop: Probability of keeping neurons.:return: flattened array."""dropout = tensorflow.nn.dropout(x=previous_layer, keep_prob=keep_prop)num_features = dropout.get_shape()[1:].num_elements()layer = tensorflow.reshape(previous_layer, shape=(-1, num_features))#Flattening the results.return layer

因为最后一个 FC 层的输出神经元的数量应该等于数据集类的数量,所以数据集类的数量被用作 create_CNN 函数的另一个输入参数。使用 fc_layer 函数创建完全连接的层。该函数接受丢弃层的展平结果、展平结果中的特征数量以及 FC 层的输出神经元数量。根据输入和输出的数量,创建一个权重张量,然后乘以展平层,以获得 FC 层的返回结果。

def fc_layer(flattened_layer, num_inputs, num_outputs):"""uilds a fully connected (FC) layer.:param flattened_layer: Previous layer after being flattened.:param num_inputs: Number of inputs in the previous layer.:param num_outputs: Number of outputs to be returned in such FC layer.:return:"""#Preparing the set of weights for the FC layer. It depends on the number of inputs and number of outputs.fc_weights = tensorflow.Variable(tensorflow.truncated_normal(shape=(num_inputs, num_outputs),stddev=0.05))#Matrix multiplication between the flattened array and the set of weights.fc_resultl = tensorflow.matmul(flattened_layer, fc_weights)return fc_resultl#Output of the FC layer (result of matrix multiplication).

使用 TensorBoard 可视化后的计算图如图 4 所示。

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

Figure 4

4。训练 CNN

在构建了 CNN 的计算图之后,接下来是针对先前准备的训练数据来训练它。训练是根据下面的代码完成的。代码首先准备数据集的路径,并将其准备到一个占位符中。请注意,路径应该更改为适合您的系统。然后它调用前面讨论过的函数。被训练的 CNN 的预测被用于测量网络的成本,该成本将使用梯度下降优化器被最小化。注意:一些张量有一个名字,这有助于以后测试 CNN 时检索这些张量。

#Nnumber of classes in the dataset. Used to specify number of outputs in the last fully connected layer.num_datatset_classes = 10#Number of rows & columns in each input image. The image is expected to be rectangular Used to reshape the images and specify the input tensor shape.im_dim = 32#Number of channels in rach input image. Used to reshape the images and specify the input tensor shape.num_channels = 3#Directory at which the training binary files of the CIFAR10 dataset are saved.patches_dir = "C:\\Users\\Dell\\Downloads\\Compressed\\cifar-10-python\\cifar-10-batches-py\\"#Reading the CIFAR10 training binary files and returning the input data and output labels. Output labels are used to test the CNN prediction accuracy.dataset_array, dataset_labels = get_dataset_images(dataset_path=patches_dir, im_dim=im_dim, num_channels=num_channels)print("Size of data : ", dataset_array.shape)"""Input tensor to hold the data read above. It is the entry point of the computational graph.The given name of 'data_tensor' is useful for retreiving it when restoring the trained model graph for testing."""data_tensor = tensorflow.placeholder(tensorflow.float32, shape=[None, im_dim, im_dim, num_channels], name='data_tensor')"""Tensor to hold the outputs label.The name "label_tensor" is used for accessing the tensor when tesing the saved trained model after being restored."""label_tensor = tensorflow.placeholder(tensorflow.float32, shape=[None], name='label_tensor')#The probability of dropping neurons in the dropout layer. It is given a name for accessing it later.keep_prop = tensorflow.Variable(initial_value=0.5, name="keep_prop")#Building the CNN architecure and returning the last layer which is the fully connected layer.fc_result2 = create_CNN(input_data=data_tensor, num_classes=num_datatset_classes, keep_prop=keep_prop)"""Predicitions probabilities of the CNN for each training sample.Each sample has a probability for each of the 10 classes in the dataset.Such tensor is given a name for accessing it later."""softmax_propabilities = tensorflow.nn.softmax(fc_result2, name="softmax_probs")"""Predicitions labels of the CNN for each training sample.The input sample is classified as the class of the highest probability.axis=1 indicates that maximum of values in the second axis is to be returned. This returns that maximum class probability fo each sample."""softmax_predictions = tensorflow.argmax(softmax_propabilities, axis=1)#Cross entropy of the CNN based on its calculated probabilities.cross_entropy = tensorflow.nn.softmax_cross_entropy_with_logits(logits=tensorflow.reduce_max(input_tensor=softmax_propabilities, reduction_indices=[1]),labels=label_tensor)#Summarizing the cross entropy into a single value (cost) to be minimized by the learning algorithm.cost = tensorflow.reduce_mean(cross_entropy)#Minimizng the network cost using the Gradient Descent optimizer with a learning rate is 0.01.error = tensorflow.train.GradientDescentOptimizer(learning_rate=.01).minimize(cost)#Creating a new TensorFlow Session to process the computational graph.sess = tensorflow.Session()#Wiriting summary of the graph to visualize it using TensorBoard.tensorflow.summary.FileWriter(logdir="./log/", graph=sess.graph)#Initializing the variables of the graph.sess.run(tensorflow.global_variables_initializer())"""Because it may be impossible to feed the complete data to the CNN on normal machines, it is recommended to split the data into a number of patches.A percent of traning samples is used to create each path. Samples for each path can be randomly selected."""num_patches = 5#Number of patchesfor patch_num in numpy.arange(num_patches):print("Patch : ", str(patch_num))percent = 80 #percent of samples to be included in each path.#Getting the input-output data of the current path.shuffled_data, shuffled_labels = get_patch(data=dataset_array, labels=dataset_labels, percent=percent)#Data required for cnn operation. 1)Input Images, 2)Output Labels, and 3)Dropout probabilitycnn_feed_dict = {data_tensor: shuffled_data,label_tensor: shuffled_labels,keep_prop: 0.5}"""Training the CNN based on the current patch.CNN error is used as input in the run to minimize it.SoftMax predictions are returned to compute the classification accuracy."""softmax_predictions_, _ = sess.run([softmax_predictions, error], feed_dict=cnn_feed_dict)#Calculating number of correctly classified samples.correct = numpy.array(numpy.where(softmax_predictions_ == shuffled_labels))correct = correct.sizeprint("Correct predictions/", str(percent * 50000/100), ' : ', correct)

不是将整个训练数据提供给 CNN,而是将数据分成一组小块,然后一个小块一个小块地通过环路提供给网络。每个补丁包含训练数据的子集。使用 get_patch 函数返回补丁。该函数接受输入数据、标签以及从这些数据中返回的样本百分比。然后,它根据输入的百分比返回数据的子集。

def get_patch(data, labels, percent=70):"""Returning patch to train the CNN.:param data: Complete input data after being encoded and reshaped.:param labels: Labels of the entire dataset.:param percent: Percent of samples to get returned in each patch.:return: Subset of the data (patch) to train the CNN model."""#Using the percent of samples per patch to return the actual number of samples to get returned.num_elements = numpy.uint32(percent*data.shape[0]/100)shuffled_labels = labels#Temporary variable to hold the data after being shuffled.numpy.random.shuffle(shuffled_labels)#Randomly reordering the labels."""The previously specified percent of the data is returned starting from the beginning until meeting the required number of samples.The labels indices are also used to return their corresponding input images samples."""return data[shuffled_labels[:num_elements], :, :, :], shuffled_labels[:num_elements]

5。保存训练好的 CNN 模型

在对 CNN 进行训练之后,模型被保存起来,供以后在另一个 Python 脚本中测试时重用。您还应该更改保存模型的路径,以适合您的系统。

#Saving the model after being trained.
saver = tensorflow.train.Saver()
save_model_path = "C:\\model\\"
save_path = saver.save(sess=sess, save_path=save_model_path+"model.ckpt")
print("Model saved in : ", save_path)

6。准备测试数据,恢复训练好的 CNN 模型

在测试训练好的模型之前,需要准备测试数据并恢复之前训练好的模型。测试数据准备与训练数据类似,只是只有一个二进制文件需要解码。根据修改的 get_dataset_images 函数对测试文件进行解码。这个函数调用 unpickle_patch 函数,就像之前对训练数据所做的一样。

def get_dataset_images(test_path_path, im_dim=32, num_channels=3):"""Similar to the one used in training except that there is just a single testing binary file for testing the CIFAR10 trained models."""print("Working on testing patch")data_dict = unpickle_patch(test_path_path)images_data = data_dict[b"data"]dataset_array = numpy.reshape(images_data, newshape=(len(images_data), im_dim, im_dim, num_channels))return dataset_array, data_dict[b"labels"]

7。测试训练好的 CNN 模型。

准备好测试数据,恢复训练好的模型后,我们就可以按照下面的代码开始测试模型了。值得一提的是,我们的目标只是返回输入样本的网络预测。这就是为什么 TF 会话只返回预测。当训练 CNN 时,会话运行以最小化成本。在测试中,我们不再对最小化成本感兴趣。另一个有趣的地方是,dropout 层的保持概率现在被设置为 1。这意味着不要删除任何节点。这是因为我们只是在确定了要删除的节点后才使用预训练模型。现在,我们只是使用模型之前所做的,并不关心通过删除其他节点来修改它。

#Dataset path containing the testing binary file to be decoded.patches_dir = "C:\\Users\\Dell\\Downloads\\Compressed\\cifar-10-python\\cifar-10-batches-py\\"dataset_array, dataset_labels = get_dataset_images(test_path_path=patches_dir + "test_batch", im_dim=32, num_channels=3)print("Size of data : ", dataset_array.shape)sess = tensorflow.Session()#Restoring the previously saved trained model.saved_model_path = 'C:\\Users\\Dell\\Desktop\\model\\'saver = tensorflow.train.import_meta_graph(saved_model_path+'model.ckpt.meta')saver.restore(sess=sess, save_path=saved_model_path+'model.ckpt')#Initalizing the varaibales.sess.run(tensorflow.global_variables_initializer())graph = tensorflow.get_default_graph()"""Restoring previous created tensors in the training phase based on their given tensor names in the training phase.Some of such tensors will be assigned the testing input data and their outcomes (data_tensor, label_tensor, and keep_prop).Others are helpful in assessing the model prediction accuracy (softmax_propabilities and softmax_predictions)."""softmax_propabilities = graph.get_tensor_by_name(name="softmax_probs:0")softmax_predictions = tensorflow.argmax(softmax_propabilities, axis=1)data_tensor = graph.get_tensor_by_name(name="data_tensor:0")label_tensor = graph.get_tensor_by_name(name="label_tensor:0")keep_prop = graph.get_tensor_by_name(name="keep_prop:0")#keep_prop is equal to 1 because there is no more interest to remove neurons in the testing phase.feed_dict_testing = {data_tensor: dataset_array,label_tensor: dataset_labels,keep_prop: 1.0}#Running the session to predict the outcomes of the testing samples.softmax_propabilities_, softmax_predictions_ = sess.run([softmax_propabilities, softmax_predictions],feed_dict=feed_dict_testing)#Assessing the model accuracy by counting number of correctly classified samples.correct = numpy.array(numpy.where(softmax_predictions_ == dataset_labels))correct = correct.sizeprint("Correct predictions/10,000 : ", correct)

8。构建 Flask Web 应用程序

在训练 CNN 模型之后,我们可以将它添加到 HTTP 服务器上,并允许用户在线使用它。用户将使用 HTTP 客户端上传图像。上传的图像将由 HTTP 服务器接收,或者更具体地说,由 Flask Web 应用程序接收。这种应用将基于训练的模型预测图像的类别标签,并最终将类别标签返回给 HTTP 客户端。图 5 总结了这种讨论。

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

Figure 5

要开始构建 flask 应用程序,需要创建 Flask 库,并使用 Flask 类创建一个新的应用程序。最后,这样的应用程序将运行以从 Web 访问。此类应用程序有一些属性,如访问它的主机、端口号和返回调试信息的调试标志。运行应用程序后,可以使用指定的主机和端口号来访问它。

import flask#Creating a new Flask Web application. It accepts the package name.app = flask.Flask("CIFAR10_Flask_Web_App")"""To activate the Web server to receive requests, the application must run.A good practice is to check whether the file is whether the file called from an external Python file or not.If not, then it will run."""if __name__ == "__main__":"""In this example, the app will run based on the following properties:host: localhostport: 7777debug: flag set to True to return debugging information."""app.run(host="localhost", port=7777, debug=True)

目前,服务器没有提供任何功能。服务器应该做的第一件事是允许用户上传图像。当用户访问应用程序的根 URL 时,应用程序什么也不做。应用程序可以将用户重定向到一个 HTML 页面,用户可以在该页面上传图像。为此,该应用程序有一个名为 redirect_upload 的函数,将用户重定向到上传图像的页面。让这个函数在用户访问应用程序的根目录后执行的是使用以下代码行创建的路由:

app.add_url_rule(rule="/", endpoint="homepage", view_func=redirect_upload)

这一行说的是如果用户访问 app 的根目录(标记为**"/),那么就会调用查看器函数(redirect_upload)。此类函数除了呈现一个名为 upload_image.html 的 HTML 页面之外什么也不做。该页面位于服务器的专用模板**目录下。模板目录中的页面通过调用 render_template 函数来呈现。请注意,有一个名为 endpoint 的属性,它使多次重用相同的路由变得容易,而无需对其进行硬编码。

def redirect_upload():"""A viewer function that redirects the Web application from the root to a HTML page for uploading an image to get classified.The HTML page is located under the /templates directory of the application.:return: HTML page used for uploading an image. It is 'upload_image.html' in this exmaple."""return flask.render_template(template_name_or_list="upload_image.html")"""Creating a route between the homepage URL (http://localhost:7777) to a viewer function that is called after getting to such URL.Endpoint 'homepage' is used to make the route reusable without hard-coding it later."""app.add_url_rule(rule="/", endpoint="homepage", view_func=redirect_upload)

呈现的 HTML 页面的屏幕如图 6 所示。

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

Figure 6

下面是这个页面的 HTML 代码。这是一个简单的表单,允许用户上传图像文件。提交该表单时,将向 URLHTTP://localhost:7777/upload/返回一条 POST HTTP 消息。

<!DOCTYPE html><html lang="en"><head><link rel="stylesheet" type="text/css" href="{{url_for(endpoint='static', filename='project_styles.css')}}"><meta charset="UTF-8"><title>Upload Image</title></head><body><form enctype="multipart/form-data" method="post" action="http://localhost:7777/upload/"><center><h3>Select CIFAR10 image to predict its label.</h3><input type="file" name="image_file" accept="image/*"><br><input type="submit" value="Upload"></center></form></body></html>

从 HTML 表单返回到服务器后,将调用与在表单动作属性中指定的 URL 相关联的查看器函数,即 upload_image 函数。该函数获取用户选择的图像,并将其保存到服务器。

def upload_image():"""Viewer function that is called in response to getting to the 'http://localhost:7777/upload' URL.It uploads the selected image to the server.:return: redirects the application to a new page for predicting the class of the image."""#Global variable to hold the name of the image file for reuse later in prediction by the 'CNN_predict' viewer functions.global secure_filenameif flask.request.method == "POST":#Checking of the HTTP method initiating the request is POST.img_file = flask.request.files["image_file"]#Getting the file name to get uploaded.secure_filename = werkzeug.secure_filename(img_file.filename)#Getting a secure file name. It is a good practice to use it.img_path = os.path.join(app.root_path, secure_filename)#Preparing the full path under which the image will get saved.img_file.save(img_path)#Saving the image in the specified path.print("Image uploaded successfully.")"""After uploading the image file successfully, next is to predict the class label of it.The application will fetch the URL that is tied to the HTML page responsible for prediction and redirects the browser to it.The URL is fetched using the endpoint 'predict'."""return flask.redirect(flask.url_for(endpoint="predict"))return "Image upload failed.""""Creating a route between the URL (http://localhost:7777/upload) to a viewer function that is called after navigating to such URL.Endpoint 'upload' is used to make the route reusable without hard-coding it later.The set of HTTP method the viewer function is to respond to is added using the 'methods' argument.In this case, the function will just respond to requests of method of type POST."""app.add_url_rule(rule="/upload/", endpoint="upload", view_func=upload_image, methods=["POST"])

将图像成功上传到服务器后,我们就可以读取图像,并使用之前训练的 CNN 模型预测其类别标签。因此,upload_image 函数将应用程序重定向到负责预测图像类别标签的查看器函数。这种查看器功能是通过其在该行中指定的端点来实现的:

return flask.redirect(flask.url_for(endpoint="predict"))

将调用与 endpoint =**“predict”**关联的方法,这是 CNN_predict 函数。

def CNN_predict():"""Reads the uploaded image file and predicts its label using the saved pre-trained CNN model.:return: Either an error if the image is not for CIFAR10 dataset or redirects the browser to a new page to show the prediction result if no error occurred.""""""Setting the previously created 'secure_filename' to global.This is because to be able invoke a global variable created in another function, it must be defined global in the caller function."""global secure_filename#Reading the image file from the path it was saved in previously.img = scipy.misc.imread(os.path.join(app.root_path, secure_filename))"""Checking whether the image dimensions match the CIFAR10 specifications.CIFAR10 images are RGB (i.e. they have 3 dimensions). It number of dimenions was not equal to 3, then a message will be returned."""if(img.ndim) == 3:"""Checking if the number of rows and columns of the read image matched CIFAR10 (32 rows and 32 columns)."""if img.shape[0] == img.shape[1] and img.shape[0] == 32:"""Checking whether the last dimension of the image has just 3 channels (Red, Green, and Blue)."""if img.shape[-1] == 3:"""Passing all conditions above, the image is proved to be of CIFAR10.This is why it is passed to the predictor."""predicted_class = CIFAR10_CNN_Predict_Image.main(img)"""After predicting the class label of the input image, the prediction label is rendered on an HTML page.The HTML page is fetched from the /templates directory. The HTML page accepts an input which is the predicted class."""return flask.render_template(template_name_or_list="prediction_result.html", predicted_class=predicted_class)else:# If the image dimensions do not match the CIFAR10 specifications, then an HTML page is rendered to show the problem.return flask.render_template(template_name_or_list="error.html", img_shape=img.shape)else:# If the image dimensions do not match the CIFAR10 specifications, then an HTML page is rendered to show the problem.return flask.render_template(template_name_or_list="error.html", img_shape=img.shape)return "An error occurred."#Returned if there is a different error other than wrong image dimensions."""Creating a route between the URL (http://localhost:7777/predict) to a viewer function that is called after navigating to such URL.Endpoint 'predict' is used to make the route reusable without hard-coding it later."""app.add_url_rule(rule="/predict/", endpoint="predict", view_func=CNN_predict)

这种方法读取图像并检查它是否与 32×32×3 的 CIFAR-10 数据集的尺寸相匹配。如果图像符合 CIFAR-10 数据集的规格,则它将被传递给负责进行预测的函数,如下所示:

predicted_class = CIFAR10_CNN_Predict_Image.main(img)

负责预测图像类别标签的主函数定义如下。它会恢复训练好的模型,并运行一个会话来返回图像的预测类。预测的类被返回给 Flask Web 应用程序。

def main(img):"""The 'main' method accepts an input image array of size 32x32x3 and returns its class label.:param img:RGB image of size 32x32x3.:return:Predicted class label."""#Dataset path containing a binary file with the labels of classes. Useful to decode the prediction code into a significant textual label.patches_dir = "C:\\cifar-10-python\\cifar-10-batches-py\\"dataset_array = numpy.random.rand(1, 32, 32, 3)dataset_array[0, :, :, :] = imgsess = tensorflow.Session()#Restoring the previously saved trained model.saved_model_path = 'C:\\model\\'saver = tensorflow.train.import_meta_graph(saved_model_path+'model.ckpt.meta')saver.restore(sess=sess, save_path=saved_model_path+'model.ckpt')#Initalizing the varaibales.sess.run(tensorflow.global_variables_initializer())graph = tensorflow.get_default_graph()"""Restoring previous created tensors in the training phase based on their given tensor names in the training phase.Some of such tensors will be assigned the testing input data and their outcomes (data_tensor, label_tensor, and keep_prop).Others are helpful in assessing the model prediction accuracy (softmax_propabilities and softmax_predictions)."""softmax_propabilities = graph.get_tensor_by_name(name="softmax_probs:0")softmax_predictions = tensorflow.argmax(softmax_propabilities, axis=1)data_tensor = graph.get_tensor_by_name(name="data_tensor:0")label_tensor = graph.get_tensor_by_name(name="label_tensor:0")keep_prop = graph.get_tensor_by_name(name="keep_prop:0")#keep_prop is equal to 1 because there is no more interest to remove neurons in the testing phase.feed_dict_testing = {data_tensor: dataset_array,keep_prop: 1.0}#Running the session to predict the outcomes of the testing samples.softmax_propabilities_, softmax_predictions_ = sess.run([softmax_propabilities, softmax_predictions],feed_dict=feed_dict_testing)label_names_dict = unpickle_patch(patches_dir + "batches.meta")dataset_label_names = label_names_dict[b"label_names"]return dataset_label_names[softmax_predictions_[0]].decode('utf-8')

返回的图像的类标签将呈现在一个名为 prediction_result.html 的新 HTML 页面上,由 CNN_predict 函数在这一行中指示,如图 7 所示。

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

Figure 7

注意,Flask 应用程序使用 Jinja2 模板引擎,该引擎允许 HTML 页面接受输入参数。在这种情况下传递的输入参数是 predicted _ class = predicted _ class。

return flask.render_template(template_name_or_list="prediction_result.html", predicted_class=predicted_class)

这个页面的 HTML 代码如下。

<!DOCTYPE html><html lang="en"><head><link rel="stylesheet" type="text/css" href="{{url_for(endpoint='static', filename='project_styles.css')}}"><script type="text/javascript" src="{{url_for(endpoint='static', filename='result.js')}}"></script><meta charset="UTF-8"><title>Prediction Result</title></head><body onload="show_alert('{{predicted_class}}')"><center><h1>Predicted Class Label : <span>{{predicted_class}}</span></h1><br><a href="{{url_for(endpoint='homepage')}}"><span>Return to homepage</span>.</a></center></body></html>

它是一个模板,由图像的预测类填充,作为参数传递给 HTML 页面,如代码的这一部分所示:

<**span**>{{predicted_class}}</**span**>

想了解更多关于 Flask RESTful API 的信息,你可以访问这样的教程【https://www.tutorialspoint.com/flask/index.htm。

完整的项目可以在 Github 的这个链接中找到:【https://github.com/ahmedfgad/CIFAR10CNNFlask

原载于 2018 年 5 月 1 日https://www.linkedin.com

原文可在 LinkedIn 的以下链接中找到:

https://www . LinkedIn . com/pulse/complete-guide-build-conv net-http-based-application-using-Ahmed-gad

联系作者

艾哈迈德·法齐·加德

领英:https://linkedin.com/in/ahmedfgad

电子邮件:ahmed.f.gad@gmail.com

基于实时 Twitter 数据的复杂事件处理

原文:https://towardsdatascience.com/complex-event-processing-with-flink-on-realtime-twitter-data-d09d9953df1b?source=collection_archive---------3-----------------------

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

最近,我决定研究 Flink 的复杂事件处理库(CEP ),看看它有什么能力。我发现它非常容易使用,我可以想象出许多可能的用例。

**什么是复杂事件处理?**在开始讨论如何进行 CEP 之前,我认为首先有必要对其进行定义,并让数据科学家和工程师了解它为什么有用。复杂事件处理对于检测流数据中的模式以及基于这些模式发送警报或通知非常有用。任何处理需要监控的时间关键型数据的人都应该知道如何使用 CEP。例如,在 Flink 网站上,他们详细介绍了如何使用复杂的事件处理来监控服务器机架温度,并在同一机架连续两次超过温度阈值时发出警告。然后,他们描述了当你有两个“连续警告”时,你如何创建一个警报。这个例子很好,但是有点过时,我想自己用 Twitter 数据测试一下。

入门:

在我之前关于 Flink 的文章中,我描述了如何建立一个 Tweets 流,并对 Tweets 中最常见的单词进行基本的字数统计。现在回想一下,我们有一个(word,count)格式的单词数据流,我称之为 dataWindowKafka(因为我们之前直接将其提供给 Kafka 制作人)。这是我们在这个例子中主要要做的事情。

现在,假设我们有兴趣了解某个特定单词在一个窗口中被提及的次数是否超过了设定的数量,而在第二个窗口中被提及的次数是否超过了设定的数量。首先,让我们扩展 SimpleCondition,以便不像在文档中那样以内联方式编写代码。

现在我们有了一个易于使用的类,让我们写出实际的 CEP 代码。

在生产中,您可能会将该流的输出传递给 Kafka 或某个数据库,但出于我们的目的,我们将只是将它作为基本的 println 写入控制台。

System.*out*.println(manyMentions.writeAsText("alert.txt"));
// Output{increasing=[(trump,137)], first=[(trump,143)]}
{increasing=[(trump s,49)], first=[(trump s,35)]}
{increasing=[(  ,42)], first=[(  ,29)]}
{increasing=[(i m,11)], first=[(i m,21)]}

我们显然有一些符号化的问题,因为 trump 和“trump 的”本质上是同一个词,空格也不应包括在内,但 CEP 本身似乎在做自己的工作。同时满足第一个过滤器“first”和第二个过滤器“increasing”。虽然如图所示,第二个并不总是实际增加。原因是因为该值是静态的,所以只要秒大于 20,它就会返回 true,即使先前的值是 42。为此我们需要迭代条件。

**迭代条件:**根据 Flink 文档,它们是:

最常见的情况。这就是您如何根据先前接受的事件的属性或它们子集的统计信息来指定接受后续事件的条件。

所以,假设我们想确保我们发布这些推文的频率确实在增加。这里的主要区别是,布尔函数将执行 current_event>previous_event,而不是使用固定值。我们可以使用迭代条件来实现。

I will add the output of this final event soon.

更复杂的例子

当然,这个例子仅仅触及了 CEP 的表面。人们可以立即想象出更多的用例。例如,一家想要监控其品牌声誉的公司可能会通过将 CEP 与情绪分析结合使用来检测可能的抵制(以便快速做出响应)。因此,该公司可以使用机器学习算法来检测和标记每条提到他们品牌的推文,带有积极或消极情绪,然后如果消极情绪超过某个阈值和/或积极情绪的数量,他们就会发出警报。

另一个例子可能是想要向用户推荐电影或产品的在线电影或购物网站。在这种情况下,他们可以查看连续的日志数据,并且如果用户在给定的时间跨度内访问了电影/项目的某个序列,则推荐另一个相关的电影/项目。

其他 Flink CEP 资源

[## Apache Flink:使用 Apache Flink 引入复杂事件处理(CEP)

复杂事件处理(CEP)正好解决了这一问题,即把连续输入的事件与一个…

flink.apache.org](http://flink.apache.org/news/2016/04/06/cep-monitoring.html) [## Apache Flink 1.4-快照文档:Flink CEP-Flink 的复杂事件处理

FlinkCEP 是在 Flink 上实现的复杂事件处理(CEP)库。它允许您检测事件…

ci.apache.org](https://ci.apache.org/projects/flink/flink-docs-release-1.4/dev/libs/cep.html) [## 用 Flink CEP 库寻找模式| Flink forward | 2017 年 9 月 11-13 日|柏林

Flink 提供复杂事件处理(CEP)库已经有一段时间了。它满足了许多人的需求…

berlin.flink-forward.org](https://berlin.flink-forward.org/kb_sessions/looking-for-patterns-with-flink-cep-library/) [## 数据工匠/flink-培训-练习

在 GitHub 上创建一个帐户,为 flink-training-exercises 的开发做出贡献。

github.com](https://github.com/dataArtisans/flink-training-exercises/blob/master/src/main/java/com/dataartisans/flinktraining/exercises/datastream_java/cep/LongRides.java)

卷积神经网络的组件

原文:https://towardsdatascience.com/components-of-convolutional-neural-networks-6ff66296b456?source=collection_archive---------11-----------------------

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

最近最先进的体系结构采用了许多附加组件来补充卷积运算。在这篇文章中,我将解释一些提高了现代卷积神经网络的速度和精度的最重要的组件。我将从解释每个组件的理论开始,并以 keras 中的实际实现结束。

联营

让 CNN 非常有效的第一个秘方是联营。池化是一种向量到标量的变换,它对图像的每个局部区域进行操作,就像卷积一样,但是,与卷积不同,它们没有过滤器,也不计算局部区域的点积,而是计算区域中像素的平均值(平均池化)或简单地挑选具有最高强度的像素并丢弃其余的像素(最大池化)。

以上是一个 2 x 2 的池,它将有效地减少了 2 的要素地图的大小。

汇集的想法看起来可能是反作用的,因为它会导致信息的丢失,然而它在实践中被证明是非常有效的,因为它使得 covnets 对于图像呈现的变化是不变的,并且它还减少了背景噪声的影响。最大池近年来工作得最好,它基于一个区域中的最大像素代表该区域中最重要的特征的思想。通常,我们希望分类的对象图像可能包含许多其他对象,例如,出现在汽车图片中某处的猫可能会误导分类器。池有助于减轻这种影响,并使 covnets 更好地泛化。

它还大大降低了 covnet 的计算成本。通常,网络中每层的图像大小与每层的计算成本(flops)成正比。随着层越来越深,池化减少了图像的维度,因此,它有助于防止网络所需的 flops 数量激增。交错卷积有时被用作池化的替代方法。

辍学者

过度拟合是一种网络在训练集上工作良好,但在测试集上表现不佳的现象。这通常是由于过度依赖训练集中特定特征的存在。辍学是一种应对过度适应的技术。它的工作原理是随机设置一些激活为 0,本质上杀死他们。通过这样做,网络被迫探索更多分类图像的方法,而不是过度依赖某些特征。这是 AlexNet 的关键要素之一。

批量标准化

神经网络的一个主要问题是梯度消失。这是一种梯度变得太小的情况,因此,训练冲浪运动员非常糟糕。来自 Google Brain 的 Ioffe 和 Szegedy 发现,这主要是由于内部协变量的变化,这种情况是由于信息在网络中流动时数据分布的变化而引起的。他们所做的是发明一种被称为批量标准化的技术。其工作原理是将每批图像归一化,使平均值和单位方差为零。

在 CNN 中,它通常位于非线性(relu)之前。它极大地提高了准确性,同时令人难以置信地加快了训练过程。

数据扩充

现代 covnets 需要的最后一个要素是数据扩充。人类视觉系统在适应图像平移、旋转和其他形式的失真方面表现出色。拍个图像随便翻一翻反正大部分人还是能认出来的。然而,covnets 并不擅长处理这种扭曲,它们可能会因为微小的翻译而严重失败。解决这个问题的关键是随机扭曲训练图像,使用水平翻转、垂直翻转、旋转、白化、移位和其他扭曲。这将使 covnets 能够学习如何处理这种失真,因此,它们将能够在现实世界中很好地工作。

另一种常见的技术是从每幅图像中减去平均图像,然后除以标准偏差。

解释了这些组件是什么以及它们为什么工作良好之后,我现在将解释如何在 keras 中实现它们。

在本文中,所有实验都将在 CIFAR10 上进行,这是一个由 60,000 张 32 x 32 RGB 图像组成的数据集。它被分成 50,000 幅训练图像和 10,000 幅测试图像

为了使事情更加模块化,让我们为每一层创建一个简单的函数

**def** Unit(x,filters):
    out = BatchNormalization()(x)
    out = Activation(**"relu"**)(out)
    out = Conv2D(filters=filters, kernel_size=[3, 3], strides=[1, 1], padding=**"same"**)(out)

    **return** out

这是我们代码中最重要的部分,单位函数定义了一个简单的层,包含三层,首先是我之前解释过的批处理规范化,然后我们添加了 RELU 激活,最后,我们添加了卷积,注意我是如何将 RELU 放在 conv 之前的,这是最近的一个实践,叫做“预激活”

现在我们将这个单元层合并成一个单一的模型

**def** MiniModel(input_shape):
    images = Input(input_shape)

    net = Unit(images,64)
    net = Unit(net,64)
    net = Unit(net,64)
    net = MaxPooling2D(pool_size=(2,2))(net)

    net = Unit(net,128)
    net = Unit(net,128)
    net = Unit(net,128)
    net = MaxPooling2D(pool_size=(2, 2))(net)

    net = Unit(net,256)
    net = Unit(net,256)
    net = Unit(net,256)

    net = Dropout(0.5)(net)
    net = AveragePooling2D(pool_size=(8,8))(net)
    net = Flatten()(net)
    net = Dense(units=10,activation=**"softmax"**)(net)

    model = Model(inputs=images,outputs=net)

    **return** model

在这里,我们使用函数式 API 来定义我们的模型,我们从三个单元开始,每个单元有 64 个过滤器,然后是最大池层,将我们的 32 x 32 图像减少到 16 x 16。接下来是 3,128 个过滤器单元,然后是池,在这一点上,我们的图像变成 8×8,最后,我们有另外 3 个单元,256 个通道。请注意,每次我们将图像尺寸缩小 2 倍,通道数量就会增加一倍。

我们以 0.5 的比率添加辍学,这将随机地停用我们的参数的 50%,正如我先前解释的,它对抗过度拟合。

接下来,我们需要加载 cifar10 数据集并执行一些数据扩充

*#load the cifar10 dataset* (train_x, train_y) , (test_x, test_y) = cifar10.load_data()

*#normalize the data* train_x = train_x.astype(**'float32'**) / 255
test_x = test_x.astype(**'float32'**) / 255

*#Subtract the mean image from both train and test set* train_x = train_x - train_x.mean()
test_x = test_x - test_x.mean()

*#Divide by the standard deviation* train_x = train_x / train_x.std(axis=0)
test_x = test_x / test_x.std(axis=0)

在上面的代码中,在加载训练和测试数据后,我们从每个图像中减去均值图像,然后除以标准差,这是一种基本的数据扩充技术,有时,我们可能只减去均值,而跳过标准差部分,应该使用效果最好的部分。

对于更先进的数据增强,我们的图像加载过程会略有变化,keras 有一个非常有用的数据增强工具,简化了整个过程。

下面的代码可以解决这个问题

datagen = ImageDataGenerator(rotation_range=10,
                             width_shift_range=5\. / 32,
                             height_shift_range=5\. / 32,
                             horizontal_flip=**True**)

*# Compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied).* datagen.fit(train_x)

在上面,首先,我们指定 10 度的旋转角度,高度和宽度都移动 5/32,最后水平翻转,所有这些变换将随机应用于训练集中的图像。请注意,还存在更多的转换,您可以查看一下可以为该类指定的所有参数。请记住,过度使用数据增强可能是有害的。

接下来,我们必须将标签转换为一键编码

*#Encode the labels to vectors* train_y = keras.utils.to_categorical(train_y,10)
test_y = keras.utils.to_categorical(test_y,10)

我已经在之前的教程中解释过了,所以我不会再在这里解释了。事实上,几乎所有组成训练过程的东西都和我以前的教程一样,因此,这里是完整的代码

*#import needed classes* **import** keras
**from** keras.datasets **import** cifar10
**from** keras.layers **import** Dense,Conv2D,MaxPooling2D,Flatten,AveragePooling2D,Dropout,BatchNormalization,Activation
**from** keras.models **import** Model,Input
**from** keras.optimizers **import** Adam
**from** keras.callbacks **import** LearningRateScheduler
**from** keras.callbacks **import** ModelCheckpoint
**from** math **import** ceil
**import** os
**from** keras.preprocessing.image **import** ImageDataGenerator

**def** Unit(x,filters):
    out = BatchNormalization()(x)
    out = Activation(**"relu"**)(out)
    out = Conv2D(filters=filters, kernel_size=[3, 3], strides=[1, 1], padding=**"same"**)(out)

    **return** out

*#Define the model* **def** MiniModel(input_shape):
    images = Input(input_shape)

    net = Unit(images,64)
    net = Unit(net,64)
    net = Unit(net,64)
    net = MaxPooling2D(pool_size=(2,2))(net)

    net = Unit(net,128)
    net = Unit(net,128)
    net = Unit(net,128)
    net = MaxPooling2D(pool_size=(2, 2))(net)

    net = Unit(net,256)
    net = Unit(net,256)
    net = Unit(net,256)

    net = Dropout(0.25)(net)
    net = AveragePooling2D(pool_size=(8,8))(net)
    net = Flatten()(net)
    net = Dense(units=10,activation=**"softmax"**)(net)

    model = Model(inputs=images,outputs=net)

    **return** model

*#load the cifar10 dataset* (train_x, train_y) , (test_x, test_y) = cifar10.load_data()

*#normalize the data* train_x = train_x.astype(**'float32'**) / 255
test_x = test_x.astype(**'float32'**) / 255

*#Subtract the mean image from both train and test set* train_x = train_x - train_x.mean()
test_x = test_x - test_x.mean()

*#Divide by the standard deviation* train_x = train_x / train_x.std(axis=0)
test_x = test_x / test_x.std(axis=0)

datagen = ImageDataGenerator(rotation_range=10,
                             width_shift_range=5\. / 32,
                             height_shift_range=5\. / 32,
                             horizontal_flip=**True**)

*# Compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied).* datagen.fit(train_x)

*#Encode the labels to vectors* train_y = keras.utils.to_categorical(train_y,10)
test_y = keras.utils.to_categorical(test_y,10)

*#define a common unit* input_shape = (32,32,3)
model = MiniModel(input_shape)

*#Print a Summary of the model* model.summary()
*#Specify the training components* model.compile(optimizer=Adam(0.001),loss=**"categorical_crossentropy"**,metrics=[**"accuracy"**])

epochs = 20
steps_per_epoch = ceil(50000/128)

*# Fit the model on the batches generated by datagen.flow().* model.fit_generator(datagen.flow(train_x, train_y, batch_size=128),
                    validation_data=[test_x,test_y],
                    epochs=epochs,steps_per_epoch=steps_per_epoch, verbose=1, workers=4)

*#Evaluate the accuracy of the test dataset* accuracy = model.evaluate(x=test_x,y=test_y,batch_size=128)
model.save(**"cifar10model.h5"**)

首先,这里有些事情是不同的

input_shape = (32,32,3)
model = MiniModel(input_shape)

*#Print a Summary of the model* model.summary()

正如我之前解释的,cifar 10 由 32 x 32 RGB 图像组成,因此,输入形状有 3 个通道。这是不言自明的。

下一行创建了我们定义的模型的实例,并传入了输入形状

最后,最后一行将打印出我们网络的完整摘要,包括参数的数量。

最后需要解释的是

epochs = 20
steps_per_epoch = ceil(50000/128)

*# Fit the model on the batches generated by datagen.flow().* model.fit_generator(datagen.flow(train_x, train_y, batch_size=128),
                    validation_data=[test_x,test_y],
                    epochs=epochs,steps_per_epoch=steps_per_epoch, verbose=1, workers=4)

*#Evaluate the accuracy of the test dataset* accuracy = model.evaluate(x=test_x,y=test_y,batch_size=128)
model.save(**"cifar10model.h5"**)

首先,我们定义要运行的周期数,以及每个周期的步数,不要与数字混淆

steps_per_epoch = ceil(50000/128)

这里的 50000 是训练图像的总数,这里我们使用 128 的批量大小,这意味着,对于 20 个时期中的每一个,网络必须处理 50000/128 批图像。

接下来是 fit 函数,这显然不同于我在之前的教程中解释的 fit 函数。

再看看下面会有帮助

*Fit the model on the batches generated by datagen.flow().* model.fit_generator(datagen.flow(train_x, train_y, batch_size=128),
                    validation_data=[test_x,test_y],
                    epochs=epochs,steps_per_epoch=steps_per_epoch, verbose=1, workers=4)

由于我们将数据生成器类用于数据扩充目的,我们必须使用 fit_generator 函数,我们也不直接传入 train_x 和 train_y,而是通过来自数据生成器的 flow 函数传入它们,我们还指定批量大小,接下来我们陈述验证数据,在这种情况下是测试数据。所有其他事情保持不变。

该设置在 20 个周期后产生 82%。

你可以尝试调整参数和网络,看看你能提高多少精度。在下一篇教程中,我将解释一些真正构建高效 cnn 架构所需的技巧和技术。本教程的目的是向您介绍基本组件。

如果你想深入研究计算机视觉。从https://John . specpal . science下载我的免费电子书《深度计算机视觉入门》

如果你有任何问题,请在下面评论或者通过 @johnolafenwa 在 twitter 上联系我

为混合物联网构建深度学习微服务

原文:https://towardsdatascience.com/composing-deep-learning-microservices-for-the-hybrid-internet-of-things-c6cb3cb23b0f?source=collection_archive---------0-----------------------

深度学习正在稳步重塑我们世界的方方面面。但是,除非开发人员有合适的工具来包装这种机器智能以进行普遍部署,否则它无法实现这种潜力。

通过整合到支持微服务架构的工具中,深度学习正在进入云数据服务开发人员的工作环境。这指的是一种越来越流行的方式,即将云应用程序开发为模块化、可重用、范围狭窄的功能套件。在微服务环境中,每个函数都在自己的容器中执行(比如 Docker)。此外,每个微服务通过 RESTful APIs 以轻量级、松散耦合的方式与其他微服务进行互操作。

深度学习将越来越依赖于在复杂的多云中执行的容器化微服务。通常,这是通过抽象的“无服务器”接口来实现的,这些接口使微服务能够在后端云基础设施上透明地执行,而开发人员无需了解 IT 资源是从哪里或如何提供的。因此,无服务器后端使基础设施能够在运行时自动为微服务提供必要的计算能力、存储、带宽和其他分布式资源。

在转向这种组合应用程序的模式时,深度学习开发人员无需担心预配置基础设施之类的事情,如服务器或操作。相反,他们可以简单地专注于建模和编码。但要让这一切在复杂的深度学习应用程序中无缝互操作,需要有一个后端中间件结构,用于可靠的消息传递、事务回滚和长期运行的编排功能(如 Kubernetes 提供的)。

当开发人员构建深度学习微服务以在物联网(IoT)中执行时,后端互操作性结构变得甚至比大多数云中更复杂。这是因为深度学习正在成为所有物联网终端的嵌入式功能,以及从物联网中心和集中式云服务向应用程序提供的服务。正如深度学习服务本身在狭义范围内将是“微”的,算法执行的物联网端点本身在资源限制方面将越来越微——或者更确切地说,是纳米。

在物联网中,嵌入式深度学习微服务将处理端点设备捕获的丰富的实时传感器数据流。这些微服务将推动物联网应用所依赖的视频识别、运动检测、自然语言处理、点击流处理和其他模式感知应用。通过这种方式,任何种类的每一个物体都将充满持续的数据驱动智能、环境意识和情境自主性。

对于物联网深度学习应用的组成和部署,开发人员需要一个中间件后端,它可以分发微服务,以便在网络端点执行。为了支持这些物联网用例,微服务架构将发展为支持名为“雾计算”的完全分布式面向边缘的云架构

在这种新模式中,开发人员使用微服务 API 和无服务器后端来构建深度学习和其他分布式功能,这些功能可以透明地分布、并行化和优化到 fog 的无数端点。说明雾架构分层的一种方式如下,但请记住,容器化的微服务使“深度(学习)分析区”能够遍及整个云,一直到智能设备、传感器和网关。

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

Fog computing architecture

下图说明了 OpenFog 协会的参考架构的应用服务层是如何支持容器化的。本质上,深度学习应用和其他微服务可以在任何容器化的环境中运行,如 Docker/Kubernetes,这是一种物联网 fog 的软件背板。这样一来,这些容器化的深度学习微服务将利用物联网/雾支持层服务(如数据库和中间件),这些服务将作为微服务在自己的容器内运行。

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

Containerization for Application Support in the IoT Fog (source: OpenFog Consortium “OpenFog Reference Architecture for Fog Computing”)

从更广的角度来看,确保所有这些深度学习微服务相互关联的团队将把数据科学作为他们的核心技能集。这些专业人员的核心工作将是构建、训练和优化回旋、递归和其他深层神经网络算法,这种技术魔法依赖于这些算法。他们将使用工具,如 IBM blue mix open shaw 构建基于事件的深度学习微服务,以部署在可能完全私有、完全公共或跨越混合架构中私有和公共部分的物联网雾/云上。

blue mixopen 晶须今天在 IBM Bluemix 上有提供,开源社区可以在这里找到。为了支持混合物联网的深度学习应用的敏捷组合,OpenWhisk 提供了内置的链接,这使得团队能够单独开发和定制深度学习和其他微服务,作为可以以协调的顺序连接在一起的小代码片段。它为物联网和其他用例的无服务器部署、认知算法、容器和语言提供了全面、灵活的支持。

下面是 open 晶须的高级功能架构:

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

OpenWhisk provides a distributed compute service to execute application logic in response to events.

关于底层 open 晶须架构和源代码的更多信息,从这里开始并进入项目的 GitHub 页面

Wolfram 暑期学校的 Reddit 计算思维

原文:https://towardsdatascience.com/computational-thinking-with-reddit-at-the-wolfram-summer-school-29961feaa85d?source=collection_archive---------1-----------------------

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

大约在去年的这个时候,我在想这个夏天该做些什么。在研究生院度过了一个相当糟糕的学期,但我终于完成了路易斯安那州立大学社会学博士项目的核心课程。学期结束时,我决定从巴吞鲁日开车去诺克斯维尔,那里的高温和潮湿不会让你的皮肤融化。我正在考虑“休假”,尽管在研究生院,这通常意味着收集数据和写论文。自从 2009 年以来,我一直在工作和上学,或者参加独立阅读课程,我想我应该休息一下。

然而,我太专注于文本分析和我的论文项目,无法放松。我参加的最后一个研讨会是社会网络分析。主持研讨会的教授想出了一种新颖的方法来分析采访记录,作为她在杜克大学的论文工作的一部分。她提出网络文本分析作为分析大量面试数据的方法。

如果你不熟悉这些类型的数据,社会学家通常依靠深度访谈的文字记录来更好地了解社会世界。例如,我的文学硕士工作包括采访 20 个主题。(你可以在 VICE.com这里阅读,而在这里阅读我为什么选择在非学术渠道出版这部作品。)

在某些情况下,社会学家使用数百名受试者的采访数据。我计划结合使用调查和访谈数据,调查在 HIV 阳性个体和有感染 HIV 风险的个体中使用暴露前预防法Truvada 药物的情况。

在我的硕士工作期间,我的导师们教我如何使用一种叫做扎根理论的东西、手写笔记和一种叫做 Atlas.ti 的软件程序来组织和分析面试数据。

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

Example of a transcript. Imagine this times one thousand.

这个过程…令人生畏,没有条理,不可复制。它也非常过时。所以,我试图想出更好更有效的方法来分析采访数据。我碰到了几个软件包,包括 Provalis QDA 矿工,它们似乎在文本挖掘方面做得相当不错,但仍然不够好。我开始在网上搜索,我偶然发现了 Wolfram Research 的 Mathematica

我对复杂性研究有些熟悉,也在想办法将其与社会学理论结合起来,特别是语言和互动如何在创造意义的过程中产生,所以史蒂夫·沃尔夫勒姆的工作对我来说并不陌生。当我在 Wolfram 网站上搜索 Mathematica 中的文本分析教程时,我看到了一个链接,链接到了 Wolfram 暑期学校。我被激起了兴趣,于是我问了几个同事是否知道这件事,其中一个说我肯定应该申请。于是我就这么做了,因为我认为一个社会学研究生根本不可能被一个似乎更适合程序员、物理学家、计算机科学家和其他 STEM 领域的项目录取。

有趣的是,当我申请时,在我的申请被考虑之前,有一个编码挑战要完成。类似于“写一个函数,使得整数列表中的所有整数都被移除。”除了统计软件的一些基础知识,我几乎没有编程经验,这有点吓人。不过我去了 Wolfram 文档中心,试了几次就能弄明白怎么做了。接下来我所知道的是,我收到了教务主任的电子邮件,要求安排一次简短的面试。在和他谈了我的兴趣、研究和目标之后,我收到了一封电子邮件,通知我已经被录取了。我欣喜若狂,因为我一直在看过去的学生参与的一些有趣的项目,以及现任和前任导师令人印象深刻的简历。哦,能见到史蒂夫·沃尔夫勒姆真是令人兴奋。

因此,有人建议我在去马萨诸塞州沃尔瑟姆参加暑期学校之前,先阅读,或者至少非常熟悉(NKS)新科学,并练习使用沃尔夫拉姆语。如果你不知道,NKS 有 1200 页那么长。我让我的一个朋友开车带我去诺克斯维尔图书馆,这样我就可以用他的借书证在几周内搞定那本大部头书(那时我不住在诺克斯维尔)。全文在网上,但我更喜欢实际的书籍,无论出于什么原因。无论如何,我尽可能地读完了它,并对简单程序的含义感到敬畏,如自然界和其他地方的细胞自动机

为此,有一次我在本特利大学的暑期学校,我们的第一个任务是在计算宇宙中寻找一个有趣的二维、三色、完全的细胞自动机(CA)。下面是我找到的 CA 的一些图片。有趣的是它们进化过程中的不规则边缘。

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

Code 144305877 of a 2-D Three-Color Totalistic Cellular Automaton at step 500

他们都有相似的特征,但有不同的边界和增长模式。

如果我们开始探索其中的一些规则空间,即在计算宇宙中搜索有趣的 CA,这是一种放松——它将你带到一个不同的外星景观和可能性的视觉空间。有些图案看起来可以用于设计目的,或者已经应用于纺织品等领域。视觉上,CA 可以很惊艳。在学术上,他们已经被证明产生了生物学上看到的模式。实际上,它们可以用来产生随机数。例如,从牛顿时代开始,方程就被用来描述物理现象。然而,越来越多的证据表明,CA 和其他类型的程序可能更好地模拟现实。基于代理的建模是一个很好的例子。但是正如托马斯·库恩在 科学革命的结构 中指出的,这种类型的进步经常在没有实时识别的情况下发生。相反,这是一个历史过程。

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

暑期学校的第一周主要包括讲座和史蒂夫·沃尔夫勒姆进行现场实验。在第二周,我们每个人都在午餐时与史蒂夫·沃尔夫勒姆见了面,这样他就可以选择我们将与导师一起工作的项目。他称这是他一年一度的“极端专业”时刻。

午餐真的很棒,因为有大约六个其他学生。斯蒂芬问了我们的兴趣和研究。这非常有趣,因为他对如此广泛的学科领域有如此多的问题。有理论物理学家,有人研究算法金融,还有另一个人研究在秀丽隐杆线虫神经元中发现的小世界网络。

午餐后,我们分别会见了斯蒂芬和我们的导师。我走进房间的时候,他们心里已经有了一个项目,而且超级爽。我将使用 Wolfram 语言中的一个新特性,它使用 Reddit API。当我问斯蒂芬我到底应该在这个项目中做什么时,他回答说,“给我看看 Reddit 的社会学。”哇哦。这是一个很高的要求,但它让我可以自由地把这个项目带到我想去的任何地方。所以,我立即开始做一些研究。我最初想从用户生成的文本中找出一种使用五大心理模式来描述特定用户的方法。我还想使用网络文本分析来有效地描绘出子街道上发生的事情。在我的导师和其他一些学生的帮助下,我能够建立一些代码来生成一些网络。

我首先分析了一个 AMA(问我任何问题)史蒂夫·沃尔夫勒姆用一些非常简单的代码做了,得到了一个很好的网络。

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

Text network from a Stephen Wolfram AMA

在那里,我去掉了有向边,并在图中放置了一个工具提示,这样当你将鼠标悬停在节点上时,你就可以可视化它所代表的文本块(AMA 中的一个问题)。

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

Text network from Stephen Wolfram AMA with Tooltip function

因此,我进一步尝试了 Wolfram 语言和 Mathematica 中的一些图形/网络功能。在社会网络分析中,我们通常对相似性、派系、社会资本和其他度量感兴趣。Wolfram 语言有一个叫做 CommunityGraphPlot 的东西,可以很容易地将节点分组在一起。在这种情况下,它将把 AMA 提出的类似问题组合在一起。

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

Community graph plot of Stephen Wolfram AMA

为了进一步形象化,我们可以根据特定问题的投票分数来调整节点大小。

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

Community graph plot of a Stephen Wolfram AMA scaled by popularity.

我在那里做了各种各样的事情,比如使用一个内置的情感分类器,一个使用脸书数据作为训练集的 T2 主题分类器,并开始开发一个能够识别文本中某些社会心理特征的分类器。但那是另一篇文章。

正如你所看到的,在我的导师的出色帮助下,我能够在两周内完成这个项目。事实上,它是如此的有用,以至于当 IRB 由于诊所中健康相关问题的敏感性而撤回对我的 HIV/PrEP 工作的批准时,我还有一个论文项目要做。考虑到我是带着相当初级的编程能力进入学校的,我能够将这个项目进行下去是相当令人印象深刻的(至少我是这样认为的)。

作为奖励,你猜怎么着?我得到了 Wolfram Research 的一份工作,这些年来其他几位校友也是如此。所以,我不仅学到了有价值的新技能,还在一家科技公司找到了工作。

所以,如果你想在夏天找点事做,或者想学习如何编程,考虑一下 Wolfram 暑期学校或者在 Wolfram|Alpha 中玩玩开放代码函数。你永远不知道它会把你带到哪里,你甚至可能因此得到一份工作。

计算机视觉:TFLearn 的艰难时期

原文:https://towardsdatascience.com/compute-vision-hard-times-with-tflearn-4765841e90bf?source=collection_archive---------4-----------------------

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

我的故事从我玩够了 OpenCV 3.3.0 并决定更进一步尝试一些我从未尝试过的酷东西开始,所以 TensorFlow 是一个像 Thor’s hammer 一样闪亮的大东西,每个人都想亲自动手,但不知道它是如何工作或做什么的(当然我们都听到过时髦的词——机器学习、数据科学、计算机视觉)。

我的工作机器是顶级 Macbook Pro,这意味着我有非常不同的体验(来自 ubuntu、fedora 等。)同时安装我工作需要的软件。当我开始使用 OpenCV 时,我使用了Python 3.6+OpenCV 3.3 docker image,这显然不太适合调试。所以,我决定让我的笔记本电脑有点“脏”(经常试图让笔记本电脑远离我开发所需的软件,这就是为什么我使用虚拟机,运行代码的容器)。

我做的第一件事是谷歌搜索“opencv 3 mac os ”,发现了几篇文章,不幸的是,github 问题试图通过安装 opencv,只要看看你应该做什么来安装 opencv 。跳到故事的结尾,我只能说一句话:“艰难时期带来了很多不必要的乐趣”。使用 OpenCV 最令人沮丧的部分是需要为您创建的每个 virtualenv 创建一个符号链接。尽管安装 OpenCV 的经历很糟糕,但我倾向于认为它是一个强大的工具——25 行代码的人脸识别,10-15 行代码的微笑识别

我的遗愿清单中的下一项是基于 TensorFlow 的库— tflearn 。我需要感谢所有开发人员和做 TensorFlow 打包的人——你们做了大量的工作来使用户体验尽可能的流畅。

scipy
h5py
numpy
tensorflow
tflearn

这是使 TensorFlow 在本地工作所需安装的软件数量,但似乎没有现成的解决方案可以利用代码运行的机器的全部计算能力(如果您需要 CUDA GPU 能力或您的 CPU 支持 SSE4.2,AVX 指令—编译您自己的 TensorFlow 二进制文件)。TensorFlow 团队还为 Docker 维护了大量图片。

不幸的是, tflearn 部署并不理想,我甚至可以说——糟透了,因为社区没有明确的指导方针,尤其是对于版本控制。这种问题会导致像分割错误这样的严重错误。从一开始 tflearn 就在依赖版本方面遇到了麻烦,导致了大量与 segfault 相关的问题,以及 Stackoverflow 上大量请求帮助克服 segfault 关键问题的主题。这里有一个例子可以说明依赖性管理有多差:

$pip install tensorflow tflearn
...
Successfully installed bleach-1.5.0 html5lib-0.9999999 markdown-2.6.9 numpy-1.13.1 protobuf-3.4.0 six-1.10.0 tensorflow-1.3.0 tensorflow-tensorboard-0.1.6 werkzeug-0.12.2 Pillow-4.2.1 olefile-0.44 tflearn-0.3.2

在第一次启动时,您会看到您需要安装更多软件包:

$python
Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import tflearn
hdf5 is not supported on this machine (please install/reinstall h5py for optimal experience)
Scipy not supported!

好吧,我明白为什么维护者这么做了,tflearn 可以在没有 hdf5 和 scipy 的情况下工作。但是实际上,大多数 ML 项目都在使用这个库,那么为什么不能让它们默认为必需的呢?无论如何,在安装完所有这些包后,我们有以下内容:

bleach==1.5.0
h5py==2.7.1
html5lib==0.9999999
Markdown==2.6.9
numpy==1.13.1
olefile==0.44
Pillow==4.2.1
protobuf==3.4.0
scipy==0.19.1
six==1.10.0
tensorflow==1.3.0
tensorflow-tensorboard==0.1.6
tflearn==0.3.2
Werkzeug==0.12.2

好吧,对维护者的另一个问题是,如果你建议用户安装特定的附加软件,为什么不指定你需要的版本?我认为我已经做得足够多了——安装了最新版本并构建了可以工作的 env,但是我是多么的鲁莽…

假设我的环境是可复制的,我可以构建一个 docker 映像,并让我的应用程序在其中运行。尽管有一个应用程序在我的机器上运行得很好,但每当我试图启动它时,Docker image 总是死机,而且,除了退出代码 139 之外,它一直在无声地死机。

在花了几个小时阅读、谷歌搜索之后,我找到了 github 的第七期。乍一看,它与 tflearn 毫无关系。但是据说尽量降级到tensor flow-1 . 0 . 0。好吧,我决定从头开始,除了记住我需要安装的使 tflearn 导入静默的包。最后,我列出了以下需求:

scipy==0.19.1
h5py==2.7.1
numpy==1.13.1
tensorflow==1.0.0
tflearn==0.3.2

令我惊讶的是,我的应用程序在 upstart 期间没有失败。

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

这意味着相对于 TensorFlow、SciPy、NumPy、h5py 的最新版本,tflearn 的最新版本被破坏。这不是开发者期望得到的。

作为结论,我只能说我在开始使用 TensorFlow 时获得的体验是非凡的,尽管花费了数小时为所有必要的包寻找可行的版本,但我倾向于同意 tflearn 带来了另一个高级 API 来构建深度神经网络模型并进行预测,这似乎非常有用(至少在我的特定情况下)。

计算机视觉及其为何如此困难

原文:https://towardsdatascience.com/computer-vision-and-why-it-is-so-difficult-1ed55e0d65be?source=collection_archive---------0-----------------------

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

Image used under standard license agreement, Depositphotos

最难理解的是那些基本的东西。我们生活在一个视觉世界。我们看到东西,立即明白它们是什么,以及我们可以用它们做什么。我们不仅可以识别它们,还可以了解它们的特殊属性和它们所属的类别。不需要深入思考,我们就可以看着一本书,理解构思、思考、写作、作家、代理人、编辑、出版社、印刷商、营销商、推销员、书店和经济的过程。这还不是围绕一本书所有关联的详尽列表。

更重要的是,我们每个人都可以看着一本书,理解它是什么,它做什么,即使我们对它的制作过程和周围发生的事情没有相同的细微差别的理解。我们的知识深度(或缺乏知识)只会在特定的环境中发挥作用(如图书大会或经济论坛),但对于大多数日常用途来说,我们中足够多的被称为“大多数”的人,将能够归因于使这本书成为一个实体的大多数关键属性。

如果一本书写得好,它可能是一本好书,但如果不是这样,它也是一个很好的入门读物。

因此,视觉实际上是一种知识,而不是眼睛,这就是事情变得非常有趣的地方。知识是基于对现实世界的接受,包括事实和想象的事物。例如,我们都同意哈利·波特是谁,他做了什么,为什么这么做,同时我们也都同意他是一个虚构的存在。这意味着,为了理解我们看到的东西,我们不仅使用演绎推理,即我们得出的结论是 100%真实的,我们还使用归纳推理,即我们从可能是真实的前提进行推断,并得出可能的结论:“如果一本书写得好,它可能是一部伟大的读物,但在情况并非如此的情况下,它也是一个伟大的门阶。”

在最后一句话中,我们不仅想象了成功和失败的例子,还想象了一个幽默和讽刺在描述品质中扮演角色的世界。计算机可以配备硬件来捕捉数据(在这种情况下是光),其光谱比我们的肉眼要宽得多,它们还可以配备算法来出色地解释这些数据,以至于仅仅通过研究光的模式,它们就可以学会看到拐角处的。计算机也可以用来进行演绎推理。

在澳大利亚墨尔本举行的 2017 年 AGI 第 10 届人工智能国际会议上,陆军实验室研究员 Douglas Summers Stay 提交了他的论文“语义嵌入知识图上的演绎推理”,摘要如下:“在连续语义向量空间中将知识表示为高维向量,可以帮助克服传统知识库的脆性和不完整性。我们提出了一种在这样的向量空间中直接执行演绎推理的方法,在推理链的每一步中以直接的方式结合了类比、联想和演绎,利用了来自不同来源和本体的知识。“——综合运用“类比、联想和演绎”以及“从不同来源和本体中汲取知识”进行推理这正是语义搜索的目的,请注意 Stay 指的是“一个连续的语义向量空间”,它反映了大脑在有限空间中实现无限存储容量的方式。

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

Image from US7519200B2 awarded to Google Inc shows the variables that must be recognized in order to assign a high degree of accuracy to the reading of a face by a computer. Image used under Fair Use Policy for educational purposes.

所以,现在听起来我们已经解决了这个问题。是也不是。是的,搜索已经变得非常擅长理解图像(有时是视频)中的对象,并建立一个索引,当它与上下文的知识库相结合时,可以创建一个非常好的智能搜索的感觉。特别是两项谷歌专利指出了如何做到这一点,让它看起来无缝

这两者都突出了主要绊脚石的问题:即上下文,通过联想,归纳推理。因为知识不断进化和变形为包含意义但毫无意义的类比(就像我上面用一本写得很差的书作为门挡的例子),计算机逻辑在无人监督的情况下会遇到归纳推理,这也会影响计算机视觉,至少在涉及特定上下文的情况下。因此,拥有一辆自动驾驶汽车可能是可以的,其中车载遥测系统提供的视觉系统优于人类能够承受的任何东西(想象一下一辆可以透过雾“看到”的汽车,知道拐角处有什么,甚至可以利用交通传感器和交通报告来优化旅程),但机器人保姆更有问题(因为儿童天生不可预测,他们的不可预测性会给他们的安全带来风险)。

归纳推理和语义搜索

一项显示出一些前景的技术来自牛津大学的计算实验室,它创新性地采用了基于可能结果和相关性的归纳计算机推理以及语义搜索技术,以在高度不确定性的环境中提供更高的信息检索准确性。

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

Ref: d’Amato, Claudia & Fanizzi, Nicola & Fazzinga, Bettina & Gottlob, Georg & Lukasiewicz, Thomas. (2013). Uncertainty Reasoning for the Semantic Web. Volume II URSW 2008–2010/UniDL 2010. Images are the copyright of their respective owners. Used under Fair Use Policy for educational purposes.

一切都是由数据组成的,数据受制于四个向量:数量、速度、多样性和准确性,我在关于谷歌语义搜索的书中详细介绍了这四个向量。这四个向量中的每一个都提出了自己的挑战,这些挑战因我们将放在网上的数据量不断增加而进一步加剧。

在计算机视觉(以及搜索中的物体识别)中,我们要求比人类更高的标准。机器犯的错误削弱了我们对它们的信任,因为与人类不同,我们通常看不到它们是如何失败的。结果,它们的失败变得普遍,我们认为一台机器(无论是搜索算法还是机器人)存在根本性的缺陷。对于人类,我们通常理解失败,因为我们可以根据自己的知识、记忆和技能参数来模拟他们的表现。失败变得可以接受,因为我们完全理解人类能力的极限。

人工智能在特定和一般意义上的发展都与破解计算机视觉挑战密切相关。毕竟,真正地视觉大多是的精神

我最新的一本书: 《狙击思维:消除恐惧,应对不确定性,做出更好的决策》是一项神经科学研究,探讨如何运用实际步骤做出更好的决策。

吴恩达的计算机视觉——11 个教训

原文:https://towardsdatascience.com/computer-vision-by-andrew-ng-11-lessons-learned-7d05c18a6999?source=collection_archive---------0-----------------------

我最近在 Coursera 上完成了吴恩达的计算机视觉课程。Ng 在解释优化任何计算机视觉任务所需的许多复杂想法方面做得非常出色。本课程中我最喜欢的部分是神经风格转换部分(见第 11 课),它允许你创作结合了克劳德·莫奈风格和你喜欢的任何图像内容的艺术品。这是一个你能做什么的例子:

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

在这篇文章中,我将讨论我在课程中学到的 11 个关键教训。注意,这是 deeplearning.ai 发布的深度学习专业化中的第四门课程,如果你想了解前 3 门课程,我建议你看看这个博客

第一课:为什么计算机视觉正在腾飞?

大数据和算法的发展将导致智能系统的测试误差收敛到贝叶斯最优误差。这将导致 AI 在所有领域超越人类水平的表现,包括自然感知任务。TensorFlow 的开源软件允许您使用迁移学习非常快速地实现任何对象的对象检测系统。使用迁移学习,你只需要 100-500 个例子,这个系统就能相对良好地工作。手动标记 100 个例子并不是太多的工作,所以你很快就会有一个最小的可行产品。

第二课:卷积如何工作?

Ng 解释了如何实现卷积运算符,并展示了它如何检测图像中的边缘。他还解释了其他滤波器,如 Sobel 滤波器,它将更多的权重放在边缘的中心像素上。Ng 接着解释说,滤波器的权重不应该手动设计,而应该使用爬山算法(如梯度下降)来学习。

第三课:为什么是卷积?

Ng 给出了卷积在图像识别任务中如此有效的几个哲学原因。他概述了两个具体原因。第一种称为参数共享。它的思想是,在图像的一部分有用的特征检测器可能在图像的另一部分也有用。例如,边缘检测器可能在图像的许多部分都有用。参数的共享允许参数的数量较小,并且还允许稳健的平移不变性。平移不变性是这样一个概念,一只猫移动和旋转后仍然是一只猫的图片。

他概述的第二个观点被称为连接稀疏。这意味着每个输出层只是少量输入(特别是滤波器大小的平方)的函数。这大大减少了网络中的参数数量,并允许更快的训练。

第三课:为什么填充?

填充通常用于保持输入大小(即输入和输出的维度相同)。它还用于使靠近图像边缘的帧与靠近中心的帧对输出的贡献一样大。

第 4 课:为什么是最大池?

通过实证研究,最大池已被证明是非常有效的 CNN 的。通过对图像进行下采样,我们减少了参数的数量,这使得特征对于尺度或方向变化是不变的。

第 5 课:经典网络架构

Ng 展示了 3 种经典网络架构,包括 LeNet-5、AlexNet 和 VGG-16。他提出的主要观点是,有效的网络通常具有通道尺寸增加、宽度和高度减小的层。

第六课:ResNets 为什么有效?

对于平面网络,由于梯度的消失和爆炸,训练误差不会随着层数的增加而单调减小。这些网络具有前馈跳过连接,这允许您在不降低性能的情况下训练非常大的网络。

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

第七课:使用迁移学习!

在 GPU 上从头开始训练大型网络(如 inception)可能需要数周时间。您应该从预训练的网络中下载权重,并只重新训练最后一个 softmax 层(或最后几层)。这将大大减少培训时间。这样做的原因是早期的图层往往与所有图像中的概念相关联,例如边缘和曲线。

第八课:如何赢得计算机视觉竞赛

Ng 解释说,你应该独立地训练几个网络,并平均它们的输出,以获得更好的性能。诸如随机裁剪图像、围绕水平和垂直轴翻转图像等数据增强技术也可能有助于提高性能。最后,您应该使用一个开源的实现和预训练的模型来开始,然后为您的特定应用程序微调参数。

第 9 课:如何实现对象检测

Ng 首先解释了图像中地标检测的概念。基本上,这些地标成为你的训练输出例子的一部分。通过一些巧妙的卷积操作,你可以得到一个输出体积,告诉你物体在某个区域的概率以及物体的位置。他还解释了如何使用并集上的交集公式来评估对象检测算法的有效性。最后,Ng 将所有这些要素放在一起解释了著名的 YOLO 算法。

第十课:如何实现人脸识别

面部识别是一次性学习问题,因为你可能只有一个示例图像来识别人。解决方案是学习给出两幅图像之间差异程度的相似性函数。因此,如果图像是同一个人的,您希望该函数输出一个小数字,反之亦然。

Ng 给出的第一个解决方案被称为“连体网络”。这个想法是将两个人分别输入到同一个网络中,然后比较他们的输出。如果输出是相似的,那么这些人可能是相同的。训练网络,使得如果两个输入图像是同一个人,则它们的编码之间的距离相对较小。

他给出的第二个解决方案使用了三重态损失法。这个想法是,你有一个三个一组的图像(锚(A),积极§和消极(N)),你训练网络,使 A 和 P 之间的输出距离比 A 和 N 之间的距离小得多。

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

第十一课:如何使用神经风格转移来创作艺术品

Ng 解释了如何生成内容和风格相结合的图像。参见下面的例子。

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

神经类型转移的关键是理解卷积网络中每一层所学内容的视觉表示。原来,早期的图层学习简单的特征,如边缘,而后期的特征学习复杂的对象,如人脸,脚和汽车。

为了构建神经风格转移图像,您只需定义一个成本函数,它是内容和风格相似性的凸组合。特别地,成本函数将是:

J(G) = alpha * J_content(C,G) + beta * J_style(S,G)

其中 G 是生成的图像,C 是内容图像,S 是样式图像。学习算法简单地使用梯度下降来最小化关于生成的图像 g 的成本函数

步骤如下:

  1. 随机生成 G。
  2. 用梯度下降法使 J(G)最小,即写出 G := G-dG(J(G))。
  3. 重复步骤 2。

结论

通过完成本课程,你将对大量的计算机视觉文献有一个直观的了解。家庭作业也给了你实践这些想法的机会。完成本课程后,你不会成为计算机视觉方面的专家,但本课程可能会启动你在计算机视觉方面的潜在想法/职业。

如果你有任何有趣的计算机视觉应用想分享,请在下面的评论中告诉我。我很乐意讨论新项目的潜在合作。

这就是所有人——如果你已经做到了这一步,请在下面评论并在 LinkedIn 上添加我。

我的 Github 是这里的。

计算机视觉概念和术语

原文:https://towardsdatascience.com/computer-vision-concepts-and-terminology-edd392a6f594?source=collection_archive---------6-----------------------

一个超像素是一个比矩形片更好地对准强度边缘的图像片。超像素可以用任何分割算法提取,然而,它们中的大多数产生高度不规则的超像素,具有广泛变化的大小和形状。可能需要更规则的空间镶嵌。

- 最大抑制通常与边缘检测算法一起使用。沿着图像梯度方向扫描图像,如果像素不是局部最大值的一部分,则它们被设置为零。

语义分割:

https://arxiv.org/pdf/1602.06541.pdf

从图像中提取超像素是这一任务或前景-背景分割的一个例子。语义分割:在语义分割中,你要给每个像素标上一类物体(汽车,人,狗,…)和非物体(水,天空,道路,…)。

语义分割是将属于同一对象类的图像部分聚集在一起的任务。这种类型的算法有几个用例,如检测路标[MBLAGJ+07],检测肿瘤[MBVLG02],检测手术中的医疗器械[WAH97],结肠隐窝分割[CRSS14],土地利用和土地覆盖分类[HDT02]。相反,非语义分割仅基于单个对象的一般特征将像素聚集在一起。因此,非语义分割的任务是不明确的

光流

光流是由物体或摄像机的运动引起的图像物体在两个连续帧之间的表观运动模式。这是 2D 矢量场,其中每个矢量是一个位移矢量,表示点从第一帧到第二帧的移动。考虑下面的图像,它显示了一个球在连续 5 帧中移动。箭头显示了它的位移矢量。

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

It shows a ball moving in 5 consecutive frames. The arrow shows its displacement vector.

光流在以下领域有许多应用:

  • 运动中的结构
  • 视频压缩
  • 视频稳定…

光流基于几个假设:

  1. 物体的像素强度在连续的帧之间不会改变。
  2. 相邻像素具有相似的运动。

方向梯度直方图(HOG)

[## 猪人探测器教程克里斯麦考密克

猪人检测器非常容易理解(例如,与 SIFT 对象识别相比)。其中一个…

mccormickml.com](http://mccormickml.com/2013/05/09/hog-person-detector-tutorial/)

HOG 代表方向梯度直方图。HOG 是一种“特征描述符”。特征描述符的目的是以这样一种方式概括对象,当在不同条件下观察时,相同的对象(在这种情况下是人)产生尽可能接近相同的特征描述符。这使得分类任务更加容易。

这种方法的创造者训练了一种支持向量机(一种用于分类的机器学习算法),或“SVM”,以识别人的 HOG 描述符。猪人检测器使用滑动检测窗口,该窗口在图像周围移动。在检测器窗口的每个位置,为检测窗口计算 HOG 描述符。然后,这个描述符被显示给经过训练的 SVM,它将其分类为“人”或“不是人”。

为了识别不同尺度的人,图像被二次抽样成多种尺寸。搜索这些二次抽样图像中的每一个。

SIFT(尺度不变特征变换)

[## OpenCV:SIFT(尺度不变特征变换)简介

因此,在 2004 年,英国哥伦比亚大学的 D.Lowe 提出了一种新的算法,尺度不变特征变换…

docs.opencv.org](http://docs.opencv.org/3.1.0/da/df5/tutorial_py_sift_intro.html)

SIFT:尺度不变特征变换(SIFT)特征描述符描述图像中的关键点。拍摄关键点周围大小为 16 × 16 的图像块。该面片被分成大小为 4 × 4 的 16 个不同部分。对于这些部分中的每一个,计算类似于 HOG 特征的 8 个方向的直方图。这导致每个关键点的 128 维特征向量。应该强调的是,SIFT 是完整图像的全局特征。

BOV:视觉词汇袋(BOV),

http://kushalvyas.github.io/BOV.html

也称为关键点包,基于矢量量化。与 HOG 特征类似,BOV 特征是直方图,它计算图像的一个片内特定模式的出现次数

Poselets:

Poselets 依赖于手动添加的额外关键点,例如“右肩”、“左肩”、“右膝”和“左膝”。它们最初用于人体姿态估计。对于像人类这样众所周知的图像类别,找到这些额外的关键点是很容易的。然而,对于像飞机、轮船、器官或细胞这样的类,人类注释者不知道关键点是很困难的。此外,必须为每个单独的类选择关键点。有一些策略可以处理这些问题,比如视点相关的关键点。Poselets 在[BMBM10]中用于检测人,在[BBMM11]中用于 PASCAL VOC 数据集的一般对象检测。

文本:

一个粒子是视觉的最小组成部分。计算机视觉文献并没有给出纹理子的严格定义,但边缘检测器可能是一个例子。有人可能会说,卷积神经网络(CNN)的深度学习技术在第一个过滤器中学习文本子。

马尔可夫随机场

https://ermongroup . github . io/cs 228-notes/re presentation/un directed/

是计算机视觉中广泛使用的无向概率图模型。MRFs 的总体思想是为每个特征分配一个随机变量,为每个像素分配一个随机变量

白粉

http://mccormickml . com/2014/06/03/深度学习-教程-PCA-and-whiting/

我们试图通过美白完成两件事:

  1. 使特征之间的相关性降低。
  2. 给所有的特征相同的方差。

美白有两个简单的步骤:

  1. 将数据集投影到特征向量上。这将旋转数据集,以便组件之间没有相关性。
  2. 将数据集归一化,使所有组件的方差为 1。这可以通过简单地将每个分量除以其特征值的平方根来实现。

我问了一个神经网络 expect,我连接的是 Pavel Skribtsov ,关于为什么这种技术是有益的更多解释:

“这是简化优化过程以找到权重的常用技巧。如果输入信号具有相关输入(某种线性相关性),那么[成本]函数将倾向于具有“类似河流”的最小区域,而不是权重空间中的最小点。至于输入白化——类似的事情——如果不这样做,误差函数将倾向于具有非对称的最小值“洞穴”,并且由于一些训练算法对所有权重具有相等的更新速度——最小化可能倾向于跳过最小值的窄维度中的好位置,同时试图取悦更宽的维度。所以和深度学习没有直接关系。如果您的优化过程收敛良好,您可以跳过这一预处理。”

医学图像的计算机视觉特征提取 101 第 1 部分:边缘检测/锐化/模糊/浮雕/超像素

原文:https://towardsdatascience.com/computer-vision-feature-extraction-101-on-medical-images-part-1-edge-detection-sharpening-42ab8ef0a7cd?source=collection_archive---------5-----------------------

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

Gif from this website

所以今天,我只想回顾一下计算机视觉中的一些核心概念,我希望把重点放在应用上,而不是理论上。如果你是计算机视觉的新手,我强烈推荐你观看我在下面链接的这个视频系列来了解这个理论。(视频系列很长,但是真的很好看。)

此外,这是我们将要使用的公开可用数据的列表。
1。 乳腺癌细胞来自 UCSB 生物分割基准数据集
2。 细胞 2D 来自 UCSB 生物分割基准数据集
3。 驱动:用于血管提取的数字视网膜图像
4。 从 kaggle 数据集进行超声神经分割
5。 脑部核磁共振来自 pixabay
6。 脑部核磁共振来自 pixabay
7。 来自 pixabay 的自然图像

请注意,这篇文章是让我回顾计算机视觉中的一些基本概念。

2D 卷积

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

Image from this website

卷积是对两个【f 和 g】进行一个* 的数学运算 产生第三个函数,也就是通常被视为原始函数之一的修改版,赋予 的积分逐点将两个函数的 相乘作为其中一个函数的量*

2D 卷积运算是计算机视觉的核心,因为这是我们将要使用的主要运算,所以请确保您理解这个概念。如果您需要帮助,请单击此处查看Song Ho Ahn 提供的 2D 卷积运算的分步示例。

原始图像

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

左上来自 UCSB 的乳腺癌细胞生物分割基准
中上来自 UCSB 的细胞 2D 生物分割基准数据集
右上驱动:用于血管提取的数字视网膜图像
左下来自 kaggle 数据集的超声神经分割【图

在我们对这些图像做任何事情之前,让我们实际上看看每个图像看起来像什么,最后下面是我们的[自然图像](http://Natural Image from pixabay)看起来像什么。

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

身份内核

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

让我们从简单的开始,身份内核不改变给定的图像,因为它是身份内核。如下图所示,图像看起来完全一样,除了所有图像都是黑白的。

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

边缘检测(水平)

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

现在让我们看看每张图片的水平方向有多少变化。令我印象深刻的一个非常有趣的观察是自然图像,我们可以看到来自照明光束的光无处可寻。

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

边缘检测(垂直)

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

现在让我们看看在垂直方向上对每张图片所做的修改。我们可以观察到光束在自然图像中返回。

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

边缘检测(梯度幅度)

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

因为我们现在在水平方向和垂直方向都有变化,我们可以用平方和的平方根来得到梯度的大小。请看下面这个维基页面上的方程式的截图。

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

Image from this website

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

边缘检测(渐变方向)

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

因为我们现在在水平方向和垂直方向都有变化,我们可以通过使用反正切函数获得梯度方向。请参见下面的方程式。

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

Image from this website

当我们可视化原始结果时,我们会得到如下结果。看起来非常奇怪的图像…

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

索贝尔滤波器(梯度幅度)

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

现在,让我们采取一个索贝尔过滤器,并获得梯度幅度。我个人看不出我们使用的过滤器有什么大的不同。

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

索贝尔滤镜(渐变方向)

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

同样,对于梯度方向,我看不出我们使用的过滤器和索贝尔过滤器之间有很大的区别。

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

高斯模糊

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

我们也可以模糊图像,通过使用高斯滤波器,如果我们看到这个滤波器,它看起来会像下面这样。这个操作通常被称为高斯模糊

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

Image from this website

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

锐化边缘

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

我们还可以锐化图像,首先找到图像的边缘,然后将该值添加到原始图像中。这将锐化图像的边缘。

锐化图像非常类似于寻找边缘,将原始图像和边缘检测后的图像彼此相加,结果将是一个边缘得到增强的新图像,使其看起来更清晰。——洛德的计算机图形学教程

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

浮雕

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

为了给图像一个阴影效果,我们也可以使用浮雕滤镜,并添加 128 的偏差。我其实不知道这个滤镜,直到我从 Lode 的计算机图形学教程上看到。结果看起来非常类似于水平方向上的边缘检测。

"一个浮雕滤镜给图像一个 3D 阴影效果,这个结果对于图像的凹凸贴图非常有用。它可以通过在中心的一侧取一个像素,并从中减去另一侧的一个像素来实现。像素可以得到正的或负的结果。要将负像素用作阴影,将正像素用作光线,对于 bumpmap,图像的偏移为 128。——洛德的计算机图形学教程

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

超级像素

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

最后,为了好玩,让我们使用 skimage 库中实现的简单线性迭代聚类制作超级像素。

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

互动码

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

对于 Google Colab,您需要一个 Google 帐户来查看代码,而且您不能在 Google Colab 中运行只读脚本,所以请在您的操场上创建一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

请注意,我不想滥用任何数据政策。所以对于谷歌 Colab,我找到了下面的图片,它被标记为重复使用。要访问在线代码,请点击此处。

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

Image from this website

最后的话

我想发这个帖子已经很久了,很高兴知道我终于发了。我希望尽快再发一篇关于特征或者特征的帖子。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。

同时,在我的推特上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. 接替艾伦。(2018).YouTube。2018 年 4 月 9 日检索,来自https://www.youtube.com/watch?v=2S4nn7S8Hk4&list = pltizwl 5 stv 3d 4 uq 6 pvzxkrlkp _ 3 xocotn
  2. 安,S. (2018)。2D 卷积的例子。Songho.ca 于 2018 年 4 月 9 日检索,来自http://www . song ho . ca/DSP/convolution/convolution 2d _ example . html
  3. 内核(图像处理)。(2018).En.wikipedia.org。检索于 2018 年 4 月 9 日,来自https://en . Wikipedia . org/wiki/Kernel _(image _ processing)
  4. 图像压花。(2018).En.wikipedia.org。检索于 2018 年 4 月 9 日,来自 https://en.wikipedia.org/wiki/Image_embossing
  5. 罗斯布鲁克(2014 年)。用 Python 访问单个超像素分割。PyImageSearch。检索于 2018 年 4 月 9 日,来自https://www . pyimagesearch . com/2014/12/29/access-individual-super pixel-segmentations-python/
  6. 生物分割|生物图像信息学中心|加州大学圣巴巴拉分校。(2018).Bioimage.ucsb.edu。检索于 2018 年 4 月 9 日,来自https://bioimage.ucsb.edu/research/bio-segmentation
  7. 驱动:下载。(2018).isi . uu . nl . 2018 年 4 月 9 日检索,来自http://www.isi.uu.nl/Research/Databases/DRIVE/download.php
  8. 超声波神经分割| Kaggle。(2018).Kaggle.com。检索于 2018 年 4 月 9 日,来自https://www.kaggle.com/c/ultrasound-nerve-segmentation
  9. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782457/
  10. Pixabay 上的免费图像——日落、灯塔、黎明、黄昏、太阳。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/sunset-light house-dawn-dusk-sun-3120484/
  11. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782459/
  12. Python 中的 DICOM:用 PyDICOM 和 VTK 将医学图像数据导入 NumPy。(2014).PyScience。检索于 2018 年 4 月 9 日,来自https://pyscience . WordPress . com/2014/09/08/DICOM-in-python-importing-medical-image-data-into-numpy-with-pydicom-and-VTK/
  13. Matplotlib 图:移除轴,l. (2018)。Matplotlib 绘图:删除轴、图例和空白。Stackoverflow.com。检索于 2018 年 4 月 9 日,来自https://stack overflow . com/questions/9295026/matplotlib-plots-removed-axis-legends-and-white-spaces
  14. SciPy . signal . convolved 2d—SciPy v 1 . 0 . 0 参考指南。(2018).Docs.scipy.org。2018 年 4 月 9 日检索,来自https://docs . scipy . org/doc/scipy/reference/generated/scipy . signal . convolved . html
  15. matplotlib,R. (2018 年)。在 matplotlib 中删除保存的图像周围的空白。Stackoverflow.com。检索于 2018 年 4 月 9 日,来自https://stack overflow . com/questions/11837979/removing-white-space-around-a-saved-image-in-matplotlib
  16. NumPy . arctan—NumPy 1.14 版手册。(2018).Docs.scipy.org。2018 年 4 月 9 日检索,来自https://docs . scipy . org/doc/numpy/reference/generated/numpy . arctan . html
  17. 空间过滤器-高斯平滑。(2018).Homepages.inf.ed.ac.uk 检索于 2018 年 4 月 9 日,来自https://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm
  18. SciPy . n image . filters . Gaussian _ filter—SciPy v 0 . 15 . 1 参考指南。(2018).Docs.scipy.org。2018 年 4 月 9 日检索,来自https://docs . scipy . org/doc/scipy-0 . 15 . 1/reference/generated/scipy . ndimage . filters . Gaussian _ filter . html
  19. 高斯模糊。(2018).En.wikipedia.org。检索于 2018 年 4 月 9 日,来自https://en.wikipedia.org/wiki/Gaussian_blur
  20. 模块:分段—对 0.14 版开发文档进行分段。(2018).Scikit-image.org。检索于 2018 年 4 月 9 日,来自http://scikit-image . org/docs/dev/API/skim age . segmentation . html # skim age . segmentation . slic

医学图像的计算机视觉特征提取 101 第 2 部分:同一性、平移、缩放、剪切、旋转和同质性

原文:https://towardsdatascience.com/computer-vision-feature-extraction-101-on-medical-images-part-2-identity-translation-scaling-90d160bcd41e?source=collection_archive---------7-----------------------

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

Gif from this website

所以今天,我想继续回顾计算机视觉的基础知识(我猜这篇文章可能更多的是关于图像处理)。今天我想回顾一下图像转换。(或矩阵)

此外,这是我们将要使用的公开可用数据的列表。
1。 乳腺癌细胞来自 UCSB 生物分割基准数据集
2。 细胞 2D 来自 UCSB 生物分割基准数据集
3。 驱动:用于血管提取的数字视网膜图像
4。 从 kaggle 数据集进行超声神经分割
5。 脑部核磁共振来自 pixabay
6。 脑部核磁共振来自 pixabay
7。 来自 pixabay 的自然图像

请注意,这个帖子是给未来的自己回过头来看资料的。

使用矩阵进行转换

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

Image from this website

在这篇文章中,如果你想复习这些运算,理解矩阵和矩阵乘法是很重要的。请点击这里

原始图片

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

左上来自 UCSB 的乳腺癌细胞生物分割基准
中上来自 UCSB 的细胞 2D 生物分割基准数据集
右上驱动:用于血管提取的数字视网膜图像
左下来自 kaggle 数据集的超声神经分割【图

在我们对这些图像做任何事情之前,让我们实际上看看每个图像看起来像什么,最后下面是我们的[自然图像](http://Natural Image from pixabay)看起来像什么。

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

身份

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

让我们从简单的开始,用单位矩阵来变换图像。我们可以看到原始图像和变换后的图像没有区别。(因为我们使用了单位矩阵…)

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

翻译

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

现在让我们将图像向 x(水平方向)和 y(垂直方向)移动 100 像素。因为我们可以怀疑图像已经向右下方移动了 100 个像素。

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

缩放比例

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

这里,我们将使图像在 x 方向(水平方向)缩小 0.75 倍,而在 y 方向(垂直方向)放大 1.25 倍。正如我们所猜测的,由于图像在 y 方向上增长,一些信息被删除了。

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

剪切

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

现在让我们做一些更有趣的事情,让剪切图像。我们绝对可以看到这些图像变换操作的威力有多大。

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

旋转

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

现在我们可以旋转图像,理解旋转的变换矩阵可能有点困难。但是使用下面的等式,我们可以很容易地构建旋转矩阵。

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

Image from this website

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

同质

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

结合我们学过的所有东西,现在我们甚至可以做透视变换,在考虑 3D 空间的同时变换 2D 坐标。结果真的很酷。

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

互动码

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

对于谷歌实验室,你需要一个谷歌帐户来查看代码,你也不能在谷歌实验室运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

请注意,我不想滥用任何数据政策。所以对于谷歌 Colab,我找到了下面的图片,它被标记为重复使用。要访问在线代码,请点击此处。

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

Image from this website

遗言

对图像进行仿射变换总是很有趣,因为有些结果看起来很滑稽。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。

与此同时,请在我的 twitter 这里关注我,并访问我的网站或我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. 剪切映射。(2018).En.wikipedia.org。检索于 2018 年 4 月 11 日,来自https://en.wikipedia.org/wiki/Shear_mapping
  2. 接替艾伦。(2018).YouTube。2018 年 4 月 9 日检索,来自https://www.youtube.com/watch?v=2S4nn7S8Hk4&list = pltizwl 5 stv 3d 4 uq 6 pvzxkrlkp _ 3 xocotn
  3. 安,S. (2018)。2D 卷积的例子。Songho.ca 于 2018 年 4 月 9 日检索,来自http://www . song ho . ca/DSP/convolution/convolution 2d _ example . html
  4. 内核(图像处理)。(2018).En.wikipedia.org。检索于 2018 年 4 月 9 日,来自https://en . Wikipedia . org/wiki/Kernel _(image _ processing)
  5. 图像压花。(2018).En.wikipedia.org。检索于 2018 年 4 月 9 日,来自 https://en.wikipedia.org/wiki/Image_embossing
  6. 罗斯布鲁克(2014 年)。用 Python 访问单个超像素分割。PyImageSearch。检索于 2018 年 4 月 9 日,来自https://www . pyimagesearch . com/2014/12/29/access-individual-super pixel-segmentations-python/
  7. 生物分割|生物图像信息学中心|加州大学圣巴巴拉分校。(2018).Bioimage.ucsb.edu。检索于 2018 年 4 月 9 日,来自https://bioimage.ucsb.edu/research/bio-segmentation
  8. 驱动:下载。(2018).isi . uu . nl . 2018 年 4 月 9 日检索,来自http://www.isi.uu.nl/Research/Databases/DRIVE/download.php
  9. 超声波神经分割| Kaggle。(2018).Kaggle.com。检索于 2018 年 4 月 9 日,来自https://www.kaggle.com/c/ultrasound-nerve-segmentation
  10. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782457/
  11. Pixabay 上的免费图像——日落、灯塔、黎明、黄昏、太阳。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/sunset-light house-dawn-dusk-sun-3120484/
  12. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782459/
  13. 图像的几何变换— OpenCV-Python 教程 1 文档。(2018).opencv-python-tutro als . readthedocs . io . 2018 年 4 月 11 日检索,来自http://opencv-python-tutro als . readthedocs . io/en/latest/py _ tutorials/py _ img proc/py _ geometric _ transformations/py _ geometric _ transformations . html
  14. 仿射变换。(2018).En.wikipedia.org。检索于 2018 年 4 月 11 日,来自 https://en.wikipedia.org/wiki/Affine_transformation
  15. Mallick,S. (2016 年)。使用 OpenCV ( Python / C ++)的单应性例子|学习 OpenCV。Learnopencv.com。检索于 2018 年 4 月 11 日,来自https://www . learnopencv . com/homography-examples-using-opencv-python-c/
  16. 齐次坐标。(2018).En.wikipedia.org。检索于 2018 年 4 月 11 日,来自https://en . Wikipedia . org/wiki/Homogeneous _ coordinates # Use _ in _ computer _ graphics
  17. (2018).Cs.utexas.edu。检索于 2018 年 4 月 11 日,来自https://www . cs . ut exas . edu/users/fussell/courses/cs 384g-fall 2011/lectures/lectures 07-affine . pdf
  18. 图像的几何变换— OpenCV-Python 教程 1 文档。(2018).opencv-python-tutro als . readthedocs . io . 2018 年 4 月 11 日检索,来自http://opencv-python-tutro als . readthedocs . io/en/latest/py _ tutorials/py _ img proc/py _ geometric _ transformations/py _ geometric _ transformations . html
  19. (2018).Web.cs.wpi.edu。检索于 2018 年 4 月 11 日,来自https://web . cs . wpi . edu/~ Emmanuel/courses/cs 545/S14/slides/lecture 11 . pdf
  20. (2018).Mrl.nyu.edu。检索于 2018 年 4 月 11 日,来自http://mrl.nyu.edu/~dzorin/ig04/lecture05/lecture05.pdf
  21. (2018).Colab.research.google.com。检索于 2018 年 4 月 11 日,来自https://colab . research . Google . com/notebook # fileId = 1 onuy 6 EFE 7 xhdfgfahddcqqxpwuetoj _ NO&scroll to = 2 Sood 3 odxg _
  22. 矩阵乘法。(2018).En.wikipedia.org。检索于 2018 年 4 月 11 日,来自 https://en.wikipedia.org/wiki/Matrix_multiplication
  23. 使用矩阵的变换(几何、变换)— Mathplanet。(2018).数学星球。检索于 2018 年 4 月 11 日,来自https://www . math planet . com/education/geometry/transformations/transformation-using-matrix

医学图像的计算机视觉特征提取 101 第 3 部分:高斯差分和高斯拉普拉斯算子

原文:https://towardsdatascience.com/computer-vision-feature-extraction-101-on-medical-images-part-3-difference-of-gaussian-and-b3cbe5c37415?source=collection_archive---------2-----------------------

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

Gif from this website

这是我试图回忆我在计算机视觉中学到的东西的另一个帖子。由于这是期末考试季节,我真的不想做一些疯狂的事情,因此狗和日志过滤器。

如果你想看第一部分,请点击这里;如果你想看第二部分,请点击这里。

此外,这是我们将要使用的公开可用数据的列表。
1。 乳腺癌细胞来自 UCSB 生物分割基准数据集
2。 细胞 2D 来自 UCSB 生物分割基准数据集
3。 驱动:用于血管提取的数字视网膜图像
4。 超声波神经分割从 kaggle 数据集
5。 脑部核磁共振来自 pixabay
6。 脑 MRI 来自 pixabay
7。 来自 pixabay 的自然图像

请注意,这个帖子是给未来的自己回过头来看资料的。

2D 卷积

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

Image from this website

卷积是对两个【f 和 g】进行一个* 的数学运算 产生第三个函数,也就是通常被视为原始函数之一的修改版,赋予 的积分逐点将两个函数的 相乘作为其中一个函数的量*

2D 卷积运算是计算机视觉的核心,因为这是我们在这篇文章中要用到的主要运算,所以请确保你理解这个概念。如果您需要帮助,请单击此处查看Song Ho Ahn 提供的 2D 卷积运算的分步示例。

原始图像

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

左上来自 UCSB 的乳腺癌细胞生物分割基准
中上来自 UCSB 的细胞 2D 生物分割基准数据集
右上驱动:用于血管提取的数字视网膜图像
左下来自 kaggle 数据集的超声神经分割【图

在我们对这些图像做任何事情之前,让我们实际上看看每个图像看起来像什么,最后下面是我们的[自然图像](http://Natural Image from pixabay)看起来像什么。

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

高斯差分

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

红框 →与原高斯图像进行卷积运算 1
绿框 →与原高斯图像进行卷积运算 2
蓝框 →将上述两部分图像相减,并设定阈值。

****请注意我们实际上需要找到过零事件,而不是设置硬阈值。但是为了简单起见,我使用了一个阈值。

顾名思义,高斯差分非常简单。只需用不同的高斯核对图像进行卷积,在上面的例子中,我们选择使用两个不同窗口大小的不同高斯滤波器。然后彼此相减,并设置一个阈值来过滤掉强度较弱的像素。

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

Image from this website.

红框 →与高斯原图像的卷积运算 1
绿框 →与高斯原图像的卷积运算 2
蓝框 →减去以上两部分图像

除了阈值,上面的图片很好地解释了一步一步的教程。

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

高斯 v2 的差值

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

红框 →选择 sigma 值为 100 的高斯核
绿框 →选择 sigma 值为 1 的高斯核

如上所述,为高斯核选择完全不同的 sigma 值会产生可怕的结果。(我只是想试试这些好玩的。)

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

高斯拉普拉斯算子(带平滑)

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

红框 →使用高斯滤波器平滑图像
绿框 →创建拉普拉斯滤波器进行卷积运算。

图像的拉普拉斯算子突出了快速强度变化的区域,因此经常用于边缘检测(参见 零交叉边缘检测器 )。拉普拉斯算子通常被应用于首先用近似 高斯平滑滤波器 平滑的图像,以降低其对噪声的敏感性。——引自本网

从上面的陈述中,我们已经可以知道,在做任何事情之前,我们需要首先平滑图像。让我们假设我们已经平滑了图像,看看我们下一步应该做什么。

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

Image from this website

现在我们知道,我们只需要使用其中一个内核来执行卷积,我将使用左边的内核。

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

高斯的拉普拉斯算子(无平滑)

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

现在我听说高斯的拉普拉斯对噪声敏感,我们在做任何事情之前平滑图像。为了好玩,让我们只应用拉普拉斯过滤器,而不平滑图像。对我来说,图像看起来更清晰,但它似乎在这里和那里有奇怪的人造物。

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

交互代码

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

对于谷歌 Colab,你需要一个谷歌帐户来查看代码,而且你不能在谷歌 Colab 中运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

请注意,我不想滥用任何数据政策。所以对于谷歌 Colab,我找到了下面的图片,它被标记为重复使用。要访问在线代码,请点击此处。

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

Image from this website

最后的话

想到在深度学习之前,研究人员只是通过卷积和复杂的数学运算来创建高级功能(如 HOG、SIFT ),真是令人着迷。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请点击这里查看我的网站。

同时,在我的推特这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。如果你感兴趣,我还在这里做了解耦神经网络的比较。

参考

  1. scipy,G. (2018)。scipy 中的高斯滤波器。Stackoverflow.com。检索于 2018 年 4 月 13 日,来自https://stack overflow . com/questions/25216382/Gaussian-filter-in-scipy
  2. 斑点检测。(2018).En.wikipedia.org。检索于 2018 年 4 月 13 日,来自https://en . Wikipedia . org/wiki/Blob _ detection # The _ Laplacian _ of _ Gaussian
  3. 生物分割|生物图像信息学中心|加州大学圣巴巴拉分校。(2018).Bioimage.ucsb.edu。检索于 2018 年 4 月 9 日,来自https://bioimage.ucsb.edu/research/bio-segmentation
  4. 驱动:下载。(2018).isi . uu . nl . 2018 年 4 月 9 日检索,来自http://www.isi.uu.nl/Research/Databases/DRIVE/download.php
  5. 超声波神经分割| Kaggle。(2018).Kaggle.com。检索于 2018 年 4 月 9 日,来自https://www.kaggle.com/c/ultrasound-nerve-segmentation
  6. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782457/
  7. Pixabay 上的免费图像——日落、灯塔、黎明、黄昏、太阳。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/sunset-light house-dawn-dusk-sun-3120484/
  8. Pixabay 上的免费图像——核磁共振成像,磁性,x 光,头骨,头部。(2018).Pixabay.com。检索于 2018 年 4 月 9 日,来自https://pix abay . com/en/MRI-magnetic-x-ray-skull-head-782459/
  9. 空间过滤器-拉普拉斯算子/高斯拉普拉斯算子。(2018).Homepages.inf.ed.ac.uk 检索 2018 年 4 月 13 日,来自 https://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm
  10. (2018).Cse.psu.edu。检索于 2018 年 4 月 13 日,来自 http://www.cse.psu.edu/~rtc12/CSE486/lecture11_6pp.pdf
  11. 安,S. (2018)。2D 卷积的例子。Songho.ca 于 2018 年 4 月 13 日检索,来自http://www . song ho . ca/DSP/convolution/convolution 2d _ example . html

用于车道识别的计算机视觉

原文:https://towardsdatascience.com/computer-vision-for-lane-finding-24ea77f25209?source=collection_archive---------2-----------------------

先进的计算机视觉技术,从安装在汽车上的摄像机中识别车道线。

这个项目的代码可以在: Github 上找到。
这篇文章也可以在我的网站这里找到。

udacity 自动驾驶汽车工程师课程的第四个项目中,我应用计算机视觉技术来检测道路上的车道线,这些车道线是使用安装在汽车前部的摄像头拍摄的。在这个项目中,大量使用了开源计算机视觉库(OpenCV) 库。

该项目包括以下几个阶段:

  1. 相机校准,以消除镜头失真的影响。
  2. 检测车道线的图像预处理。
  3. 道路透视变换有助于检测。
  4. 改造道路上的车道线检测。
  5. 车辆位置和车道曲率半径的计算。
  6. 生成结果视频。

摄像机标定

摄像机的输出是视频,本质上是图像的时间序列。由于摄影镜头的性质,使用针孔相机拍摄的图像容易发生径向失真,从而导致放大倍率不一致,这取决于物体与光轴的距离。

以下是来自 OpenCV 的示例图像,展示了两种主要类型的径向失真:

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

Figure 1. Examples of radial distortion. (source: link)

为了正确检测图像中的车道线,我们首先需要校正径向失真。

计算机视觉研究人员已经想出了一种方法来纠正这种径向扭曲。要校准的相机用于捕捉棋盘图案的图像,其中图案中的所有白盒和黑盒都具有相同的大小。如果相机失真,捕获的图像将会错误地显示棋盘的尺寸。

为了校正失真的影响,识别棋盘的角,并且使用与预期棋盘测量的偏差来计算失真系数。这些系数随后被用于从使用该相机捕获的任何图像中消除径向失真。

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

Figure 2. Checkerboard before and after fixing for distortion.

在上图中,最左边的图像显示了原始失真图像,最右边的图像显示了在失真图像上绘制的角,中间的图像显示了相机校准后得到的未失真图像。

OpenCV 函数findchesboardcornerscalibrateCamera 用于实现上述相机校准过程。

现在我们已经校准了我们的摄像机,我在汽车视频的实际镜头上测试了结果。下图显示了相机校准的结果:

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

Figure 3. Distortion correct applied for snapshots from the car driving video.

图像预处理

有了未失真的图像,我们现在回到检测道路上车道线的主要目标。分离和检测图像中的对象的一种方法是使用颜色变换和梯度来生成过滤后的阈值二进制图像。

对于颜色变换,我试验了三种颜色空间,以便找出哪一种最适合过滤代表道路上车道线的像素。测试了三种颜色空间:

  • HSL :将颜色表现为三个通道——色相、饱和度和明度。
  • LAB :将颜色表示为三个通道——亮度,分量 a 表示绿-红,分量 b 表示蓝-黄。
  • LUV :尝试感知一致性的 XYZ 色彩空间的变换。

经过一些实验,我得出结论:LAB 色彩空间的 b 通道和 LUV 色彩空间的 L 通道是检测道路上车道线的最佳组合。

还考虑了 Sobel 梯度滤波器。图像梯度测量颜色变化的方向强度。Sobel 是一种梯度滤波器,它使用高斯平滑和微分运算来减少噪声的影响。

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

Figure 4. Original undistorted images in the first column, the b/L channel thresholding in the second column, the Sobel gradient filter in the third column, and the two filters combined in the last column.

透视变换

我们现在可以区分图像中的车道线,但使用默认的相机视图很难计算出车道的准确角度/方向。在默认的相机视角中,离相机越远的物体看起来越小,车道线看起来越靠近汽车,这不是真实世界的真实表现。

修复这种透视失真的一种方法是转换图像的透视,使我们从上方观看图像,也称为鸟瞰视图。

OpenCV 提供了函数 getPerspectiveTransformwarpPerspective ,可以用来对图像中的一个片段应用透视变换。首先,我们在图像中选择我们想要应用变换的区域。在下图中,我选择了汽车前面的车道线段:

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

Figure 5. Source points we want to apply a perspective transform to.

然后,我们选择代表我们想要将线段转换到的目标空间的点,在我们的例子中,任何矩形都足够了。然后,该函数将返回一个 3x3 的变换矩阵,使用 warpPerspective 函数,该矩阵可用于将任何线段弯曲成我们选择的视角。

下图显示了成功应用透视变换的两条不同路段的车道线:

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

Figure 6. Perspective transform applied to two different sections of the road.

请注意,现在确定车道线的曲率变得更加容易了!

车道线检测

我们现在终于准备好完全检测车道线了!首先,我们将在图像预处理部分讨论的二进制阈值处理应用于透视变换车道线段。我们现在有一个图像,其中白色像素代表我们试图检测的车道线的一部分。

接下来,我们需要找到一个好的起点来寻找属于左车道线的像素和属于右车道线的像素。一种方法是生成图像中车道线像素的直方图。直方图应该有两个峰值,每个峰值代表一条车道线,其中左峰值代表左车道线,右峰值代表右车道线。下图显示了从两个二进制图像生成的两个直方图示例:

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

Figure 7. Binary thresholded images and histogram of pixels in thresholded images.

然后,两个峰值的位置被用作搜索属于每条车道线的像素的起点。我们采用滑动窗口搜索技术,从底部开始,迭代扫描到图像的顶部,将检测到的像素添加到列表中。如果在一个窗口中检测到足够数量的像素,下一个窗口将以它们的平均位置为中心,这样我们就可以跟踪整个图像中像素的路径。

在我们检测到属于每条车道线的像素后,我们通过这些点拟合一个多项式,生成一条平滑的线,作为车道线位置的最佳近似。

下图显示了滑动窗口技术的应用,多项式拟合检测到的车道像素(红色表示左侧车道像素,蓝色表示右侧车道像素):

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

Figure 8. Warped images and polynomial fit produced using sliding window technique.

下面是滑动窗口搜索技术的另一个视图,突出显示并填充了搜索区域:

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

Figure 9. Sliding window technique compared to the binary image used as input.

车辆/车道位置

最后,使用两条检测到的车道线的位置,并假设摄像机位于图像的中心,然后我们计算汽车相对于车道的位置。使用图像的分辨率计算出从像素转换为米的比例测量值。

此外,使用比例测量,我们还可以通过将新的多项式拟合到世界空间来计算车道的曲率,然后计算曲率半径。车道的曲率半径就是这两个半径的平均值。下图显示了两条车道线的曲线半径和中心偏移(图像中检测不可见):

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

Figure 10. snapshot fro the video with the lane curvature and car’s centre offset superimposed.

结果

随着我们的车道线检测管道的完成,我们现在通过将填充的多边形投影到我们认为车道线边界所在的视频上来可视化我们的检测,如下图所示:

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

Figure 11. Projection of our lane line onto the original video.

管道是在汽车行驶的录像上运行的。下面是一段演示管道运行的视频:

运动中的计算机视觉

原文:https://towardsdatascience.com/computer-vision-in-sports-61195342bcef?source=collection_archive---------4-----------------------

我最近在浏览 CVPR 的网站,无意中发现了它在运动工作坊中的计算机视觉。我认为体育是许多机器学习算法的一个有趣的应用,因为体育通常是非常快节奏的,并且(许多)包括群体动态。因此,为体育量身定制的算法可能有助于推动 CV 的发展。

我一直对将机器学习应用于体育和娱乐活动很感兴趣。特别是,在 PaddleSoft 的时候,我想用 CV 算法来检测急流中不同的划水和动作,并用它来预测划水者是否会有一条成功的路线,或者他们是否会翻转、游泳……等等。但是由于我的知识有限,我没有走多远;此外,直到最近几乎没有关于这个主题的文献。但是我很高兴看到许多新的论文处理这种复杂的事件识别。

以下是研讨会上的一些论文,我觉得特别有趣,我认为它们解决了整个 CV 中的重要问题。为了简洁起见,我选择了不涉及太多的实现细节,而是专注于这些作品中呈现的广泛主题。

学习评分奥运项目 :

作者:帕里托什·帕尔马和布伦丹·特兰·莫里斯

虽然乍看起来,为奥运赛事打分似乎是一个利基研究领域,但使用计算机视觉对一个动作或活动打分或提供反馈对许多不同的领域和问题都是有用的。例如,作者指出,与他们论文中介绍的方法类似的方法可以为自行进行物理治疗的患者或在没有教练的情况下为比赛进行训练的人提供反馈。他们还表示,他们的算法可以帮助消除奥运会比赛评判中的一些主观性。

在进入本文之前,澄清一些术语是有用的:

**动作识别:**涉及对视频中发生的活动进行分类。(即人在跑步)。

**行动质量评估:**包括根据行动的执行情况分配一个数值(即人员的运行经济性为 8.0)。

动作质量评估是一个困难的问题,因为高分和低分动作之间的差异往往非常微妙,必须考虑整个序列(不仅仅是一个片段)。此外,与动作识别数据集不同,动作质量数据集相对稀缺,并且存在的数据集非常小。在这篇论文之前,只有少数其他作者探讨了这个问题

作者建议采取多层次的方法来解决这个特定的任务。在第一层,他们使用 3d convnet 提取特征。这些特征然后被传递到三个可能的“第二级”中的一个第一个是裁剪级别要素或 L-SVR 的简单平均值,第二个是具有完全连接图层的 LSTM,第三个是用于提取要素并将其传递到 L-SVR 的 LSTM。

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

Action quality assessment model overview (taken from page 20 of Learning to Score Olympic Events)

作者评估了他们在跳水、花样滑冰和体操跳马方面的模型。他们使用的潜水数据集是一个小数据集,最初来自麻省理工学院的“评估行动质量”论文,可以在这里找到。。他们还在花样滑冰和体操数据集上测试了他们的模型。他们测试的另一个名为 UNLV 的数据集可以在这里找到。结果和性能评估是相当复杂的,如果不阅读全文就无法很好地总结。然而,TLDR 本质上是 C3D-SVR 给出了最好的总体结果,但是在行动过程中不能检测出特定的错误。如果你只是对评分感兴趣,这是可以的,但是为了提供反馈,你显然也需要能够识别行动的“问题”区域。为了弥补这一点,他们增加了 LSTM(即 C3D·LSTM-SVR ),这增加了他们的得分和实际得分之间的误差,但能够检测出参与行动的个人的具体“错误”。

总的来说,我认为这篇论文是对一个看似研究不足的领域的一个重要贡献(只希望他们把他们的代码发布在某个地方)。令人困惑的是,没有更多的研究针对动作质量评估,因为它可以直接帮助任何类型的教练/训练。

[连续视频到简单信号用卷积神经网络进行泳姿检测](http://Continuous Video to Simple Signals for Swimming Stroke Detection with Convolutional Neural Networks:) :

**作者:**布兰登·维克托,贞哼·斯图尔特·摩根,迪诺·米尼乌蒂

前面提到的动作识别集中在将整个视频分类为单个动作。相比之下,事件检测包括检测动作的开始和结束帧(在连续视频中),然后对它们进行分类。本文主要研究游泳泳姿的检测。具体来说。本文作者提出了一种用于*离散事件检测的方法。*然后,他们使用这种方法来确定视频中何时出现泳姿。

“划水率是游泳训练中使用的重要指标,目前,专家花费大量时间在视频中手动标记每一次划水,以便向游泳者提供统计反馈。我们称这个任务为离散事件检测(不同于,事件检测;检测一个动作的开始和结束)一

与简单事件检测相比,离散事件检测涉及在事件发生时定位准确的帧。

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

Figure 2 from [Continuous Video to Simple Signals for Swimming Stroke Detection with Convolutional Neural Networks](http://Continuous Video to Simple Signals for Swimming Stroke Detection with Convolutional Neural Networks:)

作者使用 CNN 来检测这些离散事件,并将它们映射到一维平面上,用峰值表示游泳中风的位置(如果你感到困惑,请参见他们的图 1)。他们的 CNN 在预测游泳或网球击球方面也做得很好(“在 3 帧容差下,F 值分别为 0.92 和 0.97”)。

这篇论文激发了我的兴趣,因为它能够检测出一连串的笔画。我还喜欢它对不同类型的动作检测的解释和对离散事件检测的介绍。然而,对我来说最有趣的部分,尤其是它如何很好地推广到网球。我很想测试它识别划水的能力。

曲棍球动作识别通过集成堆叠沙漏网络

http://open access . the CVF . com/content _ cvpr _ 2017 _ workshop/w2/papers/Fani _ Hockey _ Action _ Recognition _ CVPR _ 2017 _ paper . pdf

作者 : Mehrnaz Fani Shiraz 大学 Helmut Neher 滑铁卢大学 hne her @ uwaterloo . ca David a . Clausi,Alexander Wong,John Zelek 滑铁卢大学

作为一名曲棍球迷,我特别觉得这篇论文很吸引人。这篇论文的作者试图解决冰球运动中的动作识别问题,因为他们认为这有助于提供有价值的反馈。

动作识别为教练、分析师和观众提供了评估球员表现的内容,对教练、分析师和观众都有好处。第 29 页

然而,作者指出,冰球有许多特殊的挑战(这也可以推广到其他运动)。

姿态估计和动作识别是曲棍球中具有挑战性的问题,可以扩展到其他类型的运动。曲棍球特有的动作识别挑战包括使球员体形变形的笨重服装、与背景高度相似的球队球衣(白色)(冰和木板……第 29 页

作者称他们的模型为 ARHN 或动作识别沙漏网络。他们模型的实际细节相当复杂,因为它使用了许多不同的组件。但在最基本的层面上,他们的模型是通过将视频剪辑转换为图像序列,用堆叠的沙漏网络估计玩家的姿势(并将其作为特征输出),用潜在的转换器进行转换,然后对动作进行分类。你可以在他们的报纸上读到全部细节。

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

Figure 7 on page 35 of Hockey Action Recognition via Integrated Stacked Hourglass Network

他们将四种不同的动作分类:直滑、交叉滑、前滑和后滑。他们的精确度和回忆分数一般在 60 多到 70 多。

总的来说,考虑到他们在数据可用性方面的局限性,他们取得了相当好的结果。看看这种动作识别如何识别其他项目,如倒滑、身体检查和传球,会很有趣。此外,正如在上一篇文章中提到的,对这一行动的有效性进行分级也是有价值的,但这可能需要对上一篇文章中描述的技术进行更复杂的改进。最后,正如我们将在下面的文章中看到的,曲棍球有一个主要的团队组成部分,作者在这里并没有真正触及。

冰球控球项目分类

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

Detecting puck possession in ice hockey using an LSTM. Classification of Puck Possession Events in Ice Hockey (91).

作者穆米塔·罗伊·托拉,成建辉,吉姆·利特

本文试图解决体育运动中的群体活动识别问题。群体活动识别顾名思义就是试图观察多个人(或者在这种情况下是玩家)并确定他们作为一个群体在做什么。虽然团体活动识别在团队运动中的效用相当明显,但它也可以在体育世界之外提供效用。一个直接的用例是安全目的(例如,确定一群人是否抢劫这个地方或攻击某人)。然而,群体活动识别对于几乎任何涉及大量多人互动镜头的任务都非常有用。正如人们可能期望的那样,可以说群体活动识别的“关键”是理解个体行动之间的关系。

现在记住这些想法,让我们进入实际工作。在本文中,作者着眼于冰球控球事件。具体来说,他们想要检测和分类不同类型的压轮占有事件。他们主要专注于冰球倾入,倾出,松散冰球恢复(LPR),投篮和传球。为此,他们使用 AlexNet 的 f c7 层从球员有界子图像中提取球员的特征(在他们的算法中,球员是用有界框预先标识的),这些特征然后被最大化汇集,以便考虑球员的交互,最后它们被馈送到执行预测的 LSTM。他们测试了几种不同的特性和 LSTMs 配置,您可以在本文中了解更多。

我真的很喜欢这篇文章,因为它试图解决一个涉及多个玩家互动的非常困难的任务。正如他们在文章中提到的,我认为获得好的特征来描述玩家之间的关系对于好的性能是至关重要的。像往常一样,我真的希望看到代码或补充,更详细地描述他们的实现,因为纯粹基于他们文章中的信息重建他们的设置将是非常困难的(至少对我来说)。

由于篇幅原因,我没有在这里提到研讨会上的许多其他好论文,但我鼓励您查看研讨会的官方网站。我主要选择这三个,因为它们讨论了体育运动中不同领域的相对不同的挑战。他们主要讨论了与动作质量评估、姿态估计、离散事件检测和群体动作检测相关的挑战。我认为这些论文都展示了看似专业的运动中的进步在整个领域中的应用。他们也激励我重新审视我将 CV 应用于激流泛舟的目标。

关于计算机视觉在体育运动中的应用的其他资源

计算机视觉在体育 CVPR

运动中的计算机视觉:斯普林格出版

网球领域特定活动识别

行动质量评估 MIT

预算上的计算机视觉

原文:https://towardsdatascience.com/computer-vision-on-a-budget-3748372414c3?source=collection_archive---------19-----------------------

用不到 20 行代码实现一个动态分类器

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

在试图向我弟弟解释计算机视觉的复杂性时,他问我实现实时图像分类器的最简单的方法(不是他的原话)。

我想了一会儿,想出了一个他几乎能够理解的解决方案。它利用了 openCV 库,并且需要与预先存在的模型结合使用。然而,它可以在不到 20 行的 Python 代码中执行(加载依赖项不算在内)。

属国

  • 开源计算机视觉库 openCV
  • 如果你不想从头开始训练你的模型,你可以从 Keras/Caffe 下载预先训练好的模型权重

准备工作

首先,加载所需的库和分类器。

import cv2
import numpy as np
from keras.applications import imagenet_utils, VGG19model = VGG19(weights='imagenet') # load the model weights

在这个练习中,我将使用 VGG19,它是通过 ImageNet 训练的模型之一。VGG19 可以使用 Keras 库加载。

我们需要 imagenet_utils 来预处理图像并解码 VGG19 给出的分类。

我们开始吧

cam = cv2.VideoCapture(0) # Open webcam

这种实时分类器的想法是将网络摄像头捕捉的图像分成帧,并将每一帧视为要分类的图像。为此,我们需要创建一个无限循环来连续捕获帧。

while True:

    ret, frame = cam.read()
    k = cv2.waitKey(1)     if k%256 == 27: # if esp key is pressed
        break

这个循环捕获后续帧(frame)以及前一帧是否存在(ret)。我们还包括一个退出条件,特别是当按下退出键时。其他等待键映射可以参考 Ascii 表

接下来,我们要抓取帧,并像对待任何常规图像一样对其进行分类。这些都在我们的循环中。

 frame_pred = cv2.resize(frame, (224, 224))
   frame_pred = cv2.cvtColor(frame_pred,                                                  cv2.COLOR_BGR2RGB).astype(np.float32)
   frame_pred = frame_pred.reshape((1, ) + frame_pred.shape)
   frame_pred = imagenet_utils.preprocess_input(frame_pred) predictions = model.predict(frame_pred)
   (imageID, label, score) = imagenet_utils.decode_predictions(predictions)[0][0]

这里发生了很多事情。让我们一行一行地来:

  • 图像大小调整为(224,224),这是 VGG19 的默认输入大小
  • 图像被转换为 RGB 格式。OpenCV 使用 BGR 格式,而 Keras(以及几乎所有其他格式)使用 RGB 格式
  • 图像被重新整形以适应模型输入要求
  • 输入被预处理成模型要求的格式
  • 我们检索预测
  • 我们解码预测以获得类别、标签和分数(属于该类别的概率)

要将预测叠加在网络摄像机画面上:

 cv2.putText(frame, "%s with Probability %.2f" % (label, score), (25, 25), cv2.FONT_HERSHEY_DUPLEX, 0.9, (0, 0, 250), 2) cv2.imshow('Computer Vision on a Budget', frame)

这又是在循环内部运行。最后一行返回带有所需标签文本的原始网络摄像头捕捉(不是针对模型增强的捕捉)。

最后,你想关闭你的摄像头。这一步在循环之外,只有按下 escape 键才会执行。

cam.release()
cv2.destroyAllWindows()

完整的 20 行代码,点击这里

它所做的一些分类。回想起来,红色并不适合这个标签。

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

这是一个粗略的解决方案,使用一种过于简单的方法来解决一个非常复杂的问题。分类器不区分也不识别帧中的单个对象。根据所用的型号,它也可能非常慢。

从好的方面来看,实现起来非常简单,我想我哥哥也学到了一些东西。

感谢您的阅读!

如果你喜欢这篇文章,可以看看我关于数据科学、数学和编程的其他文章。通过 Medium 关注我的最新动态。😃

作为一个业余爱好项目,我还在 www.dscrashcourse.com建立了一套全面的免费数据科学课程和练习题。

如果你想支持我的写作,下次你报名参加 Coursera 课程时,可以考虑使用我的会员链接。完全公开—我从每一次注册中获得佣金,但不会对您产生额外费用。

再次感谢您的阅读!📕

电脑可以让你跳舞,看看“现在人人都会跳舞!”

原文:https://towardsdatascience.com/computers-can-make-you-dance-see-how-everybody-can-dance-now-501be0098916?source=collection_archive---------10-----------------------

想象过你像 MJ 一样跳舞吗?“可能在梦里吧!”,可能是你的答案,但现在这确实是可能的,让我们使用生成性对抗网络(GANs)来学习跳舞。GANs 在目前的技术研究领域获得了很大的发展势头,它改变了我们的思维方式,并试图实现不可能的事情。

我们可以利用 GANS 做一些惊人的事情:

  • GAN 具有将枯燥的黑白图像转换成彩色图像的能力。
  • 它可以使用虚拟生成的数据来扩充数据集,一个惊人的应用是,它还可以从文本合成图像,反之亦然。
  • 这些可以通过在原始图像中添加随机性来创建新的动漫角色。

哇哦。我们生活在另一个维度吗?当然,不!所以,让我们来看一次这个奇妙的网络。

甘斯简介

gan 是由 Ian Goodfellow 等人设计的生成性对抗模型。主要目标是赋予计算机想象力,使其能够使用现有的信息/数据生成新的信息和数据。GANs 由两个参与者(神经网络模型)组成,这就像一个零和锁定游戏。

一个玩家是一个生成器,它试图产生来自某种概率分布的数据。那就是,你试图复制党的门票。另一个玩家是一个鉴别者,作为一个法官。它决定输入是来自生成器还是真实的训练集。那会是党的安全,比较你的假票和有效票,找出你设计的瑕疵。

玩这个游戏有两个主要规则。第一,生成器试图最大化使鉴别器将其输入误认为真实的概率,第二,鉴别器引导生成器产生更真实的图像/用例。

GANs 是机器学习最近十年最有趣的想法!——扬·勒昆

概略地说,这是它看起来的样子;生成器向训练集图像添加随机性,而鉴别器监控随机性并识别生成的图像是真是假。

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

Generative Adversarial Model

现在,我们能让人们用 GANs 跳舞吗?加州大学伯克利分校说赞成成立!

CAROLINE CHAN,SHIRY GINOSAR,TINGHUI ZHOU,ALEXEI A. EFROS 发表了一篇惊人的论文,名为:大家现在跳舞! ( 视频)让我们从今以后,跳进深渊去了解更多。

简而言之,它是我们将源对象的舞蹈动作(一个会跳舞的对象)转移到静态目标对象(一个我们教跳舞的对象)的地方。这被称为具有时空平滑的每帧图像到图像的转换。听起来很奇怪,对吧?

为了明确这一点,让我们将这一过程分为三个简单的阶段:

  • 姿态检测
  • 全局姿态标准化
  • 从标准化的姿势简笔画到目标对象的映射

姿态检测从源视频的每一帧中估计源人物的姿态。为了做到这一点,我们使用了一个预先训练好的姿势检测器“开放姿势”。这将自动检测跳舞者的 x,y 关节坐标。然后将这些点连接起来,形成一个姿势简笔画。下图显示了如何从源图像中识别姿势。

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

Pose detection

全局姿态归一化是为了使源的对象框架与目标的环境更加一致。

从标准化的姿态简笔画到目标主体的映射最后,我们将标准化的姿态简笔画映射到目标对象,这使得它们像源对象一样跳舞。整个过程分两个阶段完成——培训和转移。

培训阶段

在训练阶段,所生成的目标人的姿势棒图被传递给生成器 G,生成器 G 的工作是从抽象的姿势棒图像生成图像。

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

这种对抗训练使用鉴别器 D 和使用预训练 VGGNet 的感知重建损失 dist 进行。这有助于优化生成的图像 G(x) 以匹配地面真实目标图像 y 。与传统 GAN 一样,鉴别器 D 试图区分真实图像 y 和伪图像 G(x) 。所有这些导致对目标图像的生成器 G 的训练。

传送阶段

在这个阶段,源物体的姿态y’被提取,产生x’。但是,由于我们不确定源对象的位置、肢体位置和环境,我们需要确保它与目标人物的位置兼容。因此,为了归一化上述内容,我们使用全局位置归一化范数生成 x 。我们找到脚踝位置和高度之间的距离,将源对象的位置线性映射到目标对象的位置。然后我们将其传递给之前训练好的 G 模型,生成目标人的 G(x)

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

到目前为止,一切顺利。我们已经使用 pix2pixHD 框架成功地从源对象的位置生成了漂亮的目标图像,该框架内部使用了条件 GAN(与我们到目前为止讨论的 GAN 相同)。在我们的用例中,经过 GAN 网络的严格训练,pix2pixHD 将从姿势简笔画生成人类图像。

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

A generator trying to colour the input image — an application of pix2pixHD.

但是,我们随后修改了 pix2pixHD 的对抗性训练,以产生连贯的视频帧,并使用时间平滑和面部 GAN 来获得逼真的面部表情。

时间平滑

它用于生成视频帧序列。因此,我们使用两个连续的帧来保持针对静态目标对象修改的视频的连续性,而不是一个单独的帧。

最初,第一输出 G(xt-1) 取决于姿态简笔画 xt-1 和零图像,比如说 z 。下一个输出 G(xt) 以其相应的姿态简笔画 xt 和先前生成的输出 G(xt-1) 为条件。鉴别器现在试图将真正的时间相干序列*(xt 1,xt,yt1,yt)* 与伪序列*(XT 1,XT,G(XT 1),G(xt))* 区分开来。

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

G(xt) is conditioned on xt and G(xt-1)

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

Discriminator tries differentiating the real and fake temporal video sequences. G(x) indicates the images generated using Generator in the pix2pixHD framework and y is the actual input given which is the same as expected output.

脸甘

脸部特写有助于提高面部表情的真实性。面 GAN 与我们之前讨论过的主 GAN 一起使用。一个发生器, G(xf) 被用来专门聚焦在使用 G 的人的脸上。然后,这与姿势简笔画 xf (从 x 生成,焦点在人的面部)一起被提供给生成器 Gf ,该生成器输出残差 r。当与 G(xf) 组合时,这给我们提供输出 r + G(xf) 。然后,鉴别器尝试将真实人脸对 (xf,yf) 与虚假人脸对 (xf,r + G(xf))区分开来。

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

Face GAN

耶!结束了。综上所述,我们首先训练主 GAN,然后优化权重,之后,应用面 GAN。现在,你也可以跳舞了!

感谢阅读。如果你觉得这个故事有帮助,请点击下面的👏去传播爱。

本文由萨姆希塔·阿拉和维哈尔·鞍马撰写。

计算机视觉:温和的介绍

原文:https://towardsdatascience.com/computers-that-learn-to-see-a2b783576137?source=collection_archive---------13-----------------------

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

贯穿人类历史和大脑研究的一个主要问题是:我们如何以自己的方式感知世界?

当谈到我们的眼睛时,这些只是传感器,帮助我们建立一个我们周围现实的可理解的表示。例如,颜色等属性并不是物理世界中的物体所固有的,而是代表了我们对不同波长的光反射的感知。尽管听起来令人沮丧,但在我们的物理现实中,一切都是“黑暗”的。当一个物体反射我们脑海中与红色联系在一起的特定波长,并吸收所有其他波长时,这个物体就呈现为红色。

这种视觉感知能力远远不止识别不同的波长。最有趣的一面是,我们有能力根据这些光子在空间中的相互关系来构建一个概念现实。例如,我们理解椅子的概念,因为我们希望它有一定的几何属性。朝向我们的眼睛,椅子反射的光必须保持一种空间关系,类似于我们概念化的椅子形状。

计算机最近也具备了视觉识别能力,学习如何看东西。这要归功于人工智能的进步,尤其是卷积神经网络(CNN)的应用。有很多关于这个主题的文章,但是很少解释统计学和线性代数之外的方法的直觉。

卷积神经网络的构造块

为了理解如何使用细胞神经网络来执行任何视觉任务,我们必须首先了解它的组成部分。所涉及的概念列表可能是压倒性的,但它们都可以缩小到该方法中已经存在的词:卷积、深度神经网络(DNNs)以及这两者的融合。

什么是卷积?

卷积是一种将两个函数合并成第三个函数的数学运算。例如,假设我们有两个给定的函数,***【f(t)**g(t) ,我们感兴趣的是将一个应用到另一个之上,并计算相交的面积:f(t) g(t)=(f * g)(t)

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

Source: Brian Amberg

在这种情况下,我们在***【f(t)上应用 g(t) (调用内核),并根据两个函数面积的交集来更改响应【f * g】【t】***。卷积的概念是信号处理中最常用的技术,因此它也应用于计算机视觉,这可以看作是处理多个 RGB 传感器的信号。卷积有效性背后的直觉是它们能够将给定的输入信号过滤成组合的、更有用的结果。

在图像的特殊情况下,信号以矩阵而不是波形的形式更容易理解。因此,我们的函数 f(t)g(t) 现在将分别变成 【图像(矩阵)【内核(矩阵) 。同样,我们可以通过将一个矩阵放在另一个之上来应用卷积:

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

Source: Machine Learning Guru

你在上面看到的只是图像中滑动窗口与内核的矩阵相乘,然后求和。在计算机视觉的背景下,卷积的能力在于它们是 RGB 传感器领域的优秀特征提取器。当单独拍摄时,每个像素(RGB 传感器)对于理解图像包含的内容是毫无意义的。正是空间中的相互关系赋予了图像真正的意义。它适用于你在电脑上阅读这篇文章的方式,像素代表字符,你的大脑将黑色像素在空间中相互匹配,形成字符的概念。

通过在图像上滑动不同的卷积核,可以执行图像操作。这是 Photoshop 或 Gimp 等图像编辑软件中的许多工具的工作原理:

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

Source: Gimp Documentation

什么是深度神经网络?

机器学习中学习的概念可以看作是试图从给定的数据中预测未知的函数。假设你有兴趣预测一个标签 y 给定输入 x 。在这个特定的场景中,您希望您的模型将您的预测和实际情况之间的误差最小化。我们以这样的方式修改我们网络中的权重和偏差,即我们尽可能将输入 x 映射到输出 y

为了更好地理解这一点,我们来看一个简单的线性回归问题。一条直线的方程可以描述为 y = mx + b ,其中 m 为斜率, b 为与 y 平面的交点(一般称为偏置)。如果只有两个点,可以用公式直接求解斜率和偏差,但是当我们有多个点 n > 2 并且没有一条线完全符合这些点时,问题就变得更难了。在这种情况下,我们会对逼近一条使到每个数据点的距离最小化的线感兴趣。为此,我们可以遵循以下步骤:

1.给 mb 随机取值。
2。计算误差,可以描述为均方误差 (MSE),就知道我们离最优线有多远了。
3。使用该误差函数的导数,计算梯度,以知道在哪个方向上移动这两个值,从而减小误差。
4。重复步骤 2 和 3,直到误差停止减小。

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

Source: Alykhan Tejani

在图的左侧,您可以看到误差空间,它是由应用于我们特定数据点的 MSE 给出的。在右侧,我们可以看到我们的数据点的表示,以及由 mb 定义的线。开始时,线完全断开,这反映在高误差值中。然而,当我们计算导数并向函数减小的地方移动时,我们最终得到类似数据点属性的线的值***【m】***和 b

在深度神经网络(DNNs)中,这是关于每个神经元上正在发生什么的核心思想。考虑到我们的问题比仅仅逼近一条线要复杂得多,我们需要更多的神经元,通常是分层的。深度学习通过使用梯度下降来最小化误差函数,由于学习是分层结构的,DNNs 最终在数据中学习一个层次。

神经网络的主要构件是人工神经元。这些有不同的类型,最简单的是感知器。人们可以将感知器视为一个单元,它接受几个二进制输入 x1,x2,…,xn ,并生成一个二进制输出 y :

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

每个输入都被赋予一个权重 w1,w2,…,wn ,代表它们对输出的重要性。最后,利用输入和给定阈值的加权和计算输出。如果这个和大于这个阈值,感知器将输出 1 ,否则输出 0 。这可以更容易地用代数术语来表达:

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

网络的人工神经元通过层相互连接。连接到输入的第一组神经元形成了输入层。提供预测的网络的最后一层被称为输出层。中间可以有任意数量的层,这些层被认为是隐藏层

深度学习这个名字来自于架构中涉及 2 层以上的神经元。在过去,超越两层是不切实际的,效果也不好。这些限制被大量训练数据和加速计算的可用性所克服。正是在这个时候,社区开始增加更多的层,产生了所谓的深度神经网络。通过层的通信能够描述数据的分层表示,其中每一层神经元代表一个抽象级别。

通过卷积神经网络学习视觉表示

将卷积提取空间特征的能力与从深度神经网络进行分层学习的能力相结合,产生了所谓的卷积神经网络。通过用卷积层代替 DNNs 中的传统神经元层,这两种技术被合并成一个解决方案。因此,权重和偏差被编码在核中,并且是优化从原始输入(图像)到预期预测(例如,图像的类别)的表示的学习参数。最初的层将编码诸如边缘的特征,而后来的边缘将编码越来越高的抽象,例如形状和纹理。

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

Source: Nvidia

在上图中,每个神经元代表对来自输入层或前一层的图像的卷积运算。我们可以让多个卷积接收相同的输入,以便提取不同种类的特征。通过这些层,卷积运算将不断地将来自先前层的给定矩阵转换成对于手头的任务来说越来越压缩/有用的表示。例如,如果我们的网络正在执行面部识别,初始层将从面部提取边缘,这些边缘将被卷成形状,这些形状将被卷成某些面部特征,这些特征有助于区分不同的个人,一直到输出,在输出中我们有给定面部的标识符。

结论

细胞神经网络可以应用于数据中存在某种空间属性的任何领域。这通常转化为以图像作为输入的问题。

优势

  • 与经典的计算机视觉技术相比,从开发的角度来看,CNN 更容易应用。有大量的教程和开源软件可以处理最常见的任务,如图像分类或物体检测,只需将数据输入到已经可用的模型中。
  • 当有足够的数据时,CNN 胜过其他的,主要是肤浅的模型。

限制

  • 任何任务所需的数据量都可能是巨大的,因为深度学习技术通常从手头任务的有限先验知识开始。在其他计算机视觉算法中,有许多技术使用这种先验知识来实现算法如何工作以减少必要的数据量。
  • 和任何深度学习方法一样,CNN 都是黑盒方法,无法形式化解释。这意味着,如果你的模型有一些问题,你将开始猜测什么可能出错。

在线性时间和空间复杂度下计算 N 皇后板中冲突对的数量

原文:https://towardsdatascience.com/computing-number-of-conflicting-pairs-in-a-n-queen-board-in-linear-time-and-space-complexity-e9554c0e0645?source=collection_archive---------7-----------------------

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

N 皇后问题是人工智能领域中的一个经典问题,我们试图找到一种棋盘配置,其中在 N × N 棋盘中将有 N 个皇后,而不是互相攻击。

解决这个问题有不同的方法,每种方法都有自己的时间复杂度。在生成状态之后,评估每一个状态中冲突对的数量也是非常耗时的。下面我们将讨论我们如何定义这个问题,以及在计算电路板中的冲突数量时如何实现线性时间复杂度。

需要注意的几件事:

  1. 为简单起见,我们将使用索引 1 中的数组(因为,我们从 1 到 N 对行和列进行了编号)。索引 0 未使用。
  2. 给出了简单的 C++代码(idea)。如果你理解这种方法,你总是可以用动态内存分配等等来编写更灵活的程序。
  3. 在本文末尾可以找到 python 实现的链接。

**问题定义:**我们将板卡配置描述为一维数组。索引将指示列号,并且相应索引中的值将指示该特定列中皇后的行号。

例如,{3,4,3,2}对应于此板配置(下图):

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

The 2-D board configuration (above) from the 1-D array (below)

为什么要这样定义?因为在每一列中,放置一个以上的女王是没有意义的,他们只会互相攻击,因此无助于解决问题。定义为一维数组可以节省大量空间。

假设我们在 O(1)中生成一个从 1 到 N 的随机值,生成一个电路板配置将花费 O(N)时间。

冲突检查(天真):我们可以使用嵌套循环来计算冲突的数量,因此对于每个皇后,检查所有接下来的皇后,并计算有多少冲突,并将其添加到结果中。冲突发生在以下情况:

  1. 皇后在同一行(两个皇后的行号相同)。
  2. 皇后在同一列中(两个皇后的列号相同,在我们的问题定义中,这不会发生)。
  3. 两个皇后在同一条对角线上(行的绝对差等于列的绝对差)。

这种方法需要 O(n)。

**实现线性时间复杂度:**我们将在冲突检查中使用 O(N)空间实现线性时间复杂度。

引入了三个一维表格(或数组)。一个用于存储每行中皇后的频率。一个用于存储主对角线中皇后的频率,另一个用于次对角线。

检查以下板图像的行和列索引,了解我们的问题定义。

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

A 8×8 chessboard

现在我们知道有 N 行,所以行频率数组的大小将是 N(或 N+1,因为索引 0 未被使用)。让我们将其声明为 f_row[],其中最初所有的索引都将包含零(0)。

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

Array to check frequency of queens in each row

让我们将棋盘配置数组表示为 Queen[]。我们可以这样填充 f_row[]:

for (int i = 1; i <= N; i++){
    int val = Queen[i];
    f_row[val]++;
}

对于每个行值,我们将 f_row[]中相应的索引增加 1。相当容易!现在我们如何检查冲突?让我们假设,一行的皇后不影响另一行的皇后(如果它们在同一条对角线上,它们会影响,但现在我们不考虑这一点)。因此,如果冲突是互斥的,我们可以分别计算每一行的冲突,然后将它们相加得到总的水平冲突,不需要检查重叠。

让我们考虑这种情况,其中 4 个皇后在同一行,冲突的对由红线连接。

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

Conflicts where 4 queens are on same row

线或边是无向的,我们不检查向后冲突,即如果女王 A 攻击女王 B,女王 B 也攻击女王 A,但是我们认为这是单个冲突。

我们可以观察到,一行中所有冲突的女王实际上形成了一个“完整的图”,因此每个女王都与其他女王相连。边的数量就是冲突的数量。检查完整图中边数的公式,其中有 N 个节点:

(N * (N-1)) / 2

需要注意的重要一点是,当我们检查对角线时,这个观察也适用。

在我们有 4 个皇后的例子中,该行的总冲突数=(4 *(4–1))/2 = 6。

我们将行频率存储在 f_row[]中。要计算横向冲突的总数,我们可以使用以下方法:

for (int i = 1; i <= N; i++){
    int queens = f_row[i];
    result += ((queens * (queens - 1) / 2);
}

为了检查对角线冲突,我们必须以不同的方式观察棋盘。首先让我们试试主对角线。请参见下图,其中每个纸板单元格包含其行值和列值的总和。

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

Every cell contains sum of row number and column number

如果你仔细观察,你会发现所有的(主)对角线都有相同的和值。也就是说,如果 A 女王站在数值为 10 的位置上,B 女王也在数值为 10 的某处,冲突就发生了!

就像行一样,我们也将使用频率表。但这次是两倍大。因为我们能拥有的最大和值是最高行和最高列的和,N + N .我们把它表示为 f_mdiag[](这里 mdiag 指的是主对角线)。

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

frequency table for main diagonals

我们可以这样填充它:

for (int i = 1; i <= N; i++){
    int row = Queen[i];
    int sum = row + i; // i is column value
    f_mdiag[sum]++;
}

对于次对角线,我们必须翻转列索引(或行,但不能两者都翻转)。现在对每个单元格的行和列值求和,并观察。

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

Every cell contains sum of row number and column number

同样,我们寻找的对角线,有相同的和值。所以我们需要另一个频率表,和上一个一样大。

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

frequency table for secondary diagonals

填充可以这样完成:

for (int i = 1; i <= N; i++){
    int row = Queen[i];
    int sum = (N - row + 1) + i; // flipping is done by N - row + 1
    f_sdiag[sum]++;
}

现在,我们可以遍历这两个数组,并使用(N * (N-1)) / 2 来生成每条对角线上的冲突数,并将它们添加到结果中。大概是这样的(对于 f_mdiag[]):

for (int i = 1; i <= (N+N); i++){ // note here, N+N, not N
    int queens = f_mdiag[i];
    result += ((queens * (queens - 1))/2);
}

实际上,我们计算冲突的方式,所有的设置都是互相排斥的。主对角线冲突不影响次对角线冲突或行冲突的计算,反之亦然,即使同一个 queen 可能一次被视为行成员,一次被视为对角线成员。因此,我们可以在一个循环中更新所有频率(行、主对角线和次对角线)(甚至在生成电路板配置时!)并在另一个循环中计算结果。

例如,检查以下内容:

for (int i=1; i<=N; i++){
    Queen[i] = generate_random(1, N); // generating queen position 
    int val = Queen[i];
    f_row[val]++;               // updating frequency of rows
    f_mdiag[val + i]++;         // and main diagonals
    f_sdiag[N - val + 1 + i]++; // and secondary diagonals
}int result = 0;for (int i=1; i<=(N+N); i++){ // this loop runs from 1 to N+N
    int x = 0, y = 0, z = 0;
    if (i <= N) x = f_row[i];  //number of queens in ith row
    y = f_mdiag[i];   //number of queens in ith main diagonal
    z = f_sdiag[i];   //number of queens in ith secondary diagonal result += (x * (x - 1)) / 2; // adding to result
    result += (y * (y - 1)) / 2;
    result += (z * (z - 1)) / 2;
}

通过这种方法,时间复杂度为 O(N)。空间复杂度也是 O(N)。

查看 Python 代码了解这种方法。

希望这对你有帮助!

让我知道你的想法:)

本周概念:让人工智能告诉你你的长相有多好

原文:https://towardsdatascience.com/concept-of-the-week-let-artificial-intelligence-tell-you-how-good-is-your-look-7dedd324d1d8?source=collection_archive---------6-----------------------

这是一系列介绍我提出的应用和产品的想法(有些可能很愚蠢)的文章。有时我会提供基本的源代码,有时会有只是描述和简单的模型。无论如何,你可以自由地将这些想法实现到一个完整的产品中,但别忘了告诉我你做到了:)。

我不擅长挑选合适的衣服。每次我自己去购物,我都会买一些看起来很傻的东西,然后再也不穿了。或者只在我需要去当地杂货店时才穿上它们,让它看起来像是“我只是迅速拿了我在壁橱里找到的第一件东西”。当然,有成群的销售人员试图帮助我,但是,由于这种帮助很少是有用的,我想,他们只是试图卖给我更贵和更不受欢迎的东西。

这就是为什么我总是试图让我的妻子给我买衣服。尽管我们有时会争论我去开会时穿这件衬衫是否合适,但几乎 99%的情况下她都是对的——那件补丁衬衫会让我看起来像是一个穿着灰色西装和浅蓝色衬衫、打着闪亮红色领带、在赚着百万美元的华尔街狮子中的古怪学生。

外面的许多人身边都没有像我妻子这样的人。因此,对于这些对时尚一无所知的单身人士,我给出了以下建议。一个后端带有神经网络的移动应用程序,它会告诉你你的新造型是好是坏。可能只有两个类别(好/不好),或 5 星或 10 星评级,或任何你认为观众会接受的东西。

基本流程是您:

  1. 给你自己拍张照片
  2. 获得评估

像这样:

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

我不知道,这个女孩是否真的看起来很棒,因为,就像我说的,我不擅长这个。

如果我给像我这样的人拍照,可能会发生这样的事情:

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

This is not me, nor my wife. Just random girl from the internet.

如果用户得到 5 英镑,那么所有常见的在 instagram 上分享并获得百万赞的事情都会发生。而且,很可能什么都不会分享,如果她得分更低,因为没有人喜欢在 Instagram 上分享糟糕的图片。

这个应用程序本身很简单。使用 Instagram 帐户登录的屏幕、相机屏幕和结果屏幕。一天之内可以在 iOS 和 Android 上实现。

后端需要建立一个简单的 API 服务器,将数据传递给“大脑”。“大脑”可能是一个张量流服务或任何你熟悉的东西。

我相信类似的东西已经存在了。想法很简单,没有什么是以前没做过的。

不过,还是有一些障碍。

这里可能存在的一个问题是获取训练集。如果您决定实现它,您将需要数千甚至数万个示例来进行神经网络的初始训练。训练数据集的大小在很大程度上取决于您用来对图像进行分级的比例。如果只有好/坏的分类,那么你需要的就更少。如果你认为用户想要更精细的东西,比如 5 级或 10 级评级,那么训练样本的数量应该相应增加。

当然,应该有一些关于模型对图像分类的反馈。一种方法是,模型在一定时间后查看每张照片的赞数与用户数的比率,即分享的照片有多少赞来自总粉丝数。例如,如果用户有 100 个关注者,只有 1 个喜欢 4 星照片,那么算法是错误的,它应该是 1 星。这种方法有一些明显的缺点,但它可能是一个很好的起点。

第二个问题是,要教会神经网络,你需要自己先给照片打分。这意味着这应该是一个具有特殊品味,风格的感觉和最新时尚知识的开发人员。我从未见过如此独特的人类物种。找一个设计师合作可能是对的。这仍然很困难,因为考虑到他或她要评价的图片数量,她或他需要有巨大的耐心。

对于像我这样的人来说,这个应用程序还有最后一个问题。购物时,每当我处于困境时,我通常不会想,“哦,有没有这方面的应用程序?”所以每当我在购物中心时,我应该能够以某种方式被提醒,我的手机上有这个应用程序。这意味着我将需要另一个应用程序,它将完全做到这一点——这可能是下周的概念。

原贴于【seigolonhcet.com】。如果你喜欢这篇文章,可以考虑在 Twitter 上关注我,获取更多的技术故事、新闻、评论和评论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值