纯干货:深度学习实现之空间变换网络-part1

简介: 本文介绍了仿射变换和双线性插值在图片变换中的应用。

更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud


1ca0bab260d25389121ff869f6703a7b1d7fe831

我的“深度学习论文实现”系列的前三个博客将涵盖2016年由Google Deepmind的Max Jaderberg, Karen Simonyan, Andrew Zisserman and Koray Kavukcuoglu提出的空间变换网络概念。空间变换网络是一个可学习模型,旨在提升卷积神经网络在计算和参数方面的空间恒定性。

在第一部分中,我们将介绍两个非常重要的概念,在理解空间变化层次的内在工作机制上起决定性作用。我们将从检验一个基于仿射变换的图像变换技术的子集开始,然后深入到服从双线性插值的一般变换过程。

在第二部分中,我们将细细重温空间变化层次并总结这篇论文。在最后的第三部分中,我们将用scratch在TensorFlow上编程并将其应用到GTSRB 数据集(德国交通标志识别标准)上。

完整代码参见我的Github Repository


e6df130fd117f056f9f6e106ed2c316c0c63c63c 39bc4788a8affd404ea6b6ef0416c6fef49075a8 702f907ea80eab94186624d73daa54f478204a24 3c0059303586f5da525bc5d5ff0ffa393df95eb6 6ea4960fa63c85d3f282e49baba2d4d7b2338796 20754a8eea318a6a1019607dc8d71831a0895c1a f7ecfa5f376b45e49ee1eeec37290bf04a9fd442 5441ed7aa790365f58e3477d6fab6032d5d2a0c2 39d71700c6f9c7a6aeddecdd33cdd95e92a35fb1
d8bc8485d4a56f815f9b27e59fdde84001053a5e

我在Github Repository(文章开始时提及了)中上传了2张猫的图片,请下载并存在桌面上叫 data/ 的文件夹中或更改为正确路径。

我还写了一个 load_img() 函数将图片插入numpy数组中,我没有细讲,但是我们要用到PIL和Numpy才能再现结果。

配上函数,加载图片并将它们连接到单输入数组中。为了使代码尽可能通俗简洁,,我们要对两张图片进行操作。

import numpy as np

from PIL import Image

# params

DIMS = (400, 400)

CAT1 = 'cat1.jpg'

CAT2 = 'cat2.jpg'

# load both cat images

img1 = load_img(CAT1, DIMS)

img2 = load_img(CAT2, DIMS, view=True)

# concat into tensor of shape (2, 400, 400, 3)

input_img = np.concatenate([img1, img2], axis=0)

# dimension sanity check

print("Input Img Shape: {}".format(input_img.shape))

我们的批处理规模是2,这表示我们需要等量的变换矩阵M对应批次中的每张图。

请初始化两个恒等变换矩阵。如果正确运用了双线性取样器,那么输出图片应该与输入的近乎一致。

# grab shape

num_batch, H, W, C = input_img.shape

# initialize M to identity transform

M = np.array([[1., 0., 0.], [0., 1., 0.]])

# repeat num_batch times

M = np.resize(M, (num_batch, 2, 3))

(再次声明:如果要包含位移,仿射变换的通用矩阵是2×3的)

现在我们需要写一个产生格点矩阵的函数并输出一个由格点矩阵产生取样网格和变换矩阵M。

我们要创造标准化格点矩阵,即x,y的值在-1到1之间,并且分别有width和height。事实上,对于图片,x代表图片的宽度(矩阵的列数),y代表高度(矩阵的行数)。

# create normalized 2D grid

x = np.linspace(-1, 1, W)

y = np.linspace(-1, 1, H)

x_t, y_t = np.meshgrid(x, y)

然后,我们要增加维度来构建齐次坐标系。

# reshape to (xt, yt, 1)

ones = np.ones(np.prod(x_t.shape))

sampling_grid = np.vstack([x_t.flatten(), y_t.flatten(), ones])

尽管我们已经构建了一个网格,我们仍然需要 num_batch 网格。同上,下一步仍需重复数组num_batch 的次数。

# repeat grid num_batch times

sampling_grid = np.resize(sampling_grid, (num_batch, 3, H*W))

让我们继续图像变换的第2步。

# transform the sampling grid i.e. batch multiply

batch_grids = np.matmul(M, sampling_grid)

# batch grid has shape (num_batch, 2, H*W)

# reshape to (num_batch, height, width, 2)

batch_grids = batch_grids.reshape(num_batch, 2, H, W)

batch_grids = np.moveaxis(batch_grids, 1, -1)

最后,我们来写双线性取样器。通过取样网格中的 xy 我们希望得到原始图像中像素的插入值。

尝试分离x,y维度并重新调节它们,使之适应高度或宽度的间隔。

x_s = batch_grids[:, :, :, 0:1].squeeze()

y_s = batch_grids[:, :, :, 1:2].squeeze()

# rescale x and y to [0, W/H]

x = ((x_s + 1.) * W) * 0.5

y = ((y_s + 1.) * H) * 0.5

对任意坐标 (xi,yi)我们希望获得4个角坐标。

# grab 4 nearest corner points for each (x_i, y_i)

x0 = np.floor(x).astype(np.int64)

x1 = x0 + 1

y0 = np.floor(y).astype(np.int64)

y1 = y0 + 1

(注意:我们只能用ceiling函数而不是增量1)

现在我们必须确定没有值超过了图像边界。假设x=399,则x0=399且x1=x0+1=400将导致一个numpy错误。因此我们用如下方法修剪角坐标。

# make sure it's inside img range [0, H] or [0, W]

x0 = np.clip(x0, 0, W-1)

x1 = np.clip(x1, 0, W-1)

y0 = np.clip(y0, 0, H-1)

y1 = np.clip(y1, 0, H-1)

我们用进阶的numpy索引来抓取每个角坐标的像素值,与(x0, y0), (x0, y1), (x1, y0) and (x_1, y_1)一致。

# look up pixel values at corner coords

Ia = input_img[np.arange(num_batch)[:,None,None], y0, x0]

Ib = input_img[np.arange(num_batch)[:,None,None], y1, x0]

Ic = input_img[np.arange(num_batch)[:,None,None], y0, x1]

Id = input_img[np.arange(num_batch)[:,None,None], y1, x1]

胜利在望!现在计算权重。

# calculate deltas

wa = (x1-x) * (y1-y)

wb = (x1-x) * (y-y0)

wc = (x-x0) * (y1-y)

wd = (x-x0) * (y-y0)

最后,用前面提到的公式加一加乘一乘。

# add dimension for addition

wa = np.expand_dims(wa, axis=3)

wb = np.expand_dims(wb, axis=3)

wc = np.expand_dims(wc, axis=3)

wd = np.expand_dims(wd, axis=3)

# compute output

out = wa*Ia + wb*Ib + wc*Ic + wd*Id

结果

我们快速通关了全部代码,快用不同值的变换矩阵M来找点乐子吧。

要做的第一件事就是复制粘贴所有更加模块化的代码,试试所有的函数是不是正确工作。


恒等变换

在脚本最后加上这两行代码并执行。

plt.imshow(out[1])

plt.show()

ba04af2aeeec12bec5a1db5c97d1609120b87215 9e48ef26d77104ea8c5e40c56869b264c2e94b58

位移

假设我们要只在x方向位移0.5,图片将向左移动,按如下方法调整代码。

M = np.array([[1., 0., 0.5], [0., 1., 0.]])

ba04af2aeeec12bec5a1db5c97d1609120b87215 94d5735d1c7016c63ec281a3cafd5b8669f18d0b

旋转

最后,如果我们想将图片旋转45度,因为cos(45)=sin(45)=2√2≈0.707,所以有:

M = np.array([[0.707, -0.707, 0.], [0.707, 0.707, 0.]])

ba04af2aeeec12bec5a1db5c97d1609120b87215 e638fa4b1ea76a114a9693d25a16851709d7dfaf

结论

在这篇博文里,我们学习了基本线性变换,如旋转、剪切和伸缩变换,并引申了包括位移在内的仿射变换。然后,我们见识了双线性插值在变换中的重要作用。最后,我们梳理了算法,通过scratch用Python编程并写了2种根据3个步骤将变换过程可视化的方法。

在下一篇博文中,我们将细细讲述空间变换网络层次并总结关于它的论文。

下周见!

参考文献

感谢 Eder Santana向我推荐了论文!

· Bilinear Interpolation Wikipedia

· Bilinear Interpolation

· Matrix Transformations PDF

· Bilinear Interpolation Code


数十款阿里云产品限时折扣中,赶紧点击领劵开始云上实践吧!

以上为译文

本文由北邮@爱可可-爱生活 老师推荐,阿里云云栖社区组织翻译。

文章原标题《Deep Learning Paper Implementations: Spatial Transformer Networks - Part I》,作者:Kevin Zakka,译者:NancyWang

文章为简译,更为详细的内容,请查看原文


相关文章
|
12天前
|
机器学习/深度学习 搜索推荐 安全
深度学习之社交网络中的社区检测
在社交网络分析中,社区检测是一项核心任务,旨在将网络中的节点(用户)划分为具有高内部连接密度且相对独立的子群。基于深度学习的社区检测方法,通过捕获复杂的网络结构信息和节点特征,在传统方法基础上实现了更准确、更具鲁棒性的社区划分。
27 7
|
13天前
|
机器学习/深度学习 自然语言处理 TensorFlow
深度学习的奥秘:探索神经网络背后的魔法
【10月更文挑战第22天】本文将带你走进深度学习的世界,揭示神经网络背后的神秘面纱。我们将一起探讨深度学习的基本原理,以及如何通过编程实现一个简单的神经网络。无论你是初学者还是有一定基础的学习者,这篇文章都将为你提供有价值的信息和启示。让我们一起踏上这段奇妙的旅程吧!
|
13天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
52 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
14天前
|
机器学习/深度学习 人工智能 自动驾驶
深度学习中的卷积神经网络(CNN)及其应用
【10月更文挑战第21天】本文旨在深入探讨深度学习领域的核心组成部分——卷积神经网络(CNN)。通过分析CNN的基本结构、工作原理以及在图像识别、语音处理等领域的广泛应用,我们不仅能够理解其背后的技术原理,还能把握其在现实世界问题解决中的强大能力。文章将用浅显的语言和生动的例子带领读者一步步走进CNN的世界,揭示这一技术如何改变我们的生活和工作方式。
|
2天前
|
机器学习/深度学习 人工智能 自动驾驶
深度学习的奇迹:如何用神经网络识别图像
【10月更文挑战第33天】在这篇文章中,我们将探索深度学习的奇妙世界,特别是卷积神经网络(CNN)在图像识别中的应用。我们将通过一个简单的代码示例,展示如何使用Python和Keras库构建一个能够识别手写数字的神经网络。这不仅是对深度学习概念的直观介绍,也是对技术实践的一次尝试。让我们一起踏上这段探索之旅,看看数据、模型和代码是如何交织在一起,创造出令人惊叹的结果。
7 0
|
3天前
|
机器学习/深度学习 人工智能 TensorFlow
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
【10月更文挑战第32天】本文将介绍深度学习中的一个重要分支——卷积神经网络(CNN),以及其在图像识别领域的应用。我们将通过一个简单的代码示例,展示如何使用Python和TensorFlow库构建一个基本的CNN模型,并对其进行训练和测试。
|
9天前
|
机器学习/深度学习 自然语言处理 TensorFlow
深度学习中的卷积神经网络(CNN)及其应用
【10月更文挑战第26天】在这篇文章中,我们将深入探讨卷积神经网络(CNN)的基本原理、结构和应用。CNN是深度学习领域的一个重要分支,广泛应用于图像识别、语音处理等领域。我们将通过代码示例和实际应用案例,帮助读者更好地理解CNN的概念和应用。
|
11天前
|
机器学习/深度学习 算法 计算机视觉
深度学习与生活:如何利用卷积神经网络识别日常物品
【10月更文挑战第24天】在这篇文章中,我们将探索深度学习如何从理论走向实践,特别是卷积神经网络(CNN)在图像识别中的应用。通过一个简单的示例,我们将了解如何使用CNN来识别日常生活中的物体,如水果和家具。这不仅是对深度学习概念的一次直观体验,也是对技术如何融入日常生活的一次深刻反思。文章将引导读者思考技术背后的哲理,以及它如何影响我们的生活和思维方式。
|
17天前
|
机器学习/深度学习 人工智能 自动驾驶
深入理解深度学习中的卷积神经网络(CNN)
【10月更文挑战第18天】深入理解深度学习中的卷积神经网络(CNN)
27 0
|
6天前
|
存储 安全 算法
网络安全与信息安全:漏洞、加密技术及安全意识的重要性
如今的网络环境中,网络安全威胁日益严峻,面对此类问题,除了提升相关硬件的安全性、树立法律法规及行业准则,增强网民的网络安全意识的重要性也逐渐凸显。本文梳理了2000年以来有关网络安全意识的研究,综述范围为中国知网中篇名为“网络安全意识”的期刊、硕博论文、会议论文、报纸。网络安全意识的内涵是在“网络安全”“网络安全风险”等相关概念的发展中逐渐明确并丰富起来的,但到目前为止并未出现清晰的概念界定。此领域内的实证研究主要针对网络安全意识现状与问题,其研究对象主要是青少年。网络安全意识教育方面,很多学者总结了国外的成熟经验,但在具体运用上仍缺乏考虑我国的实际状况。 内容目录: 1 网络安全意识的相关

热门文章

最新文章