φυβλαςのβλογ
บล็อกของ phyblas



[python] การสร้างฟังก์ชัน softmax
เขียนเมื่อ 2016/12/06 18:07
แก้ไขล่าสุด 2021/09/28 16:42
หน้านี้เขียนขึ้นเพื่อเป็นเนื้อหาเสริมให้กับบทความเรื่องการวิเคราะห์การถดถอยซอฟต์แม็กซ์ https://phyblas.hinaboshi.com/20161205

ฟังก์ชันซอฟต์แม็กซ์เขียนดังนี้


ซึ่งสามารถเขียนฟังก์ชันในไพธอนได้ง่ายๆดังนี้
def softmax(x):
    exp_x = np.exp(x)
    return (exp_x/exp_x.sum())

โดยที่ x ในที่นี้เป็นอาเรย์หนึ่งมิติซึ่งมีสมาชิกหลายตัว พอป้อนอาเรย์ x ลงไปก็จะได้ผลลัพธ์ออกมาเป็นค่าที่แปลงเป็นความน่าจะเป็น
x = np.array([1,2,5,6])
print(softmax(x))

ได้
[ 0.00483724  0.01314897  0.26410418  0.71790961]

อย่างไรก็ตามมีข้อควรระวังอยู่ นั่นคือเวลาที่ใส่ค่าสูงมากๆลงไป เช่น
x = np.array([1000,1001,1002,1003])
print(softmax(x))

จะได้
[ nan  nan  nan  nan]

ที่เป็นแบบนี้เพราะว่า np.exp(1000) นั้นมีค่ามากเกินไปทำให้ถือว่าเป็นอนันต์

และเมื่อนำค่าอนันต์มาหารกันผลที่ได้ก็จะเป็น nan ซึ่งเป็นความผิดพลาดเนื่องจากข้อจำกัดของคอมพิวเตอร์

ลองใส่ตัวเลขคำนวณดูจริงๆก็จะเห็นปัญหา
print(np.exp(1000)) # ได้ inf
print(np.exp(1000)/np.exp(1000)) # ได้ nan

วิธีการรับมือกับปัญหานี้ก็คือตอนที่คำนวณให้นำค่าตัวที่สูงที่สุดในนั้นมาเป็นฐาน ลบออกจากค่าทุกตัวก่อนที่จะนำมาเข้า exp เท่านี้ค่าก็จะไม่มีวันสูงเกินไปแล้ว

ลองแก้เป็นแบบนี้
def softmax(x):
    exp_x = np.exp(x-x.max())
    return (exp_x/exp_x.sum())

x = np.array([1000,1001,1002,1003])
print(softmax(x))

ได้
[ 0.0320586   0.08714432  0.23688282  0.64391426]

พอเขียนแบบนี้ก็จะไม่มีปัญหาแล้ว

อีกเรื่องหนึ่งที่ต้องจัดการแก้ก็คือ โดยทั่วไปแล้วข้อมูลที่เรานำมาคำนวณซอฟต์แม็กซ์นั้นมักไม่ได้มีแค่มิติเดียวแต่เป็นสองมิติ

เพราะปกติเวลาที่คำนวณมักจะป้อนข้อมูลหลายแถวในเวลาเดียวกัน และข้อมูลแต่ละแถวก็แบ่งเป็นหลายหลัก โดยทั่วไปการคำนวณจะนำแต่ละหลักในแถวหนึ่งๆมาคำนวณซอฟต์แม็กซ์โดยแต่ละแถวแยกกันโดยไม่เกี่ยวกัน

ตัวอย่าง
x = np.array([[1,3,7,11],[9,1,7,2],[1,2,4,4]])

ถ้านำอาเรย์ x มาใช้กับฟังก์ชันซอฟต์แม็กซ์ที่เพิ่งสร้างขึ้นมาตอนนี้จะเกิดข้อผิดพลาด เนื่องจากถูกทำไว้ให้ใช้กับอาเรย์มิติเดียวเท่านั้น

การเขียนซอฟต์แม็กซ์สำหรับสองมิติจะซับซ้อนขึ้นมาหน่อย โดยเขียนแบบนี้
def softmax(x):
    exp_x = np.exp(x.T-x.max(1))
    return (exp_x/exp_x.sum(0)).T

เท่านี้ก็ใช้กับสองมิติได้แล้ว ลองนำมาใช้ดู
print(softmax(x))

ได้
[[  4.45666886e-05   3.29305762e-04   1.79794854e-02   9.81646642e-01]
 [  8.79830446e-01   2.95150233e-04   1.19072103e-01   8.02301516e-04]
 [  2.27845678e-02   6.19348766e-02   4.57640278e-01   4.57640278e-01]]

จะเห็นว่าผลที่ได้นั้นจะแยกคิดเป็นแถวๆ ดังนั้นหากรวมค่าทุกหลักในแต่ละแถวก็จะได้ 1
print(softmax(x).sum(1))

ได้
[ 1.  1.  1.]



เท่านี้ก็ได้ฟังก์ชันซอฟต์แม็กซ์สำหรับนำมาใช้เป็นส่วนประกอบในการเขียนโปรแกรมสำหรับการเรียนรู้ของเครื่องแล้ว

วิธีการทั้งหมดดัดแปลงมาจากเนื้อหาในหนังสือเล่มนี้


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> ปัญญาประดิษฐ์
-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> numpy

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

ไทย

日本語

中文