Softmax Function หรือ SoftArgMax Function หรือ Normalized Exponential Function คือ ฟังก์ชันที่รับ Input เป็น Vector ของ Logit จำนวนจริง แล้ว Normalize ออกมาเป็นความน่าจะเป็น Probability ที่ผลรวมเท่ากับ 1

หรือเข้าใจง่าย ๆ ว่า Softmax รับตัวเลขเข้าไป แล้วแปลงออกมาเป็น Probability เรามาดูตัวอย่างกันจะเข้าใจง่ายขึ้น

สูตร Softmax

\(\sigma(\mathbf{z})i = \frac{e^{z_i}}{\sum{j=1}^K e^{z_j}} \text{ for } i = 1, \dotsc , K \text{ and } \mathbf z=(z_1,\dotsc,z_K) \in R^K\)

ประโยชน์ของ Softmax Function

Softmax มักถูกนำไปไว้ Layer สุดท้าย ของ Neural Network เพื่อให้ Output ออกมาเป็น Probability ไปคำนวน Negative Log Likelihood เป็น Cross Entropy Loss เช่น ในงาน Single Class Classification

Softmax ถูกนำไปใช้บ่อย ในงาน Classification จนถึงขนาดมีคนเรียกว่า Softmax Classifier หรือ Softmax Loss

ข้อเสียของ Softmax Function

  1. เหมาะกับการใช้งานที่คาดหวัง Output ที่ถูกต้องอันเดียวเท่านั้น (ใกล้เคียง Max Function)
  2. เนื่องจาก ตัวหารต้อง Sum รวมทั้งหมดทุก Item ทุกครั้ง จึงทำให้มีปัญหาเรื่อง Performance ถ้ามีจำนวน Item มาก ๆ เช่น Output เป็น 1 ใน 500,000 คำใน Dictionary ในงาน NLP

เรามาเริ่มกันเลย

Open In Colab

0. Import

In [1]:
import torch

1. Data

เราจะสร้างข้อมูลขึ้นมาเป็น Tensor ขนาด 10 Row, 3 Column เรื่อง Tensor จะอธิบายต่อไป

In [2]:
z = torch.tensor([
                  [     1,      2,      3 ],
                  [    11,     12,     13 ], 
                  [   0.1,    0.2,    0.3 ], 
                  [    -1,     -2,     -3 ],
                  [    10,     20,     30 ], 
                  [    -5,      0,      5 ], 
                  [   -11,   1/12,     13 ], 
                  [  -0.1,   -0.2,   -0.3 ], 
                  [   -11,    -12,    -13 ], 
                  [   -10,    -20,    -30 ], 
                                           ]).float()
z.shape
Out[2]:
torch.Size([10, 3])
In [3]:
z
Out[3]:
tensor([[  1.0000,   2.0000,   3.0000],
        [ 11.0000,  12.0000,  13.0000],
        [  0.1000,   0.2000,   0.3000],
        [ -1.0000,  -2.0000,  -3.0000],
        [ 10.0000,  20.0000,  30.0000],
        [ -5.0000,   0.0000,   5.0000],
        [-11.0000,   0.0833,  13.0000],
        [ -0.1000,  -0.2000,  -0.3000],
        [-11.0000, -12.0000, -13.0000],
        [-10.0000, -20.0000, -30.0000]])

2. สูตรของ Softmax คือดังนี้

$$\sigma(\mathbf{z})_i = \frac{e^{z_i}}{\sum_{j=1}^K e^{z_j}} \text{ for } i = 1, \dotsc , K \text{ and } \mathbf z=(z_1,\dotsc,z_K) \in R^K$$

2.1 ตัวตั้ง (Dividen)

เราจะมาหาตัวตั้ง เอา a มา exp ให้หมด แล้วเก็บไว้ก่อน

In [4]:
exp_z = torch.exp(z)
exp_z
Out[4]:
tensor([[2.7183e+00, 7.3891e+00, 2.0086e+01],
        [5.9874e+04, 1.6275e+05, 4.4241e+05],
        [1.1052e+00, 1.2214e+00, 1.3499e+00],
        [3.6788e-01, 1.3534e-01, 4.9787e-02],
        [2.2026e+04, 4.8517e+08, 1.0686e+13],
        [6.7379e-03, 1.0000e+00, 1.4841e+02],
        [1.6702e-05, 1.0869e+00, 4.4241e+05],
        [9.0484e-01, 8.1873e-01, 7.4082e-01],
        [1.6702e-05, 6.1442e-06, 2.2603e-06],
        [4.5400e-05, 2.0612e-09, 9.3576e-14]])

2.2 ตัวหาร (Divisor)

ตัวหารคือผลรวมของ exp_a เราจะ sum ตามมิติที่ 1 Column ให้เหลือแต่ Row โดย keepdim=True จะได้ดูง่าย

In [5]:
sum_exp_z = torch.sum(exp_z, 1, keepdim=True)
sum_exp_z
Out[5]:
tensor([[3.0193e+01],
        [6.6504e+05],
        [3.6764e+00],
        [5.5300e-01],
        [1.0687e+13],
        [1.4942e+02],
        [4.4241e+05],
        [2.4644e+00],
        [2.5106e-05],
        [4.5402e-05]])

3. หา Softmax ของ a

นำตัวตั้ง Dividen หารด้วยตัวหาร Divisor จะได้ค่า Softmax

In [6]:
softmax_z = exp_z / sum_exp_z
softmax_z
Out[6]:
tensor([[9.0031e-02, 2.4473e-01, 6.6524e-01],
        [9.0031e-02, 2.4473e-01, 6.6524e-01],
        [3.0061e-01, 3.3222e-01, 3.6717e-01],
        [6.6524e-01, 2.4473e-01, 9.0031e-02],
        [2.0611e-09, 4.5398e-05, 9.9995e-01],
        [4.5094e-05, 6.6925e-03, 9.9326e-01],
        [3.7751e-11, 2.4568e-06, 1.0000e+00],
        [3.6717e-01, 3.3222e-01, 3.0061e-01],
        [6.6524e-01, 2.4473e-01, 9.0031e-02],
        [9.9995e-01, 4.5398e-05, 2.0611e-09]])

4. Softmax Function

ได้เป็น ฟังก์ชันดังนี้

In [7]:
def softmax(z):
    exp_z = torch.exp(z)
    sum_exp_z = torch.sum(exp_z, 1, keepdim=True)
    return exp_z / sum_exp_z

5. การใช้งาน Softmax

Softmax มีคุณสมบัติพิเศษ คือ จะรวมกันได้เท่ากับ 1 จึงถูกนำมาใช้เป็นความน่าจะเป็น Probability / Likelihood

ดูตัวอย่างแถวแรก

In [8]:
z[0]
Out[8]:
tensor([1., 2., 3.])
In [9]:
softmax_z[0]
Out[9]:
tensor([0.0900, 0.2447, 0.6652])

บวกกันได้ 1

In [10]:
softmax_z[0].sum()
Out[10]:
tensor(1.)

แถวสอง

In [11]:
z[1]
Out[11]:
tensor([11., 12., 13.])
In [12]:
softmax_z[1]
Out[12]:
tensor([0.0900, 0.2447, 0.6652])

ก็บวกกันแล้วได้ 1

In [13]:
softmax_z[1].sum()
Out[13]:
tensor(1.)

6. Numerical Stability

ถ้า Input มีขนาดใหญ่มาก เมื่อ exp จะ Error ได้ เราสามารถปรับ x โดย x = x - max(x) ก่อนเข้า Softmax Function เรียกว่า Numerical Stability

In [14]:
n = torch.tensor([
                  [    10,     20,     30 ],
                  [  -100,   -200,   -300 ],
                  [ 0.001, 0.0001, 0.0001 ], 
                  [    70,     80,     90 ], 
                  [   100,   1000,  10000 ], 
                                           ]).float()

เมื่อเลขใหญ่เกินกว่าระบบจะรับได้ จะมีค่าเป็น Not a Number (nan)

In [15]:
m = softmax(n)
m
Out[15]:
tensor([[2.0611e-09, 4.5398e-05, 9.9995e-01],
        [1.0000e+00, 0.0000e+00, 0.0000e+00],
        [3.3353e-01, 3.3323e-01, 3.3323e-01],
        [0.0000e+00, 0.0000e+00,        nan],
        [       nan,        nan,        nan]])

เราจะปรับฟังก์ชัน Softmax ให้ Numerical Stability รับเลขใหญ่ ๆ ได้

In [16]:
def softmax2(z):
    z = z - z.max(1, keepdim=True)[0]
    exp_z = torch.exp(z)
    sum_exp_z = torch.sum(exp_z, 1, keepdim=True)
    return exp_z / sum_exp_z
In [17]:
m = softmax2(n)
m
Out[17]:
tensor([[2.0611e-09, 4.5398e-05, 9.9995e-01],
        [1.0000e+00, 3.7835e-44, 0.0000e+00],
        [3.3353e-01, 3.3323e-01, 3.3323e-01],
        [2.0611e-09, 4.5398e-05, 9.9995e-01],
        [0.0000e+00, 0.0000e+00, 1.0000e+00]])

5. สรุป

  1. เราสามารถคำนวน Softmax Function ได้ไม่ยาก
  2. Softmax ทำให้อะไรที่มีค่าน้อยก็จะยิ่งถูกกดให้น้อย อะไรที่มากก็จะยิ่งดันให้ใกล้ 1 ใกล้เคียงกับ Max Function ที่ใช้หาค่ามากที่สุด
  3. Softmax มักถูกนำมาใช้เป็นความน่าจะเป็น Probability / Likelihood ใช้เป็นส่วนประกอบของ Cross Entropy Loss ใน Neural Network

Credit

In [ ]:
 

แชร์ให้เพื่อน:

Keng Surapong on FacebookKeng Surapong on GithubKeng Surapong on Linkedin
Keng Surapong
Project Manager at Bua Labs
The ultimate test of your knowledge is your capacity to convey it to another.

Published by Keng Surapong

The ultimate test of your knowledge is your capacity to convey it to another.

Enable Notifications    Ok No thanks