สอนสร้าง MLP จำลองการทำงานแบบ RNN ด้วย Java Neuroph
Recurrent Neural Networks (RNNs) เป็นรูปแบบหนึ่งของโครงข่ายประสาทเทียมที่มีความสามารถในการจัดการข้อมูลที่มีลำดับ เช่น ข้อมูลเวลา (time series) หรือข้อความ (text sequences) อย่างไรก็ตาม Neuroph ซึ่งเป็นเฟรมเวิร์ก Java สำหรับสร้างและฝึกโครงข่ายประสาทเทียม ไม่มีการสนับสนุน RNN โดยตรง แต่สามารถปรับ Multilayer Perceptron (MLP) ให้ทำงานแบบ RNN ได้ด้วยการเพิ่มการจัดการสถานะ (state) ภายนอก
แนวคิดหลัก
- ใช้ MLP เป็นฐานของโครงข่ายประสาทเทียม
- เพิ่มกลไกการวนกลับ (feedback) โดยจัดเก็บผลลัพธ์ของเลเยอร์ซ่อน (hidden layer) และนำกลับมาใช้ใหม่ในลำดับถัดไป
- จัดการการทำงานที่คล้าย RNN ผ่านการเขียนโค้ดควบคุมภายนอก
ขั้นตอนการจำลอง RNN ด้วย MLP ใน Neuroph
- เตรียมข้อมูล: จัดการข้อมูลสำหรับการเรียนรู้แบบลำดับ เช่น การพยากรณ์ค่าถัดไปในลำดับตัวเลข (เช่น ลำดับ Fibonacci)
- สร้างโครงข่าย MLP: สร้างโครงข่าย MLP ด้วยเลเยอร์อินพุต เลเยอร์ซ่อน และเลเยอร์เอาต์พุต
- เพิ่มกลไก Feedback: เก็บค่าผลลัพธ์ของเลเยอร์ซ่อนในแต่ละลำดับ และรวมค่าดังกล่าวกับอินพุตใหม่
- การฝึกโครงข่าย: ใช้ค่าความผิดพลาด (error) ในการปรับน้ำหนักของโครงข่าย โดยใช้กฎการเรียนรู้ที่มีใน Neuroph
- การทดสอบ: ใช้โครงข่ายที่ผ่านการฝึกทำนายค่าถัดไปในลำดับและตรวจสอบความแม่นยำ
ตัวอย่างโค้ด
ตัวอย่างนี้แสดงการสร้างและฝึกโครงข่าย MLP ให้ทำงานแบบ RNN ด้วยการจำลองการพยากรณ์ค่าถัดไปในลำดับ Fibonacci:
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.Connection;
import org.neuroph.nnet.MultiLayerPerceptron;
public class SimulatedRNN {
public static void main(String[] args) {
// สร้างโครงข่าย MLP
MultiLayerPerceptron mlp = new MultiLayerPerceptron(2, 4, 1); // อินพุต 2, ซ่อน 4, เอาต์พุต 1
// ข้อมูลสำหรับฝึก
double[][] inputSequence = {
{0.0, 1.0},
{1.0, 1.0},
{1.0, 2.0},
{2.0, 3.0},
{3.0, 5.0}
};
double[] expectedOutputs = {1.0, 2.0, 3.0, 5.0, 8.0};
// สถานะซ่อนสำหรับ Feedback
double[] previousHiddenStates = new double[4];
// วนลูปการฝึก
for (int epoch = 0; epoch < 1000; epoch++) {
double totalError = 0.0;
for (int t = 0; t < inputSequence.length; t++) {
// รวมอินพุตปัจจุบันกับสถานะก่อนหน้า
double[] currentInput = inputSequence[t];
double[] fullInput = new double[currentInput.length + previousHiddenStates.length];
System.arraycopy(currentInput, 0, fullInput, 0, currentInput.length);
System.arraycopy(previousHiddenStates, 0, fullInput, currentInput.length, previousHiddenStates.length);
// ตั้งค่าอินพุตให้โครงข่าย
mlp.setInput(fullInput);
// คำนวณผลลัพธ์
mlp.calculate();
double output = mlp.getOutput()[0];
// คำนวณความผิดพลาด
double error = expectedOutputs[t] - output;
totalError += error * error;
// ฝึกโครงข่าย
mlp.getLearningRule().doLearningEpoch();
// เก็บสถานะของเลเยอร์ซ่อน
Layer hiddenLayer = mlp.getLayerAt(1);
for (int i = 0; i < hiddenLayer.getNeuronsCount(); i++) {
previousHiddenStates[i] = hiddenLayer.getNeuron(i).getOutput();
}
}
// แสดงผลความผิดพลาดในแต่ละ epoch
if (epoch % 100 == 0) {
System.out.println("Epoch " + epoch + " - Error: " + totalError);
}
}
// ทดสอบโครงข่าย
System.out.println("\nTesting the network:");
for (int t = 0; t < inputSequence.length; t++) {
double[] currentInput = inputSequence[t];
double[] fullInput = new double[currentInput.length + previousHiddenStates.length];
System.arraycopy(currentInput, 0, fullInput, 0, currentInput.length);
System.arraycopy(previousHiddenStates, 0, fullInput, currentInput.length, previousHiddenStates.length);
mlp.setInput(fullInput);
mlp.calculate();
double output = mlp.getOutput()[0];
System.out.println("Input: " + currentInput[0] + ", " + currentInput[1] + " -> Predicted: " + output);
}
}
}
สรุป
การใช้ Neuroph จำลอง RNN โดยปรับ Multilayer Perceptron (MLP) สามารถทำได้ผ่านการจัดการสถานะภายนอก ซึ่งช่วยให้โครงข่ายมีความสามารถในการเรียนรู้และทำนายข้อมูลที่มีลำดับได้ แม้ว่าจะไม่ใช่โครงสร้าง RNN ที่แท้จริง แต่แนวทางนี้เหมาะสำหรับการศึกษาแนวคิดพื้นฐานและการทดลองที่ไม่ซับซ้อนมากนัก หากต้องการโครงข่าย RNN ที่มีความซับซ้อนมากขึ้น อาจต้องพิจารณาเฟรมเวิร์กอื่น เช่น TensorFlow หรือ DL4J ที่สนับสนุน RNN โดยตรง
ความคิดเห็น
แสดงความคิดเห็น