GDL - Steerable CNNs
GDL - 可控卷积神经网络 ¶

Filled notebook: View on Github Open In Collab
已填满的笔记本: View on Github Open In Collab
Empty notebook: View on Github Unanswered Open In Collab Unanswered
空笔记本: View on Github Unanswered Open In Collab Unanswered
Authors: Gabriele Cesa  作者: Gabriele Cesa

During the lectures, you have learnt that the symmetries of a machine learning task can be modelled with groups. In the previous tutorial, you have also studied the framework of Group-Convolutional Neural Networks (GCNNs), which describes a neural architecture design equivariant to general groups.
在讲座中,您已经了解到机器学习任务的对称性可以用群来建模。在之前的教程中,您还学习了群卷积神经网络(GCNNs)的框架,该框架描述了一种对一般群等变的神经网络架构设计。

The feature maps of a GCNN are functions over the elements of the group. A naive implementation of group-convolution requires computing and storing a response for each group element. For this reason, the GCNN framework is not particularly convenient to implement networks equivariant to groups with infinite elements.
GCNN 的特征图是群元素上的函数。群卷积的简单实现需要为每个群元素计算和存储响应。因此,GCNN 框架在实现对具有无限元素的群等变的网络时并不特别方便。

Steerable CNNs are a more general framework which solves this issue. The key idea is that, instead of storing the value of a feature map on each group element, the model stores the Fourier transform of this feature map, up to a finite number of frequencies.
可控卷积神经网络是一个更通用的框架,可以解决这个问题。其关键思想是,模型不是在每个群元素上存储特征图的值,而是存储该特征图的傅里叶变换,直到有限数量的频率。

In this tutorial, we will first introduce some Representation theory and Fourier theory (non-commutative harmonic analysis) and, then, we will explore how this idea is used in practice to implement Steerable CNNs.
在本教程中,我们将首先介绍一些表示论和傅里叶理论(非交换谐波分析),然后,我们将探讨如何在实践中使用这一思想来实现 Steerable CNNs。

Prerequisite Knowledge  先决知识

Throughout this tutorial, we will assume you are already familiar with some concepts of group theory, such as groups, group actions (in particular on functions), semi-direct product and order of a group, as well as basic linear algebra.
在整个教程中,我们将假设您已经熟悉一些群论的概念,例如群、群作用(特别是在函数上的作用)、半直积和群的阶,以及基本线性代数。

We start by importing the necessary packages. You can run the following command to install all the requirements:
我们首先导入必要的软件包。您可以运行以下命令来安装所有要求:

> pip install torch torchvision numpy matplotlib git+https://github.com/AMLab-Amsterdam/lie_learn escnn scipy

[1]:
import torch
import numpy as np
import scipy
import os

np.set_printoptions(precision=3, suppress=True, linewidth=10000, threshold=100000)

import matplotlib
%matplotlib inline
import matplotlib.pyplot as plt
# If the fonts in the plots are incorrectly rendered, comment out the next two lines
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('svg', 'pdf') # For export
matplotlib.rcParams['lines.linewidth'] = 2.0

import urllib.request
from urllib.error import HTTPError

CHECKPOINT_PATH = "../../saved_models/DL2/GDL"
/opt/conda/lib/python3.8/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
/tmp/ipykernel_109/1932627903.py:13: DeprecationWarning: `set_matplotlib_formats` is deprecated since IPython 7.23, directly use `matplotlib_inline.backend_inline.set_matplotlib_formats()`
  set_matplotlib_formats('svg', 'pdf') # For export
[2]:
# Create checkpoint path if it doesn't exist yet
os.makedirs(CHECKPOINT_PATH, exist_ok=True)


# Files to download
pretrained_files = [
    "steerable_c4-pretrained.ckpt",
    "steerable_so2-pretrained.ckpt",
    "steerable_c4-accuracies.npy",
    "steerable_so2-accuracies.npy",
]

# Github URL where saved models are stored for this tutorial
base_url = "https://raw.githubusercontent.com/phlippe/saved_models/main/DL2/GDL/"

# For each file, check whether it already exists. If not, try downloading it.
for file_name in pretrained_files:
    file_path = os.path.join(CHECKPOINT_PATH, file_name)
    if not os.path.isfile(file_path):
        file_url = base_url + file_name
        print(f"Downloading {file_url}...")
        try:
            urllib.request.urlretrieve(file_url, file_path)
        except HTTPError as e:
            print("Something went wrong. Please contact the author with the full output including the following error:\n", e)

1. Representation Theory and Harmonic Analysis of Compact Groups
1. 紧致群的表示理论与调和分析 ¶

We will make use of the escnn library throughout this tutorial. You can also find its documentation here.
在整个教程中,我们将使用 escnn 库。您也可以在此处找到其文档。

[3]:
try:
    from escnn.group import *
except ModuleNotFoundError: # Google Colab does not have escnn installed by default. Hence, we do it here if necessary
    !pip install --quiet git+https://github.com/AMLab-Amsterdam/lie_learn escnn
    from escnn.group import *

First, let’s create a group. We will use the Cyclic Group G=C8 as an example. This group contains the 8 planar rotations by multiples of 2π8. In escnn, a groups are instances of the abstract class escnn.group.Group, which provides some useful functionalities. We instantiate groups via a factory method. To build the cyclic group of order 8, we use this factory method:
首先,让我们创建一个群。我们将使用循环群 G=C8 作为示例。该群包含 8 个平面旋转,其倍数为 2π8 。在 escnn 中,群是抽象类 escnn.group.Group 的实例,该类提供了一些有用的功能。我们通过工厂方法实例化群。要构建阶为 8 的循环群,我们使用此工厂方法:

[4]:
G = cyclic_group(N=8)

# We can verify that the order of this group is 8:
G.order()
[4]:
8

A group is a collection of group elements together with a binary operation to combine them. This is implemented in the class escnn.group.GroupElement. We can access the identity element eG as
一个群是群元素的集合,并带有一个用于组合它们的二元运算。这在类 escnn.group.GroupElement 中实现。我们可以访问单位元素 eG 作为

[5]:
G.identity
[5]:
0[2pi/8]

or sample a random element as
或随机抽取一个元素作为

[6]:
G.sample()
[6]:
1[2pi/8]

Group elements can be combined via the binary operator @; we can also take the inverse of an element using ~:
群元素可以通过二元运算符 @ 组合;我们也可以使用 ~ 取一个元素的逆:

[7]:
a = G.sample()
b = G.sample()
print(a)
print(b)
print(a @ b)
print(~a)
6[2pi/8]
1[2pi/8]
7[2pi/8]
2[2pi/8]

Representation theory is a fundamental element in Steerable CNNs and to construct a Fourier theory over groups. In this first section, we will introduce the essential concepts.
表示论是可转向卷积神经网络和构建群上的傅里叶理论的基本元素。在第一部分中,我们将介绍基本概念。

1.1 Group Representation
1.1 群体表示 ¶

A linear group representation ρ of a compact group G on a vector space (called representation space) Rd is a group homomorphism from G to the general linear group GL(Rd), i.e. it is a map ρ:GRd×d such that:
紧致群 G 在向量空间(称为表示空间) Rd 上的线性群表示 ρ 是从 G 到一般线性群 GL(Rd) 的群同态,即它是一个映射 ρ:GRd×d ,使得:

ρ(g1g2)=ρ(g1)ρ(g2)g1,g2G .

In other words, ρ(g) is a d×d invertible matrix. We refer to d as the size of the representation.
换句话说, ρ(g) 是一个 d×d 可逆矩阵。我们称 d 为表示的大小。

Example: the Trivial Representation
示例:平凡表示

The simplest example of group representation is the trivial representation which maps every element to 1R, i.e. ρ:g1. One can verify that it satisfies the condition above. We can construct this representation as follows:
群表示的最简单例子是平凡表示,它将每个元素映射到 1R ,即 ρ:g1 。可以验证它满足上述条件。我们可以如下构造此表示:

[8]:
rho = G.trivial_representation

rho is an instance of escnn.group.Representation. This class provides some functionalities to work with group representations. We can also use it as a callable function to compute the representation of a group element; this will return a squared matrix as a numpy.array. Let verify that the trivial representation does indeed verify the condition above:
rhoescnn.group.Representation 的一个实例。这个类提供了一些功能来处理群表示。我们也可以将其用作可调用函数来计算群元素的表示;这将返回一个作为 numpy.array 的方阵。让我们验证平凡表示确实验证了上述条件:

[9]:
g1 = G.sample()
g2 = G.sample()
print(rho(g1) @ rho(g2))
print(rho(g1 @ g2))
[[1.]]
[[1.]]

Note that the trivial representation has size 1:
注意,平凡表示的大小为 1

[10]:
rho.size
[10]:
1

Example: rotations  示例:旋转

Another common example of group representations is given by 2D rotations. Let SO(2) be the group of all planar rotations; note that we can identify each rotation by an angle θ[0,2π). Then, the standard representation of planar rotations as 2×2 rotation matrices is a representation of SO(2):
另一个常见的群表示例是二维旋转。设 SO(2) 为所有平面旋转的群;注意我们可以通过一个角度 θ[0,2π) 来标识每个旋转。那么,平面旋转作为 2×2 旋转矩阵的标准表示是 SO(2) 的一个表示:

ρ:rθ[cos(θ)sin(θ)sin(θ)cos(θ)]

where rθSO(2) is a counter-clockwise rotation by θ. Let’s try to build this group and, then, verify that this is a representation:
其中 rθSO(2) 是逆时针旋转 θ 。让我们尝试构建这个群,然后验证这是否是一个表示:

[11]:
G = so2_group()
rho = G.standard_representation()

g1 = G.sample()
g2 = G.sample()
print(f'g1={g1}, g2={g2}, g1 * g2 = {g1 @ g2}')
print()
print('rho(g1) @ rho(g2)')
print(rho(g1) @ rho(g2))
print()
print('rho(g1 * g2)')
print(rho(g1 @ g2))
g1=4.83985258221817, g2=4.721165128388411, g1 * g2 = 3.277832403426995

rho(g1) @ rho(g2)
[[-0.991  0.136]
 [-0.136 -0.991]]

rho(g1 * g2)
[[-0.991  0.136]
 [-0.136 -0.991]]

QUESTION 1  问题 1 ¶

Show that any representation ρ:GRd×d also satisfies the following two properties:
证明任何表示 ρ:GRd×d 也满足以下两个性质:

  • let eG be the identity element. Then, ρ(e) is the identity matrix of size d.
    eG 为单位元素。那么, ρ(e) 是大小为 d 的单位矩阵。

  • let gG and g1 be its inverse (i.e. gg1=e). Then, ρ(g1)=ρ(g)1.
    gGg1 为其逆(即 gg1=e )。然后, ρ(g1)=ρ(g)1

ANSWER 1  答案 1 ¶

First question. First, note that for any gG:
第一个问题。首先,注意对于任何 gG

ρ(g)=ρ(ge)=ρ(g)ρ(e)

Because ρ(g) is invertible, we can left multiply by ρ(g)1 to find that ρ(e) is the identity.
因为 ρ(g) 是可逆的,我们可以左乘 ρ(g)1 以发现 ρ(e) 是单位矩阵。

Second question. Note that
第二个问题。请注意

ρ(e)=ρ(gg1)=ρ(g)ρ(g1)

Using the fact ρ(e) is the identity, by left-multiplying by ρ(g)1 we recover the original statement.
利用 ρ(e) 是单位元的事实,通过左乘 ρ(g)1 ,我们恢复了原始陈述。


Direct Sum  直和

We can combine representations to build a larger representation via the direct sum.
我们可以通过直和将表示结合起来构建更大的表示。

Given representations ρ1:GRd1×d1 and ρ2:GRd2×d2, their direct sum ρ1ρ2:GR(d1+d2)×(d1+d2) is defined as
给定表示 ρ1:GRd1×d1ρ2:GRd2×d2 ,它们的直和 ρ1ρ2:GR(d1+d2)×(d1+d2) 定义为

(ρ1ρ2)(g)=[ρ1(g)00ρ2(g)]

Its action is therefore given by the independent actions of ρ1 and ρ2 on the orthogonal subspaces Rd1 and Rd2 of Rd1+d2.
因此,其作用由 ρ1ρ2Rd1+d2 的正交子空间 Rd1Rd2 上的独立作用给出。

Let’s see an example:
让我们看一个例子:

[12]:
rho_sum = rho + rho

g = G.sample()
print(rho(g))
print()
print(rho_sum(g))
[[-0.943 -0.332]
 [ 0.332 -0.943]]

[[-0.943 -0.332  0.     0.   ]
 [ 0.332 -0.943  0.     0.   ]
 [ 0.     0.    -0.943 -0.332]
 [ 0.     0.     0.332 -0.943]]

Note that the direct sum of two representations has size equal to the sum of their sizes:
注意,两个表示的直和的大小等于它们大小的总和:

[13]:
rho.size, rho_sum.size
[13]:
(2, 4)

We can combine arbitrary many representations in this way, e.g. ρρρρ:
我们可以通过这种方式组合任意多的表示,例如 ρρρρ :

[14]:
rho_sum = rho + rho + rho + rho

# or, more simply:
rho_sum = directsum([rho, rho, rho, rho])
rho_sum.size
[14]:
8

The Regular Representation
正则表示

Another important representation is the regular representation. The regular representation describes the action of a group G on the vector space of functions over the group G. Assume for the moment that the group G is finite, i.e. |G|<.
另一个重要的表示是正则表示。正则表示描述了群 G 在群 G 上的函数向量空间上的作用。暂时假设群 G 是有限的,即 |G|<

The set of functions over G is equivalent to the vector space R|G|. We can indeed interpret a vector fR|G| as a function over G, where the i-th entry of f is interpreted as the value of the function on the i-th element giG.
G 上的函数集等价于向量空间 R|G| 。我们确实可以将向量 fR|G| 解释为 G 上的一个函数,其中 f 的第 i 个条目被解释为函数在第 i 个元素 giG 上的值。

The regular representation of G is a |G| dimensional representation. Recall the left action of G on a function f:GR:
G 的常规表示是一个 |G| 维表示。回忆 G 在函数 f:GR 上的左作用:

[g.f](h):=f(g1h)

The new function g.f is still a function over G and belongs to the same vector space. If we represent the function f as a vector f, the vector representing the function g.f will have permuted entries with respect to f. This permutation is the regular representation of gG.
新函数 g.f 仍然是 G 上的一个函数,并属于同一个向量空间。如果我们将函数 f 表示为向量 f ,则表示函数 g.f 的向量相对于 f 将有置换的条目。这个置换是 gG 的常规表示。


QUESTION 2  问题 2 ¶

Show that the space of functions over G is a vector space. To do so, show that functions satisfy the properties of a vector space; see here.
证明在 G 上的函数空间是一个向量空间。为此,证明函数满足向量空间的性质;见此处。

ANSWER 2  答案 2 ¶

Let f1,f2,f3:GR be three functions and α,βR scalars. The point-wise sum of two functions is the function [f1+f2]:GR defined as
f1,f2,f3:GR 为三个函数, α,βR 为标量。两个函数的逐点和是定义为 [f1+f2]:GR 的函数。

[f1+f2](g)=f1(g)+f2(g)

The scalar multiplication is also defined pointwise as
标量乘法也被逐点定义为

[αf1](g)=αf1(G)

We now verify the required properties of a vector space.
我们现在验证向量空间所需的性质。

  • associativity: [f1+(f2+f3)](g)=f1(g)+f2(g)+f3(g)=[(f1+f2)+f3](g)  结合性: [f1+(f2+f3)](g)=f1(g)+f2(g)+f3(g)=[(f1+f2)+f3](g)

  • commutativity: [f1+f2)](g)=f1(g)+f2(g)=f2(g)+f1(g)=[f2+f1](g)  交换性: [f1+f2)](g)=f1(g)+f2(g)=f2(g)+f1(g)=[f2+f1](g)

  • identity: define the function O:G0; [f1+O](g)=f1(g)+O(g)=f1(g)
    身份:定义函数 O:G0[f1+O](g)=f1(g)+O(g)=f1(g)

  • inverse: define [f1](g)=1f1(g); then [f1+(f1)](g)=f1(g)f1(g)=0
    逆: 定义 [f1](g)=1f1(g) ; 然后 [f1+(f1)](g)=f1(g)f1(g)=0

  • compatibility: [α(βf1)](g)=αβf1(g)=[(αβ)f1](g)  兼容性: [α(βf1)](g)=αβf1(g)=[(αβ)f1](g)

  • identity (multiplication): [1f1](g)=1f1(g)=f1(g)
    恒等(乘法): [1f1](g)=1f1(g)=f1(g)

  • distributivity (vector): [α(f1+f2)](g)=α(f1+f2)(g)=αf1(g)+αf2(g)
    分配率 (vector): [α(f1+f2)](g)=α(f1+f2)(g)=αf1(g)+αf2(g)

  • distributivity (scalar): [(α+β)f1](g)=(α+β)f1(g)=αf1(g)+βf1(g)
    分配率(标量): [(α+β)f1](g)=(α+β)f1(g)=αf1(g)+βf1(g)


For finite groups, we can generate this representation. We assume that the i-th entry is associated with the element of G=C8 corresponing to a rotation by i2π8.
对于有限群,我们可以生成这个表示。我们假设第 i 个条目与 G=C8 的元素相关联,对应于旋转 i2π8

[15]:
G = cyclic_group(8)
rho = G.regular_representation
[16]:
# note that the size of the representation is equal to the group's order |G|
rho.size
[16]:
8

the identity element maps a function to itself, so the entries are not permuted
恒等元素将函数映射到自身,因此条目不被置换

[17]:
rho(G.identity)
[17]:
array([[ 1.,  0., -0.,  0., -0., -0.,  0., -0.],
       [ 0.,  1.,  0., -0., -0., -0., -0., -0.],
       [-0.,  0.,  1., -0., -0.,  0., -0.,  0.],
       [ 0., -0., -0.,  1.,  0., -0., -0., -0.],
       [-0., -0., -0.,  0.,  1.,  0., -0., -0.],
       [-0., -0.,  0., -0.,  0.,  1., -0.,  0.],
       [ 0., -0., -0., -0., -0., -0.,  1., -0.],
       [-0., -0.,  0., -0., -0.,  0., -0.,  1.]])

The regular representation of the rotation by 12π8 just cyclically shifts each entry to the next position since r12π81ri2π8=r(i1)2π8:
通过 12π8 的旋转的常规表示只是将每个条目循环移到下一个位置,因为 r12π81ri2π8=r(i1)2π8

[18]:
rho(G.element(1))
[18]:
array([[ 0., -0.,  0., -0., -0.,  0., -0.,  1.],
       [ 1.,  0., -0., -0., -0., -0.,  0., -0.],
       [-0.,  1.,  0., -0.,  0., -0., -0., -0.],
       [-0.,  0.,  1.,  0., -0.,  0., -0.,  0.],
       [-0., -0., -0.,  1.,  0., -0.,  0., -0.],
       [-0.,  0., -0.,  0.,  1.,  0.,  0., -0.],
       [-0., -0., -0., -0.,  0.,  1.,  0.,  0.],
       [-0.,  0., -0., -0.,  0., -0.,  1.,  0.]])

Let’s see an example of the action on a function. We consider a function which is zero on all group elements apart from the identity (i=0).
让我们看看一个函数上的动作例子。我们考虑一个在除单位元 ( i=0 ) 之外的所有群元素上都为零的函数。

[19]:
f = np.zeros(8)
f[0] = 1
f
[19]:
array([1., 0., 0., 0., 0., 0., 0., 0.])

Observe that ρ(e)f=f, where e=02π8 is the identity element.
注意 ρ(e)f=f ,其中 e=02π8 是单位元素。

[20]:
rho(G.identity) @ f
[20]:
array([ 1.,  0., -0.,  0., -0., -0.,  0., -0.])

f is non-zero only on the element e. If an element g acts on this function, it moves the non-zero value to the entry associated with g:
f 仅在元素 e 上为非零。如果元素 g 作用于此函数,它会将非零值移动到与 g 相关的条目:

[21]:
rho(G.element(1)) @ f
[21]:
array([ 0.,  1., -0., -0., -0., -0., -0., -0.])
[22]:
rho(G.element(6)) @ f
[22]:
array([ 0., -0.,  0., -0., -0., -0.,  1., -0.])

QUESTION 3  问题 3 ¶

Prove the result above.
证明上述结果。

ANSWER 3  答案 3 ¶

Let’s call δg:GR the function defined as
我们称 δg:GR 为定义为的函数

δg(h)={1if h=g0otherwise

which is zero everywhere apart from gG, where it is 1. The function δe is represented by the vector f above.
除了 gG 处为 1 外,其他地方均为零。函数 δe 由上面的向量 f 表示。

We now want to show that [g.δe](h)=δg(h):
我们现在想要证明 [g.δe](h)=δg(h) :

[g.δe](h)=δe(g1h)={1if g1h=e0otherwise={1if h=g0otherwise=δg(h)

Equivalent Representations
等效表示

Two representations ρ and ρ of a group G on the same vector space Rd are called equivalent (or isomorphic) if and only if they are related by a change of basis QRd×d, i.e.
如果且仅当它们通过基变换 QRd×d 相关联时,一个群 G 在同一向量空间 Rd 上的两个表示 ρρ 被称为等价(或同构)。

gGρ(g)=Qρ(g)Q1 .

Equivalent representations behave similarly since their composition is basis-independent as seen by
等价表示表现相似,因为它们的组成是基于独立的基础,如所见

ρ(g1)ρ(g2)=Qρ(g1)Q1Qρ(g2)Q1=Qρ(g1)ρ(g2)Q1 .

Direct sum and change of basis matrices provide a way to combine representations to construct larger and more complex representations. In the next example, we concatenate two trivial representations and two regular representations and apply a random change of basis Q. The final representation is formally defined as:
直和和基变换矩阵提供了一种组合表示以构建更大和更复杂表示的方法。在下一个例子中,我们连接两个平凡表示和两个正则表示,并应用一个随机基变换 Q 。最终表示形式上定义为:

ρ(g)=Q(ρtrivialρregularρregularρtrivial)Q1
[23]:
d = G.trivial_representation.size * 2 + G.regular_representation.size * 2
Q = np.random.randn(d, d)
rho = directsum(
    [G.trivial_representation, G.regular_representation, G.regular_representation, G.trivial_representation],
    change_of_basis=Q
)
[24]:
rho.size
[24]:
18

Irreducible Representations (or Irreps)
不可约表示(或 Irreps)

Under minor conditions, any representation can be decomposed in this way, that is, any representation ρ of a compact group G can be written as a direct sum of a number of smaller representations, up to a change of basis. These “smaller representations” can not be decomposed further and play a very important role in the theory of group representations and steerable CNNs and are called irreducible representations, or simply irreps.
在较小的条件下,任何表示都可以以这种方式分解,即任何紧群 G 的表示 ρ 都可以写成若干较小表示的直和,直到基变换为止。这些“较小表示”不能进一步分解,在群表示理论和可控卷积神经网络中起着非常重要的作用,被称为不可约表示,或简称为 irreps。

The set of irreducible representations of a group G is generally denoted as G^. We will often use the notation G^={ρj}j to index this set.
一个群的不可约表示集 G 通常表示为 G^ 。我们经常使用符号 G^={ρj}j 来索引这个集合。

We can access the irreps of a group via the irrep() method. The trivial representation is always an irreducible representation. For G=C8, we access it with the index j=0:
我们可以通过 irrep() 方法访问一个群的不可约表示。平凡表示总是一个不可约表示。对于 G=C8 ,我们通过索引 j=0 访问它:

[25]:
rho_0 = G.irrep(0)

print(rho_0 == G.trivial_representation)

rho_0(G.sample())

True
[25]:
array([[1.]])

The next irrep j=1 gives the representation of i2π8 as the 2×2 rotation matrix by θ=i2π8:
下一个不可约表示 j=1i2π8 表示为 θ=i2π82×2 旋转矩阵:

[26]:
rho = G.irrep(1)
g = G.sample()

print(g)
print()
print(rho(g))
1[2pi/8]

[[ 0.707 -0.707]
 [ 0.707  0.707]]

Irreducible representations provide the building blocks to construct any representation ρ via direct sums and change of basis, i.e:
不可约表示提供了构建任何表示的基本单元 ρ ,通过直接和与基变换,即:

ρ=Q(jIρj)Q1

where I is an index set (possibly with repetitions) over G^.
其中 IG^ 上的一个索引集(可能有重复)。

Internally, any escnn.group.Representation is indeed implemented as a list of irreps (representing the index set I) and a change of basis Q. An irrep is identified by a tuple id.
在内部,任何 escnn.group.Representation 实际上都实现为不可约表示的列表(表示索引集 I )和基变换 Q 。一个不可约表示由一个元组 id 标识。

Let’s see an example. Let’s take the regular representaiton of C8 and check its decomposition into irreps:
让我们看一个例子。让我们取 C8 的常规表示并检查其分解为不可约表示:

[27]:
rho = G.regular_representation
rho.irreps
[27]:
[(0,), (1,), (2,), (3,), (4,)]
[28]:
rho.change_of_basis
[28]:
array([[ 0.354,  0.5  ,  0.   ,  0.5  ,  0.   ,  0.5  ,  0.   ,  0.354],
       [ 0.354,  0.354,  0.354,  0.   ,  0.5  , -0.354,  0.354, -0.354],
       [ 0.354,  0.   ,  0.5  , -0.5  ,  0.   , -0.   , -0.5  ,  0.354],
       [ 0.354, -0.354,  0.354, -0.   , -0.5  ,  0.354,  0.354, -0.354],
       [ 0.354, -0.5  ,  0.   ,  0.5  , -0.   , -0.5  ,  0.   ,  0.354],
       [ 0.354, -0.354, -0.354,  0.   ,  0.5  ,  0.354, -0.354, -0.354],
       [ 0.354, -0.   , -0.5  , -0.5  ,  0.   ,  0.   ,  0.5  ,  0.354],
       [ 0.354,  0.354, -0.354, -0.   , -0.5  , -0.354, -0.354, -0.354]])
[29]:
# let's access second irrep
rho_id = rho.irreps[1]
rho_1 = G.irrep(*rho_id)

# we verify it is the irrep j=1 we described before
rho_1(g)
[29]:
array([[ 0.707, -0.707],
       [ 0.707,  0.707]])

Finally, let’s verify that this direct sum and this change of basis indeed yield the regular representation
最后,让我们验证这个直和和这个基变换确实产生了正则表示

[30]:
# evaluate all the irreps in rho.irreps:
irreps = [
          G.irrep(*irrep)(g) for irrep in rho.irreps
]

# build the direct sum
direct_sum = np.asarray(scipy.sparse.block_diag(irreps, format='csc').todense())

print('Regular representation of', g)
print(rho(g))
print()
print('Direct sum of the irreps:')
print(direct_sum)
print()
print('Apply the change of basis on the direct sum of the irreps:')
print(rho.change_of_basis @ direct_sum @ rho.change_of_basis_inv)
print()
print('Are the two representations equal?', np.allclose(rho(g), rho.change_of_basis @ direct_sum @ rho.change_of_basis_inv))

Regular representation of 1[2pi/8]
[[ 0. -0.  0. -0. -0.  0. -0.  1.]
 [ 1.  0. -0. -0. -0. -0.  0. -0.]
 [-0.  1.  0. -0.  0. -0. -0. -0.]
 [-0.  0.  1.  0. -0.  0. -0.  0.]
 [-0. -0. -0.  1.  0. -0.  0. -0.]
 [-0.  0. -0.  0.  1.  0.  0. -0.]
 [-0. -0. -0. -0.  0.  1.  0.  0.]
 [-0.  0. -0. -0.  0. -0.  1.  0.]]

Direct sum of the irreps:
[[ 1.     0.     0.     0.     0.     0.     0.     0.   ]
 [ 0.     0.707 -0.707  0.     0.     0.     0.     0.   ]
 [ 0.     0.707  0.707  0.     0.     0.     0.     0.   ]
 [ 0.     0.     0.     0.    -1.     0.     0.     0.   ]
 [ 0.     0.     0.     1.     0.     0.     0.     0.   ]
 [ 0.     0.     0.     0.     0.    -0.707 -0.707  0.   ]
 [ 0.     0.     0.     0.     0.     0.707 -0.707  0.   ]
 [ 0.     0.     0.     0.     0.     0.     0.    -1.   ]]

Apply the change of basis on the direct sum of the irreps:
[[ 0. -0.  0. -0. -0.  0. -0.  1.]
 [ 1.  0. -0.  0. -0. -0.  0. -0.]
 [-0.  1.  0. -0.  0. -0. -0. -0.]
 [-0.  0.  1.  0. -0.  0. -0.  0.]
 [-0. -0. -0.  1.  0. -0.  0. -0.]
 [-0.  0. -0.  0.  1.  0.  0. -0.]
 [-0. -0. -0. -0.  0.  1.  0.  0.]
 [-0.  0. -0. -0.  0. -0.  1.  0.]]

Are the two representations equal? True

1.2 Fourier Transform  1.2 傅里叶变换 ¶

We can finally approach the harmonic analysis of functions over a group G.
我们终于可以研究群 G 上的函数的调和分析了。

Note that a representation ρ:GRd×d can be interpreted as a collection of d2 functions over G, one for each matrix entry of ρ. The Peter-Weyl theorem states that the collection of functions in the matrix entries of all irreps G^ of a group G spans the space of all (square-integrable) functions over G.
注意,表示 ρ:GRd×d 可以被解释为 d2 函数在 G 上的集合,每个矩阵项对应一个 ρ 。Peter-Weyl 定理指出,所有不可约表示 G^ 的矩阵项中的函数集合在群 G 的所有(平方可积)函数在 G 上的空间中张成。

This result gives us a way to parameterize functions over the group. This is the focus of this section. In particular, this is useful to parameterize functions over groups with infinite elements.
这个结果为我们提供了一种对群上的函数进行参数化的方法。这是本节的重点。特别是,这对于对具有无限元素的群上的函数进行参数化非常有用。

In this section, we will first consider the dihedral group D8 as example. This is the group containing the 8 planar rotations by angles multiple of 2π8 and reflection along the X axis. The group contains in total 16 elements (8 normal rotations and 8 rotations preceeded by the reflection).
在本节中,我们将首先考虑二面体群 D8 作为例子。这是一个包含 8 个平面旋转的群,旋转角度是 2π8 的倍数,并沿 X 轴反射。该群总共包含 16 个元素( 8 个正常旋转和 8 个由反射引导的旋转)。

[31]:
G = dihedral_group(8)
G.order()
[31]:
16
[32]:
# element representing the reflection (-) and no rotations
G.reflection
[32]:
(-, 0[2pi/8])
[33]:
# element representing a rotation by pi/2 (i.e. 2 * 2pi/8) and no reflections (+)
G.element((0, 2))
[33]:
(+, 2[2pi/8])
[34]:
# reflection followed by a rotation by pi/2
print(G.element((0, 2)) @ G.reflection)

# we can also directly generate this element as
print(G.element((1, 2)))
(-, 2[2pi/8])
(-, 2[2pi/8])
[35]:
# a rotation by pi/2 followed by a reflection is equivalent to a reclection followed by a rotation by 6*2pi/8
G.reflection @ G.element((0, 2))
[35]:
(-, 6[2pi/8])

The list of all elements in the group is obtaied as:
组中所有元素的列表如下所示:

[36]:
G.elements
[36]:
[(+, 0[2pi/8]),
 (+, 1[2pi/8]),
 (+, 2[2pi/8]),
 (+, 3[2pi/8]),
 (+, 4[2pi/8]),
 (+, 5[2pi/8]),
 (+, 6[2pi/8]),
 (+, 7[2pi/8]),
 (-, 0[2pi/8]),
 (-, 1[2pi/8]),
 (-, 2[2pi/8]),
 (-, 3[2pi/8]),
 (-, 4[2pi/8]),
 (-, 5[2pi/8]),
 (-, 6[2pi/8]),
 (-, 7[2pi/8])]

Fourier and Inverse Fourier Transform
傅里叶和逆傅里叶变换 ¶

For most groups, the entries of the irreps don’t only span the space of functions but form also a basis (i.e. these functions are mutually orthogonal to each other). Therefore, we can write a function f:GR as
对于大多数群,不可约表示的条目不仅跨越函数空间,而且还形成一个基(即这些函数彼此正交)。因此,我们可以将函数 f:GR 写为

f(g)=ρjG^m,n<djwj,m,ndj[ρj(g)]mn

where dj is the dimension of the irrep ρj, while m,n index the dj2 entries of ρj. The coefficients {wj,m,nR}j,m,n parameterize the function f on this basis. The dj is a scalar factor to ensure the basis is normalized.
其中 dj 是不可约表示 ρj 的维度,而 m,n 索引 ρjdj2 项。系数 {wj,m,nR}j,m,n 在此基础上参数化函数 fdj 是一个标量因子,以确保基是规范化的。

We rewrite this expression in a cleaner form by using the following fact. If A,BRd×d, then
我们通过使用以下事实将此表达式重写为更简洁的形式。如果 A,BRd×d ,则

Tr(ATB)=m,n<dAmnBmnR .

By definining f^(ρj)Rdj×dj as the matrix containing the dj2 coefficients {wj,m,nR}m,n<dj, we can express the Inverse Fourier Transform as:
通过将 f^(ρj)Rdj×dj 定义为包含 dj2 系数 {wj,m,nR}m,n<dj 的矩阵,我们可以将逆傅里叶变换表示为:

f(g)=ρjG^djTr(ρj(g)Tf^(ρj))

Similarly, we can project a general function f:GR on an element ρj,m,n:GR of the basis via:
同样,我们可以通过以下方式将一般函数 f:GR 投影到基底的元素 ρj,m,n:GR 上:

wj,m,n=1|G|gGf(g)dj[ρj(g)]m,n .

The projection over all entries of ρj can be more cleanly written as follows:
ρj 的所有条目投影可以更清晰地写成如下:

f^(ρj)=1|G|gGf(g)djρj(g) .

which we refer to as Fourier Transform.
我们称之为傅里叶变换。

If the group G is infinite, we replace the average over the group elements with an integral over them:
如果群 G 是无限的,我们将群元素的平均值替换为对它们的积分:

f^(ρj)=Gf(g)djρj(g)dg ,

For a finite group G, we can access all its irreps by using the Group.irreps() method. Let’s see an example:
对于有限群 G ,我们可以通过使用 Group.irreps() 方法来获取其所有不可约表示。让我们来看一个例子:

[37]:
irreps = G.irreps()
print(f'The dihedral group D8 has {len(irreps)} irreps')
The dihedral group D8 has 7 irreps
[38]:
# the first one, is the 1-dimensional trivial representation
print(irreps[0] == G.trivial_representation == G.irrep(0, 0))
True

QUESTION 4  问题 4 ¶

We can now implement the Fourier Transform and the Inverse Fourier Transform for the Dihedral Group D8. Using the equations above, implement the following methods:
我们现在可以为二面体群 D8 实现傅里叶变换和逆傅里叶变换。使用上述方程,实施以下方法:


[39]:
def fourier_transform_D8(f: np.array):
    # the method gets in input a function on the elements of D_8
    # and should return a dictionary mapping each irrep's `id` to the corresponding Fourier Transform
    # The i-th element of `f` stores the value of the function on the group element `G.elements[i]`

    G = dihedral_group(8)
    assert f.shape == (16,), f.shape
    ft = {}

    ########################
    # INSERT YOUR CODE HERE:

    for rho in G.irreps():
        d = rho.size

        rho_g = np.stack([rho(g) for g in G.elements], axis=0)

        ft[rho.id] = (f.reshape(-1, 1, 1) * rho_g).mean(0) * np.sqrt(d)

    ########################

    return ft
[40]:
def inverse_fourier_transform_D8(ft: dict):
    # the method gets in input a dictionary mapping each irrep's `id` to the corresponding Fourier Transform
    # and should return the function `f` on the elements of D_8
    # The i-th element of `f` stores the value of the function on the group element `G.elements[i]`

    G = dihedral_group(8)
    f = np.zeros(16)

    ########################
    # INSERT YOUR CODE HERE:
    for rho in G.irreps():
        d = rho.size
        for i, g in enumerate(G.elements):
            f[i] += np.sqrt(d) * (ft[rho.id] * rho(g)).sum()
    ########################

    return f

We now want to verify that the Fourier Transform and the Inverse Fourier Transform are inverse of each other:
我们现在想要验证傅里叶变换和逆傅里叶变换是彼此的逆:

[41]:
f = np.random.randn(16)

ft = fourier_transform_D8(f)

new_f = inverse_fourier_transform_D8(ft)

assert np.allclose(f, new_f)

Parameterizing functions over infinite groups
对无限群进行函数参数化

This allows us to also parameterize functions over infinite groups, such as O(2), i.e. the group of all planar rotations and reflections.
这也使我们能够对无限群的函数进行参数化,例如 O(2) ,即所有平面旋转和反射的群。

[42]:
G = o2_group()
[43]:
# the group has infinite many elements, so the `order` method just returns -1
G.order()
[43]:
-1

The equations remain the same, but this group has an infinite number of irreps. We can, however, parameterize a function over the group by only considering a finite number of irreps in the sum inside the definition of Inverse Fourier Transform. Let G~G^ be a finite subset of the irreps of G. We can then write the following transforms within the subspace of functions spanned only by the entries of the irreps in G~.
方程保持不变,但该群有无限多个不可约表示。然而,我们可以通过在逆傅里叶变换的定义中仅考虑有限个不可约表示来对群上的函数进行参数化。设 G~G^G 的不可约表示的有限子集。然后我们可以在仅由 G~ 中的不可约表示的条目生成的函数子空间内写出以下变换。

Inverse Fourier Transform:
逆傅里叶变换:

f(g)=ρjG~djTr(ρj(g)Tf^(ρj))

and Fourier Transform:  和傅里叶变换:

f^(ρj)=Gf(g)djρj(g)dg ,

QUESTION 5