DL for Differential Equations
Deep Learning · PyTorch · Scientific ML

Deep Learning สำหรับแก้สมการเชิงอนุพันธ์

คู่มือตั้งแต่พื้นฐานของ model ไปจนถึงการเขียน PyTorch เพื่อแก้ ODE และการนำ model ที่ train แล้วกลับมาใช้ใหม่ด้วย Transfer Learning ทุกหัวข้อมีตัวอย่างให้ลองปรับค่าได้

9 หัวข้อ ตัวอย่างโค้ด PyTorch กราฟจากการ train จริง
1

Input → Model → Output

ภาพรวมของทุก model ใน Machine Learning

ทุก model ทำงานเหมือนฟังก์ชันตัวหนึ่ง คือรับ Input เข้าไป คำนวณด้วยค่า parameter ที่อยู่ข้างใน แล้วให้ Output ออกมา งานแต่ละแบบต่างกันแค่รูปแบบของ Input, ชนิดของ Model และความหมายของ Output

\[ \hat{y} = f_{\theta}(x) \]
\(x\) = input, \(f_\theta\) = model ที่มี parameter \(\theta\) (weight และ bias), \(\hat y\) = output ที่ model ทำนาย
Interactiveเลือกตัวอย่างงาน แล้วกดที่กล่องเพื่อดูรายละเอียด
i

Shape ของข้อมูลสำคัญมาก ใน PyTorch มิติแรกจะเป็นจำนวนตัวอย่าง (batch) เสมอ เช่น [N, 1] คือมี N จุด แต่ละจุดมี 1 ค่า ถ้า shape ของ input ไม่ตรงกับที่ model รับ โค้ดจะ error ทันที

2

Objective Function สำหรับแต่ละงาน

ตัวเลขที่บอกว่า model ทำนายผิดมากแค่ไหน

Objective function หรือที่นิยมเรียกว่า Loss function คือตัวเลขตัวเดียวที่วัดว่า output ของ model ห่างจากสิ่งที่ต้องการแค่ไหน การ train คือการปรับ parameter \(\theta\) ให้ค่านี้ต่ำที่สุด

\[ \theta^{*} = \arg\min_{\theta} \; \mathcal{L}(\theta) \]

งานต่างกันต้องใช้ loss ต่างกัน เลือกแท็บด้านล่างเพื่อดูสูตร ตัวอย่างโค้ด และลองปรับค่าเพื่อดูว่า loss เปลี่ยนอย่างไร

InteractiveLoss แต่ละแบบ

ใช้เมื่อ output เป็นตัวเลขต่อเนื่อง เช่น ราคา อุณหภูมิ หรือค่า u(t) ที่มี data จริงให้เทียบ

\[ \mathcal{L}_{\text{MSE}} = \frac{1}{N}\sum_{i=1}^{N}\left(\hat{y}_i - y_i\right)^2 \]
ข้อมูลและเส้นที่ทำนาย
ค่า MSE เมื่อเปลี่ยน w
MSE ตอนนี้
–
w ที่ดีที่สุด
–

เส้นประแนวตั้งในกราฟซ้ายคือความผิดพลาดของแต่ละจุด MSE คือค่าเฉลี่ยของความยาวเส้นเหล่านี้ยกกำลังสอง ลองเลื่อนให้ MSE ต่ำที่สุด

สรุป: งานแบบไหนใช้ loss อะไร

งานOutputLossPyTorch
Regressionตัวเลขต่อเนื่องMSEnn.MSELoss()
Regression ที่ data มี outlierตัวเลขต่อเนื่องMAE / Hubernn.L1Loss(), nn.HuberLoss()
Classification 2 กลุ่มความน่าจะเป็น 1 ค่าBinary cross-entropynn.BCEWithLogitsLoss()
Classification หลายกลุ่มความน่าจะเป็นของแต่ละกลุ่มCross-entropynn.CrossEntropyLoss()
PINN (รู้สมการ)u(t) หรือ u(x, t)Residual + IC/BC (+ data)เขียนเองด้วย torch.autograd.grad
Neural ODE (มี data ตามเวลา)Trajectory y(t)MSE ของ trajectoryodeint + nn.MSELoss()
Neural Operatorคำตอบทั้งฟังก์ชันRelative L2เขียนเอง หรือ neuralop.losses.LpLoss
3

การเลือก Model: จาก ML ถึง DL

ไม่จำเป็นต้องใช้ Deep Learning ทุกงาน

Model มีตั้งแต่แบบง่ายที่อธิบายได้ชัดเจนและใช้ data น้อย ไปจนถึงแบบซับซ้อนที่เรียนรู้ได้ละเอียดแต่ต้องใช้ data และเวลา train มากกว่า การเลือกให้ดูที่ ชนิดของข้อมูล, ปริมาณข้อมูล และ สิ่งที่รู้อยู่แล้วเกี่ยวกับปัญหา เช่น รู้สมการหรือไม่

Machine Learning แบบดั้งเดิม · ใช้ data น้อย · อธิบายง่ายDeep Learning · ใช้ data มาก · ยืดหยุ่นสูง

กดที่การ์ดเพื่อดูรายละเอียดเพิ่ม

Interactiveตัวช่วยเลือก Model
4

ลำดับของ Model และ Layer

ลำดับที่ลอง model และลำดับของ layer ภายใน model มีผลต่อผลลัพธ์

4.1 ลำดับการลอง Model: เริ่มจากง่ายไปยาก

ควรเริ่มจาก model ที่ง่ายที่สุดก่อนเสมอ แล้วค่อยเพิ่มความซับซ้อน เหตุผลคือ

  • มีตัวเทียบ ถ้า model ใหญ่ทำได้ไม่ดีกว่า baseline แปลว่ามีอะไรผิด เช่น data มีปัญหา หรือ loss เขียนผิด
  • หาจุดผิดง่าย model เล็ก train เร็ว ทดลองได้หลายรอบ
  • ประหยัดเวลาและทรัพยากร บางงาน Random Forest ก็ได้ผลดีพอแล้ว ไม่ต้องใช้ GPU
ขั้นตอนลำดับที่แนะนำ

4.2 ลำดับของ Layer ภายใน Model

ใน nn.Sequential ข้อมูลจะไหลผ่าน layer ตามลำดับจากบนลงล่าง ถ้าเรียงผิด model อาจยังรันได้แต่เรียนรู้ได้ไม่ดี หลักที่ใช้บ่อยคือ Linear → Activation → Linear → Activation → … → Linear ลองเรียง layer ของ PINN ด้านล่าง แล้วดูผลการตรวจทางขวา

Interactiveจัดลำดับ Layer ของ PINN (input = t, output = u(t))
ตัวอย่าง:
input t → [N, 1]
output → [N, 1]
ผลการตรวจ
5

Perceptron: สูตรของ Neuron และการหา Parameter

หน่วยที่เล็กที่สุดของ Deep Learning

Neuron หนึ่งตัวรับ input หลายค่า คูณแต่ละค่าด้วย weight \(w\) รวมกันแล้วบวก bias \(b\) จากนั้นส่งผ่าน activation function \(\sigma\) เพื่อให้ model เรียนรู้ความสัมพันธ์ที่ไม่ใช่เส้นตรงได้

\[ z = \sum_{i=1}^{n} w_i x_i + b = \mathbf{w}^\top\mathbf{x} + b, \qquad \hat{y} = \sigma(z) \]
Interactiveลองปรับค่าใน Neuron
กราฟ activation และตำแหน่งของ z

Objective: หาค่า w และ b ที่ดีที่สุด

ตอนเริ่มต้น weight และ bias เป็นค่าสุ่ม การ train คือการหาค่าที่ทำให้ loss ต่ำที่สุด โดยใช้ Gradient Descent คือคำนวณว่าถ้าขยับ parameter แต่ละตัวเล็กน้อย loss จะเปลี่ยนไปทางไหน (gradient) แล้วขยับไปทางตรงข้ามเพื่อให้ loss ลดลง

\[ w \leftarrow w - \eta\,\frac{\partial \mathcal{L}}{\partial w}, \qquad b \leftarrow b - \eta\,\frac{\partial \mathcal{L}}{\partial b} \]
\(\eta\) คือ learning rate ใช้กำหนดว่าจะขยับครั้งละมากแค่ไหน ใน PyTorch คำนวณ gradient ให้อัตโนมัติด้วย loss.backward()
InteractiveGradient Descent หาค่า w, b ของ \(\hat y = wx + b\)
ข้อมูลและเส้นของ model
Loss (MSE) ในแต่ละ step
Step
0
w (คำตอบ ≈ 2)
0
b (คำตอบ ≈ 1)
0
Loss
–

ลองตั้ง learning rate ให้สูงกว่า 0.8 แล้วกดเริ่ม loss จะไม่ลดลงแต่จะเพิ่มขึ้นเรื่อย ๆ เพราะขยับครั้งละมากเกินจนข้ามจุดต่ำสุดไป

i

จาก 1 neuron สู่ Deep Learning ถ้าเอา neuron หลายตัวมาวางเป็นชั้นเดียวกันจะได้ nn.Linear และถ้าเอาหลายชั้นมาต่อกันโดยมี activation คั่นจะได้ neural network แบบลึก (Deep) หลักการหา parameter ยังเหมือนเดิมทุกอย่าง แค่จำนวน parameter มากขึ้น

6

สร้าง Model ใน Deep Learning

5 ส่วนที่ต้องมีทุกครั้งใน PyTorch

1. Data

เตรียม input และ target ให้อยู่ในรูป torch.Tensor พร้อม shape ที่ถูกต้อง

2. Model

สร้าง class ที่สืบทอดจาก nn.Module กำหนด layer ใน __init__ และการคำนวณใน forward

3. Loss

เลือก objective function ให้ตรงกับงาน (ดูหัวข้อ 2)

4. Optimizer

ตัวปรับ parameter เช่น Adam, SGD หรือ LBFGS

5. Training loop

วนทำ forward → คำนวณ loss → backward → update ซ้ำหลายรอบ

6. Evaluate

ทดสอบกับข้อมูลที่ไม่เคยเห็น แล้วบันทึก model ด้วย torch.save

Interactiveสร้าง MLP แล้วดูโค้ดและจำนวน parameter

จำนวน parameter ของ nn.Linear(a, b) คือ \((a+1)\times b\) มาจาก weight \(a\times b\) ตัว บวก bias \(b\) ตัว

Training loop มาตรฐาน

โครงนี้ใช้ได้กับเกือบทุกงาน สิ่งที่เปลี่ยนคือ model, loss และวิธีเตรียมข้อมูล

7

ตัวอย่าง Model สำหรับแก้สมการเชิงอนุพันธ์

4 แนวทางหลัก และตัวอย่างการ train PINN จริง
PINNรู้สมการ
Input
จุดเวลา t (หรือ x, t)
Output
u(t)
Loss
Residual ของสมการ + IC/BC
เหมาะกับ
แก้สมการครั้งเดียว ไม่มี data หรือมีน้อย
Neural ODEมี data
Input
สถานะเริ่มต้น y₀ และเวลา
Output
Trajectory y(t)
Loss
MSE เทียบกับ data
เหมาะกับ
ไม่รู้สมการ อยากเรียนรู้ dynamics จาก data
DeepONetแก้ซ้ำหลายครั้ง
Input
ฟังก์ชัน input (branch) + ตำแหน่ง (trunk)
Output
ค่าของคำตอบที่ตำแหน่งนั้น
Loss
MSE เทียบกับ solver
เหมาะกับ
เปลี่ยน parameter หรือเงื่อนไขบ่อย
FNOแก้ซ้ำหลายครั้ง
Input
ฟังก์ชันบน grid เช่น u₀(x)
Output
คำตอบบน grid เดียวกัน
Loss
Relative L2
เหมาะกับ
PDE บน grid เช่น การไหลของของไหล

โจทย์ตัวอย่าง: การสั่นแบบมีแรงหน่วง

ใช้สมการของสปริงที่มีแรงเสียดทาน (damped harmonic oscillator) โดย \(\zeta\) คืออัตราส่วนแรงหน่วง และ \(\omega\) คือความถี่ธรรมชาติ

\[ u'' + 2\zeta\omega\,u' + \omega^2 u = 0, \qquad u(0)=1,\; u'(0)=0 \]
Interactiveลองเปลี่ยน ζ และ ω เพื่อดูคำตอบของสมการ

ดูการ train PINN จริงทีละช่วง

ข้อมูลด้านล่างมาจากการ train PINN ด้วย PyTorch จริงที่ \(\zeta=0.2,\ \omega=3\) จำนวน 8,000 step (MLP 3 hidden layer, 32 neuron, Tanh, Adam lr = 0.001) บันทึกผลทุก 100 step ลองเลื่อนหรือกดเล่นเพื่อดูว่า model ค่อย ๆ เรียนรู้คำตอบอย่างไร

ข้อมูลจริงการ train PINN ทีละ step
คำตอบของ model เทียบกับคำตอบจริง
Loss ระหว่าง train
Step
0
Total loss
–
Max error
–

สังเกตว่า model เรียนรู้ช่วงต้นของโดเมน (t ใกล้ 0) ได้ก่อน เพราะ initial condition อยู่ตรงนั้น แล้วค่อยขยายความถูกต้องไปทางขวา

8

โค้ด PyTorch: Model อยู่ตรงไหน

โค้ดเต็มของ PINN แบ่งเป็นส่วน ๆ

กดปุ่มด้านล่างเพื่อไฮไลต์แต่ละส่วนของโค้ด ปุ่ม เรียกใช้ Model จะแสดงทุกบรรทัดที่ส่งข้อมูลเข้า model (forward pass)

i

สรุปสั้น ๆ model คือ object model = PINN() ที่เก็บ parameter ทั้งหมด ส่วนที่เหลือของโค้ดคือการเตรียมจุด การคำนวณ loss และการสั่งให้ optimizer ปรับ parameter ของ model นั้น ดู parameter ทั้งหมดได้ด้วย model.parameters() หรือ model.state_dict()

9

Transfer Learning

เอา model ที่ train แล้วมาใช้กับโจทย์ใหม่

Transfer Learning คือการนำ parameter ของ model ที่ train กับโจทย์หนึ่งแล้ว มาเป็นจุดเริ่มต้นของโจทย์ใหม่ที่คล้ายกัน แทนที่จะเริ่มจากค่าสุ่ม ทำให้ train เร็วขึ้นและมักได้ผลดีกว่า โดยเฉพาะเมื่อโจทย์ใหม่มี data น้อยหรือเรียนรู้ยาก

ผลการทดลองจริง: จาก ω = 3 ไป ω = 4

นำ PINN ที่ train กับ \(\omega=3\) (หัวข้อ 7) มาใช้กับโจทย์ใหม่ \(\omega=4\) แล้วเทียบ 3 แบบ โดย train เท่ากันแบบละ 3,000 step

ข้อมูลจริงเปรียบเทียบการเริ่มจากศูนย์กับ Transfer Learning
Max error ระหว่าง train (ยิ่งต่ำยิ่งดี)
คำตอบหลัง train 3,000 step

กดที่ชื่อใน legend เพื่อซ่อนหรือแสดงแต่ละเส้น

วิธีทำอย่างไรMax error ที่ step 1,000Max error ที่ step 3,000

วิธีทำ Transfer Learning ใน PyTorch

วิธีที่ง่ายที่สุด โหลด parameter ทั้งหมดแล้ว train ต่อด้วย loss ของโจทย์ใหม่ ใช้เมื่อโจทย์ใหม่คล้ายของเดิมมาก

หา Model และ Data ที่ train แล้วได้จากที่ไหน

บน Kaggle Models และ Kaggle Datasets มีทั้ง model และ data ที่คนอื่นอัปโหลดไว้ ลองค้นด้วยคำว่า PDE, Navier-Stokes, Burgers หรือ PINN ใช้ library kagglehub ดาวน์โหลดได้โดยตรง รูปแบบชื่อของ model คือ owner/model/framework/variation

!

ก่อนโหลด weight ต้องสร้าง model ให้มีโครงสร้างเหมือนต้นฉบับทุกอย่าง (จำนวน layer, จำนวน neuron, activation) ให้อ่านคำอธิบายหรือ notebook ของเจ้าของ model ก่อน และโหลดไฟล์จากแหล่งที่เชื่อถือได้เท่านั้น เพราะไฟล์ .pt อาจมีโค้ดแฝงได้ ควรใช้ weights_only=True เสมอ

เทคนิค Transfer Learning อื่น ๆ ที่ควรรู้

Curriculum learning

เริ่มจากโจทย์ง่ายแล้วค่อยยากขึ้น เช่น ω = 1 → 2 → 4 → 8 แต่ละรอบใช้ model จากรอบก่อนเป็นจุดเริ่ม ช่วยได้มากกับโจทย์ที่สั่นเร็วหรือโดเมนยาว ซึ่ง PINN มักเรียนรู้ยาก

Pretrain ด้วย data แล้ว fine-tune ด้วยสมการ

train ด้วย data จาก numerical solver ก่อน (supervised) แล้วค่อย fine-tune ด้วย physics loss ทำให้เริ่มจากคำตอบที่ใกล้เคียงแล้ว

Feature extraction

ใช้ model ที่ pretrain แล้วเป็นตัวแปลง input เป็น feature โดยไม่ train ต่อเลย แล้ว train แค่ส่วนหัวเล็ก ๆ ที่ต่อท้าย เหมาะเมื่อ data น้อยมาก

Foundation model

model ขนาดใหญ่ที่ pretrain กับ PDE หลายชนิด เช่น Poseidon นำมา fine-tune กับโจทย์เฉพาะได้โดยใช้ data น้อยกว่าการเริ่มจากศูนย์มาก

!

ข้อควรระวัง การ normalize input ต้องเหมือนตอน pretrain เช่น ถ้าตอนแรกหาร t ด้วย 5 ตอน fine-tune ก็ต้องหารด้วย 5 เหมือนเดิม และถ้าโจทย์ใหม่ต่างจากเดิมมาก (เช่น สมการคนละแบบ) transfer learning อาจไม่ช่วย หรือแย่กว่าเริ่มจากศูนย์ ควรเทียบผลกับการ train จากศูนย์เสมอ

·

แหล่งอ้างอิง

Paper ต้นฉบับและ library ที่ใช้
  • Raissi, Perdikaris, Karniadakis (2019). Physics-informed neural networks. J. Comput. Phys. — arXiv:1711.10561
  • Chen et al. (2018). Neural Ordinary Differential Equations. NeurIPS — arXiv:1806.07366
  • Lu et al. (2021). Learning nonlinear operators via DeepONet. Nature Machine Intelligence — arXiv:1910.03193
  • Li et al. (2021). Fourier Neural Operator for Parametric PDEs. ICLR — arXiv:2010.08895
  • Herde et al. (2024). Poseidon: Efficient Foundation Models for PDEs. NeurIPS — arXiv:2405.19101
  • Takamoto et al. (2022). PDEBench: An Extensive Benchmark for Scientific Machine Learning. NeurIPS — GitHub
  • Library: torchdiffeq · DeepXDE · neuraloperator · kagglehub