diff --git "a/\350\256\241\347\256\227\346\226\271\346\263\225B/code/hw6/hw6.typ" "b/\350\256\241\347\256\227\346\226\271\346\263\225B/code/hw6/hw6.typ" new file mode 100644 index 0000000..52cfab2 --- /dev/null +++ "b/\350\256\241\347\256\227\346\226\271\346\263\225B/code/hw6/hw6.typ" @@ -0,0 +1,214 @@ +#import "../../../template.typ": * +#show: note.with( + title: "作业6", + author: "YHTQ", + date: datetime.today().display(), + logo: none, + withOutlined : false, + withTitle : false, + withHeadingNumbering: false +) +#set par(first-line-indent: 0pt) +#let factorial(n: int) = range(1, n + 1).product(default: 1) += 4. + #let xs = range(5).map(i => calc.pi * i / 8) + #let ys = xs.map(x => calc.sin(x)) + + 选取插值点为: + + #xs.map(str).join(",") + + 函数值为: + + #ys.map(str).join(", ") + + #let laugrange(x: float) = { + let res = 0.0 + for xi in xs{ + let l = 1 + for xj in xs{ + if xj != xi{ + l *= (x - xj) / (xi - xj) + } + } + res += l * calc.sin(xi) + } + res + } + 误差界为: + $ + abs(R(x)) = abs((f^(5) (xi))/5! product_(i = 1)^5 (x - x_i)) = abs((cos xi)/5! product_(i = 1)^5 (x - x_i)) <= 1/5! product_(i = 1)^5 abs(x - x_i) + $ + #let laugrange_err(x: float) = 1 / factorial(n: 5) * xs.map(xi => calc.abs(x - xi)).product() + #let test_point = range(10).map(i => i * 3 / 20) + 选取测试点为: + + #test_point.map(str).join(", ")\ + 计算误差界分别为: + + #test_point.map(x => laugrange_err(x: x)).map(str).join(", ") + + 实际误差为: + + #test_point.map(x => calc.abs(laugrange(x: x) - calc.sin(x))).map(str).join(", ") + + 可见误差界比较准确。要使最大误差小于 $10^(-10)$,注意到: + $ + abs(R(x)) <= 1/(n+1)! product_(i = 0)^(n) abs(x - x_i) <= 1/(n+1)! (pi/2)^(n+1)\ + $ + 最大误差为:\ + + #range(10, 20).map(i => 1/factorial(n: i) * calc.pow(calc.pi / 2, i)).enumerate( + ).map(xs => + { + let (i, x) = xs + (i + 10, x) + } + ) + 可见选取 $n = 16$ 足以 += 5. + 不能。考虑以下四点: + $ + (-2, 1), (-1, 0), (1, 0), (2, 2) + $ + 注意到分段二次多项式的导数是分段线性函数。因此容易验证假设满足条件的分段插值多项式存在,则其导数为线性的。\ + 结合数据点特征,可设 $f'(x) = a x$,再结合 $f(x)$ 的连续性, $f(x)$ 就是二次函数。然而容易验证不存在二次函数通过以上四点。 + + 一般的,若给定三点数据,则存在二次函数通过三点,此时取此二次函数便满足条件。 += 6. + == (1) + 使用归纳法,$m = 0$ 时显然,一般的: + $ + f[x_0, ..., x_m] &= (f[x_1, ..., x_m] - f[x_0, ..., x_(m-1)]) / (x_m - x_0)\ + &= (sum_(i = 1)^m (f(x_i) / (product_(j = 1, j != i)^m (x_i - x_j)) - sum_(i = 0)^(m-1) (f(x_i) / (product_(j = 0, j != i)^(m - 1) (x_i - x_j)))))/(x_m - x_0)\ + &= (f(x_m)/(product_(j = 1, j != i)^m (x_m - x_j)) - f(x_0)/(product_(j = 0, j != i)^(m-1) (x_0 - x_j)) + sum_(i = 1)^(m-1) (( (x_i - x_0) f(x_i) - (x_i - x_m) f(x_i)) / (product_(j = 0, j != i)^m (x_i - x_j))))/(x_m - x_0)\ + &= f(x_m)/(product_(j = 0, j != i)^m (x_m - x_j)) + f(x_0)/(product_(j = 0, j != i)^m (x_0 - x_j)) + sum_(i = 1)^(m-1) (f(x_i)) / (product_(j = 0, j != i)^m (x_i - x_j))\ + &= sum_(i = 0)^(m) (f(x_i)) / (product_(j = 0, j != i)^m (x_i - x_j))\ + $ + == (2) + 由 (1) 显然 + == (3) + 由 (2) 有: + $ + f[x_0, ..., x_k, x_m] &= f[x_k, x_0, ..., x_(k-1), x_m] \ + &= (f[x_0, ..., x_(k-1), x_m] - f[x_k, x_0, ..., x_(k-1)])/(x_m - x_k)\ + &= (f[x_0, ..., x_(k-1), x_m] - f[x_0, ..., x_(k-1), x_k])/(x_m - x_k) + $ + == (4) + 由余项的一致性,立刻得到: + $ + (f^(n) (xi))/n! product_(i) (x_0 - x_i) = f[x_0, ..., x_n] product_i (x - x_i) + $ + 显然插值点互不相同,因此结论显然 += 9. + // 设三次多项式为: + // $ + // sum_(i = 0)^3 a_i x^i + // $ + // 则方程组为: + // $ + // sum_(i = 0)^3 a_i x_k^i = f(x_k), k = 0, 1, 2\ + // sum_(i = 1)^3 i a_i x_1^(i-1) = f'(x_1)\ + // $ + // 也即: + // $ + // mat(1, x_0, x_0^2, x_0^3; 1, x_1, x_1^2, x_1^3; 1, x_2, x_2^2, x_2^3;0, 1, 2 x_1, 3 x_1^2) vec(a_0, a_1, a_2, a_3) = vec(f(x_0), f(x_1), f(x_2), f'(x_1)) + // $ + 我们希望取得 $h_i (x)$ 使得: + $ + h_i (x_j) = delta_(i j) f(x_j)\ + h'_i (x_1) = delta_(i 1) f(x_1) + $ + 先取三点的 Lagrange 基: + $ + l_i (x) = (product_(j = 0, j != i)^2 (x - x_j)) / (product_(j = 0, j != i)^2 (x_i - x_j)) + $ + 计算: + $ + l'_i (x_1) = (2 x_1 - sum_(j = 0, j != i)^2 x_i)/(product_(j = 0, j != i)^2 (x_i - x_j)) + $ + 再取: + $ + r(x) = product_(j = 0)^2 (x - x_j)\ + r'(x_1) = (x_1 - x_2) (x_1 - x_3) + $ + 不妨设: + $ + h_i (x) = f(x_i) l_i (x) + lambda_i r(x) + $ + 如此应有: + $ + f(x_1) (2 x_1 - x_2 - x_3)/((x_1 - x_2)(x_1 - x_3)) + lambda_i (x_1 - x_2) (x_1 - x_3) = f'(x_1)\ + f(x_i) (2 x_1 - sum_(j = 0, j != i)^2 x_i)/(product_(j = 0, j != i)^2 (x_i - x_j)) + lambda_i (x_1 - x_2) (x_1 - x_3) = 0, i != 1 + $ + 解出: + $ + lambda_1 = (f'(x_1) - f(x_1) (2 x_1 - x_2 - x_3)/((x_1 - x_2)(x_1 - x_3)))/((x_1 - x_2) (x_1 - x_3))\ + lambda_i = -f(x_i) (2 x_1 - sum_(j = 0, j != i)^2 x_i)/(product_(j = 0, j != i)^2 (x_i - x_j)) / ((x_1 - x_2) (x_1 - x_3)), i != 1 + $ + 于是就有: + $ + P(x) = sum_(i=0)^2 f(x_i) l_i (x) + lambda_i r(x) + $ + 同时: + $ + R(x) = f(x) - sum_(i=0)^2 (f(x_i) l_i (x) + lambda_i r(x)) = R(x) - (sum_(i=0)^2 lambda_i) r(x) = ((f^3 (xi))/3! - sum_(i=0)^2 lambda_i) r(x) + $ += 11. + #let aa = $alpha$ + #let taa = $tilde(aa)$ + #let bb = $beta$ + #let tbb = $tilde(bb)$ + #let xd = $(x - x_i) (x - x_(i + 1))$ + #let xd0 = $x_(i + 1) - x_i$ + #let xdn = $x_i - x_(i + 1)$ + + 首先由导数条件,不妨设: + $ + aa' = 3 a_1 xd, aa'' = 3 a_1 (2 x - x_i - x_(i + 1)) + $ + 因此根据 $x = x_i$ 处泰勒公式,有: + $ + aa = 1 + (3 a_1 (x_i - x_(i + 1)))/2 (x - x_i)^2 + a_1 (x - x_i)^3 + $ + 带入 $aa(x_(i + 1)) = 0$ 有: + $ + 0 = 1 + (3 a_1 (x_i - x_(i + 1)))/2 (x_(i + 1) - x_i)^2 + a_1 (x_(i + 1) - x_i)^3\ + = a_1 (x_(i + 1) - x_i)^3 - 3/2 a_1 (x_(i + 1) - x_i)^3 + 1\ + a_1 (x_(i + 1) - x_i)^3 = 2\ + a_1 = 2/((x_(i + 1) - x_i)^3) + $ + 同时 $x = x_(i + 1)$ 处泰勒公式给出: + $ + aa = (3 a_1 (x_(i + 1) - x_i))/2 (x - x_(i + 1))^2 + a_1 (x - x_(i + 1))^3 = 3 ((x - x_(i + 1))/xd0)^2 + 2 ((x - x_(i + 1))/xd0)^3\ + = ((x - x_(i + 1))/xdn)^2 (3 + 2 (x - x_(i + 1))/xd0) = ((x - x_(i + 1))/xdn)^2 (1 + 2 (x - x_(i))/xd0) + $ + $taa$ 的表达式可以对称的得到。 + + 再考虑 $beta$,由零点条件不妨设: + $ + beta = c (x - x_i) (x - x_(i + 1))^2\ + beta' = c((x - x_(i + 1))^2 + 2 (x - x_i) (x - x_(i + 1)))\ + $ + 代入 $beta' (x_i) = 1$ 有: + $ + 1 = c (xdn)^2\ + c = 1/(xdn)^2 + $ + 对称的可以得到 $tbb$ 的表达式。 += 16. + #let biT(i) = $b_#i^T$ + #let bi(i) = $b_#i$ + 不难验证系数矩阵事实上形如: + $ + H = (inner(b_i, b_j))_(i j) + $ + 换言之: + $ + H = autoVecNF(biT, n) autoRVecNF(bi, n) + $ + (这里 $b_i^T$ 是向量的对偶,考虑到 $P_k$ 是有限维向量空间) + + 由 $autoRVecNF(bi, n)$ 满秩不难得到 $H$ 满秩,因此解存在唯一 + + 计算得对于 $k = 5, 6, 7$ 条件数分别为 $1.5 times 10^7, 4.8 times 10^8, 1.5 times 10^10$ \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\226\271\346\263\225B/main.typ" "b/\350\256\241\347\256\227\346\226\271\346\263\225B/main.typ" index d559cc9..8b7217c 100644 --- "a/\350\256\241\347\256\227\346\226\271\346\263\225B/main.typ" +++ "b/\350\256\241\347\256\227\346\226\271\346\263\225B/main.typ" @@ -1053,68 +1053,154 @@ - 若 $A$ 是不可约的上 Hessenberg 矩阵,则 $R Q$ 也是不可约的上 Hessenberg 矩阵 ] 对上 Hessenberg 矩阵进行 QR 分解时,可以考虑利用 $n-1$ 个 Givens 变换,一次迭代计算量仅有 $O(n^2)$ -= 函数的多项式逼近 - #definition[差商][ - 对于函数 $f(x)$,定义差商为: - $ - f[x] = f(x)\ - f[x, x_0] = (f(x) - f(x_0))/(x - x_0)\ - f[x, x_0, ..., x_k] = (f[x, x_1, ..., x_(k-1)] - f[x_0, x_1, ..., x_(k-1)])/(x - x_k) - $ - ] - == 牛顿多项式 - #definition[牛顿多项式][ - 对于函数 $f(x)$,定义牛顿多项式为: += 函数的插值与逼近 + 假设函数 $f(x)$ 在 $x_0$ 处各阶导数都存在,我们就可以使用泰勒展开: + $ + f(x) = sum_i 1/(i !) f^(i) (x_0) (x - x_0)^i + $ + 逼近函数。同时,只要函数连续,就一定可以用多项式在闭区间上一致逼近某个函数。具体找到这个多项式的方法大致分成两类: + - 插值逼近 + - 最佳逼近 + == 多项式插值 + 假设我们知道函数 $f(x)$ 在若干个点 $x_i$ 上的值,找到一个经过这些点的多项式的问题称为插值问题。称满足这样的条件的多项式为*插值多项式*。 + #theorem[存在唯一性][ + 给定 $n + 1$ 个不同的插值节点,则存在唯一的次数不超过 $n$ 的多项式是插值多项式。 + ] + #proof[ + 设任意一个不超过 $n$ 次的多项式为: $ - N_n(x) =\ &f[x_0] + f[x_0, x_1] (x - x_0) + ... + f[x_0, x_1, ..., x_n] (x - x_0) (x - x_1) ... (x - x_(n-1)) + sum_(i = 0)^n a_i x^i $ - 其余项为: + 它是插值多项式当且仅当系数是线性方程组: $ - R(x) = f(x) - N_n(x) = f[x, x_0, ..., x_n] (x - x_0) (x - x_1) ... (x - x_n) + sum_(i = 0)^n a_i x_k^i = y_k, forall k = 1, 2, ..., n + 1 $ + 注意到这是线性方程组,系数矩阵是范德孟德矩阵,是非奇异的,因此解存在唯一。 ] - #remark[][ - 事实上,由插值多项式的唯一性,牛顿多项式应该和拉格朗日多项式是相同的,只是选择了不同的基函数因此看起来不太一样。此外,如果多加入一个点,拉格朗日插值需全部重新计算,而牛顿插值只需要添加一个项即可。 - ] - == 分段低次多项式插值 - 当插值节点很多时,之前构造的插值多项式次数会很高,逼近效果很多时候反而变差,这被称为 Runge 现象。一个解决此问题的简单想法是,将区间分成若干段,每段选取一个多项式进行逼近。 - === 分段线性插值 - #definition[分段线性插值][ - 对于函数 $f(x)$,定义分段线性插值为插值点: - $ - (x_i, f(x_i)) - $ - 之间的连线。这是连续的分段线性函数,并且满足插值条件。 - ] - 实际构造分段线性函数的方法是,令: + 理论上,可以直接通过解线性方程组的方法求出所有系数,但是代价很高,我们往往不会这么做。 + === 拉格朗日插值 + 显然,如果只有两个点,我们可以直接找到连接两点的线段。一般的,我们希望找到 $l_i (x)$ 作为基函数使得: + $ + l_i (x_j) = delta_(i j) + $ + 从而不难验证: $ - l_(n, i) (x_j) = cases( - (x - x_(i - 1))/(x_i - x_(i - 1)) "if" x_(i - 1) <= x <= x_i, - (x_(i + 1) - x)/(x_(i + 1) - x_i) "if" x_i <= x <= x_(i + 1), - 0 "otherwise" - ) + L_n (x) := sum_i f(x_i) l_i (x) $ - 这些函数就是我们的基函数,最后的逼近无非是: + 就是我们要找的插值多项式。事实上,可以取: $ - phi_h (x) = sum_i f(x_i) l_(n, i) (x) + l_i (x) = (product_(j != i) (x - x_i) )/(product_(j != i) (x_i - x_j)) + $ + 接下来,需要计算插值后的误差。定义插值余项: + $ + R(x) = f(x) - L_n (x) $ #theorem[][ - 若 $f(x) in C^2[a, b]$,则: + 假设函数 $f(x) in C^(n + 1)[a, b]$,则对任意 $x in [a, b]$,存在 $xi$ 使得: $ - abs(f(x) - phi_h (x)) <= (m h^2)/8 + R_n (x) = (f^(n + 1) (xi))/((n + 1)!) product_(i) (x - x_i) $ - 其中 $m = max_(a <= x <= b) abs(f''(x))$ 且 $h = max_i (x_(i + 1) - x_i)$ ] #proof[ - 假设 $x in [x_(i - 1), x_i]$,将有: + 设: + $ + R(x) = k(x) product_(i) (x - x_i) + $ + (既然 $R(x_i) = 0$) + 不妨设 $x != x_i, forall i$ + 记: + $ + W_(n + 1) (t) = product_(i) (t - x_i)\ + E(t) = R_n (t) - k(x) W_(n + 1) (t) + $ + 容易验证 $E(t)$ 有 $n + 2$ 个零点: + $ + x, x_1, ..., x_(n + 1) + $ + 利用罗尔定理,将存在 $xi$ 使得: + $ + E^(n + 1)(xi) = 0 + $ + 解得: + $ + k(x) = (f^(n + 1) (x))/((n + 1)!) + $ + ] + #remark[][ + 尽管可以证明拉格朗日插值多项式可以一致逼近连续函数,但拉格朗日插值的余项事实上难以估计。同时如果采用等距的插值,算法的稳定性将会十分糟糕。 + ] + === 牛顿多项式 + #definition[差商][ + 对于函数 $f(x)$,定义差商为: + $ + f[x] = f(x)\ + f[x, x_0] = (f(x) - f(x_0))/(x - x_0)\ + f[x, x_0, ..., x_k] = (f[x, x_1, ..., x_(k-1)] - f[x_0, x_1, ..., x_(k-1)])/(x - x_k) + $ + ] + #theorem[][ + - + $ + f[x_0, x_1, ..., x_n] = sum_(i = 0)^n (f(x_i))/(product_(j != i) (x_i - x_j)) + $ + - 差商与节点的顺序无关 + - 设 $f(x)$ 的 $m$ 阶导数存在,则: + $ + exists xi, f[x_0, ..., x_m] = (f^(m) (xi))/(m!) + $ + ] + #definition[牛顿多项式][ + 对于函数 $f(x)$,定义牛顿多项式为: + $ + N_n (x) =\ &f[x_0] + f[x_0, x_1] (x - x_0) + ... + f[x_0, x_1, ..., x_n] (x - x_0) (x - x_1) ... (x - x_(n-1)) $ - phi_h (x) &= f(x_(i - 1)) (x - x_(i - 1))/(x_i - x_(i - 1)) + f(x_i) (x_i - x)/(x_i - x_(i - 1))\ + 其余项为: $ - 它其实是两点的拉格朗日多项式,熟知结论误差估计,简单计算即可。 + R(x) = f(x) - N_n(x) = f[x, x_0, ..., x_n] (x - x_0) (x - x_1) ... (x - x_n) + $ + ] + #remark[][ + 事实上,由插值多项式的唯一性,牛顿多项式应该和拉格朗日多项式是相同的,只是选择了不同的基函数因此看起来不太一样。此外,如果多加入一个点,拉格朗日插值需全部重新计算,而牛顿插值只需要添加一个项即可。 ] - 上面的定理表明,分段线性插值有很好的逼近效果,但不幸的是它不是光滑函数。 - === 分段二次插值 - 类似上面的思路,在每个小区间上做 Hermit 插值使得插值多项式光滑即可 + === 分段低次多项式插值 + 当插值节点很多时,之前构造的插值多项式次数会很高,逼近效果很多时候反而变差,这被称为 Runge 现象。一个解决此问题的简单想法是,将区间分成若干段,每段选取一个多项式进行逼近。 + ==== 分段线性插值 + #definition[分段线性插值][ + 对于函数 $f(x)$,定义分段线性插值为插值点: + $ + (x_i, f(x_i)) + $ + 之间的连线。这是连续的分段线性函数,并且满足插值条件。 + ] + 实际构造分段线性函数的方法是,令: + $ + l_(n, i) (x_j) = cases( + (x - x_(i - 1))/(x_i - x_(i - 1)) "if" x_(i - 1) <= x <= x_i, + (x_(i + 1) - x)/(x_(i + 1) - x_i) "if" x_i <= x <= x_(i + 1), + 0 "otherwise" + ) + $ + 这些函数就是我们的基函数,最后的逼近无非是: + $ + phi_h (x) = sum_i f(x_i) l_(n, i) (x) + $ + #theorem[][ + 若 $f(x) in C^2[a, b]$,则: + $ + abs(f(x) - phi_h (x)) <= (m h^2)/8 + $ + 其中 $m = max_(a <= x <= b) abs(f''(x))$ 且 $h = max_i (x_(i + 1) - x_i)$ + ] + #proof[ + 假设 $x in [x_(i - 1), x_i]$,将有: + $ + phi_h (x) &= f(x_(i - 1)) (x - x_(i - 1))/(x_i - x_(i - 1)) + f(x_i) (x_i - x)/(x_i - x_(i - 1))\ + $ + 它其实是两点的拉格朗日多项式,熟知结论误差估计,简单计算即可。 + ] + 上面的定理表明,分段线性插值有很好的逼近效果,但不幸的是它不是光滑函数。 + ==== 分段二次插值 + 类似上面的思路,在每个小区间上做 Hermit 插值使得插值多项式光滑即可。 == 最佳平方逼近 自然的,我们要考虑怎样的逼近是最好的逼近。假如我们使用 2-范数,容易证明确实存在一个不超过 $n$ 次多项式 $p^*$,使得: $ diff --git "a/\350\256\272\346\226\207/scallop.typ" "b/\350\256\272\346\226\207/scallop.typ" index 5e87dec..0aa19f8 100644 --- "a/\350\256\272\346\226\207/scallop.typ" +++ "b/\350\256\272\346\226\207/scallop.typ" @@ -15,10 +15,33 @@ == 基本思想 -- 深度学习(梯度下降......)和符号推理(Datalog 式的逻辑编程)的结合 +- 深度学习(梯度下降......)和符号推理(Datalog 式的逻辑编程)的结合。例如说对于手写公式的求值问题,完全依赖两种模式的其中之一听起来都令人两眼一黑,需要将两者适当的结合起来。 - 符号推理是离散的,深度学习需要可微性。将离散问题连续化的一个常见思路就是概率化建模 -- 通常的概率建模计算复杂度是指数的,往往不可接受,因此我们需要采用某种替代策略,进行精度与效率的权衡 +- 通常的工作流可能是先识别出符号,再用经典方法求值。但这需要中间变量的数据被显式给出(比如已有大量的图片与其代表的符号的对应),而许多时候中间变量可能是隐式的。同时,这样做也会丢失最后结果的信息反馈。 +== #empty + #align(center)[#commutative-diagram( + node((0, 0), $"Graph(data)"$, 1), + node((0, 1), $"Exp(data)"$, 2), + node((0, 2), $"Res"$, 3), + node((1, 0), $"Graph(logic)"$, 4), + node((1, 1), "Exp(logic)", 5), + arr(1, 2, $partialDer(r, theta)$), + arr(2, 3, $partialDer(y, r)$), + arr(4, 5, $$), + arr(5, 3, "RL", label-pos: right), + arr(1, 4, $$), + arr(2, 5, "Repr", label-pos: right), + )] + 这里: + - $partialDer(r, theta)$ 代表已有的深度学习框架的学习机制,而 $partialDer(y, r)$ 是需要设计的 differential reasoning engine + - Repr 是数据的表示 + - RL (Reasoning Language) 是基于表示进行推理的逻辑语言 +== #empty + 因此主要工作就分成三部分: + - 数据表示:关系型 + - 推理语言:基于 Datalog,支持递归,否定和聚合 + - 自动微分引擎:provenance semiring 和近似算法的概率计算 == 例子 ```rust // Knowledge base facts @@ -40,19 +63,28 @@ // Count the animals rel num_animals(n) :- n = count(o: name(o, "animal")) ``` - -== 概率化建模 - #let tP = $tilde(P)$ - 假设 $X$ 是一些离散值(例如 $X = {T, F}$) $X$ 上可以建立概率空间 $cal(X)$,它由一个映射: - $ - P : X -> [0, 1] with sum_(x in X) P(x) = 1 - $ - 唯一决定。显然它也可以由向量 $tP in RR^abs(X)$ 唯一确定,其中#footnote[ - 当然实际的深度学习中我们往往不会使用上面这种比较硬的计算。一种替代是 Softmax 函数,但想法是差不多的。 - ]: +== provenance + 某种意义上,程序的执行结果就是函数值,而如果我们做微分,就要对函数的执行做出拓展。Scallop 将程序计算的代数结构抽象为一个 provenance,也就是包含以下运算: $ - P(x_i) = tP_i / norm(tP)_1 + directSum, tensorProduct, minus.circle, eq.circle $ + 以及 $0, 1$ 的代数结构。其中 $directSum, tensorProduct, 0, 1$ 构成半环(同时为了递归的安全,还需要额外的 absorptive),negation, saturation 也要满足一些性质。provenance 中的元素称为 tag,类似于概率的推广。 + + 有了这些定义,我们就可以在更加广泛的意义下去执行 Datalog 程序。Scallop 会先转换成 low-level representation *SclRam* ,程序的输入被称为 extensional database(EDB),最终的执行结果称为 intentional database(IDB)。provenance 既实现了普通的 Datalog 执行,也实现了概率化的 Datalog 程序以及梯度的传播。(当然每个具体的实现都会基于一些比较复杂的算法)。 + #image("./屏幕截图 2024-11-15 173540.png") + 其中 $sigma_beta$ 是用 $beta$ 筛选,$pi_alpha$ 是用 $alpha$ 做 map, $gamma_g$ 指用 $g$ 做 aggregation +// == 概率化建模 +// #let tP = $tilde(P)$ +// 假设 $X$ 是一些离散值(例如 $X = {T, F}$) $X$ 上可以建立概率空间 $cal(X)$,它由一个映射: +// $ +// P : X -> [0, 1] with sum_(x in X) P(x) = 1 +// $ +// 唯一决定。显然它也可以由向量 $tP in RR^abs(X)$ 唯一确定,其中#footnote[ +// 当然实际的深度学习中我们往往不会使用上面这种比较硬的计算。一种替代是 Softmax 函数,但想法是差不多的。 +// ]: +// $ +// P(x_i) = tP_i / norm(tP)_1 +// $ // == 概率的传播 // 设 $f: X -> Y$ 是函数,显然 $f(cal(X))$ 应该是一个概率空间。其上的概率非常典范的定义为: // $ @@ -99,21 +131,21 @@ // // ] // #image("./屏幕截图 2024-11-06 204619.png") // 简单来说就是把所有东西拆成若干原子命题之间的演算即可 -== 证明的构建 - Scallop 实际上不去建立命题的真值的概率分布,而是建立命题的证明的概率分布。对于任何一个命题 $X$,我们可以把它视作一个类型,其中的值是所有 $X$ 的证明#footnote[原论文实际上没有使用“类型”而是简单的使用集合语言。不过这里也只是换一个术语,应该比集合套集合清晰一些]。自然的,原子命题只有一个证明,而: - $ - A tensorProduct B := A and B = A times B, A directSum B := A or B = A + B - $ - 当然,不难验证 $tensorProduct, directSum$ 运算在命题空间上构成半环结构,称为 proof semiring。可以想象,Datalog 程序无非是由原子命题和 $tensorProduct, directSum$ 构成的表达式,因此我们可以得到析取范式: - $ - P = directSum_j (tensorProduct_i A_(i j)) - $ - 其中 $A_(i j)$ 是一些原子命题,根据 $A_(i j)$ 的概率计算 $P$ 的概率的问题称为 WMC(Weighted Model Counting)问题。当然这个计算过程听起来复杂度就是指数级的,因此需要一些近似算法。 -== top-k - 上面的思路无非是用逻辑演算构造一个分类问题,而分类问题中我们可以期望概率分布是相当不平衡的,大部分概率集中在少数几个类别上。因此,我们可以只考虑那些概率比较大的证明。具体来说,在上一页的公式中,我们可以只考虑 $P$ 中概率最大的 $k$ 个证明,这样就得到了 top-k 算法。换言之,重新定义: - $ - A tensorProduct B := "Top"_k (A and B) , A directSum B := "Top"_k (A or B) - $ - 可以证明这样定义的运算仍然构成半环,因此可以在其上高效地计算 WMC -== 梯度传播 - 可以想象梯度的计算和概率的计算应该是一体的。因此为了能够计算梯度,只需要在计算概率的同时再加一个梯度的记录即可,论文中将其称为 _gradient semiring augmented WMC procedure_ +// == 证明的构建 +// Scallop 实际上不去建立命题的真值的概率分布,而是建立命题的证明的概率分布。对于任何一个命题 $X$,我们可以把它视作一个类型,其中的值是所有 $X$ 的证明#footnote[原论文实际上没有使用“类型”而是简单的使用集合语言。不过这里也只是换一个术语,应该比集合套集合清晰一些]。自然的,原子命题只有一个证明,而: +// $ +// A tensorProduct B := A and B = A times B, A directSum B := A or B = A + B +// $ +// 当然,不难验证 $tensorProduct, directSum$ 运算在命题空间上构成半环结构,称为 proof semiring。可以想象,Datalog 程序无非是由原子命题和 $tensorProduct, directSum$ 构成的表达式,因此我们可以得到析取范式: +// $ +// P = directSum_j (tensorProduct_i A_(i j)) +// $ +// 其中 $A_(i j)$ 是一些原子命题,根据 $A_(i j)$ 的概率计算 $P$ 的概率的问题称为 WMC(Weighted Model Counting)问题。当然这个计算过程听起来复杂度就是指数级的,因此需要一些近似算法。 +// == top-k +// 上面的思路无非是用逻辑演算构造一个分类问题,而分类问题中我们可以期望概率分布是相当不平衡的,大部分概率集中在少数几个类别上。因此,我们可以只考虑那些概率比较大的证明。具体来说,在上一页的公式中,我们可以只考虑 $P$ 中概率最大的 $k$ 个证明,这样就得到了 top-k 算法。换言之,重新定义: +// $ +// A tensorProduct B := "Top"_k (A and B) , A directSum B := "Top"_k (A or B) +// $ +// 可以证明这样定义的运算仍然构成半环,因此可以在其上高效地计算 WMC +// == 梯度传播 +// 可以想象梯度的计算和概率的计算应该是一体的。因此为了能够计算梯度,只需要在计算概率的同时再加一个梯度的记录即可,论文中将其称为 _gradient semiring augmented WMC procedure_ diff --git "a/\350\256\272\346\226\207/\345\261\217\345\271\225\346\210\252\345\233\276 2024-11-15 173540.png" "b/\350\256\272\346\226\207/\345\261\217\345\271\225\346\210\252\345\233\276 2024-11-15 173540.png" new file mode 100644 index 0000000..1abb77d Binary files /dev/null and "b/\350\256\272\346\226\207/\345\261\217\345\271\225\346\210\252\345\233\276 2024-11-15 173540.png" differ diff --git "a/\350\275\257\344\273\266\345\210\206\346\236\220/hw/2100012990-\351\203\255\345\255\220\350\215\200-\350\275\257\345\210\206\347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232.typ" "b/\350\275\257\344\273\266\345\210\206\346\236\220/hw/2100012990-\351\203\255\345\255\220\350\215\200-\350\275\257\345\210\206\347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232.typ" index cdef00f..f486ca6 100644 --- "a/\350\275\257\344\273\266\345\210\206\346\236\220/hw/2100012990-\351\203\255\345\255\220\350\215\200-\350\275\257\345\210\206\347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232.typ" +++ "b/\350\275\257\344\273\266\345\210\206\346\236\220/hw/2100012990-\351\203\255\345\255\220\350\215\200-\350\275\257\345\210\206\347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232.typ" @@ -57,4 +57,4 @@ ``` - 普通的区间分析经过加宽(无法变窄)只能分析得到 $j in [0,+infinity]$ - 八边形分析得到了 $j >= 11$ - - 但理想情况下,应该可以得到 $j = 22$,既然事实上有 $x - 2 y = 0$ \ No newline at end of file + - 但理想情况下,应该可以得到 $j = 22$,既然事实上有 $j - 2 i = 0$ \ No newline at end of file