一个样本一般会被看成是一个向量. 然后将样本标签丢给 机器去学习模型.
通常也有样本, 不是向量. 例如 图, 点云(矩阵), 持续图(2维向量集合), 文本(向量序列).
对这些样本一般使用向量化手法, 大家熟悉的是 word2vet, transformer. 这里我们了解一下 DeepSet.
文章参考 Deep Sets
有一些网文介绍也对此做了介绍.
纯翻译的 https://www.cnblogs.com/wangchangshuo/p/13853491.html
添加个人理解的 https://zhuanlan.zhihu.com/p/368357090
*(按键人写此, 目的是加深理解, 分享交流, 不做盈利. 故而不详细考证哪些人已经介绍过此文.)
DeepSet 处理的对象是 向量组成的集合 S, 输出是一个实数(或者向量).
令
Set
\text{Set}
Set 我集合范畴(范畴的对象看成是集合),
DeepSet
:
Set
→
R
\text{DeepSet}:\text{Set} \to \R
DeepSet:Set→R
S
∈
Set
\text{S} \in \text{Set}
S∈Set,
DeepSet
(
S
)
=
DeepSet
(
s
1
,
s
2
,
⋯
,
s
n
)
=
DeepSet
(
s
2
,
s
1
,
⋯
,
s
n
)
\text{DeepSet}(\text{S})=\text{DeepSet}(s_1,s_2,\cdots,s_n)=\text{DeepSet}(s_2,s_1,\cdots,s_n)
DeepSet(S)=DeepSet(s1,s2,⋯,sn)=DeepSet(s2,s1,⋯,sn)
把话说清楚一些. 集合看成是矩阵. 每个元素是一个行向量
s
i
s_i
si. 学习到模型只和集合有关系, 和集合中哪个向量摆在第哪一行没有关系,即
DeepSet
(
s
1
,
s
2
,
⋯
,
s
n
)
=
DeepSet
(
s
σ
(
1
)
,
s
σ
(
2
)
,
⋯
,
s
σ
(
n
)
)
.
\text{DeepSet}(s_1,s_2,\cdots,s_n)=\text{DeepSet}(s_{\sigma(1)},s_{\sigma(2)},\cdots,s_{\sigma(n)}).
DeepSet(s1,s2,⋯,sn)=DeepSet(sσ(1),sσ(2),⋯,sσ(n)).
σ
:
{
1
,
2
,
⋯
,
n
}
→
{
1
,
2
,
⋯
,
n
}
\sigma: \{1,2,\cdots,n\} \to \{1,2,\cdots,n\}
σ:{1,2,⋯,n}→{1,2,⋯,n} 是双射.
这样的函数不好学, 需要将之转化为 对 手动函数 &任意函数相结合的模式. 其中手动函数是关键, 任意函数丢给机器去处理.
下面定理描述了手动函数
任意置换不变函数都可以写成
ρ
(
∑
s
∈
S
ϕ
(
s
)
)
\rho(\sum_{s \in \text{S}}\phi(s))
ρ(s∈S∑ϕ(s))
ρ
\rho
ρ 为函数,
p
h
i
phi
phi 为映射, 都是可学习的模型.
这个 DeepSet 模型其实很容易写了. 我们在前两篇描述过
Embedding(), Dense() 这两个映射都是向量层面的映射, 处理矩阵也是按行向量逐行处理的. 于是对 集合, 写成矩阵形式 X, 行向量是集合的元素.
先使用 Embedding 做线性运算, 再用 Dense 做非线性运算, 此即 ϕ \phi ϕ.
再做向量加法运算,然后扔给 Dense(1)得到 DeepSet.
代码
def get_deepset_model(max_length):
input_txt = Input(shape=(max_length,))
x = Embedding(11, 100, mask_zero=True)(input_txt)
# (,max_length,100)
x = Dense(30, activation='tanh')(x)
#(max_length,30)
Adder = Lambda(lambda x: K.sum(x, axis=1), output_shape=(lambda shape: (shape[0], shape[2])))
#定义一个关于 x 的运算.将 x 沿着 第二个轴相加.( ,100)
x = Adder(x)
#( ,100)
encoded = Dense(1)(x)
#( ,1)
summer = Model(input_txt, encoded)
#adam = Adam(lr=1e-4, epsilon=1e-3)
summer.compile(optimizer=tf.keras.optimizers.Adam(0.001), loss='mae')
return summer
这个是更为精细的模型, 映射是逐元素或者逐点定义的.
DeepSet
(
s
1
,
s
2
,
⋯
,
s
n
)
:
=
(
DeepSet
1
(
s
1
,
s
2
,
⋯
,
s
n
)
,
⋯
,
DeepSet
n
(
s
1
,
s
2
,
⋯
,
s
n
)
)
\text{DeepSet}(s_1,s_2,\cdots,s_n):=(\text{DeepSet}_1(s_1,s_2,\cdots,s_n),\cdots, \text{DeepSet}_n(s_1,s_2,\cdots,s_n) )
DeepSet(s1,s2,⋯,sn):=(DeepSet1(s1,s2,⋯,sn),⋯,DeepSetn(s1,s2,⋯,sn))
于是用集合矩阵调换矩阵行向量时, 输出也会跟着调换.
DeepSet
(
s
σ
(
1
)
,
s
σ
(
2
)
,
⋯
,
s
σ
(
n
)
)
=
(
DeepSet
σ
(
1
)
(
s
1
,
s
2
,
⋯
,
s
n
)
,
⋯
,
DeepSet
σ
(
n
)
(
s
1
,
s
2
,
⋯
,
s
n
)
)
.
\text{DeepSet}(s_{\sigma(1)},s_{\sigma(2)},\cdots,s_{\sigma(n)})=(\text{DeepSet}_{\sigma(1)}(s_1,s_2,\cdots,s_n), \cdots, \text{DeepSet}_{\sigma(n)}(s_1,s_2,\cdots,s_n) ).
DeepSet(sσ(1),sσ(2),⋯,sσ(n))=(DeepSetσ(1)(s1,s2,⋯,sn),⋯,DeepSetσ(n)(s1,s2,⋯,sn)).
例如
DeepSet
i
(
s
1
,
s
2
,
⋯
,
s
n
)
\text{DeepSet}_{i}(s_1,s_2,\cdots,s_n)
DeepSeti(s1,s2,⋯,sn) 为 关于 在第
i
i
i 个位置的元素的 的函数.
此种函数很难学习出来, 需要 手动至机器学习能够学习. DeepSets提供定理
令
令
令
f
Θ
(
X
)
:
=
ρ
(
Θ
X
)
f_{\Theta}(X):=\rho(\Theta X)
fΘ(X):=ρ(ΘX), 其中
Θ
:
=
(
λ
+
γ
γ
⋯
γ
γ
λ
+
γ
⋯
γ
⋮
⋮
⋮
γ
γ
⋯
λ
+
γ
)
\Theta:=\left( \begin{array}{c} \lambda+\gamma & \gamma & \cdots & \gamma\\ \gamma& \lambda+\gamma & \cdots & \gamma\\ \vdots &\vdots &&\vdots\\ \gamma& \gamma & \cdots &\lambda+ \gamma \end{array} \right)
Θ:=⎝⎜⎜⎜⎛λ+γγ⋮γγλ+γ⋮γ⋯⋯⋯γγ⋮λ+γ⎠⎟⎟⎟⎞ 矩阵.