สวัสดีครับ ก่อนที่จะสนุกสนานกับวันปีใหม่ ก็มาพูดกันในเรื่องประสาทเทียมกันก่อน (สามารถดูบทความก่อนหน้าที่ blog ที่ผมเขียนนี่แหล่ะ) คราวนี้พูดต่อกันในเรื่องฟังก์ชันถ่ายโอนกัน พร้อมการใช้งานบางอย่าง
โดยปกติฟังก์ชันถ่ายโอนนี้ตัวเราจะต้องเป็นผู้เลือกใช้ครับ ส่วนค่าน้ำหนักและไบอัสจะถูกปรับค่าตามกฎการเรียนรู้ของแต่ละแบบจำลองระบบประสาทนั้นๆ ส่วนที่ว่าฟังก์ชันถ่านโอนที่เราเลือกมานั้นจะเหมาะสมกับงานของเราหรือไม่ ก็เป็นเรื่องที่ต้องลองใช้ดูถึงจะรู้ครับ วิธีลองก็ไม่ยากคือให้ทดลองฝึกสอน (train) พอสอนเสร็จก็ลองทดสอบ (simulation)
ฟังก์ชันถ่ายโอนทำหน้าที่รวมค่าเชิงตัวเลขจากเอาท์พุตของเซลล์ประสาท(Σ) แล้วตัดสินใจว่าจะส่งเอาท์พุท y ออกมาในรูปแบบใด ซึ่งอาจเป็นไปได้ทั้งเชิงเส้นหรือไม่เป็นเชิงเส้นก็ได้ ฟังก์ชันที่เราเลือกใช้ได้ในโปรแกรม MATLAB ก็อย่างเช่น
ฟังก์ชัน 3 ตัวนี้หล่ะครับ ที่ถูกเลือกใช้กันบ่อย สังเกตว่าฟังก์ชันซิกมอยแบบลอกาลิทึมมีเอาท์พุทอยู่ในช่วง [0,1] ฟังก์ชันซิกมอยแบบเส้นสัมผัสไฮเปอร์โบลาร์มีเอาท์พุตในช่วง [-1,1] ในขณะที่ฟังก์ชันเส้นตรงมีค่าเอาท์พุตได้กว้างมาก เมื่อเป็นอย่างนี้แล้วเราก็ต้องกำหนดเอาท์พุตให้เป็นไปในช่วงของแต่ละฟังก์ชันด้วย ไม่เช่นนั้นจะได้ผลการสอนที่ไม่ดีครับ
ผมจะพูดถึงเฉพาะแบบจำลองแบบแพร่กลับ และคำสั่งในการฝึกสอนของโปรแกรม
MATLAB คือ
net = newff หมายความว่าต้องการสร้าง neural network
แบบแพร่กลับ โดยมีชื่อว่า net หรือจะเป็นชื่ออื่นก็ได้ เช่น
kikapo = netff หมายความว่าต้องการสร้าง neural network
แบบแพร่กลับ โดยมีชื่อว่า kikapo เป็นต้น
เพื่อความกระจ่างเรามาทดลองมาใช้กันดีกว่า
ในที่นี้สมมุติว่าผมต้องการประมาณค่าฟังก์ชัน f(x) =2*cos(x)
ในช่วงตั้งแต่ –pi ไปจนถึง +pi ผมก็จะเขียนเป็นอินพุตและเอาท์พุตใน
MATLAB command windows ตามนี้
>> x= -pi:pi/180:pi; % โดย x
เป็นอินพุตของระบบประสาท
>> y=2*cos(x); % โดย y เป็นเอาท์พุตของระบบประสาท
>>net=newff(x,y,[]); % สร้างระบบเครือข่ายแบบแพร่กลับในชื่อ net
%มีกลุ่มข้อมูล x เป็นอินพุตและ y เป็นเอาท์พุต
>>out=sim(net,x); %บรรทัดนี้จะทดลองเครือข่ายชื่อ net ที่สร้างไว้
%(ตอนนี้ยังไม่มีการสอน)
>>plot(out,'rp') %ลองพล็อตกราฟดูครับ
>>MSE=mse(y-out) %ทีนี้....ลองดูค่าความผิดพลาดเฉลี่ยกำลังสองดูซิ
MSE =
3.1108
เห็นได้ว่าผิดพลาดเพียบเลย คราวนี้เอาใหม่ ลองสอนให้ระบบประสาทรู้และประมาณค่า โดยใช้อินพุต x และเอาท์พุท y เดียวกัน
>> kikapo=newff(x,y,[5,5],{'tansig','tansig'});
% สร้างระบบประสาทใหม่ในชื่อ kikapo มี x,y เป็นอินพุตและเอาท์พุตตามลำดับ
% มีชั้นซ่อน (Hidden layer) 2 ชั้น ชั้นละ 5 นิวรอน และชั้นซ่อนถูกกำหนด
% ฟังก์ชันถ่ายโอนเป็นแบบซิกมอยแบบเส้นสัมผัสไฮเปอร์โบลาร์
>> kikapo.trainParam.goal = 1e-10; % กำหนดค่าผิดพลาดเป้าหมายเป็น 10^-10
>> kikapo.trainParam.epochs = 3000; % กำหนดรอบสูงสุดในการฝึกสอนเป็น 3000
>> kikapo.trainParam.max_fail =3; % กำหนดให้ตรวจสอบค่า validation =3 (ซึ่งค่า default = 4)
>> kikapo = train(kikapo,x,y); % สอนระบบประสาทให้ประมาณค่า
ภาพในขณะ MATLAB สอนระบบปราสาทเสร็จเรียบร้อยแล้ว ถ้าหากลองกดดูที่ปุ่ม Regression เพื่อดูผลของการสอน ซึ่งถ้าหากมีค่าเข้าใกล้ 1 แสดงถึงว่ามีความแม่นยำในการสอนเพื่อให้ได้เอาท์พุตที่กำหนดได้ดีครับ
คราวนี้ลองทดสอบสิ่งที่ได้สอนเอาไว้ โดยใช้ค่าอินพุตเป็นตัวทดสอบครับ
>>out=sim(kikapo,x);
>>MSE=mse(y-out) %
ลองดูค่าความผิดพลาดเฉลี่ยกำลังสองดูอีกที
เห็นว่าผิดพลาดน้อยมากเลย
MSE =
1.3824e-006
>> plot(out,'rp') %สุดท้ายครับ ไหนลองพล๊อตกราฟดูผลของการสอนดูหน่อยสิ
>> save net_Lover kikapo %บันทึกระบบปราสาท kikapo
โดยกำหนดชื่อใหม่เป็น net_Lover
ถึงตอนนี้นั่นหมายความว่าเราได้ระบบประสาทเทียม kikapo เอาไว้ใช้งานเมื่อยามต้องการในชื่อใหม่คือ net_Lover และมันได้เรียนรู้แล้วว่าถ้าหากมีอินพุตเข้ามาในรูปแบบเดียวกันกับ x จะต้องให้เอาท์พุตออกมาในรูปแบบเดียวกันกับ out ไว้เดี๋ยวครั้งหน้าหลังปีใหม่ผมจะลองทำระบบประสาทเพื่อการรู้จำสิ่งของหรือวัตถุกันบ้าง สุขสันต์ปีใหม่ครับ
ขอบคุณมากครับ สำหรับตัวอย่าง แต่อยากได้ตัวอย่างการจำใบหน้าด้วยครับ
สุดยอดครับ
ของตัวอย่างอีกหน่อยครับ เอาเป็นเรื่องการแบ่งกลุ่มข้อมูลอะไรประมาณนี้ได้ไหมครับ
ขอสอบถามปัญหาเกี่ยวกับ Matlab ดังนี้ครับ
ผมใช้ข้อมูลป้อนเข้าสำหรับฝึกสอนโครงข่ายรวม 12 ชุดข้อมูล แต่ละชุดข้อมูลประกอบด้วย 15 ปัจจัยป้อนเข้า และ 1 ข้อมูลส่งออก
ผมใช้คำสั่ง
>> net.IW{1}
ได้คำตอบดังนี้
ans =
0.7244 -0.6191 1.1896 -0.0866 1.0128 -0.0248 0.2665 -0.0745 0.9796 -0.4823 0.4598 0.8377
0.1842 0.0961 0.5958 0.5995 0.5555 0.8246 0.4573 -0.4272 0.5375 0.1071 -0.3720 0.6663
-0.7945 0.4011 -0.0807 0.4979 0.4973 0.4130 0.5002 -0.3395 -0.2516 -0.6903 -0.1349 -1.6352
-0.0256 0.8507 0.4832 0.8467 -0.2354 -0.0545 0.5148 0.0142 0.6627 -0.4736 -0.0320 0.9822
0.4975 0.5037 0.1296 0.2969 0.5214 0.1790 -0.7569 0.1656 -0.5820 0.4392 -0.5224 -0.6618
0.1543 -0.5041 0.8852 0.2438 0.3577 0.4108 0.3759 0.1873 -0.5944 0.6972 0.6792 -0.2865
-0.3864 -0.3250 0.7383 -0.4726 -0.5098 0.5046 -0.0597 -0.1354 -1.0441 0.7039 -0.5816 1.7980
0.7518 -0.7507 0.4419 0.8125 -0.1030 0.2731 -0.0463 0.1843 -0.5117 0.2010 -0.3450 0.2240
0.5194 -0.2317 -0.4364 -0.0735 -0.4237 0.1751 -0.7401 0.2962 -0.4164 1.0191 0.4347 0.3983
0.7491 0.3181 -0.1821 -0.7875 0.4316 -0.5003 0.6654 0.2793 -0.5664 0.0424 -0.3134 0.0179
ซึ่งผมเข้าใจว่าคำตอบดังกล่าวคือ ค่าน้ำหนักระหว่าง ชุดข้อมูล 12 ชุดข้อมูล กับ 10 โหนด ของชั้นซ่อน
แต่ค่าน้ำหนักที่ผมต้องการนั้นคือ ค่าน้ำหนักของ 15 ปัจจัยของแต่ละชุดข้อมูล ไม่ทราบว่าจะสามารถใช้คำสั่งใด ที่จะสามารถดึงค่าน้ำหนัก ที่ต้องการออกมาได้ครับ
ด้วยความเคารพ
ขอบพระคุณอย่างสูงครับ
สวัสดีครับ
ผมอ่านคำถามแล้ว จึงขอแสดงการใช้งานคำสั่งและผลให้พอเป็นแนวทางนะครับ
คือ ถ้าสมมุติผมสร้างระบบประสาทไว้หนึ่งตัว แล้วมีการทดลองให้แสดงน้ำหนักโดยพิมพ์คำสั่งเป็น
>> net.IW{1,1} // (หรือ >> net.IW{1} ซึ่งได้ผลเดียวกัน)
แล้วได้คำตอบแสดงเป็น
ans =
7.7055 1.8290
-7.9089 -0.4123
นั่นหมายถึงแสดงน้ำหนักในแต่ละตำแหน่ง ดังนี้
และถ้าใช้คำสั่ง
>> net.LW{2,1}
ans =
4.6527 3.1164
นั่นหมายถึงค่าที่ได้ จะแสดงตำแหน่งดังรูปข้างล่างนี้ครับ
ขอบคุณมากๆ เลยนะครับ
ถ้าลองtestอินพุตเป็นช่วงอื่นจะได้ไหมคับ
รบกวนช่วยอธิบายให้เข้าใจง่ายๆด้วยครับอย่างเช่น-หลักการทำงานของ Feed forward propagation หรือ Backward propagation เป็นอย่างไร-ทำไมจึงเลือก Feed forward propagation หรือ Backward propagation มีข้อดี ข้อเสียอย่างไร-ฟังก์ชั่นการทำงานของแต่ละอย่างแตกต่างกันอย่างไร-การกำหนดโหนดของ Hidden layer กำหนดจากอะไร จำนวนชั้นของ Hidden layer กำหนดจากอะไร-การเลือกใช้ Activation function บางแบบใช้เหมือนกัน บางแบบใช้ไม่เหมือนกัน เพราะอะไร