TensorFlow.js: Xây dựng một hệ thống phát hiện bình luận không liên quan

1. Trước khi bắt đầu

Trong hơn một thập kỷ qua, các ứng dụng web đã trở nên phổ biến và có tính tương tác cao hơn, với việc hỗ trợ nội dung đa phương tiện, bình luận và nhiều nội dung khác diễn ra theo thời gian thực, có khả năng là hàng chục nghìn người trên một trang web tương đối phổ biến.

Điều này cũng tạo ra cơ hội cho những kẻ vi phạm lợi dụng những hệ thống như vậy và liên kết nội dung ít mặn với các bài viết, video và bài đăng mà người khác đã viết nhằm mục đích tăng khả năng hiển thị.

Các phương pháp cũ hơn để phát hiện nội dung vi phạm, chẳng hạn như danh sách từ bị chặn, có thể dễ dàng bị bỏ qua và không đơn giản là phù hợp với các bot vi phạm nâng cao vì sự phức tạp này liên tục phát triển. Hôm nay, bạn có thể sử dụng các mô hình máy học đã được đào tạo để phát hiện nội dung vi phạm như vậy ngay bây giờ.

Thông thường, việc chạy mô hình máy học để lọc trước bình luận sẽ được thực hiện ở phía máy chủ, nhưng với TensorFlow.js, giờ đây bạn có thể thực thi mô hình máy học ở phía máy khách, trong trình duyệt qua JavaScript. Bạn có thể dừng thư rác trước khi thư rác thậm chí chạm vào phía sau, có thể tiết kiệm được tài nguyên phía máy chủ tốn kém.

Như bạn có thể đã biết, công nghệ máy học hiện nay đang rất thịnh hành và chạm đến hầu hết mọi ngành trên mạng, nhưng làm thế nào để bạn có thể thực hiện những bước đầu tiên để sử dụng các chức năng này với tư cách là nhà phát triển web?

Lớp học lập trình này sẽ chỉ cho bạn cách xây dựng một ứng dụng web, từ một canvas trống, để giải quyết vấn đề thực tế của bình luận không liên quan, bằng cách sử dụng chế độ xử lý ngôn ngữ tự nhiên (nghệ thuật hiểu ngôn ngữ của con người bằng máy tính). Nhiều nhà phát triển web sẽ gặp phải vấn đề này khi họ làm việc trên một trong ngày càng nhiều ứng dụng web phổ biến hiện có và lớp học lập trình này sẽ cho phép bạn giải quyết những vấn đề như vậy một cách hiệu quả.

Điều kiện tiên quyết

Lớp học lập trình này dành cho những nhà phát triển web mới sử dụng công nghệ máy học và đang muốn bắt đầu sử dụng các mô hình được đào tạo trước cùng TensorFlow.js.

Quen thuộc với HTML5, CSS và JavaScript được giả định cho phòng thí nghiệm này.

Kiến thức bạn sẽ học được

Bạn sẽ:

  • Tìm hiểu thêm về TensorFlow.js là gì và những mô hình nào có sẵn để xử lý ngôn ngữ tự nhiên.
  • Tạo một trang web HTML / CSS / JS đơn giản cho blog blog hư cấu có phần bình luận theo thời gian thực.
  • Sử dụng TensorFlow.js để tải mô hình máy học được đào tạo trước có khả năng dự đoán một câu đã nhập có khả năng là vi phạm hay không. Nếu có thì hãy cảnh báo người dùng rằng bình luận của họ đã được giữ lại để kiểm duyệt.
  • Mã hóa các câu bình luận theo cách mà mô hình máy học có thể sử dụng để phân loại.
  • Diễn giải kết quả mô hình máy học để quyết định xem bạn có muốn tự động gắn cờ bình luận hay không. Trải nghiệm người dùng giả định này có thể được sử dụng lại trên bất kỳ trang web nào mà bạn đang làm việc và được điều chỉnh cho phù hợp với mọi trường hợp sử dụng – có thể đó là một blog, diễn đàn thông thường hoặc một dạng CMS nào đó như Drupal.

Khá khá. Việc này có khó không? Không. Vậy nên hãy tấn công...

Bạn cần có

  • ưu tiên một tài khoản Glching.com và bạn có thể sử dụng môi trường phân phát web mà bạn cảm thấy thoải mái khi chỉnh sửa và tự chạy.

2. TensorFlow.js là gì?

1aee0ede85885520.png

TensorFlow.js là một thư viện công nghệ máy học nguồn mở có thể chạy ở mọi nơi có thể chạy JavaScript. Dựa trên thư viện TensorFlow được viết bằng Python nhằm mục đích tạo lại trải nghiệm này cho nhà phát triển và tập hợp các API cho hệ sinh thái JavaScript.

Tôi có thể sử dụng mục hàng này ở đâu?

Do tính di động của JavaScript, giờ đây bạn có thể dễ dàng viết bằng 1 ngôn ngữ và thực hiện công nghệ máy học trên tất cả các nền tảng sau đây:

  • Phía máy khách trong trình duyệt web sử dụng JavaScript vani
  • Phía máy chủ và thậm chí cả các thiết bị IoT như Raspberry Pi bằng Node.js
  • Ứng dụng dành cho máy tính sử dụng Electron
  • Ứng dụng gốc dành cho thiết bị di động sử dụng React Original

TensorFlow.js cũng hỗ trợ nhiều phần phụ trợ trong mỗi môi trường này (ví dụ: các môi trường dựa trên phần cứng thực tế mà nó có thể thực thi trong đó, chẳng hạn như CPU hoặc WebGL). &"backend" trong ngữ cảnh này không có nghĩa là môi trường phía máy chủ - ví dụ: phần phụ trợ cho quá trình thực thi có thể là phía máy khách trong WebGL) để đảm bảo khả năng tương thích và cũng giữ cho mọi thứ chạy nhanh. Hiện tại, TensorFlow.js hỗ trợ:

  • Thực thi WebGL trên thẻ đồ họa của thiết bị (GPU) – đây là cách nhanh nhất để thực thi các kiểu máy lớn hơn (có kích thước hơn 3MB) bằng tính năng tăng tốc GPU.
  • Quá trình thực thi Web Assembly (WASM) trên CPU – chẳng hạn như để cải thiện hiệu suất CPU trên các thiết bị, bao gồm cả điện thoại di động thế hệ cũ. Định dạng này phù hợp hơn với các kiểu máy nhỏ hơn (có kích thước nhỏ hơn 3MB) và thực sự có thể thực thi nhanh hơn trên CPU có WASM so với WebGL do quá trình tải nội dung lên bộ xử lý đồ họa.
  • Thực thi CPU - dự phòng không được có sẵn trong môi trường nào khác. Đây là tốc độ chậm nhất trong ba kết quả nhưng luôn có sẵn cho bạn.

Lưu ý: Bạn có thể chọn bắt buộc một trong những phần phụ trợ này nếu biết thiết bị mà bạn sẽ thực thi hoặc bạn chỉ cần để TensorFlow.js quyết định giúp mình nếu bạn không chỉ định việc này.

Siêu sức mạnh phía máy khách

Việc chạy TensorFlow.js trong trình duyệt web trên máy khách có thể dẫn đến một số lợi ích đáng xem.

Quyền riêng tư

Bạn có thể vừa huấn luyện và phân loại dữ liệu trên máy khách mà không cần gửi dữ liệu đến máy chủ web của bên thứ ba. Đôi khi, điều này có thể là yêu cầu để tuân thủ luật pháp địa phương, chẳng hạn như GDPR (Quy định chung về bảo vệ dữ liệu) hay khi xử lý bất kỳ dữ liệu nào mà người dùng có thể muốn lưu giữ trên máy của mình và không gửi cho bên thứ ba.

Tốc độ

Vì bạn không phải gửi dữ liệu đến máy chủ từ xa, suy luận (hành động phân loại dữ liệu) có thể nhanh hơn. Điều tuyệt vời hơn nữa là bạn có thể truy cập trực tiếp vào các cảm biến của thiết bị như máy ảnh, micrô, GPS, gia tốc kế và các cảm biến khác nếu người dùng cấp quyền truy cập cho bạn.

Phạm vi tiếp cận và quy mô

Chỉ với một cú nhấp chuột, mọi người trên thế giới đều có thể nhấp vào một đường liên kết mà bạn gửi cho họ, mở trang web trong trình duyệt của họ và sử dụng những nội dung bạn đã tạo ra. Không cần phải thiết lập máy chủ Linux phức tạp với trình điều khiển CUDA và nhiều thiết bị khác chỉ để sử dụng hệ thống máy học.

Chi phí

Không có máy chủ nào có nghĩa là bạn chỉ cần trả tiền cho một CDN là lưu trữ các tệp HTML, CSS, JS và mô hình của mình. Chi phí của CDN rẻ hơn nhiều so với việc giữ cho máy chủ (có thể gắn thẻ đồ họa) chạy 24/7.

Các tính năng phía máy chủ

Việc tận dụng việc triển khai Node.js của TensorFlow.js sẽ cho phép các tính năng sau.

Hỗ trợ CUDA đầy đủ

Về phía máy chủ, để tăng tốc thẻ đồ họa, bạn phải cài đặt trình điều khiển NVIDIA CUDA để cho phép TensorFlow hoạt động với thẻ đồ họa (không giống như trong trình duyệt sử dụng WebGL – không cần cài đặt). Tuy nhiên, với sự hỗ trợ đầy đủ của CUDA, bạn có thể tận dụng tối đa khả năng cấp thấp hơn của thẻ đồ họa, dẫn đến thời gian đào tạo và suy luận nhanh hơn. Hiệu suất ngang bằng với việc triển khai Python TensorFlow vì cả hai đều có cùng một phần phụ trợ C++.

Kích thước mô hình

Đối với các mô hình tiên tiến từ nghiên cứu, bạn có thể làm việc với các mô hình rất lớn, có thể là lớn hơn 1 gigabyte. Không thể chạy các mô hình này trong trình duyệt web do giới hạn sử dụng bộ nhớ trên mỗi tab trình duyệt. Để chạy những mô hình lớn hơn này, bạn có thể sử dụng Node.js trên máy chủ của riêng mình với thông số kỹ thuật phần cứng mà bạn cần để chạy mô hình đó một cách hiệu quả.

IOT

Node.js được hỗ trợ trên các máy tính bảng đơn phổ biến như Raspberry Pi. Điều này cũng có nghĩa là bạn cũng có thể thực thi các mô hình TensorFlow.js trên các thiết bị như vậy.

Tốc độ

Node.js được viết bằng JavaScript, có nghĩa là nó có lợi từ việc tổng hợp thời gian. Điều này có nghĩa là bạn có thể thường thấy sự tăng hiệu suất khi sử dụng Node.js vì hiệu suất sẽ được tối ưu hoá vào thời gian chạy, đặc biệt là đối với bất kỳ quá trình xử lý trước nào bạn có thể đang thực hiện. Ví dụ điển hình về điều này trong nghiên cứu điển hình này cho thấy cách H ôm Face dùng Node.js để tăng hiệu quả gấp 2 lần cho mô hình xử lý ngôn ngữ tự nhiên.

Giờ đây, bạn đã hiểu được những thông tin cơ bản về TensorFlow.js và có thể tận hưởng một số lợi ích nào đó, hãy bắt đầu làm những việc hữu ích bằng cách này!

3. Mô hình được đào tạo trước

Tại sao tôi muốn dùng mô hình đã đào tạo trước?

Bắt đầu với mô hình được đào tạo trước phổ biến, có một số lợi ích nếu mô hình đó phù hợp với trường hợp sử dụng mong muốn của bạn, chẳng hạn như:

  1. Bạn không cần phải tự thu thập dữ liệu đào tạo. Việc chuẩn bị dữ liệu theo đúng định dạng và gắn nhãn dữ liệu để hệ thống máy học có thể sử dụng dữ liệu đó để học hỏi, có thể rất tốn thời gian và chi phí.
  2. Khả năng tạo mẫu nhanh cho một ý tưởng với chi phí và thời gian giảm.
    Không có điểm quan trọng; việc đổi mới bánh xe sẽ có ý nghĩa; khi một mô hình được đào tạo trước có thể đủ tốt để làm những gì bạn cần, cho phép bạn tập trung vào việc sử dụng kiến thức do mô hình này cung cấp để triển khai các ý tưởng sáng tạo của mình.
  3. Sử dụng nghiên cứu nghệ thuật. Các mô hình được đào tạo trước thường dựa trên nghiên cứu phổ biến, cho phép bạn tiếp xúc với các mô hình đó đồng thời hiểu rõ hiệu suất của các mô hình đó trong thực tế.
  4. Tài liệu dễ sử dụng và tài liệu mở rộng. Do sự phổ biến của các mô hình này.
  5. Chuyển chức năng học. Một số mô hình được đào tạo trước cung cấp khả năng chuyển học, về cơ bản là phương pháp chuyển thông tin học được từ một tác vụ máy học sang một ví dụ tương tự khác. Ví dụ: một mô hình ban đầu được đào tạo để nhận dạng mèo có thể được đào tạo lại để nhận dạng chó, nếu bạn cung cấp cho mô hình dữ liệu huấn luyện mới. Quá trình này sẽ nhanh hơn vì bạn sẽ không bắt đầu bằng một canvas trống. Mô hình này có thể sử dụng những gì đã học được để nhận ra mèo và sau đó nhận ra những vật mới – chó cũng có mắt và tai, vì vậy, nếu đã biết cách tìm các tính năng đó, chúng ta sẽ đi được nửa chặng đường. Đào tạo lại mô hình này dựa trên dữ liệu của bạn theo cách nhanh hơn nhiều.

Mô hình phát hiện bình luận không liên quan được đào tạo trước

Bạn sẽ sử dụng cấu trúc mô hình Nhúng từ trung bình cho nhu cầu phát hiện spam nhận xét của bạn. Tuy nhiên, nếu bạn cố gắng sử dụng mô hình chưa được đào tạo thì sẽ không có khả năng đoán ngẫu nhiên nếu các câu đó là spam hoặc không.

Để mô hình này hữu ích, cần đào tạo dữ liệu tùy chỉnh trong trường hợp này, để cho phép mô hình này biết được bình luận vi phạm so với bình luận không phải nội dung vi phạm. Từ đó, việc này sẽ có cơ hội phân loại chính xác mọi thứ trong tương lai.

Rất may là ai đó đã đào tạo cấu trúc mô hình chính xác này cho nhiệm vụ phân loại spam này và bạn có thể dùng cấu trúc này làm điểm xuất phát. Bạn có thể tìm thấy các mô hình đã đào tạo trước khác bằng cùng một cấu trúc mô hình để thực hiện những việc khác nhau, chẳng hạn như phát hiện ngôn ngữ được viết trong nhận xét hay dự đoán dữ liệu biểu mẫu liên hệ của trang web có được tự động định tuyến tới nhóm công ty nhất định hay không dựa trên văn bản bán hàng (ví dụ: yêu cầu sản phẩm) hoặc kỹ thuật (lỗi kỹ thuật hoặc phản hồi). Với đủ dữ liệu đào tạo, một mô hình như thế này có thể học cách phân loại những văn bản đó trong mỗi trường hợp để giúp ứng dụng web của bạn có được hiệu quả cao hơn và cải thiện hiệu quả của tổ chức mình.

Trong phòng thí nghiệm mã trong tương lai, bạn sẽ tìm hiểu cách sử dụng Trình tạo mô hình để đào tạo lại mô hình spam nhận xét được đào tạo trước đó và cải thiện hiệu suất hơn nữa trên dữ liệu nhận xét của riêng bạn. Hiện tại, bạn sẽ sử dụng mô hình phát hiện bình luận không liên quan hiện có làm điểm xuất phát để giúp ứng dụng web ban đầu hoạt động như một nguyên mẫu đầu tiên.

Mô hình phát hiện bình luận không được huấn luyện trước này đã được phát hành lên một trang web có tên là TF Hub, một kho lưu trữ mô hình máy học do Google duy trì. Tại đây, các kỹ sư máy học có thể xuất bản các mô hình tạo trước của họ cho nhiều trường hợp sử dụng phổ biến (chẳng hạn như văn bản, thị giác, âm thanh và nhiều mô hình khác cho từng trường hợp sử dụng cụ thể). Hãy tiếp tục và tải các tệp mô hình xuống ngay bây giờ để dùng trong ứng dụng web trong lớp học lập trình này.

Nhấp vào nút tải xuống đối với mô hình JS như bên dưới:

ab65deff89b3d939.png

4. Thiết lập bằng mã

Bạn cần có

Cùng lập trình.

Chúng tôi đã tạo một mẫu Glrick.com Node.js Express cho mẫu để bắt đầu từ đó bạn có thể chỉ cần sao chép làm trạng thái cơ sở cho phòng thí nghiệm mã này chỉ bằng một cú nhấp chuột.

Trên Glrick chỉ cần nhấp vào nút "remix this" để âm thanh và tạo một bộ tệp mới mà bạn có thể chỉnh sửa.

Bộ khung rất đơn giản này cung cấp cho chúng tôi các tệp sau trong thư mục www:

  1. Trang HTML (index.html)
  2. Biểu định kiểu (style.css)
  3. Tệp để viết mã JavaScript của chúng tôi (script.js)

Để thuận tiện cho bạn, chúng tôi cũng đã thêm tệp HTML để nhập cho thư viện TensorFlow.js trông như sau:

index.html

<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js" type="text/javascript"></script>

Sau đó, chúng tôi phân phát thư mục www này qua máy chủ Node Express đơn giản thông qua package.jsonserver.js

5. Tạo mẫu cho ứng dụng HTML

Điểm xuất phát của bạn là gì?

Tất cả các nguyên mẫu yêu cầu một nền tảng HTML cơ bản mà bạn có thể hiển thị các phát hiện của mình trên đó. Hãy thiết lập ngay. Bạn sẽ thêm:

  • Tiêu đề cho trang
  • Một số văn bản mô tả
  • Video giữ chỗ đại diện cho mục nhập video trên blog
  • Khu vực để xem và nhập nhận xét

Hãy mở index.html và dán lên mã hiện có theo hướng dẫn sau để thiết lập các tính năng ở trên:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Pretend Video Blog</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css">
  </head>  
  <body>
    <header>
      <h1>MooTube</h1>
      <a id="login" href="#">Login</a>
    </header>
    
    <h2>Check out the TensorFlow.js rap for the show and tell!</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ipsum quam, tincidunt et tempor in, pulvinar vel urna. Nunc eget erat pulvinar, lacinia nisl in, rhoncus est. Morbi molestie vestibulum nunc. Integer non ipsum dolor. Curabitur condimentum sem eget odio dapibus, nec bibendum augue ultricies. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed iaculis ut ligula sed tempor. Phasellus ac dictum felis. Integer arcu dui, facilisis sit amet placerat sagittis, blandit sit amet risus.</p>
    
    <iframe width="100%" height="500" src="https://www.youtube.com/embed/RhVs7ijB17c" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

    <section id="comments" class="comments">
      <div id="comment" class="comment" contenteditable></div>
      <button id="post" type="button">Comment</button>

      <ul id="commentsList">
        <li>
          <span class="username">NotASpammer</span>
          <span class="timestamp">3/18/2021, 6:52:16 PM</span> 
          <p>I am not a spammer, I am a good boy.</p>
        </li>
        <li>
          <span class="username">SomeUser</span>
          <span class="timestamp">2/11/2021, 3:10:00 PM</span>
          <p>Wow, I love this video, so many amazing demos!</p>
        </li>
      </ul>
    </section>
    

    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js" type="text/javascript"></script>

    <!-- Import the page's JavaScript to do some stuff -->
    <script type="module" src="/script.js"></script>
  </body>
</html>

Phân tích

Hãy chia nhỏ một số mã HTML ở trên để làm nổi bật một số nội dung chính bạn đã thêm.

  • Bạn đã thêm thẻ <h1> cho tiêu đề trang cùng với thẻ <a> cho nút đăng nhập, tất cả đều có trong <header>. Sau đó, bạn thêm <h2> cho tiêu đề bài viết và thẻ <p> cho phần mô tả của video. Không có gì đặc biệt ở đây.
  • Bạn đã thêm một thẻ iframe nhúng một video bất kỳ trên YouTube. Hiện tại, bạn đang sử dụng bản rap TensorFlow.js mạnh mẽ làm trình giữ chỗ, nhưng bạn có thể đặt bất kỳ video nào mình muốn ở đây chỉ bằng cách thay đổi URL của iframe. Trên thực tế, trên trang web thực tế, tất cả các giá trị này sẽ được hiển thị động trong phần phụ trợ, tùy thuộc vào trang đang được xem.
  • Cuối cùng, bạn đã thêm section có mã nhận dạng và lớp "comments" chứa một div có thể chỉnh sửa nội dung để viết nhận xét mới cùng với button để gửi nhận xét mới mà bạn muốn thêm cùng với danh sách nhận xét không có thứ tự. Bạn có tên người dùng và thời gian đăng trong thẻ span bên trong mỗi mục trong danh sách, sau đó là chính nhận xét trong thẻ p. 2 ví dụ về nhận xét được mã hóa cứng ngay bây giờ dưới dạng phần giữ chỗ.

Nếu bạn xem trước kết quả ngay bây giờ, mã sẽ trông như thế này:

73c8338334d5b251.png

Ôi, thật tệ quá, đã đến lúc thêm một vài kiểu...

6. Thêm kiểu

Giá trị mặc định của phần tử

Trước tiên, hãy thêm kiểu cho các phần tử HTML mà bạn vừa thêm để đảm bảo rằng các kiểu này hiển thị chính xác.

Bắt đầu bằng cách áp dụng quy trình đặt lại CSS để có điểm bắt đầu nhận xét trên tất cả các trình duyệt và hệ điều hành. Ghi đè nội dung style.css bằng các mục sau:

style.css

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

Tiếp theo, hãy thêm vào một số CSS hữu ích để làm cho giao diện người dùng trở nên sống động.

Thêm phần sau vào cuối style.css bên dưới mã CSS đã đặt lại mà bạn đã thêm ở trên:

style.css

/* CSS files add styling rules to your content */
body {
  background: #212121;
  color: #fff;
  font-family: helvetica, arial, sans-serif;
}

header {
  background: linear-gradient(0deg, rgba(7,7,7,1) 0%, rgba(7,7,7,1) 85%, rgba(55,52,54,1) 100%);
  min-height: 30px;
  overflow: hidden;
}

h1 {
  color: #f0821b;
  font-size: 24pt;
  padding: 15px 25px;
  display: inline-block;
  float: left;
}

h2, p, section, iframe {
  background: #212121;
  padding: 10px 25px;
}

h2 {
  font-size: 16pt;
  padding-top: 25px;
}

p {
  color: #cdcdcd;
}

iframe {
  display: block;
  padding: 15px 0;
}

header a, button {
  color: #222;
  padding: 7px;
  min-width: 100px;
  background: rgb(240, 130, 30);
  border-radius: 3px;
  border: 1px solid #3d3d3d;
  text-transform: uppercase;
  font-weight: bold;
  cursor: pointer;
  transition: background 300ms ease-in-out;
}

header a {
  background: #efefef;
  float: right;
  margin: 15px 25px;
  text-decoration: none;
  text-align: center;
}

button:focus, button:hover, header a:hover {
  background: rgb(260, 150, 50);
}

.comment {
  background: #212121;
  border: none;
  border-bottom: 1px solid #888;
  color: #fff;
  min-height: 25px;
  display: block;
  padding: 5px;
}

.comments button {
  float: right;
  margin: 5px 0;
}

.comments button, .comment {
  transition: opacity 500ms ease-in-out;
}

.comments ul {
  clear: both;
  margin-top: 60px;
}

.comments ul li {
  margin-top: 5px;
  padding: 10px;
  transition: background 500ms ease-in-out;
}

.comments ul li * {
  background: transparent;
}

.comments ul li:nth-child(1) {
  background: #313131;
}

.comments ul li:hover {
  background: rgb(70, 60, 10);
}

.username, .timestamp {
  font-size: 80%;
  margin-right: 5px;
}

.username {
  font-weight: bold;
}

.processing {
  opacity: 0.3;
  filter: grayscale(1);
}

.comments ul li.spam {
  background-color: #d32f2f;
}

.comments ul li.spam::after {
  content: "⚠";
  margin: -17px 2px;
  zoom: 3;
  float: right;
}

Tuyệt vời! Đó là tất cả những gì bạn cần. Nếu bạn đã ghi đè thành công kiểu của mình bằng 2 đoạn mã ở trên, thì bản xem trước trực tiếp sẽ trông như sau:

b86be8e2f6e7456.png

Chế độ ban đêm ngọt ngào và chuyển đổi CSS đẹp mắt cho hiệu ứng di chuột qua các thành phần chính. Tuyệt vời. Bây giờ, hãy tích hợp một số logic hành vi bằng JavaScript.

7. JavaScript: thao tác DOM và amp; Trình xử lý sự kiện

Tham chiếu các phần tử DOM chính

Trước tiên, hãy đảm bảo rằng bạn có thể truy cập vào các phần chính của trang mà bạn sẽ cần phải thao tác hoặc truy cập sau đó trong mã cùng với việc xác định một số hằng số lớp CSS để định kiểu.

Bắt đầu bằng cách thay thế nội dung của script.js bằng các hằng số sau:

tập lệnh.js

const POST_COMMENT_BTN = document.getElementById('post');
const COMMENT_TEXT = document.getElementById('comment');
const COMMENTS_LIST = document.getElementById('commentsList');
// CSS styling class to indicate comment is being processed when
// posting to provide visual feedback to users.
const PROCESSING_CLASS = 'processing';

// Store username of logged in user. Right now you have no auth
// so default to Anonymous until known.
var currentUserName = 'Anonymous';

Xử lý bài đăng nhận xét

Tiếp theo, hãy thêm một hàm xử lý và trình xử lý sự kiện vào POST_COMMENT_BTN để nó có khả năng lấy văn bản nhận xét đã viết và đặt một lớp CSS cho biết quá trình xử lý đã bắt đầu. Lưu ý rằng bạn kiểm tra để đảm bảo rằng bạn chưa nhấp vào nút trong quá trình xử lý.

script.js

/** 
 * Function to handle the processing of submitted comments.
 **/
function handleCommentPost() {
  // Only continue if you are not already processing the comment.
  if (! POST_COMMENT_BTN.classList.contains(PROCESSING_CLASS)) {
    POST_COMMENT_BTN.classList.add(PROCESSING_CLASS);
    COMMENT_TEXT.classList.add(PROCESSING_CLASS);
    let currentComment = COMMENT_TEXT.innerText;
    console.log(currentComment);
    
    // TODO: Fill out the rest of this function later.
  }
}

POST_COMMENT_BTN.addEventListener('click', handleCommentPost);

Tuyệt vời! Nếu bạn làm mới trang web và thử đăng nhận xét, giờ đây, bạn sẽ thấy nút nhận xét và văn bản chuyển sang màu xám. Trong bảng điều khiển, bạn sẽ thấy nhận xét được in như sau:

827b5f3d09afbb21.png

Giờ bạn đã có bộ khung HTML / CSS / JS cơ bản, đã đến lúc chuyển sự chú ý của bạn sang mô hình máy học để có thể tích hợp mô hình đó với trang web đẹp mắt.

8. Phân phát mô hình máy học

Bạn gần như đã sẵn sàng tải mô hình. Trước khi làm điều đó, bạn phải tải các tệp mẫu đã tải xuống trước đó trong lớp học lập trình lên trang web của mình để tệp được lưu trữ và có thể sử dụng trong mã.

Trước tiên, nếu bạn chưa làm vậy, hãy giải nén các tệp mà bạn đã tải xuống cho mô hình ở đầu lớp học lập trình này. Bạn sẽ thấy một thư mục chứa các tệp sau có trong:

5634d536ef8be9ca.png

Bạn có gì ở đây?

  • model.json – Đây là một trong các tệp tạo nên mô hình TensorFlow.js đã qua đào tạo. Bạn sẽ thực sự tham chiếu tệp cụ thể này sau đó trong mã TensorFlow.js của bạn.
  • group1-shard1of1.bin – Đây là một tệp nhị phân có chứa các trọng số được đào tạo (về cơ bản là một tập hợp con số được tìm hiểu để thực hiện tốt nhiệm vụ phân loại) của mô hình TensorFlow.js và sẽ cần được lưu trữ ở nơi nào đó trên máy chủ của bạn để tải xuống.
  • vocab – Tệp lạ này không có phần mở rộng là nội dung của Model Maker cho chúng ta biết cách mã hóa các từ trong câu để mô hình hiểu cách sử dụng chúng. Bạn sẽ tìm hiểu kỹ hơn về vấn đề này trong phần tiếp theo.
  • labels.txt – Tên này chỉ chứa tên lớp thu được mà mô hình sẽ dự đoán. Đối với mô hình này, nếu bạn mở tệp này trong trình chỉnh sửa văn bản, tệp sẽ chỉ có "false" và "true" được liệt kê, cho biết "không phải spam" hoặc "spam" dưới dạng kết quả dự đoán.

Lưu trữ tệp mô hình TensorFlow.js

Trước tiên, hãy đặt model.json và tệp *.bin đã được tạo lên máy chủ web để bạn có thể truy cập chúng qua trang web.

Tải tệp lên hệ thống khắc phục sự cố

  1. Nhấp vào thư mục tài sản trong bảng điều khiển bên trái của dự án Glgrave.
  2. Nhấp vào tải tài sản lên và chọn group1-shard1of1.bin để tải lên thư mục này. Thì giờ URL đó sẽ có dạng như sau khi được tải lên:

25a2251c7f165184.png

  1. Tuyệt vời! Bây giờ, hãy làm tương tự đối với tệp model.json. 2 tệp cần nằm trong thư mục tài sản của bạn như sau:

51a6dbd5d3097ffc.png

  1. Nhấp vào tệp group1-shard1of1.bin mà bạn vừa tải lên. Bạn sẽ có thể sao chép URL đến vị trí của URL. Hãy sao chép đường dẫn này ngay bây giờ như sau:

92ded8d46442c404.png

  1. Bây giờ ở dưới cùng bên trái màn hình, hãy nhấp vào Công cụ > Thiết bị đầu cuối. Chờ cửa sổ dòng lệnh tải. Sau khi tải, hãy nhập nội dung sau đây rồi nhấn Enter để thay đổi thư mục thành thư mục www:

thiết bị đầu cuối:

cd www
  1. Tiếp theo, hãy sử dụng wget để tải 2 tệp vừa tải lên bằng cách thay thế các URL bên dưới bằng những URL mà bạn đã tạo cho các tệp trong thư mục tài sản trên Glcab (kiểm tra thư mục tài sản cho từng tệp tùy chỉnh của URL). Lưu ý rằng khoảng cách giữa hai URL và các URL mà bạn cần sử dụng sẽ khác với những URL bên dưới, nhưng sẽ trông giống nhau:

termal

wget https://cdn.glitch.com/1cb82939-a5dd-42a2-9db9-0c42cab7e407%2Fmodel.json?v=1616111344958 https://cdn.glitch.com/1cb82939-a5dd-42a2-9db9-0c42cab7e407%2Fgroup1-shard1of1.bin?v=1616017964562

Tuyệt vời, bạn hiện đã tạo bản sao của các tệp được tải lên thư mục www. Tuy nhiên, ngay bây giờ, tệp sẽ được tải xuống bằng những tên lạ.

  1. Nhập ls vào thiết bị thanh toán và nhấn enter. Bạn sẽ thấy nội dung như sau:

9cc90f1d053f517f.png

  1. Bạn có thể đổi tên các tệp bằng lệnh mv. Nhập nội dung sau vào bảng điều khiển và nhấn <Firebug>Enter</Firebug> hoặc <EMOJI>return</Firebug>, sau mỗi dòng:

từ khóa:

mv *group1-shard1of1.bin* group1-shard1of1.bin
mv *model.json* model.json
  1. Cuối cùng, hãy làm mới dự án Glrick bằng cách nhập refresh vào thiết bị đầu cuối rồi nhấn <Firebug>Enter</Firebug>:

từ khóa:

refresh
  1. Sau khi làm mới, bạn sẽ thấy model.jsongroup1-shard1of1.bin trong thư mục www của giao diện người dùng:

50dd98c0a8f3e629.png

Tuyệt vời! Giờ đây, bạn đã sẵn sàng sử dụng các tệp mô hình đã tải lên với một số mã thực tế trong trình duyệt.

9. Tải & sử dụng mô hình TensorFlow.js được lưu trữ

Giờ đây, bạn có thể thử nghiệm việc tải mô hình TensorFlow.js đã tải lên bằng một số dữ liệu để kiểm tra xem mô hình đó có hoạt động hay không.

Ngay bây giờ, dữ liệu đầu vào mẫu bạn sẽ thấy bên dưới sẽ trông khá bí ẩn (một dãy số) và cách chúng được tạo sẽ được giải thích trong phần tiếp theo. Hiện tại, chỉ cần xem danh sách này dưới dạng một dãy số. Ở giai đoạn này, điều quan trọng là bạn chỉ cần kiểm tra xem mô hình đó có đưa ra câu trả lời cho chúng tôi mà không gặp lỗi nào không.

Thêm mã sau vào cuối tệp script.js của bạn và đảm bảo thay thế giá trị chuỗi MODEL_JSON_URL bằng đường dẫn của tệp model.json mà bạn đã tạo khi tải tệp lên thư mục Tài sản hiển thị ở bước trước. (Hãy nhớ rằng, bạn chỉ cần nhấp vào tệp trong thư mục tài sản trên Glrick để tìm URL của tệp đó).

Hãy đọc nhận xét của mã mới bên dưới để hiểu rõ chức năng của mỗi dòng:

script.js

// Set the URL below to the path of the model.json file you uploaded.
const MODEL_JSON_URL = 'model.json';
// Set the minimum confidence for spam comments to be flagged.
// Remember this is a number from 0 to 1, representing a percentage
// So here 0.75 == 75% sure it is spam.
const SPAM_THRESHOLD = 0.75;

// Create a variable to store the loaded model once it is ready so 
// you can use it elsewhere in the program later.
var model = undefined;


/** 
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam.
 */
async function loadAndPredict(inputTensor) {
  // Load the model.json and binary files you hosted. Note this is 
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }
  
  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);
  
  // Print the result to the console for us to inspect.
  results.print();
  
  // TODO: Add extra logic here later to do something useful
}

loadAndPredict(tf.tensor([[1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]));

Nếu dự án được thiết lập chính xác, bạn sẽ thấy một số thông tin như sau được in vào cửa sổ bảng điều khiển của bạn, khi bạn sử dụng mô hình đã tải để dự đoán kết quả từ thông tin đầu vào được chuyển vào đó:

e72acc17383bec33.png

Trong bảng điều khiển, bạn thấy 2 số được in:

  1. 0,9996011
  2. 0,0003989

Mặc dù điều này có vẻ khó hiểu, nhưng những con số này thực sự thể hiện xác suất của mô hình mà họ cho là phân loại cho thông tin mà bạn đưa ra. Nhưng chúng đại diện cho điều gì?

Nếu mở tệp labels.txt từ các tệp mẫu đã tải xuống mà bạn có trên máy cục bộ, bạn sẽ thấy tệp đó có 2 trường:

  1. Sai
  2. Đúng

Do đó, mô hình trong trường hợp này cho biết đó là 99,96011% chắc chắn (được hiển thị trong đối tượng kết quả là 0,9996011) rằng đầu vào bạn đã cung cấp (là [1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] KHÔNG phải spam (tức là Sai).

Xin lưu ý rằng false là nhãn đầu tiên trong labels.txt và được biểu thị bằng kết quả đầu tiên trong bản in của bảng điều khiển. Đây là cách bạn biết được cụm từ gợi ý đầu ra có liên quan gì.

Được rồi, bây giờ bạn đã biết cách diễn giải kết quả, nhưng chính xác đó là một số lượng lớn các số được cung cấp làm dữ liệu đầu vào và làm cách nào để bạn chuyển đổi các câu sang định dạng này để sử dụng mô hình? Do đó, bạn cần tìm hiểu về việc mã hóa và biến dạng. Hãy đọc tiếp!

10. Mã hóa & Tensors

Mã hóa

Hóa ra, các mô hình máy học chỉ có thể chấp nhận một loạt số làm dữ liệu đầu vào. Bạn nên làm vậy Về cơ bản, đó là vì mô hình máy học về cơ bản là một tập hợp các phép toán theo chuỗi, vì vậy nếu chuyển nó sang một nội dung nào đó không phải là số, thì nội dung đó sẽ gặp khó khăn khi xử lý nó. Vì vậy, bây giờ câu hỏi trở thành cách chuyển đổi các câu thành số để sử dụng với mô hình mà bạn đã tải?

Quá trình chính xác sẽ khác với từng mô hình, nhưng trong quy trình này, có một tệp khác trong các tệp mô hình mà bạn đã tải xuống có tên là vocab, và đây là chìa khóa cho cách bạn mã hóa dữ liệu.

Hãy tiếp tục và mở vocab trong một trình chỉnh sửa văn bản cục bộ trên máy của bạn và bạn sẽ thấy nó như sau:

81e8bca3fbf62429.png

Về cơ bản, đây là một bảng tra cứu cách chuyển đổi các từ có ý nghĩa mà mô hình học được sang các số mà nó có thể hiểu. Ngoài ra, còn có một số trường hợp đặc biệt ở đầu tệp <PAD>, <START><UNKNOWN>:

  • <PAD> – Đây là tên viết tắt của "padding". Hóa ra các mô hình máy học như có số lượng dữ liệu đầu vào cố định bất kể câu của bạn là bao lâu. Mô hình mà bạn sử dụng dự kiến sẽ luôn có 20 số cho đầu vào (điều này do người tạo mô hình xác định và có thể thay đổi nếu bạn đào tạo lại mô hình). Vì vậy, nếu bạn có một cụm từ như "I thích video" bạn sẽ lấp đầy các khoảng trống còn lại trong mảng bằng 0&300; đại diện cho mã thông báo <PAD>. Nếu câu lớn hơn 20 từ, bạn phải chia câu để phù hợp với yêu cầu này và thay vào đó, hãy thực hiện nhiều cách phân loại cho nhiều câu nhỏ hơn.
  • <START> – Đây luôn là mã thông báo đầu tiên cho biết điểm bắt đầu của câu. Bạn sẽ thấy trong ví dụ đầu vào ở các bước trước, mảng số bắt đầu bằng "1" - đây là ký hiệu mã thông báo <START>.
  • <UNKNOWN> – Như bạn có thể đoán, nếu từ không tồn tại trong quá trình tra cứu từ này, bạn chỉ cần sử dụng mã thông báo <UNKNOWN> (được biểu thị bằng ""2") làm số.

Đối với mọi từ khác, mã này tồn tại trong quá trình tra cứu và có một số đặc biệt liên quan, vì vậy bạn sẽ sử dụng số đó hoặc số đó không tồn tại, trong trường hợp đó bạn sử dụng số mã thông báo <UNKNOWN>.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Take another look at the input used in the prior code you ran:

[1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Từ điều này, bây giờ bạn có thể thấy rằng đây là một câu có 4 từ vì phần còn lại là mã thông báo <START> hoặc <PAD> và có 20 số trong mảng. Được rồi, tôi đang bắt đầu hiểu hơn một chút.

Câu tôi thực sự viết là Bạn có thể xem ảnh chụp màn hình ở trên và "quo" được chuyển đổi sang số "3" chính xác. Nếu tra cứu các từ khác, bạn cũng sẽ tìm thấy các số tương ứng của từ đó.

Cảm biến

Có một rào cản cuối cùng trước khi mô hình máy học chấp nhận dữ liệu đầu vào của bạn. Bạn phải chuyển đổi một dãy số thành một dạng gọi là Tensor, và đúng là như vậy, TensorFlow được đặt tên theo những thứ này, về cơ bản là Luồng Tensors thông qua một mô hình.

SEM là gì?

Theo định nghĩa chính thức của TensorFlow.org:

"Cảm biến là các mảng đa chiều có loại đồng nhất. Tất cả biến thể đều không thể thay đổi: bạn không bao giờ cập nhật được nội dung của một biến thể, chỉ cần tạo một giá trị mới.

Trong tiếng Anh thuần túy, nó chỉ là một tên toán học hấp dẫn cho một mảng thuộc bất kỳ thứ nguyên nào có một số hàm khác được tích hợp vào Đối tượng Tensor, hữu ích với chúng ta với tư cách là nhà phát triển công nghệ máy học. Tuy nhiên, bạn nên lưu ý rằng Tensor chỉ lưu trữ dữ liệu của 1 loại, ví dụ: tất cả số nguyên hoặc tất cả số thập phân, và sau khi tạo, bạn sẽ không bao giờ có thể thay đổi nội dung của một Tensor, vì vậy bạn có thể coi đó là một ô lưu trữ vĩnh viễn cho các số!

Đừng lo lắng quá nhiều về điều này ngay bây giờ. Ít nhất, bạn cũng nên xem đây là một cơ chế lưu trữ đa chiều để giúp các mô hình máy học hoạt động, cho đến khi bạn tìm hiểu kỹ hơn về một cuốn sách hay như thế này – bạn nên tìm hiểu thêm về Tensors và cách sử dụng các mô hình này.

Tổng kết

Vậy làm cách nào để bạn sử dụng tệp vocab đó trong mã? Câu hỏi rất hay!

Là tệp nhà phát triển JS, tệp này không hữu ích với bạn. Sẽ tốt hơn nhiều nếu đây là đối tượng JavaScript mà bạn chỉ cần nhập và sử dụng. Bạn có thể thấy cách chuyển đổi dữ liệu trong tệp này sang định dạng tương tự như sau sẽ rất đơn giản:

// Special cases. Export as constants.
export const PAD =  0;
export const START = 1;
export const UNKNOWN = 2;

// Export a lookup object.
export const LOOKUP = {
  "i": 3,
  "check": 4,
  "video": 5,
  "song": 6,
  "com": 7,
  "please": 8,
  "like": 9
  // and all the other words...
}

Bằng cách sử dụng trình chỉnh sửa văn bản yêu thích, bạn có thể dễ dàng chuyển đổi tệp vocab thành định dạng như vậy với một số tìm và thay thế. Tuy nhiên, bạn cũng có thể sử dụng công cụ tạo sẵn này để làm việc này dễ dàng hơn.

Bằng cách thực hiện việc này trước và lưu tệp vocab theo đúng định dạng, bạn sẽ không phải thực hiện việc chuyển đổi và phân tích cú pháp này trên mỗi lần tải trang, việc này làm lãng phí tài nguyên CPU. Thậm chí tốt hơn, các đối tượng JavaScript có các thuộc tính sau:

"Tên thuộc tính đối tượng có thể là bất kỳ chuỗi JavaScript hợp lệ nào hoặc bất kỳ thứ gì có thể chuyển đổi thành một chuỗi, bao gồm cả chuỗi trống. Tuy nhiên, mọi tên thuộc tính không phải là giá trị nhận dạng JavaScript hợp lệ (ví dụ: tên thuộc tính có dấu cách hoặc dấu gạch nối, hoặc bắt đầu bằng số) đều chỉ có thể truy cập được bằng ký hiệu dấu ngoặc vuông và quot;

Do đó, miễn là bạn sử dụng ký hiệu dấu ngoặc vuông, bạn có thể tạo bảng tra cứu khá hiệu quả thông qua phép biến đổi đơn giản này.

Chuyển sang định dạng hữu ích hơn

Chuyển đổi tệp từ vựng của bạn thành định dạng ở trên, chính bạn, theo cách thủ công qua trình chỉnh sửa văn bản hoặc sử dụng công cụ này tại đây. Lưu kết quả thu được dưới dạng dictionary.js trong thư mục www của bạn.

Trên nút hành động rắc rối, bạn chỉ cần tạo một tệp mới ở vị trí này rồi dán kết quả chuyển đổi để lưu như sau:

c80f68535c92baf.gif

Sau khi đã lưu tệp dictionary.js theo định dạng được mô tả ở trên, bạn hiện có thể thêm mã sau vào đầu script.js để nhập mô-đun dictionary.js mà bạn vừa viết. Tại đây, bạn cũng xác định một hằng số bổ sung ENCODING_LENGTH để biết số lượng cần chèn thêm vào sau trong mã, cùng với hàm tokenize mà bạn sẽ dùng để chuyển đổi một chuỗi các từ thành một biến cố thích hợp có thể dùng làm dữ liệu đầu vào cho mô hình.

Kiểm tra các nhận xét trong mã bên dưới để biết thêm thông tin về chức năng của mỗi dòng:

script.js

import * as DICTIONARY from '/dictionary.js';

// The number of input elements the ML Model is expecting.
const ENCODING_LENGTH = 20;


/** 
 * Function that takes an array of words, converts words to tokens,
 * and then returns a Tensor representation of the tokenization that
 * can be used as input to the machine learning model.
 */
function tokenize(wordArray) {
  // Always start with the START token.
  let returnArray = [DICTIONARY.START];
  
  // Loop through the words in the sentence you want to encode.
  // If word is found in dictionary, add that number else
  // you add the UNKNOWN token.
  for (var i = 0; i < wordArray.length; i++) {
    let encoding = DICTIONARY.LOOKUP[wordArray[i]];
    returnArray.push(encoding === undefined ? DICTIONARY.UNKNOWN : encoding);
  }
  
  // Finally if the number of words was < the minimum encoding length
  // minus 1 (due to the start token), fill the rest with PAD tokens.
  while (i < ENCODING_LENGTH - 1) {
    returnArray.push(DICTIONARY.PAD);
    i++;
  }
  
  // Log the result to see what you made.
  console.log([returnArray]);
  
  // Convert to a TensorFlow Tensor and return that.
  return tf.tensor([returnArray]);
}

Tuyệt vời, giờ hãy quay lại hàm handleCommentPost() và thay thế bằng phiên bản mới này của hàm.

Hãy xem mã để nhận xét về nội dung bạn đã thêm:

script.js

/** 
 * Function to handle the processing of submitted comments.
 **/
function handleCommentPost() {
  // Only continue if you are not already processing the comment.
  if (! POST_COMMENT_BTN.classList.contains(PROCESSING_CLASS)) {
    // Set styles to show processing in case it takes a long time.
    POST_COMMENT_BTN.classList.add(PROCESSING_CLASS);
    COMMENT_TEXT.classList.add(PROCESSING_CLASS);
    
    // Grab the comment text from DOM.
    let currentComment = COMMENT_TEXT.innerText;
    // Convert sentence to lower case which ML Model expects
    // Strip all characters that are not alphanumeric or spaces
    // Then split on spaces to create a word array.
    let lowercaseSentenceArray = currentComment.toLowerCase().replace(/[^\w\s]/g, ' ').split(' ');
    
    // Create a list item DOM element in memory.
    let li = document.createElement('li');
    
    // Remember loadAndPredict is asynchronous so you use the then 
    // keyword to await a result before continuing.
    loadAndPredict(tokenize(lowercaseSentenceArray), li).then(function() {
      // Reset class styles ready for the next comment.
      POST_COMMENT_BTN.classList.remove(PROCESSING_CLASS);
      COMMENT_TEXT.classList.remove(PROCESSING_CLASS);
      
      let p = document.createElement('p');
      p.innerText = COMMENT_TEXT.innerText;
      
      let spanName = document.createElement('span');
      spanName.setAttribute('class', 'username');
      spanName.innerText = currentUserName;
      
      let spanDate = document.createElement('span');
      spanDate.setAttribute('class', 'timestamp');
      let curDate = new Date();
      spanDate.innerText = curDate.toLocaleString();
      
      li.appendChild(spanName);
      li.appendChild(spanDate);
      li.appendChild(p);
      COMMENTS_LIST.prepend(li);

      // Reset comment text.
      COMMENT_TEXT.innerText = '';
    });
  }
}

Cuối cùng, hãy cập nhật hàm loadAndPredict() để đặt kiểu nếu nhận xét được phát hiện là vi phạm.

Trước đây, bạn chỉ cần thay đổi kiểu, nhưng sau này bạn có thể chọn giữ lại nhận xét ở một hàng đợi kiểm duyệt nào đó hoặc dừng gửi nhận xét.

script.js

/** 
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam.
 */
async function loadAndPredict(inputTensor, domComment) {
  // Load the model.json and binary files you hosted. Note this is 
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }
  
  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);
  
  // Print the result to the console for us to inspect.
  results.print();

  results.data().then((dataArray)=>{
    if (dataArray[1] > SPAM_THRESHOLD) {
      domComment.classList.add('spam');
    }
  })
}

11. Cập nhật theo thời gian thực: Node.js + Websockets

Giờ đây, bạn đã có một giao diện người dùng hoạt động với tính năng phát hiện nội dung vi phạm, phần cuối cùng của câu đố là sử dụng Node.js với một số cổng web để giao tiếp theo thời gian thực và cập nhật theo thời gian thực mọi nhận xét không được thêm vào mà không phải là nội dung vi phạm.

Socket.io

Socket.io là một trong những cách phổ biến nhất (tại thời điểm viết bài) để sử dụng webSocket với Node.js. Hãy tiếp tục và thông báo cho Glrick rằng bạn muốn đưa thư viện Socket.io vào bản dựng bằng cách chỉnh sửa package.json trong thư mục cấp cao nhất (trong thư mục mẹ của thư mục www) để bao gồm socket.io làm một trong các phần phụ thuộc:

package. json

{
  "name": "tfjs-with-backend",
  "version": "0.0.1",
  "description": "A TFJS front end with thin Node.js backend",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.17.1",
    "socket.io": "^4.0.1"
  },
  "engines": {
    "node": "12.x"
  }
}

Tuyệt vời! Sau khi cập nhật, hãy cập nhật tiếp theo index.html trong thư mục www để bao gồm thư viện socket.io.

Chỉ cần đặt dòng mã này phía trên thẻ nhập tập lệnh HTML cho Script.js gần cuối tệp index.html:

index.html

<script src="/socket.io/socket.io.js"></script>

Bây giờ, bạn nên có 3 thẻ tập lệnh trong tệp index.html:

  • lần đầu tiên nhập thư viện TensorFlow.js
  • lần nhập thứ 2 socket.io bạn vừa thêm
  • và cuối cùng nên nhập mã Script.js.

Tiếp theo, hãy chỉnh sửa server.js để thiết lập socket.io trong nút và tạo một phần phụ trợ đơn giản để chuyển tiếp thông báo nhận được cho tất cả ứng dụng kết nối.

Xem các nhận xét mã bên dưới để biết nội dung giải thích về mã của Node.js đang làm gì:

server.js

const http = require('http');
const express = require("express");
const app = express();
const server = http.createServer(app);

// Require socket.io and then make it use the http server above.
// This allows us to expose correct socket.io library JS for use
// in the client side JS.
var io = require('socket.io')(server);

// Serve all the files in 'www'.
app.use(express.static("www"));

// If no file specified in a request, default to index.html
app.get("/", (request, response) => {
  response.sendFile(__dirname + "/www/index.html");
});


// Handle socket.io client connect event.
io.on('connect', socket => {
  console.log('Client connected');

  // If you wanted you could emit existing comments from some DB
  // to client to render upon connect.
  // socket.emit('storedComments', commentObjectArray);  
 
  // Listen for "comment" event from a connected client.
  socket.on('comment', (data) => {
    // Relay this comment data to all other connected clients
    // upon receiving.
    socket.broadcast.emit('remoteComment', data);
  });
});


// Start the web server.
const listener = server.listen(process.env.PORT, () => {
  console.log("Your app is listening on port " + listener.address().port);
});

Tuyệt vời! Giờ đây, bạn có một máy chủ web đang theo dõi các sự kiện socket.io. Cụ thể là bạn có một sự kiện comment khi một bình luận mới đến từ một máy khách và máy chủ phát ra một sự kiện remoteComment mà mã phía máy khách sẽ lắng nghe để biết cách hiển thị một bình luận từ xa. Vì vậy, điều cuối cùng bạn cần làm là thêm logic socket.io vào mã phía máy khách để phát ra và xử lý các sự kiện này.

Trước tiên, hãy thêm mã sau vào cuối script.js để kết nối với máy chủ socket.io và xử lý / xử lý các sự kiện nhận xét từ xa:

script.js

// Connect to Socket.io on the Node.js backend.
var socket = io.connect();


function handleRemoteComments(data) {
  // Render a new comment to DOM from a remote client.
  let li = document.createElement('li');
  let p = document.createElement('p');
  p.innerText = data.comment;

  let spanName = document.createElement('span');
  spanName.setAttribute('class', 'username');
  spanName.innerText = data.username;

  let spanDate = document.createElement('span');
  spanDate.setAttribute('class', 'timestamp');
  spanDate.innerText = data.timestamp;

  li.appendChild(spanName);
  li.appendChild(spanDate);
  li.appendChild(p);
  
  COMMENTS_LIST.prepend(li);
}


// Add event listener to receive remote comments that passed
// spam check.
socket.on('remoteComment', handleRemoteComments);

Cuối cùng, hãy thêm một mã nào đó vào hàm loadAndPredict để phát ra sự kiện socket.io nếu một bình luận không phải là bình luận làm phiền. Việc này cho phép bạn cập nhật nhận xét mới này với các ứng dụng đã kết nối khác vì nội dung của thư này sẽ được chuyển tiếp đến họ thông qua mã server.js mà bạn đã viết ở trên.

Chỉ cần thay thế hàm loadAndPredict hiện có của bạn bằng mã sau để thêm câu lệnh else vào quá trình kiểm tra spam cuối cùng, trong đó nếu nhận xét không phải là spam, bạn gọi socket.emit() để gửi tất cả dữ liệu nhận xét:

script.js

/** 
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam. The 2nd parameter
 * allows us to specify the DOM element list item you are currently
 * classifying so you can change it+s style if it is spam!
 */
async function loadAndPredict(inputTensor, domComment) {
  // Load the model.json and binary files you hosted. Note this is 
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }
  
  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);
  
  // Print the result to the console for us to inspect.
  results.print();

  results.data().then((dataArray)=>{
    if (dataArray[1] > SPAM_THRESHOLD) {
      domComment.classList.add('spam');
    } else {
      // Emit socket.io comment event for server to handle containing
      // all the comment data you would need to render the comment on
      // a remote client's front end.
      socket.emit('comment', {
        username: currentUserName,
        timestamp: domComment.querySelectorAll('span')[1].innerText,
        comment: domComment.querySelectorAll('p')[0].innerText
      });
    }
  })
}

Tuyệt vời! Nếu làm đúng, bạn hiện có thể mở 2 phiên bản của trang index.html.

Khi bạn đăng những nhận xét không phải là spam, bạn sẽ thấy chúng xuất hiện trên ứng dụng khác gần như ngay lập tức. Nếu nhận xét là spam, thì hệ thống sẽ không bao giờ gửi nhận xét đó mà sẽ được đánh dấu là spam trên giao diện người dùng chỉ tạo ra nhận xét đó như sau:

ee0f13398ea4e91e.gif

12. Xin chúc mừng

Xin chúc mừng, bạn đã thực hiện những bước đầu tiên để sử dụng công nghệ máy học bằng TensorFlow.js trong trình duyệt web cho một ứng dụng thực tế – để phát hiện bình luận không liên quan!

Hãy thử nghiệm, thử nghiệm với nhiều bình luận. Bạn có thể nhận thấy một số bình luận vẫn hiển thị. Bạn cũng sẽ nhận thấy rằng nếu bạn nhập một câu dài hơn 20 từ thì câu đó sẽ không thành công vì mô hình dự kiến sẽ nhập 20 từ.

Trong trường hợp đó, bạn có thể cần phải chia câu dài thành các nhóm gồm 20 từ và sau đó xem xét khả năng spam của mỗi câu phụ để xác định xem có hiển thị hay không. Chúng tôi sẽ để nguyên tác vụ bổ sung này (không bắt buộc) cho bạn thử nghiệm vì bạn có thể thực hiện nhiều cách cho việc này.

Trong lớp học lập trình tiếp theo, chúng tôi sẽ hướng dẫn bạn cách đào tạo lại mô hình này bằng dữ liệu nhận xét tùy chỉnh cho các trường hợp biên mà tính năng này hiện không phát hiện được hoặc thậm chí là thay đổi kỳ vọng đầu vào của mô hình để ứng dụng có thể xử lý các câu lớn hơn 20 từ, sau đó xuất và sử dụng mô hình đó với TensorFlow.js.

Nếu vì lý do nào đó mà bạn gặp vấn đề, hãy so sánh mã của bạn với phiên bản đã hoàn thành hiện có tại đây và kiểm tra xem bạn có bỏ lỡ mã nào không.

Tóm tắt

Trong lớp học lập trình này, bạn đã:

  1. Tìm hiểu về TensorFlow.js là gì và những mô hình nào có sẵn để xử lý ngôn ngữ tự nhiên
  2. Tạo một trang web hư cấu có nhận xét theo thời gian thực về một trang web mẫu.
  3. Tải một mô hình máy học đã qua đào tạo phù hợp để phát hiện mánh khóe tăng thứ hạng cho bình luận thông qua TensorFlow.js trên trang web.
  4. Đã tìm hiểu cách mã hóa các câu để sử dụng với mô hình máy học đã tải và đóng gói phương thức mã hóa này trong Tensor.
  5. Diễn giải kết quả của mô hình máy học để quyết định xem bạn có muốn giữ lại bình luận để xem xét hay không và nếu không, sẽ gửi tới máy chủ để chuyển tiếp đến các ứng dụng khác đã kết nối theo thời gian thực.

Nội dung tiếp theo là gì?

Giờ đây, khi đã có cơ sở làm việc, bạn có thể nghĩ ra những ý tưởng sáng tạo nào để mở rộng các mẫu nguyên mẫu trong công nghệ máy học này cho trường hợp thực tế mà bạn có thể đang thực hiện?

Chia sẻ những gì bạn làm với chúng tôi

Bạn cũng có thể dễ dàng gia hạn những gì bạn đã tạo hôm nay cho các trường hợp sử dụng tệp sáng tạo khác và chúng tôi khuyến khích bạn nên suy nghĩ thật sáng tạo và tiếp tục tấn công.

Hãy nhớ gắn thẻ chúng tôi trên mạng xã hội bằng cách sử dụng hashtag #MadeWithTFJS để có cơ hội giới thiệu dự án của bạn trên blog TeensorFlow hay thậm chí là các sự kiện trong tương lai. Chúng tôi muốn xem những gì bạn tạo ra.

Các lớp học lập trình khác về TensorFlow.js để tìm hiểu sâu hơn

Các trang web đáng chú ý