INN实现深入理解

INN实现深入理解,第1张

FrEIA 是实现 INN 的基础,可以理解为实现 INN 的最重要的工具包。其分为两个模块,每个模块又有很多重要的类,以下是对这些类及其方法的描述。

framework 模块包含用于构建网络模型和推断节点在向前和向后方向上执行的顺序的逻辑。该模块包括四个类。

<1> Node类

一个 Node 即为一个 INN 基础构建块。

build_modules(verbose=True)

该方法返回该结点的输出结点的维度列表。会递归调用其输入结点的 build_modules 方法。使用这些信息来初始化该结点的 pytorchnnModule,即构建起基础块。

run_forward(op_list)

调用该方法来确定执行到该结点前的 *** 作顺序。会递归调用其输入结点的 run_forward 方法。每个 *** 作被追加到全局列表 op_list 中, *** 作的表示形式为 (node ID, input variable IDs, output variable IDs)。

run_backward(op_list)

该方法和 run_forward 相似,只是用来确定逆向执行到该结点前的 *** 作顺序。调用该方法前须先调用 run_forward。

<2> InputNode类

InputNode 类是 Node 类的子类,是一种特殊的结点——输入结点,表示整个 INN 网络的输入数据(及逆向过程的输出数据)。

<3>OutputNode类

OutputNode 类也是 Node 类的子类,是一种特殊的结点——输出结点,表示整个 INN 网络的输出数据(及逆向过程的输入数据)。

<4>ReversibleGraphNet类

是 torchnnmodulesmoduleModule 类的子类。这个类表示了 INN 本身。这个类的构造函数会确定 node list 中的输入结点和输出结点,并调用输出结点的 build_modules 方法以获得结点间的连接关系及维度,调用输出结点的 run_forward 方法获得正向过程的所有 *** 作及涉及的变量;再调用输入结点的 run_backward 方法获得逆向过程的所有 *** 作及涉及的变量。

modules 模块中都是 torchnnModule 的子类,都是可逆的,可用于 ReversibleGraphNet 中 Node 的构建。

1 Coefficient functions

class FrEIAmodulescoeff_functsF_conv(in_channels, channels, channels_hidden=None, stride=None, kernel_size=3, leaky_slope=01, batch_norm=False)

F_conv 类使用多层卷积网络实现 INN 基础构建块中的 s、t 转换。其本身是不可逆的。

class FrEIAmodulescoeff_functsF_fully_connected(size_in, size, internal_size=None, dropout=00)

F_fully_connected 类使用包含四层全连接层的神经网络实现 INN 基础构建块中的 s、t 转换。其本身是不可逆的。

2 Coupling layers

F_ 类本身都是不可逆的,而 coupling_layers 层中的类就是赋予 INN 可逆能力的。

class FrEIAmodulescoupling_layersrev_layer(dims_in, F_class=<class 'FrEIAmodulescoeff_functsF_conv'>, F_args={})

当转换是 F_conv 时使用 rev_layer 类实现可逆。

class FrEIAmodulescoupling_layersrev_multiplicative_layer(dims_in, F_class=<class 'FrEIAmodulescoeff_functsF_fully_connected'>, F_args={}, clamp=50)

当转换是 F_fully_connected 时使用 rev_multiplicative_layer 实现可逆,思想是基于 RealNVP 基础构建块的双向转换。

class FrEIAmodulescoupling_layersglow_coupling_layer(dims_in, F_class=<class 'FrEIAmodulescoeff_functsF_fully_connected'>, F_args={}, clamp=50)

和 rev_multiplicative_layer 相似,只是思想是基于 Glow 基础构建块的双向转换。

3 Fixed transforms

这个模块的类也都是 torchnnModule 的子类,用于实现一些固定转换。在构建块之间插入置换层,用于随机打乱下一层的输入元素,这使得 u = [u1,u2] 的分割在每一层都不同,也因此促进了独立变量间的交互。

class FrEIAmodulesfixed_transformslinear_transform(dims_in, M, b)

根据 y=Mx+b 做固定转换,其中 M 是可逆矩阵。其实现为:

class FrEIAmodulesfixed_transformspermute_layer(dims_in, seed)

随机转换输入向量列顺序。其实现为:

4 Graph topology

用于对 INN 网络结构进行调整,如构建残差 INN 等。

class FrEIAmodulesgraph_topologycat_layer(dims_in, dim)

沿给定维度合并多个张量。

class FrEIAmodulesgraph_topologychannel_merge_layer(dims_in)

沿着通道从两个独立的输入合并到一个输出(用于跳过连接等)。

class FrEIAmodulesgraph_topologychannel_split_layer(dims_in)

沿通道拆分以产生两个单独的输出(用于跳过连接等)。

class FrEIAmodulesgraph_topologysplit_layer(dims_in, split_size_or_sections, dim)

沿给定维度拆分以生成具有给定大小的单独输出的列表。

5Reshapes

class FrEIAmodulesreshapesflattening_layer(dims_in)

正向过程是将 N 维张量拉平为 1 维的张量。

class FrEIAmodulesreshapeshaar_multiplex_layer(dims_in, order_by_wavelet=False)

使用 Haar wavelets 将通道按宽度和高度对半分为 4 个通道。

class FrEIAmodulesreshapeshaar_restore_layer(dims_in)

使用 Haar wavelets 将 4 个通道合并为一个通道。

class FrEIAmodulesreshapesi_revnet_downsampling(dims_in)

i-RevNet 中使用的可逆空间 downsampling。

class FrEIAmodulesreshapesi_revnet_upsampling(dims_in)

与 i_revnet_downsampling 相反的 *** 作。

INN 的 loss 分为两部分:前向训练的损失和后向训练的损失。前后向训练的简单过程如下:

对应的损失函数如下:

其中,L2 是一种求平方误差的损失函数;MMD 则用于求两个分布之间的差异。

这篇文章前后读了很多次,这次重读,又有许多新收获。

INN 的基础构建块是 RealNVP 中的仿射耦合层;如果要构建深度可逆网络,可将基础构建块和残差训练思想结合,i-RevNet 就是深度可逆网络。基础构建块本身是可逆结构,因此其中的 s、t 转换不需要是可逆的,其可以是任意复杂的网络结构;更重要的是,构建块的可逆性允许我们同时为正向训练和反向训练应用损失函数,并可以从任一方向计算 s 和 t 的梯度。

至于如何将输入分割为两部分,目前采用的方法是随机(但为了可逆,必须是固定的)分割。但为了实现更好的训练结果,往往在基础构建块之间加入置换层,用于 shuffle 输入,这样是为了使得每次分割得到的 u1、u2 和上一构建块分割得到的不同。如果没有置换层,那么在训练过程中,u1、u2 都是相互独立的。

正向过程的信息丢失使得逆向过程存在模糊性,如果使用贝叶斯方法,用 p(x|y) 表示这种模糊性,也是可行的,但非常复杂。实际上我们希望网络学习完整的后验分布 p(x|y),我们可以尝试预测简单分布的拟合参数(如均值和方差),或者使用分布(而非固定值)来表示网络权重,甚至两者结合,但无论如何,这将限制我们预先选择一种固定的分布或分布族。 也可以使用 cGAN,但它难以训练的,并且经常遭遇难以检测的模式崩溃。

因此,INN 中引入 latent variable z,其捕获了从 x 到 y 的正向过程中丢失的信息,即 x 与 [y,z] 形成了双射。在正向训练过程中,我们可以得到真实潜在分布 ztrue,从 ztrue 中采样,再结合 y 值,即可得到一个固定的 x 值。即,p(x|y) 转换成一个固定函数 x=g(y,z)。不过,为了易于采样,我们需要将 ztrue 调整为一个简单的分布(如标准正态分布),这样我们就可以从简单分布中采样,结合 y 值得到 x,这样的准确率依然是很高的,因为简单分布和 ztrue 之间只是一个简单映射关系。至此看来,INN 和 cGAN 思想是很接近的,不过 INN 的可逆性使得其训练过程与 cGAN 不同,也有其特殊的优点。

INN 同时对正向和逆向过程进行训练,累积网络两端的损失项的梯度。 我们还可以在 x 上添加类似 GAN 的鉴别器损失,但到目前为止,在我们的应用程序中,MMD 是足够的,因此我们可以避免对抗性训练的麻烦。在大量训练数据的支持下,我们可以训练网络拟合正向模型,由于网络的可逆构造,我们可以免费得到逆向模型。

faces  是定义在detectObject函数的局部变量,函数外不能访问。

类似:

def test():

    a = [1,2,3,4]

print a

执行上面的代码,a就是undefined的。

clc;

clear all;

close all; % 清理工作空间

clear

[imA,map1] = imread('Atif');

M1 = double(imA) / 256;

[imB,map2] = imread('Btif');

M2 = double(imB) / 256;

zt= 4;

wtype = 'haar';

% M1 - input image A

% M2 - input image B

% wtype使用的小波类型

% Y - fused image

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%

%% 小波变换图像融合

%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% 小波变换的绝对值大的小波系数,对应着显著的亮度变化,也就是图像中的显著特征。所以,选择绝对值大

%% 的小波系数作为我们需要的小波系数。注意,前面取的是绝对值大小,而不是实际数值大小

%%

%% 低频部分系数采用二者求平均的方法

%%

%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[c0,s0] = wavedec2(M1, zt, wtype);%多尺度二维小波分解

[c1,s1] = wavedec2(M2, zt, wtype);%多尺度二维小波分解

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% 后面就可以进行取大进行处理。然后进行重构,得到一个图像

%% 的小波系数,然后重构出总的图像效果。

%% 取绝对值大的小波系数,作为融合后的小波系数

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

KK = size(c1);

Coef_Fusion = zeros(1,KK(2));

Temp = zeros(1,2);

Coef_Fusion(1:s1(1,1)) = (c0(1:s1(1,1))+c1(1:s1(1,1)))/2; %低频系数的处理

%这儿,连高频系数一起处理了,但是后面处理高频系数的时候,会将结果覆盖,所以没有关系

%处理高频系数

MM1 = c0(s1(1,1)+1:KK(2));

MM2 = c1(s1(1,1)+1:KK(2));

mm = (abs(MM1)) > (abs(MM2));

Y = (mmMM1) + ((~mm)MM2);

Coef_Fusion(s1(1,1)+1:KK(2)) = Y;

%处理高频系数end

%重构

Y = waverec2(Coef_Fusion,s0,wtype);

%显示图像

subplot(2,2,1);imshow(M1);

colormap(gray);

title('input2');

axis square

subplot(2,2,2);imshow(M2);

colormap(gray);

title('input2');

axis square

subplot(223);imshow(Y,[]);

colormap(gray);

title('融合图像');

axis square;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[ca,ch,cl,cd]=dwt2(x,'haar'); %x=imread('lenabmp');

II=[ca ch;cl cd];

imshow(II,gray(256));

假设给定的离散时间信号为:

s=[1 2 3 4]

通过小波变换

[cA,cD] = wavedec(s,N,‘haar’),得到的是近似小波系数cA,和细节小波系数cD,N是分解的层数,

在小波变换中一般很少得到频谱图,但是使用小波系数解决问题的情况较多。希望我的回答对你有一些帮助。

以上就是关于INN实现深入理解全部的内容,包括:INN实现深入理解、python人脸检测的程序报错 line 15, in <module> if faces: NameError: name 'faces' is not defined、求小波变换图像融合的MATLAB程序,毕设用。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10079343.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存