Spatial Transformer Networks 空间变换网络 详解

https://blog.csdn.net/zqx951102/article/details/107760893
在这篇论文中,作者用到了STN网络,所以了解了一下:
https://www.cnblogs.com/liaohuiqiang/p/9226335.html
这篇链接给出了详细的公式和概念介绍STN网络
为什么提出(Why):
一个理想中的模型:我们希望鲁棒的图像处理模型具有空间不变性,当目标发生某种转化后,模型依然能给出同样的正确的结果
什么是空间不变性:举例来说,如下图所示,假设一个模型能准确把左图中的人物分类为凉宫春日,当这个目标做了放大、旋转、平移后,模型仍然能够正确分类,我们就说这个模型在这个任务上具有尺度不变性,旋转不变性,平移不变性
CNN在这方面的能力是不足的:maxpooling的机制给了CNN一点点这样的能力,当目标在池化单元内任意变换的话,激活的值可能是相同的,这就带来了一点点的不变性。但是池化单元一般都很小(一般是2*2),只有在深层的时候特征被处理成很小的feature map的时候这种情况才会发生。
Spatial Transformer:本文提出的空间变换网络STN(Spatial Transformer Networks)可以使得模型具有空间不变性。
STN是什么(What)
1.STN对feature map(包括输入图像)进行空间变换,输出一张新的图像
2.我们希望STN对feature map进行变换后能把图像纠正到成理想的图像,然后丢进NN去识别,举例来说,如下图所示,输入模型的图像可能是摆着各种姿势,摆在不同位置的凉宫春日,我们希望STN把它纠正到图像的正中央,放大,占满整个屏幕,然后再丢进CNN去识别。
3.这个网络可以作为单独的模块,可以在CNN的任何地方插入,所以STN的输入不止是输入图像,可以是CNN中间层的feature map
如果网络能够对经过平移、旋转、缩放及裁剪等操作的图片得到与未经变换前相同的检测结果,我们就说这个网络具有空间变换不变性(将平移、旋转、缩放及裁剪不变性统称为空间不变性)。具有空间变换不变性的网络能够得到更精确地分类结果。传统CNN网络的池化层具有平移不变性(网络在平移小于池化矩阵的范围时具有平移不变性。所以只有平移小于这个范围,才能保证平移不变性。),但是CNN网络对于大尺度的空间变换并不具备不变性。Spatial Transformer Networks提出的空间网络变换层,具有平移不变性、旋转不变性及缩放不变性等强大的性能。这个网络可以加在现有的卷积网络中,提高分类的准确性。

空间变换网络主要有如下三个作用:
1可以将输入转换为下一层期望的形式 2可以在训练的过程中自动选择感兴趣的区域特征 3可以实现对各种形变的数据进行空间变换
链接::https://blog.csdn.net/zhuiqiuk/article/details/87286713
这个有STN的代码 可以运行 试了 我这个做出了效果不太一样 哈哈
原图
在这里插入图片描述
我这效果:
在这里插入图片描述
测试原图:
在这里插入图片描述
测试效果:
在这里插入图片描述
大小都是25632大小,可以看出经过STN网络,可以实现:::1可以将输入转换为下一层期望的形式 2可以在训练的过程中自动选择感兴趣的区域特征 3可以实现对各种形变的数据进行空间变换
测试:都是640
480大小
在这里插入图片描述
测试:
在这里插入图片描述
所以不能用整个虹膜图像测试,这样容易随机选取了,最好是像https://blog.csdn.net/zqx951102/article/details/107760893论文中用分割后的虹膜圆环图,或者是像我第一个测试那样,直接用归一化后的图测试,这样stn后又多了一个类的一个图片。
记得要修个图片大小和输入图片一样的规格,然后这样才能看出来是随机裁剪的。

将 spatial transformers 模块集成到 cnn 网络中,允许网络自动地学习如何进行 feature
map 的转变,从而有助于降低网络训练中整体的代价。定位网络中输出的值,指明了如何对
每个训练数据进行转化。

#https://github.com/oarriaga/STN.keras 代码来自,keras可以运行的代码,main函数贴出来如下:

#https://github.com/oarriaga/STN.keras  代码来自

import keras.backend as K
import sys
sys.path.append("D:/PyCode/STN.keras-master/src/")  #加上这句话 可以使得data_manager可以导入
from data_manager import ClutteredMNIST
from visualizer import plot_mnist_sample
from visualizer import print_evaluation
from visualizer import plot_mnist_grid
from models import STN
dataset_path = "D:/PyCode/STN.keras-master/datasets/mnist_cluttered_60x60_6distortions.npz"
batch_size = 256
num_epochs = 30

data_manager = ClutteredMNIST(dataset_path)
train_data, val_data, test_data = data_manager.load()
x_train, y_train = train_data
plot_mnist_sample(x_train[7])


model = STN()
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.summary()


input_image = model.input
output_STN = model.get_layer('bilinear_interpolation_1').output
STN_function = K.function([input_image], [output_STN])

for epoch_arg in range(num_epochs):
    for batch_arg in range(150):
        arg_0 = batch_arg * batch_size
        arg_1 = (batch_arg + 1) * batch_size
        x_batch, y_batch = x_train[arg_0:arg_1], y_train[arg_0:arg_1]
        loss = model.train_on_batch(x_batch, y_batch)
    if epoch_arg % 10 == 0:
        val_score = model.evaluate(*val_data, verbose=1)
        test_score = model.evaluate(*test_data, verbose=1)
        print_evaluation(epoch_arg, val_score, test_score)
        plot_mnist_grid(x_batch, STN_function)
        print('-' * 40)
plot_mnist_grid(x_train)
plot_mnist_grid(x_train, STN_function)

在这里插入图片描述
经过stn网络后 图片具体区域看着变大了。
在这里插入图片描述

在这里插入图片描述
来自繁体字地区的博客:https://www.cnblogs.com/neopenx/p/4851806.html
在这里插入图片描述
regular grid是提供坐标,sampling grid提供的是源图像的像素值
在这里插入图片描述
反向传播,其中第二阶段的求导流向断了,没有流回到原图像输入的那端。
在这里插入图片描述
这个地方明白了为什么第二阶段求导分开两个部分了。

猜你喜欢

转载自blog.csdn.net/zqx951102/article/details/108003808