|| hsfzxjy || | 言えない言葉は、ここに隠される

Proof of the Gumbel Max Trick

Statement

Assume that $\alpha_1, \alpha_2, \ldots, \alpha_n$ satisify $\sum_k\alpha_k=1$. Define

$$Z=\arg\max_k\{\log\alpha_k+G_k\}$$where $G_1,\ldots,G_n \text{ i.i.d.}\sim Gumbel(0,1)$, whose PDF and CDF are defined as

$$\begin{align} f(x)&=e^{-(x+e^{-x})} \\ F(x)&=e^{-e^{-x}}\end{align}$$. Then $\mathbb{P}(Z=k)=\alpha_k$.

Proof

Set $u_k=\log{\alpha_k}+G_k$. We prove by direct calculations.

$$\begin{align} \mathbb{P}(Z=k)&=\mathbb{P}(u_k \geq u_j,\forall j \neq k) \\ &=\int_{-\infty}^\infty \mathbb{P}(u_k \geq u_j, \forall j \neq k|u_k)\mathbb{P}(u_k) du_k \\ &=\int_{-\infty}^\infty \prod_{j\neq k}\mathbb{P}(u_k \geq u_j|u_k)\mathbb{P}(u_k) du_k \\ &=\int_{-\infty}^\infty \prod_{j\neq k}e^{-e^{-u_k+\log \alpha_j}} e^{-(u_k-\log\alpha_k+e^{-(u_k-\log\alpha_k)})} du_k \\ &=\int_{-\infty}^\infty e^{-\sum_{j\neq k}\alpha_je^{-u_k}} \alpha_k e^{-(u_k+\alpha_k e^{-u_k})} du_k \\ &=\alpha_k \int_{-\infty}^\infty e^{-u_k-(\alpha_k+\sum_{j\neq k}\alpha_j)e^{-u_k}} du_k \\ &= \alpha_k \end{align}$$.

Application

The trick is commonly used in DL to make sampling over a discrete distribution differentiable.

References


七月十三日·別れの前日

旅立ちのとき
ひぐらしの声が聞きった

帰る道に
もう雪が積もる

あなたのいない世界
きっと寂しいんだ


Option::as_ref

Let’s consider the following function:

1
2
3
4
5
use std::ptr::NonNull;
fn transform<T>(option: &Option<NonNull<T>>) -> Option<&T> {
option.map(|x| unsafe { x.as_ref() })
}

The function transform takes in an Option<NonNull<T>> as input, and convert the inner pointer to immutable reference &T if available. The method NonNull::as_ref() is marked unsafe so we need an unsafe block. The snippet didn’t compile well however:

Read More


Rc and RefCell tricks

Say we need a Cursor<T> type, which should contain a mutable reference to T. The type has a method .dup() that will create a new instance of Cursor<T> while sharing the reference between new and old instances. This is common in database driver designing, where users might expect to have multiple cursors alive simultaneously, owning references to the same connection object. A possible implementation might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Cursor<'a, T> {
obj: &'a mut T,
}
impl<'a, T> Cursor<'a, T> {
fn new(t: &'a mut T) -> Cursor<'a, T> {
Cursor { obj: t }
}
fn dup(&mut self) -> Cursor<T> {
Cursor { obj: self.obj }
}
}
fn main() {
let mut i = 1;
let mut cursor_a = Cursor::new(&mut i);
let _cursor_b = cursor_a.dup();
}

Perfect and neat, and luckily Rust compiler did not complain. As a Rust freshman, like me, it’s not easy to keep compiler silent all the time, especially when playing with references. But once I try to chain up the constructor and .dup(), the compiler screams:

Read More


三月十日杂感

我还是说出了那句话。我们走到一起,已经有七天了。

起初并没有表白的想法。当晚看完电影后,两人都有微妙的感觉,但直到最后也没有表露心意。「就当做又一次平常的约电影好了」目送她进楼时我想。看电影时没有说出来,她回去了我就更说不出来了——我认为我们当时还是普通朋友关系,表白显得太唐突了。我兴奋又失落地回到宿舍。兴奋的是我们之间的关系貌似又近了一些,失落的是这样下去大概率是没有结果的。

但当晚,她接连发了几条动态,内容和语气都暗示了她对我的好感,只是和我一样,缺乏勇气。两个相互有好感却又没有恋爱经验的人(当然这是我后来知道的),就要这样还未开始便结束了彼此的关系,这怕是上天对胆小鬼的惩罚吧。

Read More


Visualizing Correlation

Say we have a matrix A of shape N x M, which can be viewed as a collection of N vectors of shape 1 x M. The code below gives us the correlation matrix of A:

1
A_corr = np.corrcoef(A) # shape: (N, N)

To visualize it, just use plt.matshow(A_corr).

If N is so large that the figure could not provide a clear insight, we might alternatively use histograms like this:

1
2
3
4
5
def corr_matrix_to_array(corr_mat):
N = corr_mat.shape[0]
return np.array([corr_mat[i][j] for i in range(1, N) for j in range(i + 1, N)])
plt.hist(corr_matrix_to_array(A_corr), bins=np.linspace(-1, 1, N_bins))

三月一日杂感

我是怎么想的呢?我应该是喜欢她了。她看起来像是一个单纯的女孩,长得可爱,有些呆,总是一副样子很努力的样子。我们有共同的话题,应该可以谈得来,虽然谈话常因为关系不够深入而戛然而止。

她是怎么想的呢?她专心起来很少注意周围,我们有许多次出现在同一个场所,但她很少注意到我。看她朋友圈,大学时应该是有过被人纠缠的烦恼。她成绩不是很理想,为未来烦恼着。

我希求的是一段相互平等的关系,两人的能力和价值观不应该有太大的差距,两人的走近不应该妨碍各自的理想。我不希望我的另一半为了我而放弃自己一直追求的东西。伴侣就是伴侣,不是任何一方的附属品,也不应被任何一方「占有」。如果坚持这个理念,我们的关系想来是不会长久的,至少我走的路,我要去的地方,她不会想去。

那么,就让这段关系不要开始?这或许是一个好选择。我们的认识源于偶然,一年中保持着模糊的朋友关系。进一步发展,如果她不接受,那我就会陷入尴尬的境地;就算接受,毕业时也是要告别的。没有开始,就不会有结束。

但或许,我只是个胆小鬼罢了。

天性の弱虫さ


二月十一日杂感

学生时代的我很怕父亲检查我的作文。四年级以前还没有真正意义的作文一说,因此这大概是从四年级开始的,一直持续到高中。父亲是学文的,在单位也常有写报告的工作。修改作文可以说是比较拿手。现在回想起来,父亲指导作文时还算温和,遇到写得不好的地方也不会破口大骂,只是表情比较严肃。但每当这个时候,我都会感到莫名的畏惧,就像是手无寸铁地撞上一个巨人。为此我会努力减少这种机会,时不时谎称没有布置作文作业,或是隐瞒语文测验。

我是慑于父亲的威严吗?不完全是。我更多地是不想将自己的不完美暴露在父亲面前。在写作这方面,我一直都无法超越父亲。当然这是一种很正常的心理,父亲也不会因为我的不完美而对我不利。尽管如此,我还是对这种事十分敏感。仔细想想,这样的情况还出现在我生活的其它方面。我会因此刻意隐瞒病情,压制心中的迷茫。除非是再三确认过交流过程不会暴露自己的缺陷,我不会轻易和父亲谈话。

我不知是自己天生性格使然,还是因小时候某个「导火索」事件所致。在其他人面前,我也或多或少会有类似的倾向,但这也有可能是因与父亲的关系而起的。小时候父亲总是很忙,有时甚至会长时间到另一个城市去工作。若要追究这种现象背后的原因,我想,这段经历要承担大部分的责任。

当然这不是父亲的错,为了生存,面对两难作出的选择,总会留下一些遗憾的。


一月二十六日杂感

小姑躺在床上,脸色苍白。一根管子从胸口伸出来,随着呼吸剧烈起伏着。长长的管子在床下绕了一圈,接上了一个白色塑料桶,里面尽是浑浊的黄色液体。病床对面坐着阿伯,一脸忧愁的样子。

我顿时感到有些难过——但也仅此而已。这感觉像是一种怜悯,却不是因为血缘,而是来自本性深处,对病危的同物种的怜悯。换句话说,如果躺在面前的是一个素未谋面的人,我的怜悯不会因此减少半分。这么说很残忍,但确实是我内心的真实写照。这种想法当然没有向任何人透露过,可在自己的博客我不想隐瞒这一点。

我身后有一个庞大的家族,但我时刻都想着和他们切断联系。这种想法来源已久了,或许是受到母亲的影响。母亲时常叨念家乡的事,这个人的小心眼,那个人的不作为。但由于外婆依旧健在,母亲还是保持着较高的探亲频率。说是探亲,不过也是周末偶尔回去住个两天,便匆匆回来了。四百公里的路,火车跑起来快得很。

我所不喜欢的,是老家那种到处是熟人的氛围。在那个小镇子上生活的人们从几代以前就互相认识了,出门走几步遇到的人大都能叫出你的名字。熟人社会有着他们自己认为的优点,办事方便,有困难时可以相互扶持。但在我看来这种关系状态是一种束缚。「熟人」们的指指点点会限制你的行为,即使你的行为并没有什么问题。如果将熟人社会看做一个整体,这个庞然大物的思想进步是非常缓慢的。社会中的人相互牵制,根深蒂固的观念不断同化着想要脱离的人。封闭而保守,也许有人喜欢那种状态,反正我是不喜欢的。

亲人又怎么样呢?如果不是经常见面,相互没有过印象深刻的经历,不过也是「熟人」罢了。血缘这种东西,粗暴地将一个人与另一个人捆绑在一起,物质上或许有一些牵连,但精神关系的认同仍然得看彼此的共同经历。自小我便和父母在另一个城市生活,除了曾经照顾过我的,家族中的许多人,同辈或是不同辈的,对于我都只是「熟人」。但遗憾的是,我常常需要回到这些「熟人」当中,有时甚至需要过多地流露一些感情,让我感到如坐针毡。而这一切,只因为我们有「血缘关系」。

有人说,计划生育和网络的崛起让我们这一代变得孤独而冷酷。但我觉得,如果孤独和冷酷不影响我们在现代社会生活的话,倒也无可厚非。熟人的相互关心也罢,沉迷于网络中的光怪陆离也罢,都是为了使精神不空虚,这是一个人活下去的必要条件。过去的人们没有过多的方式解决这个问题,但现在有了,我们应该有权利依自己的意志去选择。我们已经过了几千年的熟人/家族式社会,但不意味着这是常态。二三十年前的文学作品描绘了一个个乡土社会,它们透着幸福的气息,却不能使我产生憧憬。科技在瓦解旧的人际关系和社会结构,在此之前生活的人或许会感到痛惜,但在此之后的人只会无感甚至欣喜。我想,之前许多时代的接口处都会有这样的阵痛。

我盼望着,能尽早告别这一切。


SS Configuration

SS Client

1
$ [sudo] pip3 install shadowsocks

/etc/ss.json:

1
2
3
4
5
6
7
8
9
10
{
"server": "<server ip>",
"server_port": "<server port>", // must be Number
"password": "<password>",
"local_address":"127.0.0.1",
"local_port":1081,
"timeout":300,
"method":"aes-256-cfb",
"fast_open":false
}
1
$ [sudo] sslocal -c /etc/ss.json -d start

proxychains

clone repository from https://github.com/rofl0r/proxychains-ng, make && sudo make install.

Append following lines to /etc/proxychains.conf:

1
2
3
4
5
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks5 127.0.0.1 1081

Usage: proxychains [command].

Chrome Addons

SwitchyOmega.