9 λΆ
π€ Rustμ λ―ΈλΆνκΈ° 03: μ λ°©ν₯ μλ λ―ΈλΆ
π Automatic Differentiation Series
λ₯λ¬λμ ꡬνν¨μ μμ΄μ κ°μ₯ μ€μν μμκ° λκΉμ? λ¬Όλ‘ λ§μ νλ¬ΈμΌλ‘ ꡬμ±λ λ₯λ¬λμ νΉμ±μ λͺ¨λ μμλ€μ΄ λ€ μ€μνμ§λ§, κ·Έ μ€μμλ νΉν μ κ²½μ¨μΌνλ μμκ° μμ΅λλ€. μ΄λ₯Ό μ°Ύμλ΄κΈ° μν΄μ λ€μμ PyTorch μ½λλ₯Ό μ΄ν΄λ΄ μλ€.
net = nn.Sequential(
nn.Linear(2, 1),
nn.Sigmoid()
)
# x = ...
# y = ...
# criterion = ...
opt = optim.SGD(net.parameters(), lr=0.01)
opt.zero_grad()
loss = criterion(net(x), y)
loss.backward()
opt.step()
μ΄λ₯Ό μλ¬΄λ° λ₯λ¬λ νλ μμν¬λ₯Ό μ°μ§ μκ³ κ΅¬ννλ€κ³ μκ°ν΄λ΄
μλ€.
μΌλ¨ μλ°νκ² κ°μ ꡬνμ μλμ§λ§ Linear
μ Sigmoid
ν¨μ μ체μ ꡬνμ λ¨μν νλ ¬κ³±κ³Ό 벑ν°νλ sigmoid ν¨μλ₯Ό μ¬μ©νμ¬ κ΅¬νν μ μμΌλ―λ‘ net(x)
λ₯Ό λ§λλ κ²μ μ΄λ ΅μ§ μμ΅λλ€.
λ€μμΌλ‘ μ¬κΈ°μ criterion
μ΄ λ¬΄μμΈμ§ λͺ
μνμ§λ μμμ§λ§ κ°μ₯ κΈ°λ³Έμ μΈ MSE
λ₯Ό μ¬μ©νλ€λ©΄ μ΄ μμ κ°λ¨ν©λλ€.
λ¬Έμ λ opt
λΆν° μμλ©λλ€.
SGD
λ₯Ό ꡬννλ €λ©΄, μ΄λ€ criterion
μ΄λ μ κ²½λ§ κ΅¬μ‘°μμλ gradient μ¦, λν¨μλ₯Ό ꡬν μ μμ΄μΌ ν©λλ€.
μ΄λ₯Ό μν΄ μμμ λ°°μ΄ μμΉλ―ΈλΆμ μ¬μ©ν μ μμ κ²μ λλ€. μ κ²½μ°μλ μ κ²½λ§μ΄ λ¨μΌ κ³μΈ΅μΌλ‘ λμ΄μκ³ μ λ ₯, μΆλ ₯ μ°¨μλ μμΌλ―λ‘ ν¬κ² λ¬Έμ λμ§ μκ² μ§λ§ λ³΄ν΅ λ₯λ¬λ λͺ¨λΈλ€μ λ€μΈ΅μΌλ‘ λμ΄μμΌλ©° μ μΆλ ₯ μ°¨μλ ν°λ°λ€ μ±κ³΅μ μΈ νλ ¨μ μν΄μλ μμ², μλ§ λ² μ΄μ νλ ¨μ ν΄μΌν μ μμ΅λλ€. κ·Έλ΄ κ²½μ°, μμΉλ―ΈλΆμΌλ‘ μΈν μ¬μν μ€μ°¨κ° νλ ¨μ κ±°λνλ©° λλ©μ΄μ²λΌ λΆμ΄λ μ μμ΅λλ€.
κ·Έλ λ€λ©΄ μμμ λ°°μ΄ κΈ°νΈλ―ΈλΆμ μ΄λ¨κΉμ? κΈ°νΈλ―ΈλΆμ μ νν λν¨μμ ννλ₯Ό μ»μ μ μκΈ°μ λΆλμμμ μ€μ°¨μΈμλ λ³λμ μ€μ°¨κ° λμ λμ§ μμ΅λλ€. νμ§λ§ μμ κΈμμλ μ§μ νλ€μνΌ κΈ°νΈλ―ΈλΆμ ν λ² κ³μ°ν λλ§λ€ ν° κ³μ° λΉμ©μ μꡬν©λλ€. μ΄λ¬ν κ³μ° λΉμ©μ μμ²λ² μ΄μμ νλ ¨μ κ±°μΉλ©΄μ κΈ°νκΈμμ μΌλ‘ μ¦κ°νλ©°, μ΄λ μνλ μκ° λ΄μ, νΉμ μ νλ λ©λͺ¨λ¦¬ μν©μμ νλ ¨μ μ΄λ ΅κ² λ§λ€ μ μμ΅λλ€.
μμ λ°°μ΄ λ κ°μ§ λ―ΈλΆλ°©λ² λͺ¨λ λΆμ ν©νλ€λ©΄ λ체 μ΄λ»κ² ꡬνν΄μΌν κΉμ? λ€νν κ³Όνμλ€μ λ₯λ¬λμ΄ λμ€κΈ° μ΄μ μ μ΄λ―Έ μ΄λ₯Ό μν λꡬλ₯Ό λ°λͺ ν΄λμμ΅λλ€. λ°λ‘ μλλ―ΈλΆ (Automatic Differentiation) μ λλ€. μλλ―ΈλΆμ κ³μ°λ°©λ²μ λ°λΌ ν¬κ² λ κ°μ§λ‘ λλ μ μλλ°, μ λ ₯ λ³μμ λ³νμ λ°λΌ κ° ν¨μμ μ νλλ λν¨μλ₯Ό κ³μ°νλ λ°©μμ μ λ°©ν₯ μλλ―ΈλΆμ΄λΌ λΆλ₯΄λ©°, λ°λλ‘ μΆλ ₯ λ³μμ λ³νμ λ°λΌ λν¨μλ₯Ό κ³μ°νλ λ°©μμ μλ°©ν₯ μλλ―ΈλΆμ΄λΌ λΆλ¦ λλ€. κ° λ°©μμ μλ‘ λ€λ₯Έ μ₯λ¨μ μ κ°κ³ μμ΄ κ²½μ°μ λ°λΌ μ νν΄μ μ¬μ©ν μ μλλ°, μ΄λ² κΈμμλ νΉν μ λ°©ν₯ μλλ―ΈλΆμ μ§μ€νλλ‘ νκ² μ΅λλ€.
1. Truncated Taylor Series
μλλ―ΈλΆμ΄λΌλ κ±°μ°½ν μ΄λ¦μ΄ λΆμμ§λ§, μ λ°©ν₯ μλλ―ΈλΆμ κ°λ μ λνκ΅ λ―Έμ λΆνμκ°μ λ°°μ°λ ν μΌλ¬ κΈμμμ μ λν©λλ€. λ―ΈλΆκ°λ₯ν ν¨μ $f$μ νΉμ μ§μ $x_0$μμμ ν μΌλ¬ κΈμλ λ€μκ³Ό κ°μ΄ μ κ°λ©λλ€.
$$ f(x) = f(x_0) + f’(x_0)(x - x_0) + \frac{f’’(x_0)}{2!}(x - x_0)^2 + \cdots $$
μ΄λ $x$ λμ $x$μ μΆ©λΆν μμ (infinitesimal) λ³λ $\epsilon$μ κ°νκ³ μ΄λ₯Ό $x$μ λν΄μ ν μΌλ¬ κΈμλ₯Ό μ κ°νλ©΄ λ€μκ³Ό κ°μ΅λλ€.
$$ f(x+ \epsilon) = f(x) + f’(x)\epsilon + \mathcal{O}(\epsilon^2) $$
$\epsilon$μ΄ μΆ©λΆν μλ€κ³ κ°μ νμΌλ―λ‘ ($|\epsilon| \ll 1$), $\epsilon^2$ μ΄μμ νλ€μ 무μν μ μμ΅λλ€.
$$ f(x + \epsilon) = f(x) + f’(x)\epsilon $$
μ΄λ κ² νΉμ μ°¨μκΉμ§λ§ μμ±νλ ν μΌλ¬ κΈμλ₯Ό Truncated Taylor SeriesλΌ λΆλ¦ λλ€. κΌ μΌμ°¨νκΉμ§λ§ λ¨κ²¨λμ νμλ μμ§λ§, λλΆλΆμ λ₯λ¬λ λ¬Έμ λ λν¨μκΉμ§μ μ λ³΄λ§ μꡬνλ―λ‘ μ¬κΈ°μλ μΌμ°¨νκΉμ§λ§ μμ±νκ² μ΅λλ€.
μ΄μ $\epsilon$μ κ³μκ° κ³±ν΄μ Έμλ ννλ₯Ό μκ°ν΄λ΄ μλ€.
$$ f(x + \overline{x} \epsilon) = f(x) + f’(x)\overline{x}\epsilon $$
μ μμ 보면 $\epsilon$μ΄ λ§μΉ μΌμ’ μ κΈ°μ μ²λΌ μμ©νλ€λ κ²μ λ³Ό μ μμ΅λλ€. $x + \overline{x} \epsilon = x \mathbb{1} + \overline{x} \epsilon$ μΌλ‘ 보면 $\mathbb{1}$κ³Ό $\epsilon$μ΄ κΈ°μ μΈ κ³΅κ°μμ μλ₯Ό λνλΈ κ²μ²λΌ 보μ λλ€. λ°λΌμ μ΄λ₯Ό νλμ μλ‘ μ·¨κΈνκ³ λ€μκ³Ό κ°μ΄ κ°λ¨ν ννν΄λ΄ μλ€.
$$ x \mathrel{\rhd} \overline{x} \equiv x + \overline{x}\epsilon $$
μ΄λ¬ν μλ₯Ό μ΄μμ (Dual number) λΌ λΆλ₯΄λ©° λ¬΄λ € 1873λ μ William Cliffordμ μν΄ μ°½μλμμ΅λλ€. μ΄μμλ μ²μ λͺ©μ μ΄ μλλ―ΈλΆμ μλμμ§λ§ μ΅κ·Όμ μμλ μλλ―ΈλΆμ λνλ΄λ λνμ μΈ μ체κ³λ‘ μ리μ‘μμ΅λλ€. μ΄μ μ΄ μλ₯Ό μ΄μ©νμ¬ λ€μ μΌμ°¨νκΉμ§μ ν μΌλ¬ κΈμλ₯Ό μμ±ν΄λ΄ μλ€.
$$ f(x \mathrel{\rhd} \overline{x}) = f(x) \mathrel{\rhd} f’(x)\overline{x} $$
μ΄μ μ’ λ κ°λ¨ν΄μ‘μ§λ§ νλμ λ¬Έμ κ° λ¨μμμ΅λλ€. ν¨μ $f$μ μ μκ° λͺ ννμ§ μλ€λ κ²μ λλ€. $x$λ₯Ό 1μ°¨μ μ€μλ‘ κ°μ νκ³ $x \mathrel{\rhd} \overline{x}$λ₯Ό μΌμ°¨μ μ΄μμ($\mathbb{D}\mathbb{R}$)λΌ κ°μ νλ©΄ μ’λ³μμμ ν¨μ $f$λ $\mathbb{DR} \rightarrow \mathbb{DR}$ ν¨μμ΄μ§λ§ μ°λ³μμμ ν¨μ $f$λ $\mathbb{R} \rightarrow \mathbb{R}$ μ΄λ―λ‘ μ μκ° λμ§ μμ΅λλ€. μ΄λ λ€νν μλ‘μ΄ μ°μ°μμΈ $\vec{\mathcal{J}}$μ λμ νλ©΄ μ½κ² ν΄κ²°ν μ μμ΅λλ€.
$$ \vec{\mathcal{J}}f(x \mathrel{\rhd}\overline{x}) = f(x) \mathrel{\rhd} f’(x)\overline{x} $$
μ΄λ μ°μ°μ $\vec{\mathcal{J}}$λ λ€μν κ΄μ μμ ν΄μλ μ μλλ°, λͺ κ°μ§λ§ μλμ κΈ°μ νκ² μ΅λλ€.
-
$f$λΌλ μ€μ곡κ°μ νΌμ³μ§ μ₯(field)μ μ΄μμ 곡κ°μ μ₯μΌλ‘ λ³νν μ°μ°μμ΄λ―λ‘ λ―ΈλΆκΈ°ννμμμ Push-forward κ°λ μΌλ‘ λ°μλ€μΌ μ μμ΅λλ€.
-
μλ μ€μ νμ μ λ°μμ μ€μ νμ μ λ°ννλ ν¨μ $f$μ μμ©ν΄μ μλ‘μ΄ ν¨μλ₯Ό λ§λ€μ΄λμΌλ―λ‘ ν¨μν νλ‘κ·Έλλ°μμμ lifting κ°λ μΌλ‘ λ°μλ€μΌ μ μμ΅λλ€.
-
μ€μ ν¨μλ‘ μμ±λ ν¨μ $f$μ μμ©νμ¬ μλ‘μ΄ ν¨μ ννλ₯Ό μμ±νλ―λ‘ Source code transformation, Operator overloading νΉμ Multiple dispatch ννλ‘ μ΄ν΄ν μ μμ΅λλ€.
μ΄μ²λΌ λ€μν λ°©μμΌλ‘ ν΄μν μ μμ§λ§ μ μμ μλ―Έλ νλλ‘ κ·κ²°λλλ°, λ°λ‘ “μ λ°©ν₯ μλλ―ΈλΆ"μ ννν μμ΄λΌλ κ²μ λλ€. λ¨μν μΌμ°¨νκΉμ§ ννν ν μΌλ¬ κΈμκ° μ΄λ»κ² λ―ΈλΆμ νννλμ§ μμνμ€ν λ νλμ μμλ₯Ό λ€μ΄λ΄ μλ€. μμλ‘λ μμ£Ό κ°λ¨ν ν¨μμΈ $v = \sin u$λ₯Ό μ¬μ©νκ² μ΅λλ€.
1.1. μμ: Sin ν¨μ μλλ―ΈλΆ
$$ \begin{aligned} &\begin{aligned} v \mathrel{\rhd} \overline{v} &= \vec{\mathcal{J}}\sin (u \mathrel{\rhd} \overline{u}) \\ &= \sin u \mathrel{\rhd} (\cos u) \overline{u} \end{aligned} \\ \therefore ~ &v = \sin u,\quad \overline{v} = (\cos u) \overline{u} \end{aligned} $$
μ΄λ‘μ¨ $v = \sin u$μ λν¨μλ $\overline{v} = (\cos u) \overline{u}$μ΄λΌλ κ²°κ³Όλ₯Ό μ»μμ΅λλ€. μ΄λ μ°λ¦¬κ° νν μ¬μ©νλ μ°μ λ²μΉ(Chain rule)κ³Ό μΌλ§₯μν΅νλ―λ‘ μ¬λ°λ₯Έ κ³μ°μμ μ μ μμ΅λλ€. νμ§λ§, μΈλ» 보면 $\sin u$μ λν¨μλ₯Ό $\cos u$λ‘ μλ € μ€ λ€μ κ³μ°μ ν μ μ΄λ κΈ°νΈλ―ΈλΆκ³Ό 무μμ΄ λ€λ₯Έμ§ μμν μ μμ΅λλ€. μ΄λ μ§μ μ½λλ₯Ό μμ±ν΄λ³΄λ©΄ μ΄ν΄ν μ μμ΅λλ€.
#[derive(Debug, Copy, Clone)]
struct Dual {
x: f64,
dx: f64,
}
trait Sin {
fn sin_(self) -> Self;
}
impl Sin for f64 {
fn sin_(self) -> Self {
self.sin()
}
}
impl Sin for Dual {
fn sin_(self) -> Self {
Dual {
x: self.x.sin(),
dx: self.dx * self.x.cos(),
}
}
}
fn main() {
let u = Dual { x: 1.0, dx: 1.0 }; // x at x=1
let v = u.sin_();
println!("v: {}, dv: {}", v.x, v.dx);
// sin(1) = 0.8414..
// sin'(x) = cos(x) = cos(1) = 0.5403..
let w = v.sin_();
println!("v: {}, dv: {}", v.x, v.dx);
// sin(sin(1)) = 0.7456..
// (sin(sin(x)))' = cos(sin(1)) * cos(1) = 0.3600..
}
Rustλ₯Ό μ΄μ©νμ¬ κ°λ¨ν μ΄μμ ꡬ쑰체λ₯Ό ꡬννκ³ μ€μμ μ΄μμ λͺ¨λμ μ μ©λλ Sin
μ΄λΌλ trait
λ₯Ό μμ±νμ¬ Method overloadingμ μ΄μ©νμ¬ μλλ―ΈλΆμ ꡬνν΄λ³΄μμ΅λλ€.
main
ν¨μμ 첫λ²μ§Έ μμλ₯Ό 보면 $u = 1 \mathrel{\rhd} 1$λ‘ μ μλ κ²μ λ³Ό μ μλλ°, μ΄λ κ°μ΄ 1μ΄κ³ λν¨μκ° 1μ΄λΌλ μλ―Έμ΄λ―λ‘ $x$λ₯Ό ννν κ²μΌλ‘ λ³Ό μ μμ΅λλ€.
μ΄μμμ sin_
ν¨μ μ체μ λν¨μ κ³μ°μ΄ ν¬ν¨λμ΄μμΌλ―λ‘ let v = u.sin_();
λΌλ μ λ§μΌλ‘ μ΄λ―Έ ν¨μ«κ°κ³Ό λν¨μ«κ°μ΄ κ³μ°λκ³ μ΄λ v.x
μ v.dx
λ‘ μ μ₯λ©λλ€.
μ΄λ κ² κ³μ°λ λν¨μμλ λΆλμμμ μ€μ°¨λ₯Ό μ μΈν λ€λ₯Έ μ€μ°¨λ μ‘΄μ¬νμ§ μμΌλ©° κ³μ° λΉμ©λ λ¨μν κ³±νκΈ° ν λ²κ³Ό μ½μ¬μΈ νλ²μ κ³μ°νκ² μ λΆμ
λλ€.
λ λ²μ§Έ μμλ₯Ό 보면 μλλ―ΈλΆμ μμ²λ μ±λ₯μ κ°λ ν μ μλλ°, μμ κ³μ°ν v
μ νλ² λ sin_
μ μ·¨νμ¬ w
λ₯Ό μ μνμμ΅λλ€.
μ¦, $w = \sin(\sin(u))$μΈλ°, ν¨μκ° λ³΅μ‘ν΄μ§κ²κ³Ό κ΄κ³μμ΄ κ³μ° μ½λλ λμΌν κ²μ λ³Ό μ μμ΅λλ€.
κ·Έλ κ² κ³μ°λ κ²°κ³Όλ λλκ²λ ν©μ±ν¨μμ κ°κ³Ό λν¨μλ₯Ό μ νν κ³μ°ν΄λ΄λ κ²μ λ³Ό μ μμ΅λλ€.
λ°λΌμ μ λ°©ν₯ μλλ―ΈλΆμ μ΄μ©νλ©΄ μμ£Ό κ°λ¨ν λν¨μ μ ν κ·μΉμ λͺ
μν΄λλ κ²λ§μΌλ‘ 볡μ‘νκ² ν©μ±λ ν¨μλ₯Ό λ§€μ° μ μ λΉμ©μΌλ‘ κ³μ°ν μ μλ€λ κ²μ λ³Ό μ μμ΅λλ€.
2. μ λ°©ν₯ μλλ―ΈλΆ κ΅¬ν
μμ²λΌ μλλ―ΈλΆμ ν¨μμ ννμ μκ΄μμ΄ μλνλ μμΉλ―ΈλΆκ³Όλ λ€λ₯΄κ² κ° ν¨μμ ννλ§λ€ λν¨μμ μ ν κ·μΉμ λͺ μν΄μ€μΌν©λλ€. λ°λΌμ μ΄λ²μλ μ¬μΉμ°μ°μ ν¬ν¨νμ¬ λνμ μΈ ν¨μ λͺ κ°μ§μ λν΄ μλλ―ΈλΆμ ꡬνν΄λ³΄λλ‘ νκ² μ΅λλ€.
2.1. μ¬μΉμ°μ°
$w = u \pm v$λ‘ μ μλ $w$μ λν΄μ μκΉμ λ§μ°¬κ°μ§λ‘ μλλ―ΈλΆμ μνν΄λ΄ μλ€.
$$ \begin{aligned} &\begin{aligned} w \mathrel{\rhd} \overline{w} &= u \mathrel{\rhd} \overline{u} + v \mathrel{\rhd} \overline{v} \\ &= (u + v) \mathrel{\rhd} (\overline{u} + \overline{v}) \end{aligned} \\ \therefore ~ &w = u + v,\quad \overline{w} = \overline{u} + \overline{v} \end{aligned} $$
λ§μ°¬κ°μ§λ‘ μ΄λ²μ $w = u \times v$μ μλλ―ΈλΆμ μ μ©ν΄λ΄ μλ€.
$$ \begin{aligned} &\begin{aligned} w \mathrel{\rhd} \overline{w} &= (u \mathrel{\rhd} \overline{u}) \times (v \mathrel{\rhd} \overline{v}) \\ &= (u + \overline{u}\epsilon) \times (v + \overline{v}\epsilon) \\ &= uv + (u \overline{v} + \overline{u}v)\epsilon \\ &= (u \times v) \mathrel{\rhd} (u\overline{v} + \overline{u}v) \end{aligned} \\ \therefore ~ &w = u \times v,\quad \overline{w} = u\overline{v} + \overline{u}v \end{aligned} $$
μ λ κ²°κ³Όλ κ°κ° μ°λ¦¬κ° μ΅ν μκ³ μλ λ―ΈλΆμ μ νμ±κ³Ό λΌμ΄νλμΈ κ·μΉκ³Ό μ νν λ€μ΄λ§μ΅λλ€.
μ΄λ₯Ό μμμ μ μν Dual
ꡬ쑰체μ μ μ©ν΄λ΄
μλ€.
use std::ops::{Add, Sub, Mul};
impl Add for Dual {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
dx: self.dx + rhs.dx,
}
}
}
impl Sub for Dual {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
x: self.x - rhs.x,
dx: self.dx - rhs.dx,
}
}
}
impl Mul for Dual {
type Output = Self;
fn mul(self, rhs: Self) -> Self {
Self {
x: self.x * rhs.x,
dx: self.x * rhs.dx + self.dx * rhs.x,
}
}
}
fn main() {
let u = Dual { x: 1f64, dx: 1f64 }; // x at x=1
let v = Dual { x: 2f64, dx: 4f64 }; // 2x^2 at x=1
let w = u + v;
println!("w: {}, dw: {}", w.x, w.dx);
// w: 3, dw: 5
let w = u * v;
println!("w: {}, dw: {}", w.x, w.dx);
// w = 2x^3 at x=1 = 2
// dw = 6x^2 at x=1 = 6
}
Β
2.2. μ§μ, λ‘κ·Έ, λ€ν ν¨μ
λ€μμΌλ‘λ μ§μ λ‘κ·Έ ν¨μμ λνμ μΈ ν¨μλ€μΈ $y=e^x,\,y=\ln x$μ λ€νν¨μμΈ $y=x^n$μ λν΄μ μλλ―ΈλΆμ μνν΄λ΄ μλ€.
-
μ§μν¨μ $$ \begin{aligned} &\begin{aligned} v \mathrel{\rhd} \overline{v} &= \exp(u \mathrel{\rhd} \overline{u}) \\ &= e^u \mathrel{\rhd} e^{u} \overline{u} \end{aligned} \\ \therefore ~ &v = e^u,\quad \overline{v} = e^{u} \overline{u} \end{aligned} $$
-
λ‘κ·Έν¨μ $$ \begin{aligned} &\begin{aligned} w \mathrel{\rhd} \overline{w} &= \ln(u \mathrel{\rhd} \overline{u}) \\ &= \ln u \mathrel{\rhd} \frac{\overline{u}}{u} \end{aligned} \\ \therefore ~ &w = \ln u,\quad \overline{w} = \frac{\overline{u}}{u} \end{aligned} $$
-
λ€νν¨μ $$ \begin{aligned} &\begin{aligned} w \mathrel{\rhd} \overline{w} &= (u \mathrel{\rhd} \overline{u})^n \\ &= u^n \mathrel{\rhd} n u^{n-1} \overline{u} \end{aligned} \\ \therefore ~ &w = u^n,\quad \overline{w} = n u^{n-1} \overline{u} \end{aligned} $$
μμ ꡬνν sin
ν¨μμ κ°μ΄ λ€λ₯Έ μΌκ°ν¨μλ€λ λͺ¨λ ꡬννμ¬ νλμ trait
μ μ μΈνλ©΄ λ€μκ³Ό κ°μ΅λλ€.
trait Ops {
fn exp(self) -> Self;
fn ln(self) -> Self;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn tan(self) -> Self;
fn powi(self, n: i32) -> Self;
}
impl Ops for Dual {
fn exp(self) -> Self {
Self {
x: self.x.exp(),
dx: self.x * self.dx.exp(),
}
}
fn ln(self) -> Self {
Self {
x: self.x.ln(),
dx: self.dx / self.x,
}
}
fn sin(self) -> Self {
Self {
x: self.x.sin(),
dx: self.x.cos() * self.dx,
}
}
fn cos(self) -> Self {
Self {
x: self.x.cos(),
dx: -self.x.sin() * self.dx,
}
}
fn tan(self) -> Self {
let tan = self.x.tan();
Self {
x: tan,
dx: self.dx * (tan * tan + 1.0),
}
}
fn powi(self, n: i32) -> Self {
Self {
x: self.x.powi(n),
dx: n as f64 * self.x.powi(n - 1) * self.dx,
}
}
}
Β
2.3. μκ·Έλͺ¨μ΄λ ν¨μ
μμ μλ ν¨μλ€μ λͺ κ°μ§ μ°μ° ꡬνμ λνλ©΄ λ³λλ‘ μκ·Έλͺ¨μ΄λ ν¨μμ μ νλ°©λ²μ ꡬννμ§ μλλΌλ μκ·Έλͺ¨μ΄λ ν¨μμ λν μλλ―ΈλΆμ κ³μ°ν μ μμ΅λλ€.
trait Sigmoid: Sized
+ Ops
+ Neg<Output=Self>
+ Add<f64, Output=Self>
where
f64: Div<Self, Output=Self> {
fn sigmoid(self) -> Self {
1f64 / ((-self).exp() + 1f64)
}
}
impl Sigmoid for Dual {}
fn main() {
let u = Dual { x: 1.0, dx: 1.0 }; // x at x=1
let z = u.sigmoid();
println!("z: {}, dz: {}", z.x, z.dx);
// sigmoid(1), sigmoid'(x) = sigmoid(1) * (1 - sigmoid(1))
}
μ£Όμ: μμ μκΈ°ν μ½λμΈμλ
f64
μμ μ°μ°μ΄ μΆκ°μ μΌλ‘ μ μλμ΄μΌ μλνλ μ½λμ λλ€. μ€μ λ‘ μ΄ μ½λλ₯Ό μ€ννκ³ μΆλ€λ©΄ λ€μ λ§ν¬λ₯Ό μ°Έκ³ νμΈμ.
λ§μΉλ©°
μ§κΈκΉμ§ μ΄μμλ₯Ό μ΄μ©ν μ λ°©ν₯ μλλ―ΈλΆμ λν΄μ μμ보μμ΅λλ€. μ½κ² μ€λͺ νκΈ° μν΄μ κ΅μ₯ν κ°λ¨ν κ²½μ°μ λν΄μλ§ λ€λ€λλ°, μ€μ λ‘ μ μλλλ μλλ―ΈλΆ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ§λ€κΈ° μν΄μλ λ€μκ³Ό κ°μ μ¬νλ€μ κ³ λ €ν΄μΌν©λλ€.
-
κ³ κ³ λν¨μμ λν μλλ―ΈλΆ
-
λ€λ³μ ν¨μμ λν μλλ―ΈλΆ
-
νλ ¬κ³Ό λ²‘ν° λ³μλ₯Ό ν¬ν¨ν ν¨μμ μλλ―ΈλΆ
μ΄ μ€ μ²« 2κ°μ§ μ¬νμ λν΄μλ Rust μμΉκ³μ° λΌμ΄λΈλ¬λ¦¬μΈ Peroxideμ μ ꡬνλμ΄ μμΌλ―λ‘ μ°Έκ³ νμλ©΄ λ©λλ€. λ§μ§λ§ μ¬νμ λν΄μλ μλ°©ν₯ μλλ―ΈλΆκ³Ό ν¨κ» λ€μ κΈμμ λ€λ£¨λλ‘ νκ² μ΅λλ€.
μ°Έκ³ λ¬Έν
-
Axect, Peroxide, Github
-
Barak A. Pearlmutter, Automatic Differentiation: History and Headroom