Mô hình và lớp

Trong học máy, mô hình là một hàm với các tham số có thể học được để ánh xạ đầu vào thành đầu ra. Các tham số tối ưu thu được bằng cách huấn luyện mô hình trên dữ liệu. Một mô hình được đào tạo tốt sẽ cung cấp ánh xạ chính xác từ đầu vào đến đầu ra mong muốn.

Trong TensorFlow.js có hai cách để tạo mô hình học máy:

  1. bằng cách sử dụng API Lớp trong đó bạn xây dựng mô hình bằng cách sử dụng các lớp .
  2. sử dụng API lõi với các hoạt động cấp thấp hơn như tf.matMul() , tf.add() , v.v.

Đầu tiên, chúng ta sẽ xem xét API Lớp, đây là API cấp cao hơn để xây dựng mô hình. Sau đó, chúng tôi sẽ trình bày cách xây dựng mô hình tương tự bằng API lõi.

Tạo mô hình bằng API lớp

Có hai cách để tạo mô hình bằng API Lớp: Mô hình tuần tự và mô hình chức năng . Hai phần tiếp theo xem xét từng loại kỹ hơn.

Mô hình tuần tự

Loại mô hình phổ biến nhất là mô hình Sequential , là một chồng các lớp tuyến tính. Bạn có thể tạo mô hình Sequential bằng cách chuyển danh sách các lớp tới hàm sequential() :

const model = tf.sequential({
 layers: [
   tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
   tf.layers.dense({units: 10, activation: 'softmax'}),
 ]
});

Hoặc thông qua phương thức 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'}));

QUAN TRỌNG: Lớp đầu tiên trong mô hình cần inputShape . Đảm bảo bạn loại trừ kích thước lô khi cung cấp inputShape . Ví dụ: nếu bạn dự định cung cấp các tensor mô hình có hình dạng [B, 784] , trong đó B có thể có kích thước lô bất kỳ, hãy chỉ định inputShape[784] khi tạo mô hình.

Bạn có thể truy cập các lớp của mô hình thông qua model.layers và cụ thể hơn là model.inputLayersmodel.outputLayers .

Mô hình chức năng

Một cách khác để tạo LayersModel là thông qua hàm tf.model() . Sự khác biệt chính giữa tf.model()tf.sequential()tf.model() cho phép bạn tạo biểu đồ các lớp tùy ý, miễn là chúng không có chu trình.

Đây là đoạn mã xác định mô hình tương tự như trên bằng API tf.model() :

// 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});

Chúng tôi gọi apply() trên mỗi lớp để kết nối nó với đầu ra của lớp khác. Kết quả của apply() trong trường hợp này là SymbolicTensor , hoạt động giống như Tensor nhưng không có bất kỳ giá trị cụ thể nào.

Lưu ý rằng không giống như mô hình tuần tự, chúng tôi tạo SymbolicTensor thông qua tf.input() thay vì cung cấp inputShape cho lớp đầu tiên.

apply() cũng có thể cung cấp cho bạn một Tensor cụ thể, nếu bạn chuyển một Tensor cụ thể cho nó:

const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]

Điều này có thể hữu ích khi kiểm tra các lớp riêng biệt và xem kết quả đầu ra của chúng.

Giống như trong một mô hình tuần tự, bạn có thể truy cập các lớp của mô hình thông qua model.layers và cụ thể hơn là model.inputLayersmodel.outputLayers .

Xác thực

Cả mô hình tuần tự và mô hình chức năng đều là các thể hiện của lớp LayersModel . Một trong những lợi ích chính khi làm việc với LayersModel là xác thực: nó buộc bạn phải chỉ định hình dạng đầu vào và sẽ sử dụng nó sau này để xác thực đầu vào của bạn. LayersModel cũng tự động thực hiện suy luận hình dạng khi dữ liệu truyền qua các lớp. Việc biết trước hình dạng cho phép mô hình tự động tạo các tham số của nó và có thể cho bạn biết liệu hai lớp liên tiếp có tương thích với nhau hay không.

Tóm tắt mô hình

Gọi model.summary() để in bản tóm tắt hữu ích của mô hình, bao gồm:

  • Tên và loại của tất cả các lớp trong mô hình.
  • Hình dạng đầu ra cho mỗi lớp.
  • Số thông số trọng lượng của mỗi lớp.
  • Nếu mô hình có cấu trúc liên kết chung (được thảo luận bên dưới), đầu vào mà mỗi lớp nhận được
  • Tổng số tham số có thể huấn luyện và không thể huấn luyện của mô hình.

Đối với mô hình mà chúng tôi đã xác định ở trên, chúng tôi nhận được kết quả đầu ra sau trên bảng điều khiển:

Lớp (loại) Hình dạng đầu ra Thông số #
dày đặc_Dense1 (Dày đặc) [không, 32] 25120
dày đặc_Dense2 (Dày đặc) [không,10] 330
Tổng thông số: 25450
Thông số có thể đào tạo: 25450
Thông số không thể đào tạo: 0

Lưu ý các giá trị null trong hình dạng đầu ra của các lớp: lời nhắc rằng mô hình mong muốn đầu vào có kích thước lô là kích thước ngoài cùng, trong trường hợp này có thể linh hoạt do giá trị null .

Tuần tự hóa

Một trong những lợi ích chính của việc sử dụng LayersModel so với API cấp thấp hơn là khả năng lưu và tải mô hình. Một LayersModel biết về:

  • kiến trúc của mô hình, cho phép bạn tạo lại mô hình.
  • trọng lượng của mô hình
  • cấu hình đào tạo (mất mát, trình tối ưu hóa, số liệu).
  • trạng thái của trình tối ưu hóa, cho phép bạn tiếp tục đào tạo.

Để lưu hoặc tải mô hình chỉ cần 1 dòng mã:

const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');

Ví dụ trên lưu mô hình vào bộ nhớ cục bộ trong trình duyệt. Xem model.save() documentation cũng như hướng dẫn lưu và tải để biết cách lưu vào các phương tiện khác nhau (ví dụ: lưu trữ tệp, IndexedDB , kích hoạt tải xuống trình duyệt, v.v.)

Lớp tùy chỉnh

Các lớp là các khối xây dựng của một mô hình. Nếu mô hình của bạn đang thực hiện tính toán tùy chỉnh, bạn có thể xác định một lớp tùy chỉnh, lớp này tương tác tốt với các lớp còn lại. Dưới đây chúng tôi xác định một lớp tùy chỉnh tính tổng bình phương:

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'; }
}

Để kiểm tra nó, chúng ta có thể gọi phương thức apply() bằng một tenxơ cụ thể:

const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30

QUAN TRỌNG: Nếu bạn thêm một lớp tùy chỉnh, bạn sẽ mất khả năng sắp xếp theo thứ tự một mô hình.

Tạo mô hình bằng API lõi

Ở phần đầu của hướng dẫn này, chúng tôi đã đề cập rằng có hai cách để tạo mô hình học máy trong TensorFlow.js.

Nguyên tắc chung là luôn cố gắng sử dụng API Lớp trước tiên vì nó được mô hình hóa theo API Keras được áp dụng tốt, tuân theo các phương pháp hay nhất và giảm tải nhận thức . API Lớp cũng cung cấp nhiều giải pháp sẵn có khác nhau như khởi tạo trọng lượng, tuần tự hóa mô hình, đào tạo giám sát, tính di động và kiểm tra an toàn.

Bạn có thể muốn sử dụng API lõi bất cứ khi nào:

  • Bạn cần sự linh hoạt hoặc kiểm soát tối đa.
  • Bạn không cần tuần tự hóa hoặc có thể triển khai logic tuần tự hóa của riêng mình.

Các mô hình trong API lõi chỉ là các hàm lấy một hoặc nhiều Tensors và trả về Tensor . Mô hình tương tự như trên được viết bằng API lõi trông như thế này:

// 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();
}

Lưu ý rằng trong Core API, chúng tôi chịu trách nhiệm tạo và khởi tạo trọng số của mô hình. Mỗi trọng số đều được hỗ trợ bởi một Variable báo hiệu cho TensorFlow.js rằng các tensor này có thể học được. Bạn có thể tạo một Variable bằng cách sử dụng tf.variable() và chuyển vào một Tensor hiện có.

Trong hướng dẫn này, bạn đã tự làm quen với các cách khác nhau để tạo mô hình bằng cách sử dụng Lớp và API lõi. Tiếp theo, hãy xem hướng dẫn về mô hình đào tạo để biết cách đào tạo mô hình.