>> ต่อจาก
บทที่ ๙ ในบทที่แล้วได้อธิบายวิธีการสร้างชั้นต่างๆสำหรับประกอบในโครงข่ายประสาทเทียม ส่วนในบทนี้จะลองนำมาใช้
ขอยกตัวอย่างด้วยการสร้างคลาสเพอร์เซปตรอนสองชั้นสำหรับจำแนกประเภทหลายกลุ่มแบบเดียวกับที่ทำในบทที่ ๘ แค่เปลี่ยนมาใช้วิธีการประกอบขึ้นโดยเอาชั้นมาต่อกัน
จะเริ่มจากสร้างคลาสของชั้นต่างๆขึ้น จากนั้นก็สร้างคลาสของโครงข่ายประสาทเทียม ๒ ชั้นซึ่งใช้ชั้นต่างๆนั้นข้างใน
import numpy as np
import matplotlib.pyplot as plt
class Affin:
def __init__(self,m0,m1,sigma):
self.m = m0,m1
self.w = np.random.normal(0,sigma,self.m)
self.b = np.zeros(m1)
self.gw = 0
self.gb = 0
def pai(self,X):
self.X = X
return np.dot(X,self.w) + self.b
def yon(self,g):
self.gw += np.dot(self.X.T,g)
self.gb += g.sum(0)
return np.dot(g,self.w.T)
class Sigmoid:
def pai(self,a):
self.h = 1/(1+np.exp(-a))
return self.h
def yon(self,g):
return g*(1-self.h)*self.h
class Softmax_entropy:
def pai(self,a,Z):
self.Z = Z
exp_a = np.exp(a.T-a.max(1))
self.h = (exp_a/exp_a.sum(0)).T
return -(np.log(self.h[Z]+1e-10)).mean()
def yon(self,g):
return g*(self.h-self.Z)/len(self.h)
def ha_1h(z,n):
return z[:,None]==range(n)
class Prasat2chan:
def __init__(self,m,eta):
self.m = m
self.eta = eta
def rianru(self,X,z,n_thamsam):
self.kiklum = int(z.max()+1)
Z = ha_1h(z,self.kiklum) # แปลเป็นวันฮ็อต
# ชั้นทั้งหมดของโครงข่ายประสาท
self.chan = [Affin(X.shape[1],self.m,1),
Sigmoid(),
Affin(self.m,self.kiklum,1),
Softmax_entropy()]
self.khanaen = []
self.entropy = []
for o in range(n_thamsam):
# คำนวณไปข้างหน้า
a = X
for c in self.chan[:-1]:
a = c.pai(a)
# คำนวณค่าเสียหายจากชั้นสุดท้าย
entropy = self.chan[-1].pai(a,Z)
self.entropy.append(entropy)
khanaen = (a.argmax(1)==z).mean() # คำนวณคะแนน
self.khanaen.append(khanaen)
# แพร่ย้อนกลับ
g = 1
for c in reversed(self.chan):
g = c.yon(g)
# ปรับพารามิเตอร์จากค่าอนุพันธ์ที่เก็บไว้หลังแพร่ย้อน
for i in [0,2]:
self.chan[i].w -= self.eta*self.chan[i].gw
self.chan[i].b -= self.eta*self.chan[i].gb
self.chan[i].gw = 0
self.chan[i].gb = 0
def thamnai(self,X):
for c in self.chan[:-1]:
X = c.pai(X)
return X.argmax(1)
ชั้น Affin ในที่นี้นิยามต่างจากที่แนะนำในบทที่แล้วโดยแค่ป้อนขนาดขาเข้า (m0) ขาออก (m1) กับความกว้างการแจกแจงค่า (sigma) แล้วให้ไปสร้างค่า w และ b ตามที่กำหนด แบบนี้สะดวกในการใช้งานมากกว่า
ส่วนชั้น Softmax_entropy นี้คือซอฟต์แม็กซ์แล้วต่อด้วยเอนโทรปีไขว้ ที่เอามาเชื่อมกันโดยไม่แยกเพราะอนุพันธ์ของสองชั้นนี้ต่อกันคำนวณง่ายกว่าแยกทีละชั้น ดังนั้นยุบรวมกันแบบนี้คำนวณเร็วขึ้น ไม่มีประโยชน์ที่จะแยกเป็นชั้น
ตอนคำนวณไปข้างหน้า ที่ไม่ได้รวมชั้น Softmax_entropy ซึ่งเป็นชั้นสุดท้ายไว้ใน for ด้วยก็เพราะชั้นนี้ต้องใส่ค่าป้อนเข้า ๒ ตัว คือมี z ด้วย อีกทั้งผลจากชั้น Affin สุดท้ายยังต้องนำไปใช้ทำนายคำตอบเพื่อคำนวณคะแนนด้วย
ส่วนตอนแพร่ย้อนกลับก็ให้ไล่ย้อนจากชั้นสุดท้ายมาจนถึงชั้นแรก ระหว่างนั้นค่าอนุพันธ์ก็จะถูกคำนวณและเก็บไว้ในตัวชั้นแต่ละชั้น สุดท้ายก็เอาค่านั้นมาใช้เพื่อปรับพารามิเตอร์ เพียงแต่ว่าชั้นที่จะปรับมีแค่ชั้น Affin เท่านั้น
ต่อไปเป็นตัวอย่างการนำคลาสที่สร้างขึ้นนี้มาใช้ ขอยกตัวอย่างเป็นข้อมูลลักษณะแบบนี้
np.random.seed(7)
r = np.tile(np.sqrt(np.linspace(0.5,25,200)),3)
t = np.random.normal(r,0.4)
z = np.arange(3).repeat(200)
t += z*np.pi/3*2
X = np.array([r*np.cos(t),r*np.sin(t)]).T
plt.scatter(X[:,0],X[:,1],50,c=z,edgecolor='k',cmap='winter')
plt.show()
สร้างโครงข่ายประสาทเพื่อจำแนกกลุ่มแล้วแสดงเขตการแบ่ง พร้อมทั้งแสดงความคืบหน้าในการเรียนรู้ด้วย
prasat = Prasat2chan(m=47,eta=0.5)
prasat.rianru(X,z,n_thamsam=2000)
mx,my = np.meshgrid(np.linspace(X[:,0].min(),X[:,0].max(),200),np.linspace(X[:,1].min(),X[:,1].max(),200))
mX = np.array([mx.ravel(),my.ravel()]).T
mz = prasat.thamnai(mX).reshape(200,-1)
plt.axes(aspect=1,xlim=(X[:,0].min(),X[:,0].max()),ylim=(X[:,1].min(),X[:,1].max()))
plt.contourf(mx,my,mz,cmap='winter',alpha=0.2)
plt.scatter(X[:,0],X[:,1],50,c=z,edgecolor='k',cmap='winter')
plt.figure()
plt.subplot(211,xticks=[])
plt.plot(prasat.entropy,'#8899dd')
plt.ylabel(u'เอนโทรปี',family='Tahoma')
plt.subplot(212)
plt.plot(prasat.khanaen,'#8899dd')
plt.ylabel(u'คะแนน',family='Tahoma')
plt.xlabel(u'จำนวนรอบ',family='Tahoma')
plt.show()
จะเห็นว่าเมื่อแบ่งเป็นชั้นๆแล้วคำนวณแบบนี้ทำให้การเขียนดูสะดวกขึ้นมาก แบบนี้จะสร้างเป็น ๓ ชั้นหรือกี่ชั้นก็แค่ต่อชั้นเพิ่มเข้าไป
แต่ว่ายังมีวิธีที่จะสามารถทำให้สะดวกขึ้นได้มากกว่านี้อีก ซึ่งจะแนะนำต่อในบทต่อไป
>> อ่านต่อ
บทที่ ๑๑