ในการเรียนรู้ของเครื่อง โมเดล คือฟังก์ชันที่มี พารามิเตอร์ ที่สามารถเรียนรู้ได้ ซึ่งจับคู่อินพุตกับเอาต์พุต พารามิเตอร์ที่เหมาะสมที่สุดได้มาจากการฝึกฝนโมเดลเกี่ยวกับข้อมูล โมเดลที่ได้รับการฝึกอบรมมาอย่างดีจะให้การแมปที่แม่นยำตั้งแต่อินพุตไปยังเอาต์พุตที่ต้องการ
ใน TensorFlow.js มีสองวิธีในการสร้างโมเดลแมชชีนเลิร์นนิง:
- ใช้ Layers API ที่คุณสร้างโมเดลโดยใช้ เลเยอร์
- ใช้ Core API กับ ops ระดับล่างเช่น
tf.matMul()
,tf.add()
เป็นต้น
ขั้นแรก เราจะดูที่ Layers API ซึ่งเป็น API ระดับที่สูงกว่าสำหรับการสร้างแบบจำลองอาคาร จากนั้น เราจะแสดงวิธีสร้างโมเดลเดียวกันโดยใช้ Core API
การสร้างโมเดลด้วย Layers API
มีสองวิธีในการสร้างโมเดลโดยใช้ Layers API: โมเดล ต่อเนื่อง และโมเดล เชิงฟังก์ชัน สองส่วนถัดไปจะพิจารณาแต่ละประเภทให้ละเอียดยิ่งขึ้น
โมเดลตามลำดับ
ประเภทของโมเดลที่พบบ่อยที่สุดคือโมเดล Sequential
ซึ่งเป็นสแต็กเชิงเส้นของเลเยอร์ คุณสามารถสร้างโมเดล Sequential
ได้โดยส่งรายการเลเยอร์ไปยังฟังก์ชัน sequential()
:
const model = tf.sequential({
layers: [
tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
tf.layers.dense({units: 10, activation: 'softmax'}),
]
});
หรือผ่านทาง add()
วิธีการ:
const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
สำคัญ: เลเยอร์แรกในโมเดลจำเป็นต้องมี
inputShape
ตรวจสอบให้แน่ใจว่าคุณยกเว้นขนาดแบทช์เมื่อระบุinputShape
ตัวอย่างเช่น หากคุณวางแผนที่จะป้อนเทนเซอร์โมเดลของรูปร่าง[B, 784]
โดยที่B
อาจเป็นขนาดแบตช์ใดก็ได้ ให้ระบุinputShape
เป็น[784]
เมื่อสร้างโมเดล
คุณสามารถเข้าถึงเลเยอร์ของโมเดลได้ผ่านทาง model.layers
และโดยเฉพาะอย่างยิ่ง model.inputLayers
และ model.outputLayers
รูปแบบการทำงาน
อีกวิธีหนึ่งในการสร้าง LayersModel
คือผ่านฟังก์ชัน tf.model()
ข้อแตกต่างที่สำคัญระหว่าง tf.model()
และ tf.sequential()
ก็คือ tf.model()
ให้คุณสร้างกราฟของเลเยอร์ต่างๆ ได้ตามใจชอบ ตราบใดที่เลเยอร์เหล่านั้นไม่มีวงจร
นี่คือข้อมูลโค้ดที่กำหนดโมเดลเดียวกันกับด้านบนโดยใช้ tf.model()
API:
// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});
เราเรียก apply()
ในแต่ละเลเยอร์เพื่อเชื่อมต่อกับเอาต์พุตของเลเยอร์อื่น ผลลัพธ์ของ apply()
ในกรณีนี้คือ SymbolicTensor
ซึ่งทำหน้าที่เหมือน Tensor
แต่ไม่มีค่าที่เป็นรูปธรรม
โปรดทราบว่าไม่เหมือนกับโมเดลตามลำดับ เราสร้าง SymbolicTensor
ผ่าน tf.input()
แทนที่จะจัดเตรียม inputShape
ให้กับเลเยอร์แรก
apply()
ยังสามารถให้ Tensor
ที่เป็นรูปธรรมแก่คุณได้ หากคุณส่ง Tensor
ที่เป็นรูปธรรมไปให้:
const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]
สิ่งนี้มีประโยชน์เมื่อทดสอบเลเยอร์แบบแยกเดี่ยวและดูผลลัพธ์
เช่นเดียวกับในโมเดลตามลำดับ คุณสามารถเข้าถึงเลเยอร์ของโมเดลผ่านทาง model.layers
และโดยเฉพาะอย่างยิ่ง model.inputLayers
และ model.outputLayers
การตรวจสอบ
ทั้งโมเดลตามลำดับและโมเดลการทำงานเป็นอินสแตนซ์ของคลาส LayersModel
ประโยชน์หลักประการหนึ่งของการทำงานกับ LayersModel
คือการตรวจสอบความถูกต้อง โดยจะบังคับให้คุณระบุรูปร่างอินพุต และจะใช้ในภายหลังเพื่อตรวจสอบอินพุตของคุณ LayersModel
ยังทำการอนุมานรูปร่างอัตโนมัติเมื่อข้อมูลไหลผ่านเลเยอร์ การรู้รูปร่างล่วงหน้าช่วยให้โมเดลสร้างพารามิเตอร์ได้โดยอัตโนมัติ และสามารถบอกคุณได้ว่าเลเยอร์ที่ต่อเนื่องกันสองชั้นเข้ากันไม่ได้หรือไม่
สรุปโมเดล
โทร model.summary()
เพื่อพิมพ์ข้อมูลสรุปที่เป็นประโยชน์ของโมเดล ซึ่งประกอบด้วย:
- ชื่อและประเภทของเลเยอร์ทั้งหมดในโมเดล
- รูปร่างผลลัพธ์ของแต่ละชั้น
- จำนวนพารามิเตอร์น้ำหนักของแต่ละชั้น
- หากโมเดลมีโทโพโลยีทั่วไป (ตามที่อธิบายด้านล่าง) อินพุตที่แต่ละเลเยอร์จะได้รับ
- จำนวนพารามิเตอร์ที่สามารถฝึกได้และไม่สามารถฝึกได้ทั้งหมดของโมเดล
สำหรับโมเดลที่เรากำหนดไว้ข้างต้น เราได้รับเอาต์พุตต่อไปนี้บนคอนโซล:
ชั้น (ชนิด) | รูปร่างเอาท์พุต | พารามิเตอร์ # |
หนาแน่น_Dense1 (หนาแน่น) | [ว่าง,32] | 25120 |
หนาแน่น_Dense2 (หนาแน่น) | [ว่าง,10] | 330 |
พารามิเตอร์ทั้งหมด: 25450 พารามิเตอร์ที่ฝึกได้: 25450 พารามิเตอร์ที่ไม่สามารถฝึกได้: 0 |
สังเกตค่า null
ในรูปร่างเอาต์พุตของเลเยอร์: คำเตือนว่าโมเดลคาดว่าอินพุตจะมีขนาดแบตช์เป็นมิติด้านนอกสุด ซึ่งในกรณีนี้สามารถยืดหยุ่นได้เนื่องจากค่า null
การทำให้เป็นอนุกรม
ข้อดีหลักประการหนึ่งของการใช้ LayersModel
บน API ระดับล่างคือความสามารถในการบันทึกและโหลดโมเดล LayersModel
รู้เกี่ยวกับ:
- สถาปัตยกรรมของแบบจำลองทำให้คุณสามารถสร้างแบบจำลองขึ้นมาใหม่ได้
- น้ำหนักของแบบจำลอง
- การกำหนดค่าการฝึกอบรม (การสูญเสีย เครื่องมือเพิ่มประสิทธิภาพ เมตริก)
- สถานะของเครื่องมือเพิ่มประสิทธิภาพทำให้คุณสามารถกลับมาฝึกอบรมต่อได้
หากต้องการบันทึกหรือโหลดโมเดลให้ใช้โค้ดเพียง 1 บรรทัด:
const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');
ตัวอย่างด้านบนจะบันทึกโมเดลลงในที่จัดเก็บในตัวเครื่องในเบราว์เซอร์ ดู model.save() documentation
และคำแนะนำใน การบันทึกและโหลด สำหรับวิธีบันทึกลงในสื่อต่างๆ (เช่น พื้นที่จัดเก็บไฟล์, IndexedDB
, ทริกเกอร์การดาวน์โหลดเบราว์เซอร์ ฯลฯ )
เลเยอร์ที่กำหนดเอง
เลเยอร์เป็นส่วนสำคัญของโมเดล หากโมเดลของคุณกำลังคำนวณแบบกำหนดเอง คุณสามารถกำหนดเลเยอร์แบบกำหนดเองได้ ซึ่งจะโต้ตอบกับเลเยอร์ที่เหลือได้ดี ด้านล่างนี้เรากำหนดเลเยอร์ที่กำหนดเองซึ่งคำนวณผลรวมของกำลังสอง:
class SquaredSumLayer extends tf.layers.Layer {
constructor() {
super({});
}
// In this case, the output is a scalar.
computeOutputShape(inputShape) { return []; }
// call() is where we do the computation.
call(input, kwargs) { return input.square().sum();}
// Every layer needs a unique name.
getClassName() { return 'SquaredSum'; }
}
เพื่อทดสอบ เราสามารถเรียกเมธอด apply()
ด้วยเทนเซอร์ที่เป็นรูปธรรม:
const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30
สิ่งสำคัญ: หากคุณเพิ่มเลเยอร์ที่กำหนดเอง คุณจะสูญเสียความสามารถในการซีเรียลไลซ์โมเดล
การสร้างโมเดลด้วย Core API
ในตอนต้นของคู่มือนี้ เราได้กล่าวไว้ว่ามีสองวิธีในการสร้างโมเดลแมชชีนเลิร์นนิงใน TensorFlow.js
หลักการทั่วไปคือพยายามใช้ Layers API ก่อนเสมอ เนื่องจากได้รับการออกแบบตาม Keras API ที่ได้รับการยอมรับอย่างดี ซึ่งเป็นไปตาม แนวทางปฏิบัติที่ดีที่สุดและลดภาระการรับรู้ Layers API ยังนำเสนอโซลูชันที่มีอยู่ทั่วไปมากมาย เช่น การเริ่มต้นน้ำหนัก การทำให้เป็นอนุกรมของโมเดล การฝึกอบรมการตรวจสอบ ความสะดวกในการพกพา และการตรวจสอบความปลอดภัย
คุณอาจต้องการใช้ Core API ทุกครั้ง:
- คุณต้องการความยืดหยุ่นหรือการควบคุมสูงสุด
- คุณไม่จำเป็นต้องทำให้เป็นอนุกรม หรือใช้ตรรกะการทำให้เป็นอนุกรมของคุณเองได้
โมเดลใน Core API เป็นเพียงฟังก์ชันที่รับ Tensors
อย่างน้อย 1 ตัวและส่งคืน Tensor
โมเดลเดียวกันกับที่เขียนไว้ข้างต้นโดยใช้ Core API มีลักษณะดังนี้:
// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));
function model(x) {
return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}
โปรดทราบว่าใน Core API เรามีหน้าที่รับผิดชอบในการสร้างและเริ่มต้นน้ำหนักของโมเดล ทุกน้ำหนักได้รับการสนับสนุนโดย Variable
ซึ่งจะส่งสัญญาณไปยัง TensorFlow.js ว่าเทนเซอร์เหล่านี้สามารถเรียนรู้ได้ คุณสามารถสร้าง Variable
โดยใช้ tf.variable() และส่งผ่าน Tensor
ที่มีอยู่
ในคู่มือนี้ คุณได้ทำความคุ้นเคยกับวิธีต่างๆ ในการสร้างโมเดลโดยใช้เลเยอร์และ Core API จากนั้น ดูคำแนะนำ โมเดลการฝึก สำหรับวิธีฝึกโมเดล