- การวัดตำแหน่งและความเร็วในโลกจริงมีความสั่นไหวอยู่เสมอ ดังนั้นจึงอาจเข้าใจ Kalman filter ได้ว่าเป็นวิธีรวม แหล่งข้อมูลที่ไม่สมบูรณ์หลายแหล่ง เพื่อสร้างค่าประมาณสถานะที่เชื่อถือได้มากกว่า
- ในตัวอย่างตำแหน่งของเรือ โมเดลที่สมมติว่าเครื่องยนต์วิ่งด้วยความเร็ว 10m/s อาจคลาดเคลื่อนเพราะลมและคลื่น ขณะที่ เซนเซอร์ อย่าง GPS ก็ไม่แม่นยำเสมอไปเพราะมี noise หรือเหตุขัดข้อง
- โค้ดตัวอย่างใช้ผู้โดยสาร 1000 คน โดยแต่ละคนสร้างทั้งค่าประมาณจากความเร็วและค่าที่วัดจากเซนเซอร์ แล้วนำสองค่านี้มารวมกันด้วย ค่าเฉลี่ยถ่วงน้ำหนัก เพื่ออธิบาย intuition ของ Kalman filter
- ความน่าเชื่อถือของแหล่งข้อมูลคำนวณจาก ความแปรปรวน ของค่าที่วัดได้ โดยฝั่งที่ผันผวนมากจะถูกเชื่อน้อยกว่า และฝั่งที่สม่ำเสมอกว่าจะถูกให้น้ำหนักมากกว่าด้วย
1/variance
- เมื่อเซนเซอร์ทำงานปกติ ระบบจะให้น้ำหนักกับค่าเซนเซอร์มากกว่า แต่ในช่วงที่สั่นไหวอย่าง
t=3 และ t=6 อิทธิพลของมันจะลดลงโดยอัตโนมัติ ทำให้ยังรักษาค่าประมาณที่เสถียรกว่าไว้ได้
สถานการณ์ที่ต้องใช้ Kalman filter
- Kalman filter มองได้เหมือนกรวยที่บีบอัด แหล่งข้อมูลที่มี noise หลายแหล่ง ให้กลายเป็นค่าสถิติเดียวที่แม่นยำขึ้น
- ในเชิงคณิตศาสตร์เกี่ยวข้องกับพีชคณิตเชิงเส้น ความน่าจะเป็น และแคลคูลัส แต่ที่นี่จะเน้น intuition มากกว่าทฤษฎีเต็มรูปแบบ
- สมมติว่าเรือออกจากท่าเรือที่
x=0 แล้วเคลื่อนที่ในหนึ่งมิติ โดยเครื่องยนต์ให้ความเร็วคงที่ 10m/s
- ถ้าเป็นโลกอุดมคติ ตำแหน่งหลัง 2 วินาทีจะเป็น
2 * 10 = 20m แต่ในโลกจริง ความเร็วและตำแหน่งจะไม่คงที่เป๊ะเพราะเครื่องยนต์ ลม และคลื่น
- ดังนั้นจึงยากที่จะมั่นใจในตำแหน่งจริงของเรือหากอาศัยเพียงสูตรตำแหน่งอย่างเดียว
เซนเซอร์ก็ไม่ได้สมบูรณ์แบบ
- หากมี เซนเซอร์ อย่าง GPS ก็สามารถวัดตำแหน่ง ณ ช่วงเวลาหนึ่งได้โดยตรง แต่ค่าที่เซนเซอร์วัดได้ก็ไม่ได้ถูกต้องเสมอไป
- GPS อาจให้ค่าใกล้กับตำแหน่งจริงอย่าง 29.998m หรือ 30.002m ในเวลา 3 วินาที แต่บางครั้งก็อาจให้ค่าคลาดเคลื่อนมากอย่าง 100m ได้ แม้จะเกิดไม่บ่อย
- ในพื้นที่ที่ไม่มีสัญญาณครอบคลุมจากดาวเทียม GPS ก็อาจใช้งานไม่ได้แทบทั้งหมด
- ถ้าเซนเซอร์ไม่เคยออฟไลน์เลยและสามารถวัดค่าอะไรก็ได้ด้วยความแม่นยำตามต้องการ ก็ไม่จำเป็นต้องมี Kalman filter
- Kalman filter สามารถรวมหลายแหล่งข้อมูล เช่น การประมาณตำแหน่งจากความเร็ว, การประมาณจาก GPS, เรดาร์ หรือโซนาร์ เพื่อคาดคะเนตำแหน่งได้แม่นยำขึ้น
การประมาณตำแหน่งผ่านโค้ด
- ตัวอย่างนี้สมมติว่ามีผู้โดยสาร 1000 คนอยู่บนเรือ และแต่ละคนมีอุปกรณ์ GPS ของตัวเอง
- ผู้โดยสารแต่ละคนจะเริ่มจากประมาณตำแหน่งใหม่โดยใช้ตำแหน่งก่อนหน้า บวกความเร็วและความผันผวนจากปัจจัยภายนอก
from random import gauss
def new_position(last):
velocity = 10
wind = gauss(0, 2)
wave = gauss(0, 0.1)
return last + velocity + wind + wave
gauss สุ่มค่าที่อาจเป็นบวกหรือลบได้ โดยพารามิเตอร์ตัวที่สองแสดงขนาดของความผันผวน
- เพราะไม่สามารถวัดผลของลมและคลื่นได้โดยตรง ตัวอย่างนี้จึงใช้เลขสุ่มที่มีค่าเฉลี่ย 0 และส่วนเบี่ยงเบนมาตรฐาน
2 กับ 0.1 เพื่อจำลอง noise
- ในขั้นตอนที่สอง เซนเซอร์จะคืนค่าการวัดโดยนำตำแหน่งจริงมาบวกกับ noise ของเซนเซอร์
def sensor(t):
if t == 3:
# oops, passing through a thunderstorm. GPS fluctuating!
sensor_noise = gauss(5, 10)
elif t == 6:
# uh-oh, satellite unavailable!
sensor_noise = gauss(-5, 10)
else:
sensor_noise = gauss(0, 1)
return true_position[t] + sensor_noise
- ที่
t=3 เป็นการจำลองกรณี GPS แกว่งเพราะพายุฝนฟ้าคะนอง และที่ t=6 เป็นสถานการณ์ที่ไม่สามารถใช้ดาวเทียมได้
- แม้อยู่ในเวลาเดียวกัน ผู้โดยสารแต่ละคนก็จะได้ค่าที่วัดจากเซนเซอร์ต่างกัน
เส้นทางการเคลื่อนที่จริงและค่าเฉลี่ยธรรมดา
- ตำแหน่งจริงของเรือกำหนดไว้ด้วยลิสต์ต่อไปนี้
true_position = [0, 9, 19.2, 28, 38.1, 48.5, 57.2, 66.2, 77.5, 85, 95.2]
- เรือออกจากท่าเรือที่
x=0 และหลัง 1 วินาทีอยู่ที่ 9m หลัง 2 วินาทีอยู่ที่ 19.2m จากนั้นก็เคลื่อนที่ตามค่าที่อยู่ในลิสต์นี้
- เป้าหมายของผู้โดยสารคือคาดการณ์ตำแหน่งในแต่ละวินาทีให้แม่นที่สุดเท่าที่จะทำได้ จากค่าการวัดที่มี noise และไม่น่าเชื่อถือ
- ถ้าที่
t=1 ผู้โดยสารคนหนึ่งประมาณจากความเร็วได้ 9.37 และเซนเซอร์วัดได้ 8.98 ค่าเฉลี่ยธรรมดาจะเป็น 9.17
- เมื่อเทียบกับตำแหน่งจริงที่ 9m ค่าเฉลี่ยธรรมดานี้คลาดเคลื่อนน้อยกว่าค่าประมาณจากความเร็ว แต่แย่กว่าค่าที่เซนเซอร์วัดได้ในตัวอย่างนั้น
ค่าเฉลี่ยถ่วงน้ำหนักและความน่าเชื่อถือ
- วิธีที่ดีกว่าค่าเฉลี่ยธรรมดาคือใช้ ค่าเฉลี่ยถ่วงน้ำหนัก
def combine(A, B, trustA, trustB):
total_trust = trustA + trustB
return (A * trustA + B * trustB) / total_trust
combine(9.37, 8.98, 10, 1) ให้ผลเป็น 9.33 ซึ่งใกล้ 9.37 มากกว่า เพราะเชื่อค่าประมาณจากความเร็วมากกว่า
combine(9.37, 8.98, 1, 10) ให้ผลเป็น 9.01 ซึ่งใกล้ 8.98 มากกว่า เพราะเชื่อค่าที่เซนเซอร์วัดได้มากกว่า
- ค่าเฉลี่ยถ่วงน้ำหนักตามความน่าเชื่อถือ นี้คือ intuition สำคัญของ Kalman filter และเป็นแก่นของการรวมข้อมูล
- การจะเชื่อแหล่งข้อมูลใดมากกว่ากัน ตัดสินจาก ความแปรปรวน
- แหล่งข้อมูลที่ให้ข้อสรุปแกว่งมากจะน่าเชื่อถือน้อยกว่า
- แหล่งข้อมูลที่ให้ข้อสรุปสม่ำเสมอจะถูกให้น้ำหนักมากกว่า
- ถ้าสถานีวิทยุ 10 แห่งมี 4 แห่งบอกว่าฝนตกและ 6 แห่งบอกว่าท้องฟ้าโปร่ง แต่ใน 10 เว็บไซต์มีถึง 9 แห่งบอกว่าฝนตก ฝั่งเว็บไซต์จะมีความแปรปรวนต่ำกว่าและจึงน่าเชื่อถือกว่า
ขั้นตอนการอัปเดต
- การอัปเดตทั้งหมดทำโดยสร้างค่าประมาณจากความเร็วและค่าจากเซนเซอร์สำหรับผู้โดยสารแต่ละคน แล้วคำนวณความน่าเชื่อถือจากความแปรปรวนของชุดค่าทั้งสอง
from statistics import variance
def update(t, last):
velocity_updates = []
sensor_updates = []
for p in range(1000):
velocity_updates.append(new_position(last[p]))
sensor_updates.append(sensor(t))
fluctuation_velocity = variance(velocity_updates)
fluctuation_sensor = variance(sensor_updates)
trust_velocity = 1 / fluctuation_velocity
trust_sensor = 1 / fluctuation_sensor
combined = []
for p in range(1000):
combined.append(combine(
A=velocity_updates[p],
B=sensor_updates[p],
trustA=trust_velocity,
trustB=trust_sensor
))
return sensor_updates, velocity_updates, combined
- ยิ่งความแปรปรวนมาก ความน่าเชื่อถือก็ยิ่งต่ำ จึงใช้
1/variance
- ผู้โดยสารแต่ละคนอัปเดตตำแหน่งของตัวเองแยกกัน
- เมื่ออัปเดตตำแหน่งของผู้โดยสารทุกคนเสร็จแล้ว ก็สามารถอนุมานค่าประมาณตำแหน่งจริงของเรือจากค่าเฉลี่ยของตำแหน่งผู้โดยสารได้
วิธีอ่านผลลัพธ์
- ฟังก์ชัน
update_plot จะเก็บตำแหน่งจริง ค่าประมาณจากเซนเซอร์ ค่าประมาณจากความเร็ว และค่าประมาณแบบรวมของแต่ละช่วงเวลาเพื่อใช้สร้างกราฟ
- ลูปหลักจะอัปเดตการประมาณตำแหน่งต่อไปในแต่ละช่วงเวลา โดยใช้ค่าประมาณที่ดีที่สุดซึ่งผู้โดยสารมีอยู่ในขณะนั้น
- envelope รอบเส้นในกราฟหมายถึงความไม่แน่นอน โดยยิ่งกว้างก็ยิ่งแปลว่าค่านั้นมีความไม่แน่นอนสูง
- ในช่วง
t=0.75 ถึง t=1 ที่เซนเซอร์ยังทำงานปกติ ค่าประมาณตำแหน่งแบบรวมดีกว่าการใช้ค่าประมาณจากความเร็วอย่างเดียว แต่ก็อาจแย่กว่าการใช้ค่าจากเซนเซอร์อย่างเดียว
- ในช่วง
t=2 ถึง t=4 ที่เซนเซอร์เริ่มเสีย ค่าประมาณแบบรวมให้ผลดีกว่าการใช้ค่าจากเซนเซอร์ที่เสียเพียงอย่างเดียว
- เมื่อเซนเซอร์ฟื้นกลับมาในช่วง
t=4 ถึง t=5 Kalman filter ก็จะเริ่มให้น้ำหนักกับเซนเซอร์มากขึ้นอีกครั้ง
ภาคผนวก: gauss และความแปรปรวน
normal distribution function อย่าง gauss(0, 0.1) และ gauss(0, 2) มักสร้างค่าสุ่มที่อยู่ใกล้ 0
- พารามิเตอร์ตัวที่สองคือ ส่วนเบี่ยงเบนมาตรฐาน ซึ่งควบคุมว่าค่าที่วัดได้จะแกว่งมากแค่ไหน
gauss(0, 0.1) มีแนวโน้มจะให้ค่าขนาดเล็กใกล้ 0 เช่น 0.06, -0.07, 0.02
gauss(0, 2) มีแนวโน้มจะให้ค่าที่กระจายกว้างกว่า เช่น 1.05, -1.06, 1.29, -1.72
- ในโค้ดตัวอย่างนี้สมมติว่าลมมีความแปรปรวนมากกว่า ส่วนคลื่นมีความแปรปรวนน้อยกว่า
- ความแปรปรวน เป็นตัวชี้วัดความสม่ำเสมอ ยิ่งสม่ำเสมอมาก ความแปรปรวนยิ่งต่ำ และยิ่งสม่ำเสมอน้อย ความแปรปรวนยิ่งสูง
- การแจกแจงที่มีส่วนเบี่ยงเบนมาตรฐาน 2 จะมีความแปรปรวน 4 ส่วนการแจกแจงที่มีส่วนเบี่ยงเบนมาตรฐาน 0.1 จะมีความแปรปรวน 0.01
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
อ่านบทความแล้วสนุก แต่การนำไปใช้งานผิด จุดผิดพลาดที่ใหญ่ที่สุดคือ ไม่ได้เผยแพร่ความไม่แน่นอนไปตามแกนเวลา ทำให้ประเมินค่าความคลาดเคลื่อนต่ำเกินไป
เห็นได้จากกราฟด้วย โดยช่วงความคลาดเคลื่อนควรครอบคลุมสถานะจริงในเวลาส่วนใหญ่ แต่ผลลัพธ์กลับไม่เป็นเช่นนั้น
ไม่ใช่ว่าผู้โดยสารกำลังเติม noise เข้าไปในค่าประมาณ แต่จากมุมมองของผู้โดยสาร เมื่อรู้สถานะ ณ เวลา k แล้ว ค่าคาดหมายของสถานะ ณ เวลา k+1 ก็เป็นเพียง
position_k+1 = position_k + velocity * Delta_tเท่านั้น พลวัตจริงมี noise อยู่ และในตัวกรองจะสะท้อนสิ่งนี้ด้วยการบวกเข้าไปใน covariance ของค่าประมาณเหตุผลที่โค้ดไม่พังทันทีคือใช้ผู้โดยสาร 1,000 คนเพื่อสุ่มตัวอย่างพลวัตจำนวนมาก แล้วคำนวณ variance ของผลลัพธ์เชิงตัวเลข ซึ่งค่อนข้างต่างจากวิธีที่มักทำกันในงานจริง
อีกอย่าง การที่ GPS ได้รับผลกระทบจากสภาพอากาศเป็นความเข้าใจผิดที่พบได้บ่อย และในความเป็นจริงไม่ใช่เช่นนั้น นอกจากนี้นิยามเรื่อง consistency ที่ใช้ในบทความก็ไม่ใช่มาตรฐาน ในทฤษฎีการประมาณ การบอกว่า estimator มีความ consistent หมายความว่าเมื่อมีข้อมูลมากขึ้น ค่าประมาณจะลู่เข้าสู่ค่าจริง
เป็นเรื่องดีที่อธิบายให้ง่ายสำหรับผู้อ่านทั่วไป แต่ดูเหมือนความเข้าใจผิดบางอย่างกำลังสร้างปัญหา ผมเป็นนักศึกษาปริญญาโทด้านทฤษฎีการประมาณ ถ้าคุยต่ออาจช่วยได้
ถึงขั้นทำให้สงสัยว่าทำไมวิชาประมวลผลสัญญาณในมหาวิทยาลัยถึงไม่สอน Kalman Filter ให้เรียบง่ายแบบนี้ แนวคิดทางคณิตศาสตร์ก็ควรสอนแบบคณิตศาสตร์ แต่สำหรับคนที่พื้นฐานไม่พอ มันทำให้ข้อมูลบางส่วนสูญหายไป
ก่อนหน้านี้เคยสอน Discrete Cosine Transform และ Wavelet Transform โดยเน้นภาพเป็นหลัก วิธีที่ให้สัญชาตญาณก่อนความเคร่งครัดทางคณิตศาสตร์ใช้ได้ผลดีกว่าการสอนในลำดับตรงข้ามเสมอ
เหตุผลที่อาจารย์ไม่ให้สัญชาตญาณก่อนอาจมีหลายอย่าง เช่น ตัวอาจารย์เองมีความเชี่ยวชาญลึกกว่าในด้านตัวเลขและการจัดการสมการมากกว่าสัญชาตญาณ, ความสามารถด้านการสอนไม่ได้รับการตอบแทน จึงเอาเวลาที่ต้องใช้ในการอธิบายอย่างเป็นสัญชาตญาณไปเขียนข้อเสนอทุนวิจัยหรือดูแลนักศึกษาปริญญาเอกแทน, และเมื่อเข้าใจคณิตศาสตร์แล้ว คำอธิบายเชิงสัญชาตญาณกลับรู้สึกเหมือนเป็น “ทางที่ยาก” ทำให้สมองไม่อยากย้อนกลับไป
โดยเฉพาะข้อที่สาม ผมคิดว่าเป็นเหตุผลใหญ่ที่สุด เรื่องนี้ไม่ได้เป็นแค่ปัญหาการศึกษาคณิตศาสตร์ แต่ยังเป็นความต่างระหว่าง ความเชี่ยวชาญ กับ ความสามารถในการสอน ด้วย ถ้าจะเรียนตีไดรฟ์กอล์ฟ อาจจะดีกว่าถ้าเรียนกับคนที่เริ่มจากตีได้ 100 หลาแล้วค่อย ๆ พัฒนาจนตีได้ 300 หลาอย่างสม่ำเสมอ มากกว่าคนที่ตีได้ไกลที่สุด
ถ้าจะให้คำเตือนทั่วไปกับคนที่ต้องการ implement Kalman Filter วิธีจัดการกับ ความไม่เสถียรเชิงตัวเลข คือควรอ่านสองสามหน้าแรกของ https://www.stat.berkeley.edu/~brill/Stat248/kalmanfiltering...
ในงานจริง ต่อให้ทำแบบนั้นก็แทบไม่เคยเห็น artifact เชิงตัวเลขที่เด่นชัด แต่ก็เป็นทางออกที่น่าสนใจมาก
เพื่ออ่านเสริมจากบทความนี้ หากอยากเริ่มต้นกับตระกูล Kalman Filter ให้ละเอียดและเป็นคณิตศาสตร์มากขึ้น ขอแนะนำหนังสือเล่มนี้อย่างยิ่ง: https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Pyt...
เป็นหนังสือที่เขียนโดย software engineer ที่จำเป็นต้อง implement Kalman Filter ในงานจริง ดังนั้นวิธีสร้างแรงจูงใจและถ่ายทอดแนวคิดอาจเหมาะกับผู้อ่านกลุ่มนี้มาก เขียนเป็น Jupyter Notebook แบบโต้ตอบได้ จึง clone repository แล้วรันตามเองได้
หนังสือค่อย ๆ ปรับปรุงทีละขั้น เริ่มจาก filter แบบง่าย ใส่กฎของ Bayes แล้วขยายไปเป็นการแจกแจงความน่าจะเป็น จึงเป็นทางเข้าที่ลาดชันไม่มากสู่ Kalman Filter
มีแง่มุมหนึ่งที่ขาดไป เวลาเฉลี่ยถ่วงน้ำหนักระหว่างค่าพยากรณ์กับค่าที่วัดได้ น้ำหนักของ Kalman Filter สามารถเปลี่ยนไปตามเวลาได้ ถ้าไม่เป็นแบบนั้น ผมคิดว่ามันคงถูกเรียกด้วยชื่ออื่น
ตัวอย่างที่ดีคือการวัดค่าที่เปลี่ยนแปลงช้า ๆ ด้วยเซนเซอร์ตัวเดียว เช่น ในมาตรวัดน้ำมันเชื้อเพลิง ควรประมาณว่าในระดับวินาทีค่านั้นไม่เปลี่ยนแปลง แต่ค่าที่วัดได้อาจมี noise เช่น น้ำมันในถังกระฉอก
ในกรณีนี้ Kalman Filter จะดูเหมือน ตัวกรองผ่านต่ำอันดับหนึ่ง ที่มี gain ลดลงแบบเอ็กซ์โปเนนเชียล ความถี่ตัดเปลี่ยนไป ทำให้หาค่าระดับเริ่มต้นได้เร็วภายในไม่กี่วินาที และหลังจากนั้นสามารถเมิน noise ด้วยความถี่ตัดที่ต่ำมากอย่าง 0.01Hz ได้
เป็นบทความที่ดีเกี่ยวกับเครื่องมือสำคัญ
เท่าที่ผมเข้าใจ linear Kalman Filter คือคำตอบที่เหมาะที่สุดสำหรับปัญหาเชิงเส้น และค่อนข้างเข้าใจและนำไป implement ได้ง่าย แต่แอปพลิเคชันส่วนใหญ่ที่ผมเคยเห็นเป็นแบบไม่เชิงเส้น
Extended Kalman Filter และ Unscented Kalman Filter เข้าใจและ implement ได้ยากกว่ามาก อีกทั้งเอกสารและไลบรารีก็มีน้อยกว่าและใช้งานได้น้อยกว่า
ตัวอย่างเช่นตอนทำงานกับอุปกรณ์ AHRS/GNSS CAN สำหรับ UAV ขนาดเล็ก Extended Kalman Filter ที่เห็นใน PX4 หรือ Ardupilot นั้นซับซ้อนมากและมีพารามิเตอร์เยอะมาก ดังนั้นวิธีที่เริ่มจากหลักการพื้นฐานของ quaternion แล้วค่อย ๆ ปรับแก้คำตอบจาก gyro ไปทาง “ทิศขึ้น” ของ accelerometer และเวกเตอร์ความเอียงของ magnetometer จึงเรียบง่ายกว่า
หากขนาดความเร่งต่างจาก 1G มาก หรือเวกเตอร์สนามแม่เหล็กต่างจากความเข้มสนามแม่เหล็กโลกเฉพาะพื้นที่มาก ก็ลดน้ำหนักหรือข้ามการอัปเดตจากเซนเซอร์นั้น แล้วปล่อยให้ gyro เดินหน้าต่อไปเอง บางที EKF น่าจะเป็นคำตอบที่ถูกต้อง แต่ผมยอมแพ้กับการทำให้มันอยู่ในรูปที่เข้าใจ สร้าง ปรับจูน และวินิจฉัยได้ง่าย
แต่ใน quadrotor อุปสรรคใหญ่คือการหมุน โมเดลเชิงเส้นของ Kalman Filter สมมติว่าทุกอย่างอยู่ในปริภูมิ Euclidean แต่การหมุนอยู่บน manifold ในกรณีของ quaternion manifold นี้คือเซตของ unit quaternion
หากนำ EKF ไปใช้แบบตรง ๆ เพื่อประมาณค่า quaternion มันจะไม่เป็น unit quaternion อีกต่อไป และค่าประมาณจะพัง มีวิธีที่เป็นที่รู้จักกันดีในการจัดการข้อจำกัดของ manifold นี้ แต่ในบรรดาสมการที่ผมเคยแปลงเป็นโค้ด มันจัดว่าเป็นหนึ่งในชุดที่ดูน่าเกลียดที่สุด
ตัวอย่างง่าย ๆ คือพิจารณาสถานะ
(x, y)ที่ต้องอยู่บนวงกลมหน่วยเสมอเพราะกฎฟิสิกส์ dynamics จริงf(x, y)จะให้จุดใหม่บนวงกลม แต่ dynamics โดยประมาณที่ได้จากการทำให้เป็นเชิงเส้นไม่มีหลักประกันว่าจะคงอยู่บนวงกลมหน่วย ซึ่งอาจนำไปสู่สถานะที่ผิดฟิสิกส์หรือการประมาณสถานะของ EKF ที่ผิดพลาดได้ตัวเลือกที่น่าดูมี ForneyLab.jl, Infer.net, Gen.jl, Pyro
แต่มีหลายวิธีในการใช้ Kalman Filter และขึ้นอยู่กับว่าคุณเริ่มจากตรงไหน การจัดการการแปลงแบบไม่เชิงเส้นให้ถูกต้องอาจยุ่งยากอย่างยิ่ง
ผมมีสายตาสั้นและสายตาเอียง พอลองหลับตาข้างหนึ่งแล้วมองอะไรอย่างนาฬิกาแขวน ก็พบว่าตาแต่ละข้างสร้างภาพที่บิดเบี้ยวต่างกันเล็กน้อย ตาทั้งสองข้างไม่เหมือนกัน
แต่พอมองนาฬิกาด้วยสองตา ภาพกลับคมชัดกว่ามาก และดีกว่าการมองด้วยตาข้างใดข้างหนึ่ง สถานการณ์ในบทความที่ผู้โดยสารเรือ 1,000 คนรายงานพิกัด GPS ของตนเองทำให้นึกถึงปรากฏการณ์นี้
สมองก็น่าจะใช้ อัลกอริทึมฉลาด ๆ แบบ Kalman Filter อย่างแพร่หลายเหมือนกัน
เข้าใจว่า Kalman Filter คือการประมาณค่าจากค่าที่สังเกตได้ซึ่งมี noise ให้ดีกว่าค่าเฉลี่ยธรรมดา แบบนี้ถูกไหม?
เช่น ถ้าวัดอะไรบางอย่าง 3 ครั้งได้ 7, 8, 9 เราก็คงเดาว่าค่าจริงคือ 8 แล้ว Kalman Filter จะให้ค่าประมาณอย่างอื่นหรือไม่?
โดยดั้งเดิม Kalman Filter ใช้ประมาณค่าสิ่งที่เคลื่อนที่ตามเวลา ลองนึกถึงคนในวิดีโอหรือการเดินแบบสุ่มบางประเภท
ถ้าสมมติว่าระหว่างเวลาหรือค่าการวัดสองจุดติดต่อกันมีความสัมพันธ์กัน เช่น ความเร็วและทิศทางปัจจุบัน ก็สามารถผสมข้อมูลจากโมเดลการเคลื่อนที่กับข้อมูลจากโมเดลการวัดที่มี noise เพื่อประมาณตำแหน่งหรือค่า หรือแม้แต่ประวัติการเคลื่อนที่ทั้งหมดได้ดีขึ้น
ถ้าโมเดลการเคลื่อนที่ผิดไปอย่างมีนัยสำคัญ การประมาณค่าก็จะไม่ดีขึ้น วิธีที่ขยายต่อมาหลายแบบจึงมุ่งเน้นการรวมโมเดลการเคลื่อนที่ที่ละเอียดขึ้น เช่น ล้อไถลในหุ่นยนต์
เช่น ถ้ากำลังวัดค่าคงที่ อาจใช้โมเดลพื้นฐานเป็นค่าคงที่ที่มีความไม่แน่นอนเริ่มต้น เช่น การแจกแจง Gaussian ที่มีส่วนเบี่ยงเบนมาตรฐาน และค่าการวัดที่มี noise แบบ Gaussian พร้อมส่วนเบี่ยงเบนมาตรฐานเช่นกัน เราสามารถปรับความไม่แน่นอนเริ่มต้นรอบค่าคงที่ที่ต้องการประมาณ และความไม่แน่นอนของค่าการวัดได้
ในตัวอย่างนี้ Kalman Filter จะไม่ทำงานเหมือนค่าเฉลี่ย ถ้าค่าการวัดดี คือมีความไม่แน่นอนต่ำ ก็จะลู่เข้าอย่างรวดเร็ว แต่ถ้าค่าการวัดแย่ ค่าประมาณก็จะแกว่งและใช้เวลานานกว่าจะลู่เข้า
และคำกล่าวที่ว่า Kalman Filter ใช้ได้เฉพาะกับสิ่งที่เคลื่อนที่นั้นไม่จริง มันถูกใช้กับ การประมาณค่าคงที่ อยู่เสมอ เพียงแต่มีชื่อเสียงมากกว่าในกรณีวัตถุที่เคลื่อนที่
Kalman Filter จัดการกรณีที่ sample มีความสัมพันธ์กันเพราะ dynamics เชิงเส้นบางอย่าง ค่าที่วัดได้ไม่จำเป็นต้องเป็นสิ่งที่สนใจโดยตรงก็ได้ แต่อาจเป็นฟังก์ชันเชิงเส้นของสิ่งนั้นบวกกับ noise แบบ Gaussian
ดังนั้นความรู้จากการวัดครั้งแรกว่าเห็นค่า 7 จะเปลี่ยนความน่าจะเป็นที่จะเห็นค่า 8 ในการวัดครั้งที่สอง ถ้าเอาแต่หาค่าเฉลี่ย sample อย่างข้างต้น โดยทั่วไปจะไม่ลู่เข้าสู่ค่าเฉลี่ยจริง
ในตัวอย่างนี้จะให้อะไรออกมานั้นขึ้นอยู่กับโมเดลที่แน่นอน แม้แต่ในสถานการณ์ที่ง่ายที่สุดเท่าที่จินตนาการได้ ก็ต้องกำหนดก่อนว่าจะเริ่มด้วย expected value ใดเหมือนใน Bayes
ถ้า encode การแสดงออกนั้นเป็น linear Gaussian model ก็จะได้ Kalman Filter
บทความสั้นอีกชิ้นที่ช่วยให้เข้าใจ Kalman Filter และทำให้ได้ข้อคิดอีกอย่างคือบันทึกของ John D. Cook: https://www.johndcook.com/blog/applied-kalman-filtering/
การสร้างแบบจำลองระบบแบบดั้งเดิมที่อิงแคลคูลัสและสมการเชิงอนุพันธ์มองว่าข้อมูลไม่มีความไม่แน่นอน และทุกอย่างถูกรวมอยู่ในแบบจำลองของระบบ ขณะที่ตัวประมาณค่าแบบอิงข้อมูลมองว่า “ทุกอย่างอยู่ในข้อมูล” และละเลยแบบจำลองของกระบวนการทางฟิสิกส์ที่สร้างข้อมูลขึ้นมาโดยสิ้นเชิง
ความงดงามของ Kalman Filter อยู่ที่การผสานสองแนวทางนี้เข้าด้วยกัน
ยังมีบทความอื่นที่มีภาพประกอบดีด้วย: https://www.bzarg.com/p/how-a-kalman-filter-works-in-picture...
เป็นบทความที่เคยขึ้น HN มาแล้วสามครั้ง