MATLAB | 这是我见过最离谱的转置操作

电子说

1.3w人已加入

描述

** PART.0 长相离谱的张量转置**

注:此转置操作与 t-product 积相对应,在其他类型张量运算中的转置操作可能有不同的定义方式,请注意区分。

MATLAB仿真

简单描述一下:

我们把三维张量每一个frontal slices(面向我们的切片),进行转置,然后将序号2到n的切片顺序完全反过来,图片描述如下:

假如以下为原始张量:

MATLAB仿真

转置完成后:

MATLAB仿真

那么。。。为什么会有如此的操作呢,其实这都是为了之后的张量inside product做准备(不叫做内积是因为有某些性质不符合内积的定义),和向量内积很像,张量内积也需要其中某个张量转置之后和另一个张量做 t-product 积,既然是做 t-product 积,就要迁就于 t-product 积的某些性质。

这里再重提一下 t-product 积的定义:

MATLAB仿真

** PART.1 转置的特殊性质**

首先说明一下 squeeze 操作及 twist, 简单一张图就可以描述:

MATLAB仿真

MATLAB仿真

这都可以相等。。very amazing 啊 ,光证明出来咋能不验证呢?

** PART.2 MATLAB实现**

我们编写如下 MATLAB 程序(引用的子函数放到最后):

X=zeros([2,1,3]);
X(:,:,1)=[1;2];
X(:,:,2)=[3;4];
X(:,:,3)=[5;6];

c=zeros([1,1,3]);
c(:)=[1,2,3];

squeeze(t_prod(X,c))
squeeze(X)*bcirc(t_T(c))

ans =

20    20    14

26    26    20

ans =

20    20    14

26    26    20

左右两边运行结果一致,非常完美,另外各个子函数如下:

t-product

function C=t_prod(A,B)
% @author:slandarer
% 用于进行张量t-product积
% A*B=fold(bcirc(A)·unfold(B))

% 获取张量大小
[l,p,n]=size(A);dimA=[l,p,n];
[p,m,n]=size(B);dimB=[p,m,n];
dimC=[l,m,n];

if dimA(2)~=dimB(1) || dimA(3)~=dimB(3) 
    error('Inner tensor dimensions must agree.');
end

% 对A,B进行unfold展开操作
ufold_A=reshape(permute(A,[2,1,3]),dimA(2),[])';
ufold_B=reshape(permute(B,[2,1,3]),dimB(2),[])';

% 对A构建循环矩阵
bcirc_A=zeros([l*n,p*n]);
for i=1:n
    bcirc_A(:,(1:p)+(i-1)*p)=circshift(ufold_A,l*(i-1),1);
end

% bcirc(A)·unfold(B)
AB=bcirc_A*ufold_B;

% 还原张量维度
C=ipermute(reshape(AB',dimC([2,1,3])),[2,1,3]);
end

张量转置

function AT=t_T(A)
% @author:slandarer
% 应对与张量t-product积的转置

[l,m,n]=size(A);
AT=zeros([m,l,n]);
% fronral slices转置
for i=1:size(A,3)
    AT(:,:,i)=A(:,:,i)';
end

% 径向重排序
if size(A,3) >1
    AT(:,:,1:end)=AT(:,:,[1,end:-1:2]);
end
end

squeeze

function squeezeX=squeeze(X)
% @author:slandarer
% lateral slice 翻转

if size(X,2)==1
    squeezeX=permute(X,[1,3,2]);
else
    error('MyComponent:incorrectType',...
       'Error input: nInput must be a lateral slice.')
end
end

bcirc

function bcircA=bcirc(A)
% @author:slandarer
% 用于张量展开为循环矩阵

% 获取张量大小
[l,p,n]=size(A);dimA=[l,p,n];

% 对A进行unfold展开操作
ufold_A=reshape(permute(A,[2,1,3]),dimA(2),[])';

% 对A构建循环矩阵
bcircA=zeros([l*n,p*n]);
for i=1:n
    bcircA(:,(1:p)+(i-1)*p)=circshift(ufold_A,l*(i-1),1);
end
end
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分