用 Python 的爽点之一就是其一定的元编程和运行时动态生成与改变代码的能力。比较常见的一种操作,是给类动态挂载一些函数。最出名的例子如下:
class A:
pass
def foo(self):
print("hi")
A.foo = foo
a = A()
a.foo()
# "hi"
如果我们只是能以变量的形式拿到需要挂载函数的名字,那么反射机制还是可以很好的解决问题:setattr(A, "foo", foo)
即可。但这并不是问题的全部,当情况变得稍微复杂,我们将面临各种各样的组合,其中有些可以 work,另一些会报错。本文我们通过从中抽象出几组最小对立的案例来分析,从而全面理解实例方法动态绑定的机制,这实际上也是对 Python 描述器机制的温习,关于描述器的具体内容可以参考我之前写的1。
我们观察引言里最简单的例子
class A:
pass
def foo(self):
print("hi")
A.foo = foo
a = A()
a.foo()
# "hi"
和
class A:
pass
def foo(self):
print("hi")
a = A()
a.foo = foo
a.foo()
# TypeError: foo() missing 1 required positional argument: 'self'
这两者一个成功一个失败,其区别应该是怎么理解呢。对于类属性对应的函数,我们在调用的时候自动实现了”函数“这个类的描述器行为,也即 a.foo() = A.foo(a)
, 注意到描述器行为的定义,只有”函数“这种定义了描述器行为的对象是类(这里是 A)属性时才有这种描述器机制,实例属性是描述器对象,并不会触发描述器机制,也即不会完成将实例作为第一个变量送入函数这种转换。这就是为什么会报错缺少一个变量 self
。
对于后者报错的例子,我们有两种改正可以让其 work (当然个人认为前者直接把方法注册到类上,而非具体实例上,大部分时候更好一点)。但如果有需求注册到具体实例上的函数,两修正方案如下,分别依赖于偏函数和 types 模块,两者方案还有细微差别。对于挂载后的实例的属性 foo
是否是方法的判定是相反的。其原因在对立三会进一步分析。
import types
import functools
class A:
pass
def foo(self):
print("hi")
a = A()
a.foo = functools.partial(foo, a)
isinstance(a.foo, types.MethodType) # False
a.foo()
# "hi"
import types
class A:
pass
def foo(self):
print("hi")
a = A()
a.foo = types.MethodType(foo, a)
isinstance(a.foo, types.MethodType) # True
a.foo()
# "hi"
这一对最小对立如下
class A:
def bar(self):
print("hi")
a = A()
a.foo = a.bar
a.foo()
# hi
和
class A:
def bar(self):
print("hi")
a = A()
a.foo = A.bar
a.foo()
# TypeError: bar() missing 1 required positional argument: 'self'
其原因还是在于”函数“这一对象的描述器定义,继续回顾1谈到的内容,函数对应的描述器定义等效为
class Function():
'''
of course, there are many other attrs omitted here
'''
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
由此可以看出,当从实例拉起实例方法时,也即 a.bar()
由于 a
是实例,相应的根据描述器机制变成了 A.bar(a)
。而从类拉起时 A.bar()
传入 bar
对应的 __get__
时,obj
参数为 None
,由此该方法原样被返回,因此会报错缺少变量传入。
对于动态绑定到类上的函数,如果有一些变量需要在绑定时指定的话,最简单的两种方案分别是闭包和偏函数,两者恰好也形成一组对立。
class A:
pass
def foo(i):
def fooinside(self):
return i
return fooinside
A.foo = foo(2)
a = A()
isinstance(a.foo, types.MethodType) # True
print(a.foo()) # 2
import functools
class A:
pass
def foo(self, i):
return i
A.foo = functools.partial(foo, i=2)
a = A()
isinstance(a.foo, types.MethodType) # False
print(a.foo()) # TypeError: foo() missing 1 required positional argument: 'self'
嵌套函数和偏函数明明看起来行为完全一致,为何一个成功绑定成了类的实例方法,另一个没有呢,原因还是得从描述器机制说起。闭包返回的函数确实还是一个”函数“对象,其依旧继承了函数对象描述器定义的 __get__
方法,这是实例方法实现的根本。而另一方面,Python 里 partial
的实现,并不是函数闭包,而是一个自定义的,带 __call__
的类,这一个类已经不是”函数“类的子类了,因此其默认不具有 __get__
方法,从而没有相应的描述器机制来自动转化为实例方法。这一点 Python 官方文档里写的很清楚2:
functools.partial(func, /, *args,**keywords)
Return a new partial object
partial
objects are likefunction
objects in that they are callable, weak referencable, and can have attributes. There are some important differences. For instance, the__name__
and__doc__
attributes are not created automatically. Also,partial
objects defined in classes behave like static methods and do not transform into bound methods during instance attribute look-up.
注意最后一句就是我们这里说的意思,所谓 instance attribute look-up 就是我们这里说的方法的描述器机制。
一个可能的 workaround 是用 functools 里提供的 partial
的姐妹方法 partialmethod
,例子如下:
import functools
class A:
pass
def foo(self, i):
return i
A.foo = functools.partialmethod(foo, i=2)
a = A()
print(isinstance(a.foo, types.MethodType)) # False
print(a.foo()) # 2
注意到这时实例方法绑定后可以正常工作了,但是对应的是否是实例方法的判断返回的还是 False。原因在于,本质上 partialmethod
返回的还是一个非函数的对象,只不过这次其妥善处理继承了函数类的 __get__
也即描述器机制而已。
综上,本质上要妥善处理和理解上述的各种情形,都是需要对 Python 的描述器机制有深刻的认识。
最近做分子问题的 VQE 看了些量子化学的内容。深感其大多数情形下语言之落后繁琐,以及和物理学科的代沟。因此本文用物理学家更熟悉的数值方法语境和二次量子化的语言,来简要概述量子化学的一些基本概念和数值方法,以使物理背景的读者更加快速简洁地了解量子化学的基本内容。
我们的出发点和固体物理相同,都是考虑了波恩奥本海默近似,将原子核背景固定的多电子薛定谔方程 (下式我们省略了无关的常数)。
\[H = \sum_i \nabla^2_{r_i} +v(r_i) + \frac{1}{2}\sum_{r_i, r_j}\frac{1}{\vert r_i-r_j\vert}\label{Sh}\]为了引入二次量子化的语言来描述这一多体哈密顿量,我们需要找到一组希尔伯特空间(近似)的单体完备基。和固体物理唯一的区别是量子化学的问题中没有平移对称性,因此不用广延的平面波波函数做单体展开的基。相反我们用分子中原子固有的原子轨道来作为分子哈密顿量希尔伯特空间展开的基矢。这些轨道波函数来自于氢原子中心力场单电子薛定谔方程的解,但是考虑到二次量子化时,我们需要计算在这组基下边的交叠积分,为了可以简化积分计算,在量子化学计算中,通常是用若干个高斯波函数的权重叠加,来做各个原子轨道波函数的近似。也即(忽略归一化因子)
\[\chi(r) \approx\sum_i c_i e^{-\alpha_i r^2}\]也就是说量子化学里的每一种基组名称,描述了两个事情:1.每个原子轨道是怎么被近似的 2. 整组基我们一共都选取了哪些原子轨道。比如 STO-3G,其告诉我们:1. 每个原子轨道都由三个高斯函数的叠加近似 2. 整组基只包括对应原子有填充的主量子数对应的原子轨道集合。关于不同基组对应的 2,也即轨道数目,可以参考讨论1。这里的高斯函数及其叠加权重,一般来讲都是提前和原子波函数对比拟合好的固定基组,当然这些参数也可以放开作为能量优化的变分参数,这是后话。有了单体基组后,我们就可以将\(\eqref{Sh}\)表达成二次量子化的形式:
\[H = \sum_{ij} t_{ij}a^\dagger_ia_j+\sum_{ijmn}V_{ijmn} a^\dagger_ia^\dagger_j a_ma_n\label{ssh}\]其中 \(t_{ij}=\int\int \chi_i^{*(1)} \hat{H}_1\chi_j^{2} d\vec{r}^{1} d\vec{r}^{2}\), \(V_{ijmn}=\iint \chi_{i}^{*(1)} \chi_{j}^{*(2)} \hat{H}_{2} \chi_{m}^{(2)} \chi_{s}^{(1)} d \vec{r}^{(1)} d \vec{r}^{(2)}\)。关于二次量子化的形式体系,和这里的系数作为交叠积分的推导,可以参考2。这里费米子升降算符 \(a^\dagger_i\) 和原子轨道波函数 \(\chi_i\) 联系在一起。
所谓的 LCAO,就是用一组原子轨道的线性组合来近似分子轨道。在二次量子化的语言里,就是找到一个 unitary \(U\),使得 新算符 \(\vec{c}=U\vec{a}\) 下对应的 n 电子填充基态 \(\vert\Omega\rangle =\prod_i^n c_i^\dagger\vert 0\rangle\),给出的能量期望 \(\langle\Omega\vert H\vert \Omega\rangle\) 最小。变分优化能量期望以得到最优的矩阵 U,这就是 Hartree-Fock 方法。其特点和做的近似其实就是,假设分子系统的基态可以用一个 Slater 行列式 \(\prod_i^n c_i^\dagger\vert 0\rangle\) 表达,而实际系统里的真实基态,需要多个 Slater 行列式态的叠加才可以表示。这里新的算符 \(c^\dagger\) 对应的波函数,即是所谓的分子轨道波函数。其对应的变换矩阵 U 的每一列,物理意义则是所谓的轨道杂化。之后所有的更复杂的计算,将基于变换之后的,以分子轨道为基的哈密顿量 \(H(c^\dagger, c)\) 讨论。这里的分子轨道,在不考虑自旋轨道耦合等相对论效应时,每个对应两个简并的自旋轨道。
HF 方法在二次量子化这一自动考虑了费米子反对称性的语境里,就是如此简单。但其在传统量子力学的语言中则比较复杂,在量子力学的语境中对应的 HF 方法论可以参考3。值得注意的是,对于变分数值方法,量子化学往往喜欢叫做自洽场方法。传统上其通过每次迭代来实现优化,并以某些量的自洽和收敛作为结束条件。实际上,所有这种自洽场方法,也可以用更加新的可微编程范式所实现,从而直接对大量变分参数进行梯度优化,理解和实现上都更加直接。已经有文献给出了既可以优化 LCAO 参数,又可以同时优化原子轨道近似的基中参数的可微 HF 方案 4。这种自洽场方法,也可以出现在之后更复杂的方法里,SCF 实际上暗示着对应算法除了计算能量,还要在相应的框架里变分优化能量,进一步调整 LCAO,即分子轨道的波函数。
Hartree-Fock 用物理的语言理解,就是做了一个平均场,来近似能量\(\eqref{ssh}\)。量子化学计算的现代方法,则是从 Hartree-Fock 的平均场结果出发,也即从 \(c^\dagger\) 定义的哈密顿量出发,来更好得到分子哈密顿量的能谱,尤其是其基态能量的信息。对于有四费米子相互作用的哈密顿量求解其基态,也是整个凝聚态物理的核心,因此其实量子化学和计算凝聚态物理的方法非常类似。我们对量子化学这些 post Hartree-Fock 的方法,用物理的语言做一简单列举,并给出其在计算物理中的对应。
该方法就是简单的量子力学微扰论。以 HF 多体基态出发,计算四费米子项的微扰贡献对分子基态能量的修正(本质上修正项是 \(H-H_0\), \(H_0(a^\dagger, a)=a^\dagger (U^\dagger \Lambda_cU)a\) 是优化过的给出 HF 基态和分子轨道能谱的含参哈密顿量)。该方案在微扰阶数低时,需要的计算资源较少。不同阶的微扰论分别记作 MP2,MP3,MP4 等等。
现在我们考虑在多体 Fock space 来将二次量子化的哈密顿量对角化。所谓 configuration interaction 就是考虑真实的基态是在 HF 轨道下的不同直积态的叠加。当考虑了所有可能的形如 \(c_i^\dagger ... c_m...\vert \Omega\rangle\) 填充和激发后,我们就可以得到分子基态的严格能量(忽略原子轨道基的不完备性后),这种方法其实就是物理中的严格对角化。当然其缺点是所需资源随着轨道自由度数目指数发散。
因此很多时候,我们需要限制在一些更重要的子空间来做对角化。其中只包含了单电子激发(singlet)和双电子激发(double)的方法可称为 CISD。截止到四个电子激发的空间可称为 CISDTQ。更进一步,我们可以只考虑较低能的可能态上的激发,这被称为对 active space 的限制,从而有效减少轨道自由度的数目。对于 complete active space,需要我们指定 core,active 和 virtual 三种分子轨道。其中 core 轨道一直全满,active 是可能填充的计算空间,而 virtual 轨道一直是空的。对于 n 个电子填充进 m 个分子轨道(2m 个自旋轨道)的解空间,通常记为 CAS(n, m)。投影掉 virtual 轨道,只需直接舍弃包含相应分子轨道算符的哈密顿量分量,而投影掉 core 轨道,则需考虑包含相应算符对角项给出的能量平移。二者在 openfermion 和 qiskit chemistry 中都有相应的 API 来约化量子比特空间。除了 complete active space,还有诸如 restricted active space 和 generalized active space 的概念,他们允许存在一些只能有特定激发的轨道对应的基。这些 active space 的对角化配合上分子轨道上的变分,组成了著名的 CASSCF,RASSCF 和 GASSCF 方法。
以上我们讨论的空间,都是从 HF 或自洽分子轨道基态填充上完成的激发。我们可以同时取多个多体波函数作为待激发的构型来构造基,这被称为 multireference 方法,也即 MRCI。关于 multiconfigurational 和 multireference 的一个讨论,可以参见5。
CC 类的方法是指对于变分波函数 \(e^{\theta_{ij} c^\dagger c + \theta_{ijmn}c^\dagger...c...+...}\vert \Omega\rangle\) 做哈密顿量期望的变分优化。相应的只考虑到四费米子算符的情形,被称为 CCSD。VQE 中最著名的 UCC ansatz 就来自于该方法的 unitary 化 (\(e^T\rightarrow e^{T-T^\dagger}\))。数值时间上,需要对该指数算符做泰勒展开和截断来近似。
对于这里的费米子二次量子化哈密顿量\(\eqref{ssh}\),我们总是可以通过 Jordan-Wigner 或 Bravi-Kitaev 变换,将其转化为泡利矩阵的量子比特自由度,这一方面是 VQE 的理论基础,另一方面也可以利用一些凝聚态物理中的先进数值方法来进行哈密顿量基态优化。DMRG 就是这其中的典型代表。传统 DMRG 中的实空间自由度被量子化学中的分子轨道自由度替代。关于 DMRG 在量子化学中的应用和其可能的独有困难(比如长程相互作用和数量极大的四费米子项),可以参考6。
除此之外,多体物理中常用的量子蒙卡方案也可以用来计算分子哈密顿量的基态。
密度泛函理论方法和物理中的也没太多区别,我们选取电子密度而非电子波函数作为优化的参数。唯一不同的还是展开基是原子轨道而不是平面波基组。DFT 由于对交换作用的泛函做了近似,本质上问题约化到了单体问题,因此可以计算较大的系统,当然在量子化学问题中,可能精度没有上述的方法有优势。
最后,关于这一计算量子化学方向,比较好的一个系列讲解可以参考7,不过这一讲解是基于一次量子化语言的。
How many basis functions used in STO-3G and 6-31+G** for the water molecule? ↩
Automatic Differentiation in Quantum Chemistry with Applications to Fully Variational Hartree–Fock ↩
What exactly is meant by ‘multi-configurational’ and ‘multireference’? ↩
Density matrix renormalization group with long-range interactions and its applications range interactions and its applications ↩
硬性条件:发行于 2011 到 2020 年的韩国歌曲,不包括韩国艺人发行的日语专辑歌曲。
候补来源:2011 到 2019 年的 Melon 年榜 TOP100,加自己音乐软件里的收藏歌曲,加突然想起来的,因此不保证榜单完整,没有遗漏优秀歌曲。
考虑因素:以自己的喜好为主,但为了纪念和怀旧,还是尽可能的包括了更多不同风格的代表作和具有历史意义的作品。以爱豆音乐为主,有少量的 OST 作品,但基本不包含韩式抒情,trot,indie 等类型的作品。
시간을 달려서 by 여자친구 @2016
准备这个榜单,很多位置和排名,我都相当地纠结。但唯独这个第一的位置,我甚至都没有思考过。上个十年,重逢的世界是当之无愧的年代歌曲,时至今日,仍然每次听都有别样的感动,以至于偶尔潸然。幸运地是,在这个十年,还是出了一首可以勉强和重逢放在一起讨论的歌曲,即使相提并论,也已经是这个年代音乐的最高荣誉。李奇勇裴校园三部曲渐入佳境,走向巅峰,配合上朴俊熙的神仙级编舞,GFRIEND 的刀群舞,打造出了这样一颗十年里最璀璨的宝石。“还没来得及说出的话,只有我喜欢你啊”。浓郁的冬日氛围,和校园日漫调性的背后,是柔弱但不可忽视的坚定和力量。从精神渊源上来看,这首歌里蕴含的最深刻的感情和感动是和重逢一脉相承的。“眼神中不需要语言,这停止的时间”;“像儿时的梦,像奇迹,时间快点流逝”。“我绝不放弃,请你用不变的爱守护我,连同我这颗受伤的心”;“能成为大人的话,我会在这艰难的世界握住你的手”。都是艰难的世界,未知的明天,无助的脆弱,但又都是坚定的守护,不屈的力量,永恒的追求。重逢和时间流逝,都不是写爱情的歌曲,爱情只是世间值得用生命捍卫事物的一个象征,这两首歌曲的真正精神早就超脱了爱情歌曲的范畴,成为了可以永远激励人心,永远照亮黑暗的不朽旋律。
Lonely by 2NE1 @2011
谁是这个十年的年代制作人呢,也许我会在勇敢兄弟,新沙洞老虎和 Teddy 之间无限纠结。但凭借这首 lonely,我觉得 Teddy 足以获得此殊荣。不过是归于平凡,不过是也会孤独,孤独不在于是不是一个人,和你在一起,我还是孤独地刻骨铭心。可以将孤独感这么艺术地表达出来,Teddy 和 21 缺一不可。永远的传说,无人可以替代的 2NE1,那孤独,是一种一览众山小的孤独,也是一种平凡到尘埃的孤独。每个人的孤独不一样,可是 lonely 却能唱出每个人心底的孤独。
Roly-Poly by 티아라 @2011
老虎和崔圭成,写出了这首十年最强复古 disco 神曲。老虎是真的很擅长从这种熟悉旋律里取样,管他是民谣还是“借鉴”。这种久经考验的旋律作 hook,再配上熟悉的魔性编曲套路,就是老虎系的创作成功公式。而这首就是成功公式最成功的一次,一举让皇冠拿下了当年年榜头名。魔性的歌曲配上魔性的编舞,谁能顶得住蹦迪的快乐呢。复古里带着些小女生的活泼,disco 里又有着别样的现代感。皇冠,属于这个十年开端的百变女王。
나혼자 (Alone) by 씨스타 @2012
2010 年代,女团尝试了各种能想到的风格。hiphop,朋克,青春,力量,crush,性感,森系,搞怪。但是要评出这十年的年代风格的话,我自己心里还是怨妇风。而这首歌曲,就是怨妇风的巅峰之作,引领了几年的怨妇风潮流,勇敢兄弟的神来之笔。鹤腿舞更是画龙点睛。比起夏日风,我还是更喜欢姐妹的怨妇风,音乐会更加耐听而不浮躁。半空气的声线,勇敢擅长的编曲设计,简直是为怨妇风而生的。我一个人的日常带来的 dejavu,也给这首怨妇风的歌曲扩展了更大的共鸣群体。
Something by 걸스데이 @2014
二段横踢制作的歌曲,和勇敢老虎比,往往自带一些高级感,少了一些烟火气,很多时候这会导致歌曲不如勇敢和老虎的 hook 一样让人中毒。但是这首 something 实在是艺术表达和女团表演完美结合的典范。这首歌曲沿着期待的成功路径,也是蹭地板,抓出轨,在音乐的艺术水平上可以更上一层楼,跨越过了一个大台阶,这是很多女团有了成功的路径依赖后很难做到的。可以把这么俗套的主题,这么露骨的性感,表达得这么艺术,打造出 something 这样一件高级艺术品,不知道在这个领域是否还能后有来者。
비가 오는 날엔 by 비스트 @2011
雨和樱花,无疑是韩语流行音乐最常见,也最容易引起共鸣的两大意象。每年的樱花季和雨季,都会有大量的歌曲回榜。窗外的无论是大雨磅礴,还是细雨霏霏,都是很容易唤起人心底的感性。崔圭成单打独斗的作曲实力,不由得让人怀疑老虎是抱了他的大腿。这首歌,在我看来,是 2010 年代十年里的男团音乐最高峰了。哀而不伤,前奏雨声带来的现实与歌曲的交融。下雨的日子,听着这首歌,你又会想起谁呢。
STAY by BLACKPINK @2016
square 2 回归时,好像是出歌前就放出了 behind the scene。视频 stay 的 bgm 第一次让我对一首歌感到惊为天人。那旋律,让我梦回 lonely。这梦幻的乡村风格,淡雅的吉他和弦,我肉梦幻的音色。“如你般悲伤的旋律,让我如此潸然泪下”。Teddy 的下一首 Stay,Blackpink 的下一首 Stay,还会出现吗,会在何时到来呢。
벚꽃이 지면 by I.O.I @2016
眼看他,起高楼。眼看他,宴宾客。眼看他,楼塌了。伤春,是韩语歌曲的重要主题。看到樱花时,所见的往往并非它的美丽绚烂,而是其飘落时给人的感伤,感伤时光流逝,感伤注定的离别。风前欲劝春光住。春在城南芳草路。未随流落水边花,且作飘零泥上絮。镜中已觉星星误。人不负春春自负。梦回人远许多愁,只在梨花风雨处。振永 2016 的创作少女心和绝妙的伤春主题完美融合,成就了这首如果樱花凋落。“如果樱花凋落,我们的爱情会像夏天一样炙热吗?” 梦幻之处,在于这样一首歌终是成为 ioi 和整个 produce 系列的最好注脚。筵席越热闹,收场时就注定越落寞吧。属于 produce 的时代,落幕了。属于我们的青春,也结束了。
UGLY by 2NE1 @2011
2010 年代的十年,如果非要评选一张年代专辑,那么非 2NE1 在 2011 年的这张 mini 专莫属。这张专辑是 Teddy 制作能力和 21 音乐水平的最好诠释,也是在我看来也是 21 甚至 Teddy 的音乐巅峰。黑泡的精神内核,就是在极度自大和极度自卑之间反复摇摆。这样一首卑微到尘埃的曲子,却同时有着乡村的 intro 和摇滚的副歌。这首歌从 mv 到内容的设定,都类似后来大棒的 loser。“这世界啊,全是谎言”。明明是极其自卑和负能量的歌词,却表达出了这样给人力量和感动的旋律,这也许就是真正的音乐魅力。
DAY BY DAY by 티아라 @2012
后废土风格的与 behind the scene 合体的超长 MV,马上出事前的最后光辉岁月。和横跨事件前后的 sexy love 组成的 30 min 剧情两连发,现实里的事件奇妙和凄凉的纠缠,这一切都使得这首歌成为曾经最强音源王者一个不可磨灭的历史烙印。音乐本身也带有一种后废土的风格,抒情和蹦迪本是皇冠的一体两面,现在看来,能用这种很不舞曲的曲风作为打歌主打的女团回归,也是极其罕见的。
오늘부터 우리는 by 여자친구 @2015
李奇勇裴给油炸的歌,都是那么的优美,不只曲调优美,歌词更加的优美。微笑大神的视频,也算是成就了饭拍史上的两大传奇之一。元气的味道,初恋的感觉,甜美中透出的力量,神一样的 intro,终于被一场大雨彻底浇醒。“像风中飘动的花瓣一样,无法预测的未来”,在下一个平凡的夏日,你还能回想起这首歌曲的旋律和背后的人和事吗,还能记忆起初听这首歌,初见微笑饭拍时的自己吗。
눈, 코, 입 by 태양 @2014
Teddy,不愧是可以同时驾驭蹦迪神曲和完美抒情的制作人。看似清淡的编曲里,也藏着渐渐宏大的背景空间的起承转合。客串了一镜到底 mv 被烧的旗帜上人像的闵孝琳,也算是 BIGBANG 这些年的坎坷里的少有的一丝温暖和佳话吧。
있다 없으니까 by 씨스타19 @2013
一首题目很难翻译成中文的歌曲。勇敢的兄弟和姐妹的组合,打造出了怨妇曲的新角度。因为从有到无,一种清幽的哀怨和自弃,而非传统的浓烈型怨妇曲。最开始的电话声一秒入戏。独特的编舞更是在这首经典上打下了更深的烙印。
기대해 by 걸스데이 @2013
就凭副歌的旋律和背带舞,就值得这个位置了。女孩日这些抓出轨的歌,yyds!跳舞就应该和地板亲切接触!可惜演员团和公司都志不在此吧,不然15,16年还是有机会再留下些经典的。
삐딱하게 (Crooked) by G-DRAGON @2013
GD 和 Teddy 这样的超级创作双核,总是可以迸发出不一样的火花。这首 crooked 算是 GD solo 中期的典型代表,这种极致的颓废风,硬核的 hiphop 表达。表面的蹦迪神曲,骨子里的放浪形骸。浓重的电音后边,是难以察觉的魏晋风骨。
Trouble Maker by Trouble Maker @2011
新沙洞老虎和 rado,在老虎的巅峰期,留下了这样的辉煌。前奏里的口哨声,老虎标志性的鼓点。这首歌也算是标志着方块开始迎来了全盛期。 TM 终究是一场空,现在再看只余下感慨。
LOSER by BIGBANG @2015
2015 年第一发,一鸣惊人,从此开启了横扫 2015 的旋风。导入电音部分无论是歌词还是旋律都是我心目中的最佳。尤其是 YG 特别喜欢的自我嫌弃主题,无论是大棒的 loser,还是 21 的 ugly 都具有极强的震撼力和艺术表现力。世事无常,白云苍狗,经典横跨了两个十年的 BIGBANG,又终将何去何从呢。
달라달라 by ITZY @2019
酱油瓶女团的出道曲,自然是无条件信任,而这首明显在上一个师姐出道曲水平之上。虽然表达是俗套典型的 girl crush,但是副歌的旋律太无敌了!队长的副歌第一句表达得真的太好了,百听不厌。只可惜看起来 ITZY 也落入了最近女团和 JYP 女团的双重规律:作品质量出道最高,之后开始稳步下滑。
HER by 블락비 @2014
每一个高质量音乐的团体里都有一个创作天才,导入就开口跪的神作。很有 hiphop 内核的表达,Jesus 还有什么好说的呢!一句就可以载入史册,每一个这种级别的小节,都是老天直接赏饭。
12시 30분 by 비스트 @2014
龙俊亨,似乎韩国这些天才爱豆制作人总会非常坎坷。前奏的钟声,像命运一样的时针和分针的天各一方,终于成了写给自己的谶语。BEAST 的音乐质量和风格,真的是在 2010 年代独树一帜的存在。在那个时代就难能可贵,在现时这个没有任何男团歌曲能听出旋律的时代,就更是降维打击。
Don’t Cry by 박봄 @2011
Teddy 加 21 就是永远的神。朴春 solo,特别的音色,遇上这样一首抒情。 It’s OK, please don’t cry。2NE1 这种团还能够在现在的女团市场生存吗?KPOP 发展到底是在向何处去呢。
심쿵해 by AOA @2015
在阿粉和女孩日后劲不足的 2015,天使在夏日的女团大战中率先出场并且更上一层楼,也由此来到了天使的巅峰期。勇敢兄弟的编曲和 aoa 的音色再次相遇,比起天使 14 年歌曲里的魅惑元素,这首歌曲多了些活泼和灵动。歌曲初听嘈杂,反而越听越是中毒,越听越觉得流畅,一气呵成,歌曲里的电音也一点不让人觉得吵和俗气,到处都是恰到好处和完美的样子,天使最好的样子,也那样定格在了 15 年的夏天。
SAVE ME by 방탄소년단 @2016
比起同期的 fire,更喜欢这首副主打,也是防弹里我最爱的一首。一镜到底的 mv 是防弹中早期 mv 的标配之一。简单的旋律抓人而反复不会显得重复过多,混合在里面的 rap 部分显得灵动,但融合的很好,又不会分裂和跳脱。这也是防弹很多歌曲都有的重要特点。在这首歌里充分地展现了出来。mv 的草原背景和歌曲配乐的空旷感,又给人了一种微妙的体验,是一种跌落感的具象化。
We all lie by 한진 @2018
We all lie~ 这首歌配合天空之城食用,除了绝了没有其他的形容词了。每当剧情戛然而止,片尾曲导入时,才忽然惊觉原来刚才没入的是另一个虚拟世界。每个人都在重复着别人的悲剧,每个人都在带着面具诉说着谎言。
You are not alone by 여자친구 @2019
李奇勇裴,还是可以接续时间流逝的精神内核,写出这种高度的作品。遗憾的是,这首歌没有成为主打,庆幸的也是,这首歌最终没被选成主打。不然估计为了配合舞台,会对副歌作节奏感加强,那反而就破坏了这首歌曲的整体意境了。这首歌的歌词实在是太美了,每首过于美的歌曲都会显得有些悲伤。不知道这首歌会不会在将来更加的悲伤呢。倾泻而下的银河水彼岸,感谢站在我身边的你。
빛나리 by PENTAGON @2018
副歌实在是太绝,hook 过于抓人,不得不选进榜单。配合上编舞,中毒性十足。前奏也足够灵动,和 YG 一样,方块也是盛产创作型爱豆,而且似乎也是不大可控。
사계 by 태연 @2019
歌词和意境过于超神,配上泰妍的音色,和恰到好处的配器,成就了四季这样的作品。这种比兴的手法,和细腻的心境刻画,把一首看似平铺直叙的歌渲染的波澜四起。整首曲子就是人生若只如初见的绝妙注脚。
All For You by 정은지, 서인국 @2012
请回答 1997 是至今没完整看过几部韩剧的我心中毫无争议的 TOP1。这首 OST 也无需多说,1997 是恩地的天选时刻,这首歌曲开启了请回答系列,也算是见证了阿粉三不前的沉淀。
쩔어 by 방탄소년단 @2015
“欢迎,第一次听防弹吧。”在防弹红起来之前,真正将防弹本来的风格展现的淋漓尽致的一首经典。绝了,就是防弹的 fantastic baby 时刻。而歌曲的流畅和完成程度,甚至要更高一筹。
첫사랑 by After School @2013
勇敢兄弟的因为你似乎质量更高,但是那已经是 21 世纪第一个十年的事情了。这首初恋进榜单也不虚,也算是这个名单里少有的 09 女团的作品了吧。这种舞台概念也怕是再也不会有了吧。遗憾,为放学遗憾,也为整个 KPOP 遗憾。
같은 곳에서 by 소녀온탑 @2016
自此首标杆之后,每一个 mnet 的成团选秀决赛自作曲轮,我都期待有没有一首可以一战的,属于每个节目的那首同一个地方在哪里。振永的 2016 和 101 相互成就,和 101 最后的悲情色彩过于交相辉映,以至于这首少女心的悲歌成为了 ioi 自己的注脚。“每次听到那首歌,就会想起你”,每次听到同一个地方,就会想起你们。歌词与歌名反其道而行之,明明成为满天星不同地方的陌路人,却起了一个同一个地方的题目。“我们还太年轻吧,不太懂爱情呢”。“现在,再见,再见”, 再见!
마지막처럼 by BLACKPINK @2017
一首 Teddy 写的典型的 2NE1。但是 mv 太好看了!我肉太美了!音色太好听了!虽然整体上电音元素还是加的有点不协调,但都不重要了。犹记得发歌第二天,正好从 hk 回来,在机场就一直在单曲循环这首,一天就听了几百遍。应该是这个榜单里,发歌第一时间,我听得遍数最多的。mv 是真的下饭,不是之后 mv 烂俗的狂炫拽。
LATATA by (여자)아이들 @2018
最近几年出道的女团有一个特点,出道作品往往音乐质量最高。也许这就是人生若只如初见吧。面姐的音色和雨琦的羊毛卷,都过于让人迷恋。队长也算是一个难得的女团创作天才。一般的女团歌曲,我最喜欢的往往是 bridge,而副歌往往会因为审美疲劳多落入俗套。而这首则不同,整首歌曲都很脱俗,完全的天才作品。
다른 남자 말고 너 by 미쓰에이 @2015
黑眼必胜:我比 JYP 更懂他家的女团。这首也算是 miss A 的绝唱,也是继好女孩坏女孩之后,miss A 的又一个音乐高峰。黑眼在音乐创作上更多地继承了老虎的旋律性和连贯性,hook 依旧抓耳,但是配器的活用要比老虎丰富得多,不会始终伴随着略显审美疲劳的鼓点。
I NEED U by 방탄소년단 @2015
腾飞的起点,防弹从 13,14 时期比较浓重的硬核 hiphop 风格中开始了转变,以更强的旋律性主动迎合市场,终于走上了一发不可收拾的成功之路。从此之后 hiphop 最重的歌曲往往都会被收录成副主打,而主打歌曲都会尽量选的旋律部分比重更大一些。花样年华,就这样悄无声息地开始了,在 call me baby 和 loser 的对打之间。
내꺼하자 by 인피니트 @2011
副歌部分一句的旋律就足以入榜了。在雄壮感中讲述小情爱,也算是 2010 年代开端时,男团们的一个缩影吧。
휘파람 by BLACKPINK @2016
在新世代女团全面爆发的 2016,拖延症晚期的 YG 终于忍不住了,放出了和四年前传出组成一模一样的女团,对我来说,简直是新鲜感全无。但是这首出道曲还是着实令人改变看法。歌曲的设计和结构比较新颖大胆,bridge 做的很有魅力,整个歌曲又很克制,不像崩拔牙一样无脑蹦迪,而不无脑蹦迪是的 Teddy 还是强的。
사뿐사뿐 by AOA @2014
2014 年,现在看来只不过算是 2.5 代的女团们,展现了异彩纷呈的成功回归。凭借短裙,短发,猫步三部曲,伴随着勇敢兄弟的熟悉的节奏,天使也算后来居上,成为了阿粉和女孩日之外的另一股力量。猫步里的 lalala,听过之后简直会一直萦绕在脑海。这首歌曲如此典型,再次听,还是会一下把人拉回那个火热的 2014,那个可以光明正大走性感风的时代,那个经典作品层出不穷的时代,那个舞台上曾经美好的 ace of angles。
DNA by 방탄소년단 @2017
防弹无可置疑的登基曲目,从此成绩全方位碾压所有对手,对比的对象也再也不在韩国的一亩三分地。自 I NEED U 初一位崭露头角,到 DNA 一举封神,防弹用了两年多一点的时间。“这一切不是偶然,因为是被命运选择的呀”。一个名不见经传的小团,可以创下这样前无古人,后也难有来者的成绩,当然可以找到很多原因。稳定的歌曲制作团队,编舞团队,不掉线的持续策划和音乐的一致性,连续性。不过这些只是后视镜罢了,爱豆团体那么多,为什么防弹只有一个,是 DNA 吗,还是偶然,没有人可以说得清了。
I by 태연 (TAEYEON) @2015
虽然经常被调侃成山歌,但拥有无数钻石级 OST 加持的8年女帝队长,蛰伏已久,出道已经足够惊艳。这之后,大开大合的抒情歌曲开始减少,浅吟低唱的 R&B 小调开始占据了主导。据说副歌的四句是泰妍自己写的,天空下的孩子,终会被美丽生活祝福。
우연히 봄 by 로꼬, 유주 @2015
在那个油炸还没有摔跤的时代,俞宙的清澈嗓音就已经继玻璃珠之后,划开了女团新时代的一角面纱。这个女声简直是耳机测试的必备曲目,清新的感觉可以无死角的将人包围,能看到的味道,又何尝不能被听见。偶然的春天明媚之后就会是今天开始我们的夏日大雨。旧时代的秩序将要倒下,新时代的力量开始破土萌芽。
라비앙로즈 by 아이즈원 @2018
如果这个世界上有什么比真香还香的话,那一定是在表演出道曲的真香。香就完事了。一首被置换的曲子,几个被置换的人生?破茧蝴蝶,含苞待放,玫瑰人生,到底过的是谁的人生?在 Girl Crush 烂大街的 10 年代后半,真香虽是个临时团,还是成功地选择了一个连续和完整的风格展开了各次回归,花三首风格独特,有点仙,有点 power,又有点灵动,再配合上每次都赏心悦目的编舞变换,终于绽放出了年代末最美丽的一抹色彩。虽然过程中充满了坎坷,惟祝愿各位满天星后都能有自己的远大前程。
The Boys by 소녀시대 @2011
一份 2010 年代的榜单,没有少时是不完整的。但是少时在 2010 年代的歌曲尝试往往过于魔幻。选择那年夏天又觉得代表性很是不足,最后还是选了这首九腿都在的主打。这首也一定程度上反映了在 2010 年代转型的少时的歌曲画风。电音,尖厉,不连贯,这也在同时反映了 2010 年代这家公司音乐创作的迷茫,实验和彷徨,以至于终于以前当之无愧的第一造星公司开始光辉不再。永远是少女时代的口号也终于把句号画在了这个十年。
Only One by 보아 @2012
可惜亚特兰蒂斯少女是上个十年的歌曲,不过 only one 也足够有资格进入这个榜单了。出道二十年,永远的亚特兰蒂斯少女。从 No.1 到 Only One,时间流逝,经典永存。
봄날 by 방탄소년단 @2017
2017 年,防弹终于走上了登顶封神的最后一战。年初冬日中的一曲春日,是花样风格的再次回归。少年长大了,多了一份感伤,多了一份细腻。花样系列的最后回眸,暗示着告别和新的出发,很快 LOVE YOUSELF 的起承转结,终将为新王加冕。
Heaven by 에일리 @2012
Heaven Heaven Heaven,大气,DIVA。南韩少有的欧美嗓。足够惊艳的出道。
펑펑 울었어 by Stellar @2016
Brave sounds ~ Let’s go. 如果除了老虎,还有哪种鼓点充斥了 2010 年代的上半期,那就听听这首勇敢兄弟的作品作为一个勇敢全盛期的落幕总结吧。“I wanna go back,像从前那样”。
뿜뿜 by 모모랜드 @2018
想不到新沙洞老虎在 2018 年还是可以靠这些老套路再次创造奇迹。那熟悉的鼓点,简直充斥了整个 2010 年代的女团 KPOP。如此复古的蹦迪神曲,配上记忆点超强的 hook 编舞,稍微有了点梦回 Roly Poly 的恍惚感。
금요일에 만나요 by 아이유 @2014
“星期一大概会很忙吧,星期二会显得我太心急不是吗,星期三有点模棱两可的感觉,星期四不知为何我就是不喜,这周星期五~星期五怎么样?” 星期五见面无疑是 IU 在 2010年代中期,民谣小调的巅峰作品。包揽词曲也显示出了IU 的天才,其天才之处又何止是词曲。一个在综艺(民宿,无挑歌谣祭),影视(大叔,德鲁纳),歌曲领域同时获得了爆款式成功的艺人,在 2010 年代是无人可以企及的真正的年代艺人。在 2010 年的十年里,IU 完成了从爱豆到歌手再到艺术家的蜕变,那么星期五见面也许算是歌手 IU 的代表作品。不是每个人都最爱艺术家,也许有人最怀念的是那个作为歌手或者爱豆的 IU,那个青涩的在写生簿弹唱 Gee 的小姑娘,那个在英雄豪杰里的18岁的李知恩。
불장난 by BLACKPINK @2016
前奏和导入超神,“我妈妈每天和我说,无论何时都要小心男人”。向副歌的过渡也丝般顺滑。唯一白玉微瑕就是副歌的音乐表现稍落俗套,但这丝毫不掩盖这是一首极其成功,极其 YG 的优质女团歌曲。那时的 Teddy 估计正好有很多还没有用出去的经典女团作曲存货吧。玩火和 STAY 的 square two,直接在我心里一战封神。四个人音色特点,和歌曲融合之巧妙,以及那时 Teddy 编曲里的减法和克制,不知何时还能否完美再现。
공허해 by WINNER @2014
温拿出道作品,在男团里曲风算是独树一帜。B.I 写的曲子,还是希望 B.I 可以有更远大的前程。
니가 하면 by GOT7 @2015
黑眼必胜出品的男团歌。从这首之后,got7 就走上了一首更比一首烂,完全不能听的典型男团路线。
NoNoNo by Apink @2013
有了恩地请回答和娜恩我结的铺垫,再有三不这种新沙洞老虎鼓点运用巅峰之作,不大火太难。当然这首歌抄袭的阴影也是摆脱不掉的。但从歌曲到舞蹈,还是一个非常出色的作品,也算是我的半个初心吧。
IF YOU by BIGBANG @2015
2015 四连发第三张的曲子,深沉的抒情一样可以完美驾驭。这首曲子里已经有了些 GD 后来 solo 专无题的影子。后边的鼓点也是一大亮点。
한발짝 두발짝 by 오마이걸 @2016
在振永的奇迹年里,师妹也跟着沾光,拿到了一首神曲。论少女心,振永的创作真是空前绝后。配上噜妹的音色,你一步两步远去时,我就会走三步靠近,谁能阻挡这样的少女心。
그리워해요 by 2NE1 @2013
2NE1 的抒情,yyds!TEDDY 当时是真的强。钢琴响起,副歌导入,谁会不想念呢。
팔레트 (Feat. G-DRAGON) by 아이유 @2017
IU 也有点半空气了。和 GD 的 rap 真的是天作之合。
너 그리고 나 (NAVILLERA) by 여자친구 @2016
你还有我,算是成功的续写了时间流逝的辉煌,李奇勇裴也算是再造经典。但是时间流逝高度太高,终是无法超越。整个编曲还是略显紧促了。
비밀이야 by 우주소녀 @2016
这首算是宇少的音乐高峰了,自此再难超越。2016 也简直是所有音乐的奇迹年。
한숨 by 이하이 @2016
一声叹息,一生叹息,呼吸又何尝不是一种奢侈。你的叹息,虽然我不理解其真义,但是没关系。
러시안 룰렛 (Russian Roulette) by 레드벨벳 @2016
这首歌把红毛音色的缺陷遮盖的比较好,副歌前的导入的渐强感设计的很舒服。轮盘赌和歌曲跳脱曲风的对比,也算是红毛的一大特色吧。
Still falls the rain by AOA @2016
榜单里实在无法割舍这首非主打,可能是对于前奏里有雨声的歌曲无法抗拒吧。
Wild by Nine Muses @2013
过于顺畅和丝滑,简直是 Mr 再现。各方面简直是一首模板型的 2010 年代第一个五年的女团曲,这也是我心目中女团歌曲应有的样子。
첫눈처럼 너에게 가겠다 by 에일리 @2017
继 16 年的太阳的后裔之后,17 年被鬼怪 OST 再次屠榜,这首年榜第一的歌曲,也成为了有史以来 OST 第一次年榜第一。
FANTASTIC BABY by BIGBANG @2012
第一蹦迪神曲,在这一领域恐怕是永远无法望其项背的巅峰。歌曲已经成为了一个历史注解,boomshakala 简直就是一种文化符号。五个人声音的特点都混合在沉重的电音里,但还是可以释放的淋漓尽致。
사랑을 했다 by iKON @2018
从大街小巷横扫到幼儿园的 2018 年榜第一。简洁易跟唱的旋律,有共鸣的歌词,YG 有创作才华的才子太多,毁人和堕落的也太快,一声叹息。
OOH-AHH하게 by TWICE @2015
The story begins. 专辑名称像是宣言一样,预告了一代天团的诞生。这首出道曲在我看来也是两次音乐质量的巅峰了。这也没什么奇怪的,Bad Girl Good Girl 之于 missA,달라달라 之于 Itzy,酱油瓶祖传老出道即巅峰了。
으르렁 (Growl) by EXO @2013
饿了龙,这歌曲和舞蹈,想不大火太难。直接从新星登顶。而现在的公司,好像失去了这种造星就登顶的魔力。
LUV by Apink @2014
阿粉的一览众山小时刻。新沙洞老虎自己抄自己算是最后的灵光乍现。其实曲子的鼓点已经开始渐渐显露出俗套和油腻的颓势了。
What is Love? by TWICE @2018
终于,在 Cheer Up 之后,两次的 MV 制作重回巅峰,还是熟悉的配方,还是熟悉的味道。那个 16 年黄金期的 TWICE 就这么又重现了。这首的曲风也算是 TWICE 17 年之后风格一次少有的背离,但是背离的好!
옥탑방 by N.Flying @2019
我不喜欢逆袭曲,因为有太多的套路,太俗套的抒情。但这首是个例外。
빨간 맛 by 레드벨벳 @2017
一曲白干妈承包了整个夏天,在一个没有姐妹的夏天。这首歌词联觉的运用,实在增色。
Blueming by 아이유 @2019
IU 作词水平达到这样的高度,包裹的音乐内核还是和星期五见面一脉相承。
크레용 (Crayon) by G-DRAGON @2012
GD 从不会让人失望,那独特的音乐是只属于他的。那种藐视型的出世,独此一家。
SOLO by 제니 @2018
想不到在黑粉连出烂曲之时,Teddy 竟然还有这样不错的存货。歌曲也和 Jennie 天作之合,不知其他人的 solo 何时能实现,Teddy 又能不能 hold 另几个人的风格。
Rumor by 국.슈 @2018
自从同一个地方之后,每到这种节目的自创曲轮,总会期待有一个可以媲美的歌曲。Rumor 当然做不到,也和同一个地方的曲风完全不同,但是也算是 303 里最有印象的一首。仅以这首,来怀念追 303 的那两个月,和决赛错愕的晚上。就真的是不只是 Rumor。
벚꽃 엔딩 by 버스커 버스커 @2012
Melon 十年榜音乐第一,真正的封神制作。樱花结局的年年回榜,人们怀念的是那年的樱花还是那年的人呢。
Roller Coaster by 청하 @2018
101 的满天星,终于是只有请夏走得更顺利。在一个女 solo 很难生存的市场里,开辟出了自己的风格。黑眼必胜的这首助攻,开启了请夏的成功之路。
피 땀 눈물 by 방탄소년단 @2016
血,汗,和眼泪,2016 年,防弹终于从籍籍无名走向了双雄争霸。而趋势毫无疑问在防弹这边。花样年华系列之后的曲风变化,依旧可以让防弹再上一层楼,KPOP 历史上的最大奇迹,正在筑牢他的地基。
PICK ME by PRODUCE 101 @2015
这首歌好听吗,不,甚至相当难听。但是这首歌也算是标志着一段历史的开始,从此成团选秀的大幕拉开,演绎出了无数的喜怒哀乐,每个人不过都是别人舞台上的演员。15 年底,101 这段在 MCD 的亮相,必将是载入史册的。在 2010 年代的第二个五年,produce 系列是一个没人可以绕过的中心。
함께 B1A4 @ 2016
榜里有一首男团的 fan song,就充分说明了这首歌的质量。2016 年无疑是振永的奇迹年,无论是几首女团歌曲还是这首一起,简直才华已经溢出了音乐。
You and I by Dreamcatcher @ 2018
捕梦一直不火是我没怎么料到的。这充分说明了音乐本身对于爱豆发展的贡献正在衰减,这多少有点悲哀。捕梦这一系列曲子,是真的有自己的风格和表达,每次主打之间,每首主打本身,都有着相当的完整性和流畅度。这种日漫风,也基本算是爱豆音乐的一个空白。然而,还是一点都没有出圈。
봄 사랑 벚꽃 말고 by HIGH4, 아이유 @2014
2010 年代中期,这种轻快,小调,民谣型的歌曲占据了 IU 当时音乐表达的一大部分。樱花也算是和下雨,圣诞一样可以诞生孝子曲的重点领域。
내가 제일 잘 나가 by 2NE1 @2011
年代最神专的主打,也算是上启 fire,下开 fantastic baby 之先声。这种极致 YG 风作品的最经典的代表之一。
Lovesick Girls by BLACKPINK @2020
2020 年,在连出两年粪曲后,黑粉终于出了些能听的歌。这首歌终于又有点回到了麻吉麻的影子,一点点的乡村和欢快,浓妆艳抹的电音和发狠元素终于有所减少。不过现在每次听到这个歌,都会想到 PUBG。
우주를 줄게 by 볼빨간사춘기 @2016
脸红在 2016 年异军突起,一张神专靠音乐慢慢抓住了韩国人的耳朵。这首主打也算是脸红风格的最好诠释,可惜青涩的两个人一起上周偶的场面,终是再也不得见了。
이 사랑 by 다비치 @2016
2016 是被太阳的后裔 OST 霸榜的一年,全专 OST 都达到了相当的高度。
밤편지 by 아이유 @2017
IU 的抒情曲开始在专辑中占比越来越大,歌曲也开始越来越清淡,宏大的器乐背景开始消解。对音乐的理解和表达也渐渐的从爱豆舞曲走向成熟的自我表达。夜信无疑是这一转变过程中的重要一笔。
까탈레나 by 오렌지 캬라멜 @2014
也许再也不会有橙子焦糖这样的小分队了,从上海之恋到 Catallena,独特的主题,耳目一新的风格,也许只是属于那个时代,属于她们几个的独一无二了。
24시간이 모자라 by 선미 @2013
宣美由此走上了华丽的 solo 之路,并且算是创造了不少经典。这半空气的唱法,也不会让人误会所属社的师承。
썸 by 소유, 정기고 @2014
男女 duet 的经典之作,甚至成为了 Melon 年榜第一。一曲唱尽了微妙的暧昧,更有昭宥这样的合唱女王的加持。
Mr. Chu by Apink @2014
2014 年的阿粉如日中天,要不是世越号的沉没,这首初先生将会提前于 LUV 创下惊人的打歌成绩。这首歌也成为了女团清纯的定式曲,被人反复地致敬。和二段横踢的合作,也引入了一些新鲜感,开启了阿粉音乐上的更多可能,不是局限在新沙洞老虎的鼓点里,而是可以更加地狡黠和俏皮。
위아래 by EXID @2014
Hani 的直拍,最终直接拯救了一个面临解散的女团。逆袭的上下,也给 14 年女团歌曲的百花齐放画上了一个更饱满的句号。新沙洞老虎也由此和 LUV 统治了那年的年末。这之后逆袭曲成为了每年韩国乐坛的保留项目,但没有一个逆袭能像这首元祖逆袭曲一样,具有如此传奇的色彩,以至于婊吧的音源楼都成为了许愿楼。
너랑 나 by 아이유 @2011
可惜好日子虽然霸占了 2011 的 Melon 年榜,但是是 2010 年发行的歌曲。因此这首你和我,就自然成为了那时 IU 风格的代表入选。大编制,带点魔幻风,这首你和我基本就是好日子成功路径的延续。
뱅뱅뱅 (BANG BANG BANG) by BIGBANG @2015
一波四连发,BIGBANG 就这样控制了 2015 的夏日,其中成绩最好的就是这首 3 BANG,算是 FantasticBaby 那个路线的风格延续。
환상속의 그대 by fromis_9 @2017
犹记得偶学决赛看到这首歌的舞台的时候,我想,虽然不如,但大概这就是同一个地方之于 101 吧。总要选一个歌作为纪念,也算是曾经看过这么个小糊节目。这歌的录制的音源版似乎节奏慢了些,没有舞台版小分队的燃。这个小分队也算是天选之人了,差一个没出道,反而在 303 下岗再就业了。
Loca by FAVORITE @2019
在近两年,甚至有一首编曲顺畅连贯,整体性高的歌曲都快成为了一种奢求。一首流畅的歌曲,配上抓人的 hook,微微的异域情调,和一些复古到五年前的鼓点,就足以在 2019 年脱颖而出。不知道这是不是算近几年爱豆音乐的悲哀。即使在零碎的爱豆音乐碎片中这样突出的歌曲,还是没有收到广泛的关注。也许之前那个爱豆有国民度,爱豆歌曲霸占每年 Melon 年榜,在街头巷尾传唱的时代,真的一去不复返了。
NUMBER 9 by 티아라 @2013
一首国内比韩国传唱还要广的歌曲,也是皇冠团经典曲风的一个落幕,再次由新沙洞老虎和崔圭成联袂制作,还是熟悉的味道。自此之后,伴随从 12 年开始的运势下坡路,音乐的质量也渐趋平凡,渐渐失去了 11,12 年巅峰时的神采。
CHEER UP by TWICE @2016
借助 Shy Shy Shy 的春风,一曲加油终于成功地让其时已然炙手可热的 TWICE 走上了女团的登顶之路,结合当年秋天的 TT,两次回归,完成了少女时代之后第一次真正意义上的女团头名易主。2015 年夏日女团大战时,没有人能够取代女帝的豪言,在第二年被那时不在讨论名单上的新生代轻松击破,也由此拉开了七年一轮回的新生代女团爆发的序幕。这首歌本身,我的喜爱还不如它的 mv,但是这样一份榜单,总不能将 cheer up 和 TT 同时淘汰,因此留下这首具有重要意义的歌曲,来标记 2010 年代第二个五年的开始和变化。
강남스타일 by 싸이 @2012
最后还是有这首歌做了榜单的守门员。无论如何,一个缺少了江南 style 的音乐榜单都无法完整概括 2010 年代的韩国音乐的成就和风貌。这首歌曲的 MV 曾经数年保持 Youtube 播放量第一的纪录,从侧面反映了这首歌在当时流行的程度。而在韩国国内,这首歌曲则连续压制了其他歌曲数个月,从夏天爆红到了冬天。
一些不得不割爱的歌曲,排名不分前后。
Rain by 태연 @2016
비도 오고 그래서 by 헤이즈 @2017
희망고문 by 이하이 @2016
PIRI by Dreamcatcher @2019
TT by TWICE @2016
Dolphin by 오마이걸 @2020
Lovey-Dovey by 티아라 @2012
너의 의미 by 아이유 @2014
한여름밤의 꿀 by San E, 레이나 @2014
별이 빛나는 밤 by 마마무 @2018
Dynamite by 방탄소년단 @2020
BLUE by BIGBANG @2012
이럴거면 그러지말지 by 백아연 @2015
넌 is 뭔들 by 마마무 @2016
Psycho by 레드벨벳 @2019
Fiction by 비스트 @2011
STEP by 카라 @2011
짧은 치마 by AOA @2014
잠은 안오고 배는 고프고 by Nine Muses @2015
LONELY by 씨스타 @2017
에너제틱 by 워너원 @2018
Euphoria by 방탄소년단 @2018
]]>本文将围绕 Quantum Computation and Quantum Information by Michael Nielsen and Issac Chuang 1 (以下简称教材)关于 Shor 算法讲述里出现的三个错误,对这些错误的地方进行订正,并发散到 Shor 算法里的其他一些细节的分析。我们将会看到,Shor 算法的难度完全在于经典部分预处理后处理的各种细节和其复杂度和正确性的严格证明,反而其量子核心部分的 phase estimation 是非常简单的。因此很多物理教材舍本逐末,其实完全没有讲清楚 Shor 算法的复杂性,那些一带而过的话其实并不平庸。如此一本圣经级别的教材在这么短短一小节,就出现了至少三处错误,这也侧面反应了 Shor 算法经典部分的困难。本文默认读者对 Shor 算法,计算复杂度理论和初等数论2有一定的了解。
在这一部分,教材给出了错误的定理 5.3, 任取与 N 互质的 \(x\),成功概率 \(P(2\vert r \text{ and } x^{r/2}\neq -1(\mod N))\geq 1-\frac{1}{2^{m-1}}\), 而非教材中的 \(1/2^m\)。这也能说明我们为什么要首先排除 N 是 perfect power 也即 \(N=a^b\) 的情形。此时若 a 为素数,则 \(m=1\),那么这样的 N 对应的成功概率下界降到了 0,由此无法有效保证选出合适的 x ,使得定理 5.2 可以应用。而 \(m=2\) 时,成功概率至少一半。注意到这里的概率,根据每次输出的结果可以简单验证是否成功,因此不需要概率严格大于 \(1/2\) 即可(因为不需要重数投票确定正确答案)。常数 \(k\) 次取样后,取到满足条件 \(x\) 的概率将会变为 \(1-\frac{1}{2^{k(m-1)}}\)。
这一证明在 Shor 论文原文中有一证明梗概,下面将作一简要的分析。值得指出的是,factoring 到 order finding 的 reduction 是 Shor 独立作出的,详情可参考 stackoverflow 上3 Shor 本人的回答。
首先我们需要如下引理:p 是一个奇素数,\(\phi(p^\alpha)\) 的质数分解中包含 \(d\) 个 2,那么对于和 \(p^\alpha\) 互质的全体元素 \(Z^*_{p^\alpha}\) , 恰好有一半可以被 \(2^d\) 整除。
证明概述:考虑到 \(Z^*_{p^\alpha}\) 是循环群4, 所有元素可以表示成 \(g^k (\mod p^\alpha)\) 的形式,对于奇数 k, \(g^{kr}=1\mod p^\alpha\),考虑到 \(\phi(p^\alpha)\) 是 g 的 order,那么 \(\phi(p^\alpha)\vert kr\),因此 \(2^d\vert r\). 若 k 为偶数,\(g^{k\phi(p^\alpha)/2}=1\mod p^\alpha\),因此 \(r\vert (\phi(p^\alpha)/2)\),那么 r 里的含 2 量要比 \(\phi\) 少,所以 \(2^d\) 无法整除奇数 k 元素对应的 r。(这里的含 2 量是为了直观,指的是对应数字质数分解中 2 的个数)。
这一引理我们只需要用一个基于其的非常松的推论:对于 \(Z^*_{p^\alpha}\) 的所有元素,至多有一半元素 order r 的含 2 量相同。证明:对于群里一半元素,对应的 r 含 2 量大于等于 \(\phi(p^\alpha)\) 的含 2 量 \(d\);而另一半元素,其 r 无法被 \(2^d\) 整除,也即他们 order 的含 2 量小于 \(d\)。
基于这一推论,我们给出定理 5.3 的证明概要。\(N=p_1^{\alpha_1}...p_m^{\alpha_m}\),根据剩余定理,随机取 \(x\) 和 \(N\) 互质,等价于分别随机取 \(x_j\) 与 \(p_j^{\alpha_j}\) 互质,\(x=x_1..x_m\),他们对应的 order 分别为 \(r_j\)。首先我们需要展示,当 r 是奇数或者 \(x^{r/2}\) 是平凡解的时候,对应的全部 \(r_j\) 含 2 量相同。那么根据上面的推论,每一个任取的元素 \(x_j\),其 order \(r_j\) 要想和 \(r_1\) 含 2 量相同,概率至多为 \(1/2\),因为至多一半元素 r 含 2 量一样。由此失败概率上界为 \(\frac{1}{2^{m-1}}\),因为对于取出的 \(x_1\) 的 order \(r_1\) 并没有限制。
那么 r 是奇数时,各个 \(r_i\) 均为奇数,全部 order 含 2 量为 0,相同。当 \(x^{r/2}=-1\mod N\), 则 \(x^{r/2}=-1\mod p_j^{\alpha_j}\), 也就是说 \(r\) 是 \(r_j\) 的奇数倍,那么所有的 \(r_j\) 都和 \(r\) 含 2 量相同。证毕。
正如我们上面所说,要想保证 Shor 算法正确性,前处理需要用经典算法排除掉 \(N=a^b\) 的情形。这一排除同样是很多素性测试方案所必需的前处理。这一方法,教材以练习 5.17 的形式呈现,但很明显,这个练习所给出的证明方式和最后复杂度结论应该都是错误的。下面我们先展示一个最基本的解法,其复杂度要高于教材暗示的 \(O(LM(L))\),因为该教材默认了 \(M(L)=L^2\)。我们最后会看到,这一问题虽然可以在 \(O(LM(L))\) 甚至更低的复杂度里解决,但需要的算法远不是一道教材习题的难度,因此在这一问题的分析上,教材作者理解是错误的。
对于不同的 b,从 \(2\) 增加,直到 \(2^b>N\),共 \(O(L)\) 个不同的 \(b\), \(L\) 是 \(N\) 的位数。每次通过评估 \(a^b\) 和 \(N\) 的大小关系二分,来搜索是否有合适的 \(a\),使得 \(a^b=N\)。\(b=2\) 时先将二分起始右界移动到了 \(N^{1/2}\) 处,之后每一轮 \(b\) 对应的左右界初始值分别为 \(1,N^{1/(b-1)}\), 由此可得所需要的二分评估指数 \(a^b\) 的总次数为:(注意该推导里的等号其实都是 scaling 意义下的放缩)
\[\sum_{b=2}^L \log(N^{1/b})= L\sum_{b=2}^L \frac{1}{b} = L \log b = L\log L\]而每个快速指数评估需要的操作数目是 \(\log b M(L)=\log L M(L)\), 因此 Power Test 不太 naive 的复杂度其实为 \(M(L)L\log L^2\).
该问题更精妙的复杂度结果是一些90年代发表的文章56,前者将复杂度降到了 \(O(L^3)\),后者甚至该问题的复杂度可以降低到接近线性。但这些算法本身是不可能作为同为 90 年代的教材的一道课后习题的,因此教材作者对这一问题的复杂性的理解完全有误。
这一错误是作者的理解问题,其错误的理解了 \(s_1', s_2'\) 的含义。
正解:要想保证求出正确的 \(r\),要保证每次测量均匀得出的 \(0\leq s\leq r-1\) 不能和 \(r\) 约分(互质)。这样的 s 的数目即为 \(\phi(r)\)。考虑到在 \(r\rightarrow \infty\) 的极限下,我们有 \(\frac{\phi(r)}{r\log\log r} -> \delta\),因此我们只需要运行 phase estimation \(O(\log\log r)=O(\log L)\) 次,从每次提取的分数中选取最大的分母即为真实的 \(r\)。这也是 Shor 原始文章7给出的方案。考虑到 phase estimation 中复杂度有 \(O(L^3)\),这将使得整个复杂度略高于该值。
而教材中,第一种方案给出的分析依赖于素数个数而不是和 \(r\) 互质的数的个数,因此复杂度放大到了 \(O(L)\) 次分数 \(s/r\) 估计。而在第三种方案中,作者给出了一种所谓常数次计算来估计真实分母的方案,并计算了概率,其假设是说,如果找到两组 \(s', r'\), 且分子互质,那么分母的最小公倍数即为 r。然而 \(r=16,s_1=6, s_2=10\),对应的 \(s', r'\) 分别为 \(3,8\) 和 \(5,8\),按照作者的方案,得出的 \(r=8\),显然是错误的。其实这里作者给出的方案是有问题的,正确的讲述方式是考虑两次取得的 \(s\) 互素,而非约分后才互素,这种情况对应的约分后分母的最小公倍数才是真实的 \(r\)。这一概率对应的证明不变,只是没有了作者错误并画蛇添足的解释:“so to upper bound \(p(q\vert s_1')\) it suffices to upper bound \(p(q\vert s_1)\)”。事实上,公式 5.56 中的 \(s\) 本来就没有 prime。
事实上 factoring 和 order finding 是多项式等价的。我们在 Shor 算法中看到了一个将 factoring 多项式约化到 order finding 的随机算法,这小节将给出反向约化的多项式级别算法,注意到反向的约化是一个确定性的算法。
正确性分析:order r 一定可以整除 \(\phi(N)\)。
复杂度分析:忽略 factoring 所需的复杂度,计算 \(\phi(N)\) 可通过对 N 质因数分解再带入欧拉公式完成,O(1)。循环每次成功除以一个因子为一轮,最坏情况需要 \(\sum_i \alpha_i<\log N=L\) 轮。每轮最多尝试全部不同的因子共 \(m<L\) 个。每次的指数可以用 divide conquer 方法进行快速指数计算,最多需要 \(L\) 次乘法。因此这一反向的归约也是多项式级的。
对于所有分母不大于 \(r\) 的分数,最小的距离就是 \(1/r-1/(r-1)=1/r(r-1)\),因为该距离的分母已经最大,分子已经最小。那么如果选取足够多的比特数,使得准确值的位数达到 \(2L+1\) 的情形下,我们测量出的值和真实的 \(s/r\) 的距离小于 \(\frac{1}{2^{2L+1}}<\frac{1}{r^2}<\frac{1}{r(r-1)}\) (\(r<N<2^L\)),也就是说对于所有分母不大于 \(r\) 的分数里,最多只存在一个与测量值的距离满足理论条件,这是唯一性的一边,这部分证明很少有人提到。大家都会提到的是如何求这个数,也即连分数算法,该待求分数必定是测量小数的某阶连分数展开近似。我们依据连分数的算法将测量值逐阶展开,并根据递推关系计算相应的对应的分数 \(p/q\) (教材附录定理 A4.15)。每计算出一阶的该分数,就计算该分数和我们的测量小数的距离是否小于 \(1/2^{L+1}\),直到第一个满足条件的阶数成立,对应分数即位待求的 \(s/r\) 或其约分式。满足条件分数的存在性,是 phase estimation 取的精度位数所保证的。因此这一从有限精度小数到求出分数的过程,需要三个定理来保证:分别是 phase estimation 精度估计对应的存在性,这里定理提到了唯一性,和教材定理 5.1 保证的求解方法。
以下是其它一些在 Shor 算法过程中会利用到的经典算法。
整数乘法
小学数学 \(M(L) = O(L^2)\)
Schonhage-Strassen 算法 \(M(L)=O(L\log L\log\log L)\),利用了快速傅立叶变换
整数除法
小学数学 \(O(L^2)\), 注意到商的每一位只能取 0 到 b-1,b 是进制位数,因此每一位的暴力猜解是常数复杂度。
更精巧的 Newton–Raphson division,可以将除法复杂度约化成乘法复杂度。也即 \(O(M^n)\)。
更多大整数算术运算的复杂度可以参见8。
辗转相除寻找最大公约数和判断是否互质
每两轮对应数字至少折半,因此只需要 \(O(L)\) 步就可完成 gcd 计算。每步的除法是 \(O(L^2)\),因此整个辗转相除法的复杂度是 \(O(L^3)\)。实际上如果仔细考察的话,会发现每一步除法的复杂度等于除数的位数乘以商的位数,而每轮商的位数是相邻两轮除数位数之差,考虑到该效应求和,则辗转相除的总复杂度仅为 \(O(L^2)\)。
随机素性测试
随机可直接利用费马小定理检验素性,只需要 \(O(1)\) 次,每次一个快速指数计算 O(LM(L))
事实上确定性的素数测试也已经被证明是一个 P 问题9。
快速指数计算 \(a^b\)
divide and conquer \(O(\log b\, M(L))\),这里考虑到了 \(a,b\) 位数不同。
连分数的收敛性
连分数各阶近似对应的分数,每两次分母至少翻倍,因此可以保证展开 \(O(L)\) 阶即可完全表达一个 L bit 分母的分数。
There is a discussion on GitHub about why or why not to replace master as the default branch name. I don’t want to comment on this topic, but my personal choice is to stick with master branch on both my old projects and new projects in the future. Therefore, in this very short post, I make a note on how to maintain master branch on GitHub (and possibly on git if git itself shifts the default from master to main in the future).
git push -u origin master
as before. Just ignore the instruction given by GitHub on the repo page such as git branch -M main
, and go through the exact same workflow as before.In this post, I’ll present the (not so) rigorous math and the logic flow behind REINFORCE estimator: which is widely utilized in reinforcement learning setup, such as plain policy gradient or actor-critic frameworks. The readers should be familiar with RL since I won’t talk about inspiration or details of these RL algorithms here, and you can easily find great materials on these topic elsewhere.
The math of REINFORCE is elaborated in 1 with great detail, we here instead try to use more elegant notations and utilize ideas from 2 to futher bridge the missing gap in 1 when advantage baseline is involved.
The original objective to be optimized is the total reward:
\[\mathcal{L} = E_{s[0:T], a[0:T-1]} [R].\]We only consider typical Markov decision process for now, which indicates that:
The total reward is defined as \(R=\sum_{t=0}^{T-1} r_t\). The formula in this post has finite time cutoff \(T\), but all formulas are easily generalized to \(T\rightarrow\infty\) case.
To present the math behind REINFORCE, we should figure out what on earth these expectation \(E\) stands for and what properties do these expectation operators have. These facts are vitally important and often omitted in other introductory posts.
Suppose we always start from a fixed state \(s_0\), (a probabilistic starting state can be easily generalized), then \(E\) actually stands for
\[E_{s[0:T], a[0:T-1]}(\cdot) = \sum_{a_0} \pi_\theta(a_0\vert s_0)\sum_{s_1}P(s_1\vert s_0, a_0)\sum_{a_1}\pi_\theta(a_1\vert s_1)...\sum_{s_T} P(s_T\vert s_{T-1}, a_{T-1}) (\cdot). \label{def}\]We have several important properties of such operator:
\[E_{s[0:T], a[0:T-1]} = E_{s[0:t], a[0:t-1]}E_{s[t+1:T]a[t:T]} = E_{s[0:t], a[0:t]}E_{s[t+1:T]a[t+1:T]}, ~~~\forall \; 0<t<T\]Note this decomposition must be in time sequence, i.e. the following is not allowed:
\[E_{s[0:T], a[0:T-1]} \neq E_{s[t+1:T]a[t:T]} E_{s[0:t], a[0:t-1]}\]One can justify this by considering the definition in \(\eqref{def}\) directly. Namely one cannot first trace out things of early time as objects in later time depends on them. Or more percisely, the notation should be something like \(E_{(s[t:T], a[t:T])\vert (s[t-1], a[t-1])}\) which is actually a conditioned expectation. That is why it cannot be inverted, since the condition is always in the direction of time.
The second propety is the generalization of score function, namely we have the following gradient exchange:
\[\nabla_\theta E_{s[0:T], a[0:T-1]}( O(s[0:T], a[0:T-1])) = E_{s[0:T], a[0:T-1]}(O(\cdot)\sum_{t=0}^{T-1} \nabla_\theta\ln \pi_\theta(a_t\vert s_t)).\]Together with the zero property from score function (\(C\) is a constant):
\[\nabla_\theta E_{s[0:T], a[0:T-1]}( C) = E_{s[0:T], a[0:T-1]}(C\sum_{t=0}^{T-1} \nabla_\theta\ln \pi_\theta(a_t\vert s_t))=0.\]Also, we have:
\[E_{s[0:T], a[0:T-1]}[O(s_t, a_t)] = E_{s[0:t-1], a[0:t-1]} E_{a_t, s_t}[ O(s_t, a_t)].\label{prop2}\]And if \(O = \nabla\ln \pi_\theta(a_t\vert s_t)\), we are left with
\[E[\nabla_\theta\ln \pi_\theta(a_t\vert s_t)] = 0.\label{prop3}\]This relation can be taken as the outcome of either \(\eqref{prop2}\) or \(\eqref{prop3}\).
We now have the gradient of the total reward as:
\[\nabla_\theta \mathcal{L} = E_{s[0:T], a[0:T-1]}(\sum_{t=0}^{T-1} r_t\sum_{t=0}^{T-1} \nabla_\theta\ln \pi_\theta(a_t\vert s_t)) \label{org}\]Note from now on, all simplification and generalization are directly manipulated on gradient level, this indicates that no corresponding loss function can be found in the following in general. One should directly utilized gradient formula in the implementation. (This is where both TensorFlow and Keras did the things WRONG, see 3.)
To simplify \(\eqref{org}\), we notice that:
\[E[r_t \nabla_\theta \ln \pi_\theta(a_{t'}\vert s_{t'})] = E_{s[0:t+1], a[0:t]} [r_t E_{s[t+2:T], a[t+1:T-1]} \nabla_\theta \ln \pi_\theta(a_{t'}\vert s_{t'})] =0~~~(t+1<t').\]And when \(t+1=t'\), one can also show the expectation is zero (one need to expand relevant expectation to original sum expressions to see that.) Therefore, we have the simplification of \(\eqref{org}\):
\[\nabla_\theta \mathcal{L} = E[\sum_{t=0}^{T-1} (\nabla_\theta \pi_\theta(a_t\vert s_t)\sum_{t'=t}^{T-1}r_{t'})].\label{pg}\]This is the familiar expression as in policy gradient.
\(\eqref{pg}\) shows higher variance and we need to include some baseline to reduce the variance. In other words, we need the formula looks like:
\[\nabla_\theta \mathcal{L} = E[\sum_{t=0}^{T-1} (\nabla_\theta \pi_\theta(a_t\vert s_t)(\sum_{t'=t}^{T-1}r_{t'}-b_{t'}(s[0:T],a[0:T-1])))].\]Of course the most general form of b as the above introduces bias in the estimation, what we need is to find some specific forms of b, such that
\[E[ (\nabla_\theta \pi_\theta(a_t\vert s_t)b_{t'}(s[0:T],a[0:T-1])] = 0.\]This can be done as long as b has dependence only on early times, namely \(b_t(s[0:t], a[0:t-1])\). This automatically include the trivial case, where the baseline is a function of the current state \(s_t\) such as another value network \(V(s_t)\). This zero propety is proved in very similar fashion as the above derivation and you can see them in 2 Appendix B.
We can also change the reward sum part using the same philosophy. The reward part can be any \(A_t\) as long as
\[E_{s[t+1:T], a[t+1, T-1]| a_t, s_t } [A_t(s[t:T], a[t:T-1])] = Q(s_t, a_t) , ~~~ \forall s_t\in S, a_t \in A \label{cond}\]where \(Q(s_t, a_t)\) is the expectation value of total reward after that time (also see proof in 2 Appendix B which is very straightforward with expectation decomposing notation). Therefore, the sum of later reward trivially falls into this category. The possibilities for \(A_t\) include:
All of these are justified with rigorous math since they all follow the condition \(\eqref{cond}\). They are established by solid math instead of some random arguments or so called intuitions as other posts presented.
All discussion above are exact, the deviation is from fluctuation of Monte Carlo estimation. We can in princinple add decay factor \(\gamma\) on the reward such that \(A_t = \sum_{t'=t}^{T-1}\gamma^{t'-t} r_{t'}\). And we can pull this into \(\eqref{pg}\) which is in general better in practice. But this totally change the formula and has no corresponding loss function origins. Namely, it is hard to come up with a natural loss function definition, whose gradient actually gives such formula with discounted rewards. All decay factor stuff is ad-hoc and is forced directly into the gradient formula with no reason. It just works in practice and that’s all. Theoretically, I cannot see any benefits from such factor which deviates the correct formula. (I really dislike the decay factor idea, but it just works in experiments. One has to admit dirty tricks for no reason often outperforms perfect math.)
最近一个月,折腾了几种主流的量子软件方案,因此想一篇小文总结一下。想到哪说到哪,纯意识流,而且这种对比和自己做的东西更偏重于哪些方向也有很大的关系。之前已经有很多列表,对比甚至专门的文章来讨论不同量子软件性能的区别,功能的差异等等。但一来这些内容可能不一定 up to date,这个领域的软件开发还很活跃,好多都是挂在 beta 版的形式;二来他们比较关注的点可能并不是我关心的点,有些应用在意能够模拟的尺寸,有些应用在意真实量子硬件的连接性,有些应用更在意软件和其他机器学习框架的结合等等。本文只比较几个主流的,基于 Python 或至少原生前端是 Python 的软件,同时可能关注的点更倾向于 quantum programming 和 differentiable programming 的结合。其他语言当然也有一些很优秀的类似功能的软件,但我没怎么用过,也没有什么发言权,就不在讨论范围之内了,一个比较全的 quantum software 列表可以参考1。
Qiskit 来自 IBM,这在这次的对比中是最重的一个,依赖极多,本身也分成了多个库开发(我得承认我不喜欢这种工作流,很多东西被人为割裂了,而且这导致 qiskit 的命空间嵌套非常恐怖,没有都 reimport 到顶层实现函数的扁平化。这样的问题就是,你想用的每个函数都得去查文档,不然你都不知道从哪个3级或者4级子包里导入它)。如果想安装 qiskit,强烈建议使用单独的 conda 虚拟环境。不然海量依赖和版本要求很容易把其他库的依赖给破坏了。
Qiskit 比较拧巴的地方在于,为了模拟真实硬件的行为,其不能直接输出最后的波函数或者密度矩阵。为了能直接拿到这些量来分析测量期望(要知道这可比跑几千次 sample 求平均快多了,而且更准确,除非想研究测量次数的影响,否则数值模拟时知道波函数不去用,纯属自讨苦吃。)为了绕过这一问题,可以使用所谓 snapshot
的操作,该操作可以插入到线路里,相当于一个量子门,但其会记录下当时的波函数等信息,最后模拟的结果里就可以拿到了。但这东西还是很 subtle,你直接用 QuantumCircuit 对象,会报错没有该方法。这再次体现了 Qiskit 劈裂成多个库的设计哲学的问题,snapshot 类方法竟然是在另一个库动态注册上去的,而不在原始的 terra 库的 API 里,虽然文档里还是显示相应函数在 terra 库。Qiskit 虽然在量子软件里算是重些,但在那些大块头的软件工程面前,也只是个一般软件而已,这种多个库的分割,实在是带来的问题多于好处,额外的概念也会给用户带来很多困惑。关于 snapshot 究竟要怎么才能用,请查看 2,我硬是看了源代码,才明白了怎么才能调用的。
关于自动微分,Qiskit 当然是做不了了,只能手动 finite difference 了,这种 finite difference 范式和 Pytorch 的结合,可以参考官方例子3。
Cirq 来自 Google。首先的一点吐槽,cirq 的 API 设计有点烂,虽然用习惯了也能忍,但就是不太行,各种冗余都需要输入,一点都不漂亮。或者说句难听的,我无法想象怎么才能把量子计算这种接口设计几乎是送分题的东西实现得这么差劲,糟糕到了我不得不专门吐槽一下的程度。还有就是 cirq 挂着 beta 的名义,文档自然是相当糟糕。开个地图炮,这似乎是 Google 开源软件的通病,TensorFlow,TensorNetwork,TensorFlow Probability 文档都极其的不怎么样。
功能上,cirq 内置了 moment 的概念(每列对齐),对于找线路里的 gap 之类的比较方便,而 qiskit 似乎需要手动写算法 schedule 那些 gate,手动找 gap。现在 noisy 线路和 density matrix simulator, cirq 也都实现了,用起来还行。我们关注的微分部分,作为一个传统量子软件,当然是不默认支持了。其实之前有 proposal4 希望 cirq 把 numpy 迁移到 jax 上去,这样好支持自动微分(因为反正 cirq 是纯 python 的),但似乎开发者都不太感冒。
TensorFlow Quantum同样来自 Google, 设计想法就是基于 cirq,并且使得量子线路可微分,从而可以嵌入到一般的机器学习模型,作为 Keras layer 出现。不过其设计相当局限,首先是微分方式都是 finite difference based (parameter shift 是一种特殊的 finite difference),这相比传统的反向传播,在参数多的时候时间消耗会非常恐怖。其次是可以自动微分的输出量太少了,基本上只有量子线路输出期望可以自动微分。实际上,大多数时候我们需要更灵活的自动微分,包括直接波函数分量就反向传播回去了。不知道为何 tfq 明明有输出 wavefunction 的 layer,但不支持微分。然后就是输入也很局限,不是很能处理任意波函数作为输入5,而这在量子机器学习模型里可能很必要(已知的 cirq 是支持任意波函数输入,qiskit 似乎也不行?反正大部分软件可能都支持的不好,因为后端模拟器必须是量子态模拟器才能比较好的兼容)。
其次 TensorFlow Quantum 利用了 c++ 后端模拟器,但是也可以用传统的 cirq 里的 python 模拟器,就是慢而已。还有问题就是 tfq 不支持 noise,这个问题也很有趣,分为两个方面。由于 tfq 里的序列化根本就不支持 cirq 中 noise 相关的 gate,那么你就构造不出 noise 线路放进 tfq 框架。但另一方面,又由于 tfq 的模拟器可以替换为 cirq 中具有某种噪声的模拟器,因此可以实现这种所有 gate 前后都插入噪声的模拟。因此本质上,倒不是说 tfq 自己的 c++ 模拟器不支持噪声(也确实不支持),真正的阻碍实际上是 tfq 没实现 cirq 噪声相关 gate 的序列化协议。相关问题可以参考6.
Pennylane 出品自 XanaduAI,这个库的设计初心就是怎样更好的结合量子计算和机器学习,因此这个库天然就很适合做机器学习相关的任务,因为该库设计核心就是怎样让量子前向可以微分。整个库的代码很漂亮也很简单,结构可扩展性很好,整个库提供了很多可能的接口,因此一方面量子计算的部分可以 dispatch 到 cirq,qiskit 等不同库上计算,一方面又提供了和 TensorFlow, Pytorch 等兼容的机器学习 layer 接口。而且整个库文档和教学案例非常清楚漂亮。
稍微微观一点讲,这个库采用将量子线路部分封装进一个函数的形式,而该函数的微分操作一般来讲还是 finite difference based,这个也是没有办法的事情。因为 quantum simulation 可能是多后端,多语言 evaluate 的,肯定是没办法 trace 做传统的自动微分的。当然 Pennylane 提供了基于 TensorNetwork 的 simulator,由于这样 quantum simulation 的部分实际上是发生在了 Tensorflow 上,因此是可以用传统反向传播的,这样做的好处自然是多参数时可以保证复杂度只 scale with 线路深度,而不 scale with 参数数目。理论上和实践上,对于量子线路这样的完全可逆计算,我们都可以用 adjoint state 或者说 neural ODE 类似的办法,来实现空间复杂度为常数,而不依赖于线路深度的反向传播,其原理就是反向传播和共轭传播在反向可以同时进行,用来恢复中间值,而不需要前向时记录在内存里。这一想法具体可以参考7,事实上 Julia 中的 Yao.jl 已经实现了这种常数空间复杂度的量子线路自动微分。但据我所知到的信息,目前还没有 Python based quantum software 支持量子线路常数空间复杂度的自动微分。 事实上,支持这种量子线路传统自动微分想法的库,也就只有 Pennylane 而已(当然还有下面我自己写的 demo 库,tensorcircuit)。大部分量子软件库不支持量子线路自动微分的理由很简单粗暴:这一操作无法在真实的量子实验实现。其实这根本是他们的接口,本质就是他们懒得去改模拟量子线路的 C++ 代码来添加自动微分的部分,或者同时对自动微分部分和量子模拟算法部分感兴趣又都了解的开发者少而已。
说了这么多,似乎 Pennylane 对于我们的需求堪称完美了,灵活性高,框架漂亮,接口丰富,支持传统反向传播的量子线路微分,除了期望还支持波函数幅度等作为目标函数的一部分自动微分。但是,一个缺点就让我实际项目里放弃了 Pennylane,那就是它太慢了。它的 Tensornetwork simulator 不知道为什么,比我的也没做任何优化的 tensorcircuit 慢上几百到几千倍,更不要提像 tensorflow quantum 或者 qiskit 这种后端是优化过的 C++ 专用量子线路模拟器的软件了。这个速度实在是这一软件的唯一缺点,其他部分的表现都很完美,但是这一缺点却是致命的,直接导致了无法用它上到实际的研究项目。
最后带点私货,tensorcircuit 也是基于 TensorNetwork,我顺手写的。其实一个简单的量子线路模拟器,核心代码也就小几百行。本来有了 pennylane 这么漂亮的库,其又有基于 TensorNetwork 的模拟器并且支持反向传播,我这个库好像有点画蛇添足。要说我这个库和 pennylane 比有啥优势,那就是快。其实我也没做任何优化,我也不知道为什么 pennylane 那么慢。反正现实就是 tensorcircuit 中等规模 size,做项目速度还可以接受,pennylane 的 tensornetwork 模拟器完全无法接受。
最后总结一下,需要微分线路的话,大 size 还得用 tfq,毕竟是 c++ 的模拟器,快很多,当然微分部分会乘以线路参数倍的慢,不过一般时候还是更快。中 size 或者变分参数较多的情形,tensorcircuit 可能更快。而如果需要比较特别的目标函数,不止依赖于观测量期望,而依赖于输出波函数的细节的话,那么就只有 tensorcircuit 能胜任了。
Implementation of traditional mean field approach in condensed matter physics but with AD infrastructure (powered by jax engine).
ADMF enables simple code and swift implementation for complicated quantum models.
]]>Behold, the power of qop.
Playing with symbols and quantum algebra has never been so easy and straightforward before.
from qop.boson import *
assert (b0.D*b0)**3 == b0.D*b0+3*b0.D**2*b0**2+b0.D**3*b0**3
from qop.fermion import *
assert (c0.D*c0)**3 == c0.D*c0
from qop.hardcoreboson import *
assert (hb0.D*hb0)**2 ==hb0.D*hb0
assert hb0*hb1 == hb1*hb0
from qop.spin import *
assert s0.x*s0.y == 1j/2*s0.z
assert s0.z*s1.x == -2j*s1.x*s0.x*s0.y
from qop.grassmann import *
assert (1+g(0)*g(1))**2 == 1+2*g(0)*g(1)
from qop.quaternion import *
assert (1-qi)/(1-qj) == 0.5*(1-qi+qj-qk)
from qop.symbol import *
a = Symbol("a")
assert np.conj(2+a).evaluate({"a": 1j}) == 2-1j
from qop.fermion import *
from qop.state import *
assert Sf("1").D | c1.D * c1 | c1.D | Sf() == 1.0
And mix all, we have
U = Symbol("U")
assert Sf("12").D | U * (np.array([c1.D, c2.D]) @ np.array([c1, c2])) ** 2 | Sf("12") == 4 * U
Or einsum with opt_einsum
from qop.base import *
from qop.symbol import *
from opt_einsum import contract
a,b,c,d = Symbols("abcd")
simplify(contract("ijk,i->jk", d*np.ones([3,3,3]), np.array([a,b,c]), backend="qop"))
Try the package by pip install hpcsubway
.
The package that you have ever dreamt of when interacting with super computers, subway can take care every aspects of HPC tasks. It can build solid and automatical pipelines from submitting jobs to data management, from version control to resource consumptions. It also provides very powerful git-like command line interface.
This package is designed for HPC enviroment, which requries no third party package as dependence and can be installed simply by python setup offline.
]]>