import numpy as np
import matplotlib.pyplot as plt
X = plt.imread('ruprang-raisi-25x25x1000x5/4/00112.png')
plt.figure(figsize=[6.5,5.7],dpi=100)
tick = np.arange(1,26)
plt.xticks(tick-0.5,tick)
plt.yticks(tick-0.5,tick)
plt.xlabel('ตำแหน่งในมิติ 1 ($t_1$)',family='Tahoma',size=14)
plt.ylabel('ตำแหน่งในมิติ 2 ($t_2$)',family='Tahoma',size=14)
plt.imshow(X,cmap='gray')
plt.colorbar(pad=0.01,aspect=50)
plt.grid(ls='--')
plt.tight_layout()
plt.show()
X = plt.imread('ruprang-misi-25x25x1000x6/4/00005.png')
X = X[:,:,:3]
plt.figure(figsize=[6.5,6.5],dpi=100)
tick = np.arange(1,26)
plt.subplot(2,2,1,xticks=tick-0.5,yticks=tick-0.5,xticklabels=[],yticklabels=[])
plt.title('ภาพเดิม',family='Tahoma',size=13)
plt.imshow(X)
plt.grid(ls='--')
for i in range(3):
plt.subplot(2,2,2+i,xticks=tick-0.5,yticks=tick-0.5,xticklabels=[],yticklabels=[])
plt.title(['ส่วน R (ช่อง 1)','ส่วน G (ช่อง 2)','ส่วน B (ช่อง 3)'][i],family='Tahoma',size=13)
X_ = np.zeros_like(X)
X_[:,:,i] = X[:,:,i]
plt.imshow(X_)
plt.grid(ls='--')
plt.tight_layout()
plt.show()
import numpy as np
from unagi import Chan,Param
class Conv2d(Chan):
def __init__(self,m0,m1,kk,st=1,pad=0,sigma=1):
'''
m0 : จำนวนช่องขาเข้า
m1 : จำนวนช่องขาออก
kk : ความสูงและความกว้างของตัวกรอง
st : ความสูงและกว้างที่เลื่อน
pad : ขอบที่เติมตามแนวความสูงและกว้าง
sigma : ส่วนเบี่ยงเบนมาตรฐานของค่าสุ่มเริ่มต้นของพารามิเตอร์น้ำหนัก
'''
# kk,st,pad นั้นควรเป็นลิสต์ของสองค่า แต่หากใส่ค่าเดียวมาให้ทำเป็นเท่ากันทั้งสองมิติ
if(type(kk)==int):
kk = [kk,kk]
if(type(st)==int):
st = [st,st]
if(type(pad)==int):
pad = [pad,pad]
# พารามิเตอร์ตัวแรกคือน้ำหนักในแต่ละช่อง มีจำนวน [m1,m0,kk[1],k[0]]
# อีกตัวคือไบแอส มีจำนวนเป็น m1 ให้เริ่มต้นจาก 0
self.param = [Param(np.random.normal(0,sigma,[m1,m0,kk[1],kk[0]])),
Param(np.zeros(m1))]
self.st = st
self.pad = pad
def pai(self,X):
px,py = self.pad
stx,sty = self.st
# เติมขอบ ถ้า pad>0
X = np.pad(X,[(0,0),(0,0),(py,py),(px,px)],'constant')
# ขนาดในแต่ละมิติของพารามิเตอร์ w (จำนวนช่องขาออก, จำนวนช่องขาเข้า, ความสูงตัวกรอง, ความยาวตัวกรอง)
m1,m0,kky,kkx = self.param[0].kha.shape
# ขนาดของข้อมูลขาเข้า (จำนวนข้อมูล, จำนวนช่องขาเข้า, ความสูงตัวกรองหลังเติมขอบ, ความกว้างตัวกรองหลังเติมขอบ)
n,m0_,ky0,kx0 = X.shape
# จำนวนช่องของข้อมูลขาเข้าควรเท่ากับจำนวนช่องของพารามิเตอร์ w ขาเข้า
assert m0_==m0
# ความสูงข้อมูลขาออก
kx1 = int((kx0-kkx)/stx)+1
# ความกว้างข้อมูลขาออก
ky1 = int((ky0-kky)/sty)+1
# สร้างอาเรย์ของข้อมูลขาเข้าที่ปรับรูปใหม่เพื่อให้ทำการคำนวณสะดวก
X_ = np.zeros([n,m0,kky,kkx,ky1,kx1])
for _j in range(kky):
j_ = _j+ky1*sty
for _i in range(kkx):
i_ = _i+kx1*stx
X_[:,:,_j,_i,:,:] = X[:,:,_j:j_:sty,_i:i_:stx]
X_ = X_.transpose(0,4,5,1,2,3).reshape(-1,m0*kkx*kky)
w = self.param[0].kha.reshape(m1,-1).T
b = self.param[1].kha
a = np.dot(X_,w) + b
a = a.reshape(n,ky1,kx1,-1).transpose(0,3,1,2)
self.ruprang = n,m1,m0,kky,kkx,ky0,kx0,ky1,kx1
self.X_ = X_
return a
def yon(self,g):
px,py = self.pad
stx,sty = self.st
# จำนวนข้อมูล, จำนวนช่องขาเข้า, จำนวนช่องขาออก, ความสูงตัวกรอง, ความกว้างตัวกรอง, ความสูงข้อมูลขาเข้า, ความกว้างข้อมูลขาเข้า, ความสูงข้อมูลขาออก, ความกว้างข้อมูลขาออก
n,m1,m0,kky,kkx,ky0,kx0,ky1,kx1 = self.ruprang
g = g.transpose(0,2,3,1).reshape(-1,m1)
w = self.param[0].kha.reshape(m1,-1).T
self.param[0].g = np.dot(self.X_.T,g).transpose(1,0).reshape(m1,m0,kky,kkx)
self.param[1].g = g.sum(0)
gX_ = np.dot(g,w.T)
gX_ = gX_.reshape(-1,ky1,kx1,m0,kky,kkx).transpose(0,3,4,5,1,2)
gX = np.zeros([n,m0,ky0+2*py,kx0+2*px])
for _j in range(kky):
j_ = _j+ky1*sty
for _i in range(kkx):
i_ = _i+kx1*stx
gX[:,:,_j:j_:sty,_i:i_:stx] += gX_[:,:,_j,_i,:,:]
return gX[:,:,py:ky0-py,px:kx0-px]
import numpy as np
import matplotlib.pyplot as plt
from unagi import Chan,Param
class MaxP2d(Chan):
def __init__(self,kk,st=None):
'''
kk : ความยาวตัวกรอง
st : ความยาวการเลื่อน (ถ้าไม่กำหนด ก็ให้เท่ากับความยาวตัวกรอง)
'''
if(type(kk)==int):
self.kk = [kk,kk]
else:
self.kk = kk
if(st==None):
self.st = self.kk
elif(type(st)==int):
self.st = [st,st]
else:
self.st = st
def pai(self,X):
stx,sty = self.st
kkx,kky = self.kk
# ขนาดของข้อมูลขาเข้า (จำนวนข้อมูล, จำนวนช่องขาเข้า, ความสูงข้อมูลขาเข้า, ความกว้างข้อมูลขาเข้า)
n,m,ky0,kx0 = X.shape
kx1 = int((kx0-kkx)/stx)+1
ky1 = int((ky0-kky)/sty)+1
X_ = np.zeros([n,m,kky,kkx,ky1,kx1])
for _j in range(kky):
j_ = _j+ky1*sty
for _i in range(kkx):
i_ = _i+kx1*stx
X_[:,:,_j,_i,:,:] = X[:,:,_j:j_:sty,_i:i_:stx]
X_ = X_.transpose(0,4,5,1,2,3).reshape(-1,kkx*kky)
self.argmax = X_.argmax(1)
self.ruprang = n,m,ky0,kx0,ky1,kx1
return X_.max(1).reshape(n,ky1,kx1,m).transpose(0,3,1,2)
def yon(self,g):
g = g.transpose(0,2,3,1)
stx,sty = self.st
kkx,kky = self.kk
# ขนาดของข้อมูลขาเข้า (จำนวนข้อมูล, จำนวนช่องขาเข้า, ความสูงข้อมูลขาเข้า, ความกว้างข้อมูลขาเข้า, ความสูงข้อมูลขาออก, ความกว้างข้อมูลขาออก)
n,m,ky0,kx0,ky1,kx1 = self.ruprang
gX_ = np.zeros([g.size,kkx*kky])
gX_[np.arange(self.argmax.size),self.argmax.flatten()] = g.flatten()
gX_ = gX_.reshape(-1,ky1,kx1,m,kky,kkx).transpose(0,3,4,5,1,2)
gX = np.zeros([n,m,ky0,kx0])
for _j in range(kky):
j_ = _j+ky1*sty
for _i in range(kkx):
i_ = _i+kx1*stx
gX[:,:,_j:j_:sty,_i:i_:stx] += gX_[:,:,_j,_i,:,:]
return gX
import numpy as np
import matplotlib.pyplot as plt
from unagi import Affin,Relu,Softmax_entropy,ha_1h,Adam,Conv2d,Plianrup,MaxP2d
class PrasatConvo2D:
def __init__(self,c0,n,eta):
'''
c0: จำนวนช่องขาเข้า
n: จำนวนกลุ่มของคำตอบ
eta: อัตราการเรียนรู้
'''
self.chan = []
# ชั้น 1 คอนโวลูชัน (ช่องขาเข้า c0, ช่องขาออก 32, ขนาดตัวกรอง 2×2)
self.chan.append(Conv2d(c0,32,[2,2],[1,1],[0,0],sigma=1))
self.chan.append(Relu())
self.chan.append(MaxP2d(2)) # ชั้นบ่อรวมสูงสุด
# ชั้น 2 คอนโวลูชัน (ช่องขาเข้า 32, ช่องขาออก 32, ขนาดตัวกรอง 3×3)
self.chan.append(Conv2d(32,32,[3,3],[1,1],[0,0],sigma=1))
self.chan.append(Relu())
self.chan.append(MaxP2d(2)) # ชั้นบ่อรวมสูงสุด
# ชั้นเปลี่ยนรูปก่อนเข้าสู่ชั้นเชิงเส้น
self.chan.append(Plianrup(-1))
# ชั้น 3 เชิงเส้น (เซลล์ขาเข้า 800, เซลล์ขาออก 64)
self.chan.append(Affin(800,64,np.sqrt(2./800)))
self.chan.append(Relu())
# ชั้น 4 (เซลล์ขาเข้า 64, เซลล์ขาออก n)
self.chan.append(Affin(64,n,np.sqrt(2./64)))
self.chan.append(Softmax_entropy())
self.opt = Adam(self.param(),eta=eta)
self.n = n
def rianru(self,X,z,X_truat,z_truat,n_thamsam=100,n_batch=50,ro=0):
n = len(z)
Z = ha_1h(z,self.n)
self.entropy = []
self.khanaen_fuek = []
self.khanaen_truat = []
khanaen_sungsut = 0
for o in range(n_thamsam):
lueak = np.random.permutation(n)
for i in range(0,n,n_batch):
Xb = X[lueak[i:i+n_batch]]
Zb = Z[lueak[i:i+n_batch]]
entropy = self.ha_entropy(Xb,Zb)
entropy.phraeyon()
self.opt()
entropy,khanaen_fuek = self.ha_entropy(X_fuek,Z,ao_khanaen=1)
khanaen_truat = self.ha_khanaen(X_truat,z_truat)
self.entropy.append(entropy.kha)
self.khanaen_fuek.append(khanaen_fuek)
self.khanaen_truat.append(khanaen_truat)
print('รอบที่ %d. เอนโทรปี=%.3e, ทำนายข้อมูลฝึกแม่น=%.3f, ทำนายข้อมูลตรวจสอบแม่น=%.3f'%(o,entropy.kha,khanaen_fuek,khanaen_truat))
if(khanaen_truat>khanaen_sungsut):
khanaen_sungsut = khanaen_truat
maiphoem = 0
else:
maiphoem += 1
if(ro>0 and maiphoem>=ro):
break
def ha_entropy(self,X,Z,ao_khanaen=0):
for c in self.chan[:-1]:
X = c(X)
if(ao_khanaen):
return self.chan[-1](X,Z),(X.kha.argmax(1)==Z.argmax(1)).mean()
return self.chan[-1](X,Z)
def ha_khanaen(self,X,z):
return (self.thamnai(X)==z).mean()
def param(self):
p = []
for c in self.chan:
if(hasattr(c,'param')):
p.extend(c.param)
return p
def thamnai(self,X):
for c in self.chan[:-1]:
X = c(X)
return X.kha.argmax(1)
from glob import glob
X = np.array([plt.imread(x) for x in sorted(glob('ruprang-raisi-25x25x1000x5/*/*.png'))]) # โหลดภาพขาวดำ
X = X.reshape(-1,1,25,25) # แปลงรูป ให้มีมิติของจำนวนช่องซึ่งเป็น 1
z = np.arange(5).repeat(1000) # คำตอบ เป็นเลข 0,1,2,3,4
np.random.seed(0)
sumlueak = np.random.permutation(5000) # สุ่มสลับลำดับ
# ข้อมูลมี 5000 ภาพ ในที่นี้แบ่งให้เป็นข้อมูลฝึก 4000 ภาพ ข้อมูลตรวจสอบ 1000 ภาพ
X_fuek,X_truat = X[sumlueak[:4000]],X[sumlueak[4000:]]
z_fuek,z_truat = z[sumlueak[:4000]],z[sumlueak[4000:]]
# สร้างโครงข่าย จำนวนช่องขาเข้าเป็น 1 เพราะเป็นภาพขาวดำ ส่วนคำตอบมี 5 กลุ่ม
prasat = PrasatConvo2D(1,5,eta=0.005)
prasat.rianru(X_fuek,z_fuek,X_truat,z_truat,n_thamsam=200,n_batch=64,ro=20)
# วาดกราฟแสดงเอนโทรปีและคะแนนสำหรับข้อมูลฝึกและข้อมูลตรวจสอบ
plt.figure(figsize=[5,7],dpi=100)
plt.subplot(211)
plt.semilogy()
plt.plot(prasat.entropy,'b')
plt.title('เอนโทรปี',family='Tahoma',size=14)
plt.grid(ls='--')
plt.subplot(212)
plt.plot(prasat.khanaen_fuek,'m',label='ข้อมูลฝึก')
plt.plot(prasat.khanaen_truat,'g',label='ข้อมูลตรวจสอบ')
plt.grid(ls='--')
plt.title('คะแนน',family='Tahoma',size=14)
plt.legend(prop={'family':'Tahoma','size':14})
plt.tight_layout()
plt.show()
X = np.array([plt.imread(x) for x in sorted(glob('ruprang-misi-25x25x1000x6/*/*.png'))]) # โหลดภาพสี
X = X.transpose(0,3,1,2)[:,:3] # ภาพที่โหลดมาจะมีมิติของสีสามสีเป็นมิติที่ 4 ให้ทำการสลับเอามิติของสีมาไว้เป็นมิติที่ 2
z = np.arange(6).repeat(1000) # เลขบอกกลุ่ม 0,1,2,3,4,5
np.random.seed(0)
sumlueak = np.random.permutation(6000) # สุ่มสลับลำดับ
# แบ่งข้อมูล 6000 ภาพเป็นข้อมูลฝึก 4800 ภาพ ข้อมูลทดสอบ 1200 ภาพ
X_fuek,X_truat = X[sumlueak[:4800]],X[sumlueak[4800:]]
z_fuek,z_truat = z[sumlueak[:4800]],z[sumlueak[4800:]]
# สร้างโครงข่าย จำนวนช่องขาเข้าเป็น 3 เพราะเป็นภาพสี ส่วนคำตอบมี 6 กลุ่ม
prasat = PrasatConvo2D(3,6,eta=0.005)
prasat.rianru(X_fuek,z_fuek,X_truat,z_truat,n_thamsam=200,n_batch=64,ro=20)
# วาดกราฟแสดงเอนโทรปีและคะแนนสำหรับข้อมูลฝึกและข้อมูลตรวจสอบ
plt.figure(figsize=[5,7],dpi=100)
plt.subplot(211)
plt.semilogy()
plt.plot(prasat.entropy,'b')
plt.title('เอนโทรปี',family='Tahoma',size=14)
plt.grid(ls='--')
plt.subplot(212)
plt.plot(prasat.khanaen_fuek,'m',label='ข้อมูลฝึก')
plt.plot(prasat.khanaen_truat,'g',label='ข้อมูลตรวจสอบ')
plt.grid(ls='--')
plt.title('คะแนน',family='Tahoma',size=14)
plt.legend(prop={'family':'Tahoma','size':14})
plt.tight_layout()
plt.show()
ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ