TensorFlow.js: Yorum spam algılama sistemi oluşturma

1. Başlamadan önce

Geçtiğimiz on yılda web uygulamaları, giderek daha da sosyal ve etkileşimli hale geldi. Artık orta ölçekli popüler bir web sitesinde on binlerce kişi tarafından gerçek zamanlı olarak multimedya, yorum ve daha pek çok konuda destek sunuluyor.

Bu ayrıca, spam yapan kişilerin daha fazla görünürlük sağlamak için bu tür sistemleri kötüye kullanmalarına ve başkalarının yazdıkları makaleler, videolar ve yayınlarla daha az tutkulu içerik ilişkilendirmelerine olanak tanır.

Engellenen kelimeler listesi gibi eski spam algılama yöntemleri kolayca atlanabilir ve karmaşık karmaşıklıklara sürekli olarak ulaşan gelişmiş spam botlarıyla eşleşmez. İleriye dönük bugünlere geldik. Artık, bu tür spam'leri algılamak için eğitilmiş makine öğrenimi modellerini kullanabilirsiniz.

Genelde, yorumları önceden filtrelemek için bir makine öğrenimi modeli çalıştırılıyordu ancak TensorFlow.js ile artık JavaScript aracılığıyla tarayıcıda istemci tarafında makine öğrenimi modelleri yürütebiliyordunuz. Arka uçta dokunmadan önce spam'i durdurabilir, böylece sunucu tarafında yüksek maliyetli kaynaklardan tasarruf edebilirsiniz.

Bildiğiniz gibi, makine öğrenimi günümüzde her sektöre hitap ediyor. Peki, bu özellikleri web geliştiricisi olarak kullanmak için ilk adımı nasıl attınız?

Bu codelab'de, boş bir tuvalden web uygulaması oluşturma hakkında daha fazla bilgi bulabilirsiniz. Boş bir tuvalden yararlanarak, spam yorumlarının gerçek sorununu çözmeyi amaçlayan doğal dil işleme (bilgisayarla insan dilini anlama sanatı) Günümüzde var olan giderek artan popüler web uygulamalarından biri üzerinde çalışırken çoğu web geliştiricisi bu sorunla karşılaşacaktır. Bu codelab sayesinde bu tür sorunları etkili bir şekilde çözebilirsiniz.

Ön koşullar

Bu codelab, TensorFlow.js ile önceden eğitilmiş modelleri kullanmaya başlamak isteyen, makine öğrenimine yeni başlayan web geliştiricileri için yazılmıştır.

Bu laboratuvarda HTML5, CSS ve JavaScript bilgisine sahip olduğunuz varsayılmaktadır.

Neler öğreneceksiniz?

Aşağıdaki işlemleri gerçekleştirirsiniz:

  • TensorFlow.js'nin ne olduğu ve doğal dil işleme için hangi modellerin kullanıldığı hakkında daha fazla bilgi edinin.
  • Gerçek zamanlı bir yorum bölümü olan kurgusal bir video blogu için basit bir HTML / CSS / JS web sayfası oluşturun.
  • Girilen bir cümlenin spam olup olmadığını tahmin edebilen ve önceden eğitilmiş bir makine öğrenimi modeli yüklemek için TensorFlow.js'yi kullanın. Bu durumda, kullanıcıyı yorumunun moderasyon için bekletildiği konusunda uyarın.
  • Yorum cümlelerini sınıflandırmak için makine öğrenimi modelinin kullanabileceği bir şekilde kodlayın.
  • Yorumu otomatik olarak işaretlemek isteyip istemediğinize karar vermek için makine öğrenimi modelinin sonucunu yorumlayın. Bu varsayımsal kullanıcı deneyimi, üzerinde çalıştığınız herhangi bir web sitesinde tekrar kullanılabilir ve herhangi bir müşteri kullanım alanına uyacak şekilde uyarlanabilir. Bu normal bir blog, forum veya Drupal gibi bir içerik yönetim sistemi olabilir.

Oldukça düzenli. Yapması zor mu? Hayır. Bilgisayar korsanlığı yapalım...

Gerekenler

  • Takip etmek için tercih ettiğiniz bir Glitch.com hesabı kullanılabilir veya kendiniz kolayca düzenleyip çalıştırabileceğiniz bir web yayınlama ortamı kullanabilirsiniz.

2. TensorFlow.js nedir?

1aee0ede85885520.png

TensorFlow.js, JavaScript'in çalıştırabildiği her yerde çalışabilen bir açık kaynak makine öğrenimi kitaplığıdır. Python'da yazılmış orijinal TensorFlow kitaplığına dayanan bu geliştirici deneyimini ve JavaScript ekosistemi için API grubunu yeniden oluşturmayı amaçlar.

Nerede kullanılabilir?

JavaScript'in taşınabilirliği düşünüldüğünde, artık 1 dilde yazıp aşağıdaki platformların tamamında kolayca makine öğrenimi yapabilirsiniz:

  • Vanvan JavaScript kullanarak web tarayıcısında istemci tarafı
  • Node.js kullanan Sunucu tarafı ve hatta Ahududu Pi gibi IoT cihazları
  • Electron kullanan masaüstü uygulamaları
  • Tepki Yerel kullanan yerel mobil uygulamalar

TensorFlow.js, bu ortamların her birinde birden çok arka ucu da destekler (örneğin, CPU veya WebGL gibi, gerçek ortam tabanlı donanımların yürütülebileceği ortamlar). Bu bağlamda "arka uç", bir sunucu tarafı ortam anlamına gelmez. Uyumluluk sağlamak ve yürütme sürecini hızlandırmak için yürütmenin arka uçları istemci taraflı olabilir. TensorFlow.js şu anda aşağıdakileri desteklemektedir:

  • Cihazın grafik kartında WebGL yürütmesi (GPU): Bu, GPU hızlandırmasıyla daha büyük modelleri (3 MB'tan büyük) yürütmenin en hızlı yoludur.
  • Örneğin, daha eski nesil cep telefonları dahil olmak üzere cihazlar arasında CPU performansını artırmak için CPU'da Web Montaj (WASM) yürütme. Bu model, içeriğin boyut olarak 3 MB'tan küçük olması nedeniyle WASM ile CPU üzerinde CPU'ya göre daha hızlı performans gösterebilen, grafik işlemciye içerik yükleme yükü nedeniyle daha uygundur.
  • CPU yürütme: Yedek, diğer ortamların hiçbiri kullanılabilir olmamalıdır. Bu en yavaş üç yöntem olsa da her zaman yanınızdayız.

Not: Hangi cihazda çalışacağınızı biliyorsanız bu arka uçlardan birini zorunlu kılmayı seçebilir veya bunu belirtmezseniz TensorFlow.js'nin sizin için karar vermesine izin verebilirsiniz.

İstemci tarafı süper güçler

İstemci makinedeki web tarayıcısında TensorFlow.js'yi çalıştırmak, dikkate alınmaya değer çeşitli avantajlara neden olabilir.

Gizlilik

Üçüncü taraf bir web sunucusuna hiç veri göndermeden istemcideki verileri eğitebilir ve sınıflandırabilirsiniz. Bunun, örneğin GDPR gibi yerel yasalara uymak ya da kullanıcının makinesinde tutmak isteyebileceği ve üçüncü taraflara gönderilmeyeceği verileri işlemesi gereken durumlar olabilir.

Hız

Verileri uzak bir sunucuya göndermek zorunda olmadığınız için çıkarım (verileri sınıflandırma işlemi) daha hızlı olabilir. Daha da iyisi, kullanıcı size erişim izni verirse kamera, mikrofon, GPS, ivme ölçer ve diğer bilgiler gibi cihazın sensörlerine doğrudan erişebilirsiniz.

Erişim ve ölçeklendirme

Tüm kullanıcılar, tek bir tıklamayla onlara gönderdiğiniz bir bağlantıyı tıklayabilir, web sayfalarını tarayıcılarında açabilir ve yaptıklarınızdan yararlanabilir. CUDA sürücülerini içeren karmaşık bir sunucu tarafı Linux kurulumuna ve çok daha fazlasında yalnızca makine öğrenimi sistemini kullanmaya gerek yoktur.

Maliyet

Sunucu yok. HTML, CSS, JS ve model dosyalarınızı barındırmak için tek yapmanız gereken bir CDN'dir. CDN'nin maliyeti, sunucuyu (grafik kartı eklenmiş olarak) 7/24 açık tutmaktan çok daha ucuzdur.

Sunucu tarafı özellikler

TensorFlow.js'nin Node.js uygulamasından yararlanmak aşağıdaki özellikleri etkinleştirir.

CUDA için tam destek

Sunucu tarafında, TensorFlow'un grafik kartıyla çalışabilmesi için NVIDIA CUDA sürücülerini yüklemeniz gerekir (WebGL'yi kullanan tarayıcıdan farklı olarak). Yükleme gerekmez. Ancak tam CUDA desteği sayesinde, grafik kartının daha alt düzey yeteneklerinden tam anlamıyla yararlanabilir, böylece daha hızlı eğitim ve çıkarım elde edebilirsiniz. Aynı C++ arka ucunu paylaşan Python TensorFlow uygulaması ile aynı performansa sahiptir.

Model Boyutu

Araştırma alanındaki en son modellerde, gigabayt büyüklüğündeki çok büyük modellerle çalışıyor olabilirsiniz. Tarayıcı başına bellek kullanımı konusundaki sınırlamalar nedeniyle, bu modeller şu anda web tarayıcısında çalıştırılamaz. Bu büyük modelleri çalıştırmak için Node.js'yi kendi sunucunuzda bu tür bir modeli verimli bir şekilde çalıştırmak üzere ihtiyaç duyduğunuz donanım spesifikasyonlarıyla kullanabilirsiniz.

KS

Node.js, Raspberry Pi gibi popüler tek kartlı bilgisayarlarda desteklenir. Bu da TensorFlow.js modellerini bu tür cihazlarda da yürütebileceğiniz anlamına gelir.

Hız

Node.js, JavaScript'te yazılır. Yani, yalnızca zaman derlemesinden faydalanır. Diğer bir deyişle, Node.js'yi kullanırken çoğu zaman performans kazancı elde edebilirsiniz. Çünkü bu protokol, özellikle yapıyor olabileceğiniz tüm ön işlemeler için çalışma zamanında optimize edilir. Bunun mükemmel bir örneğini, Hugging Face'ın Node.js'yi kullanarak doğal dil işleme modeli için 2 kat performans artışı sağladığını gösteren bu örnek olay bölümünde görebilirsiniz.

Artık TensorFlow.js'nin nerede çalışabileceğiyle ilgili temel bilgileri ve sunduğu bazı avantajları biliyorsunuz. Şimdi, bu teknolojiyle faydalı şeyler yapmaya başlayalım.

3. Önceden eğitilmiş modeller

Neden önceden eğitilmiş bir model kullanmak isteyeyim?

Tercih ettiğiniz kullanım alanına uyan popüler bir önceden eğitilmiş modelle başlamak birçok avantaj sağlar. Örneğin:

  1. Eğitim verilerini kendiniz toplamanız gerekmez. Verileri doğru biçimde hazırlamak ve makine öğrenimi sisteminin bu verilerden yararlanabilmesi için etiketlemek, çok zaman alabilir ve maliyetli olabilir.
  2. Maliyeti ve zamanı azaltarak fikirleri hızlı bir şekilde prototip oluşturma becerisi.
    Önceden eğitilmiş bir model, ihtiyacınız olanı yapacak kadar iyi olduğunda, söz konusu modelle sağlanan bilgiden yararlanarak reklam fikri fikirlerinizi uygulamaya odaklanabilirsiniz.
  3. Son teknoloji araştırmaların kullanımı. Önceden eğitilmiş modeller genellikle popüler araştırmalara dayanarak bu modelleri size gösterirken gerçek dünyadaki performanslarını anlamanızı sağlar.
  4. Kullanım kolaylığı ve kapsamlı dokümanlar. Bu tür modellerin popülerliği nedeniyle.
  5. Aktarım öğrenimi özellikleri. Önceden eğitilmiş bazı modeller aktarım öğrenmesi özellikleri sunar. Bu, temel olarak bir makine öğrenimi görevinden öğrenilen bilgileri başka bir benzer örneğe aktarmaktır. Örneğin, ilk başta kedileri tanımak için eğitilen bir modele yeni eğitim verileri verdiyseniz köpekleri tanımayı yeniden eğitebilirsiniz. Boş bir tuvalle çalışmayacağınız için bu işlem daha hızlı olacaktır. Model, kedileri tanımak için öğrendiklerini kullanarak yeni şeyleri tanıyabilir. Ayrıca köpeklerin gözleri ve kulakları da vardır, dolayısıyla bu özellikleri nasıl bulacağını zaten biliyorsa, yolun yarısındayız. Modeli çok daha hızlı bir şekilde kendi verilerinizle yeniden eğitin.

Önceden eğitilmiş bir yorum spam'i algılama modeli

Yorum spam'i algılama ihtiyaçlarınız için Ortalama Kelime Yerleştirme modeli mimarisini kullanacaksınız. Ancak eğitimsiz bir model kullanmaya çalışırsanız cümlelerin spam olup olmadığını tahmin etme şansınız yükselir.

Modelin kullanışlı olması için özel verilerle ilgili eğitim alması gerekir. Bu örnekte model, spam olmayan ve spam olmayan yorumların nasıl görüneceğini öğrenmesine izin verir. Bu sayede, derslerin daha sonra doğru şekilde sınıflandırılma olasılığı daha yüksek olacaktır.

Neyse ki kullanıcılar tam olarak bu model mimarisini bu yorum spam sınıflandırma görevi için eğitmiş. Bu nedenle, bu projeyi başlangıç noktası olarak kullanabilirsiniz. Aynı model mimarisini kullanan ve bir yorumun hangi dilde yazıldığını algılamak ya da web sitesi iletişim formu verilerinin satış (ürün sorgusu) veya mühendislik (teknik hata veya geri bildirim) metinleri gibi metinleri temel alarak belirli bir şirket ekibine otomatik olarak yönlendirilip yönlendirilmeyeceğini tahmin etmek gibi farklı kullanımlara sahip, önceden eğitilmiş başka modeller bulabilirsiniz. Bunun gibi bir model, yeterli düzeyde eğitim verisi sayesinde, web uygulamanıza güç kazandırmak ve kuruluşunuzun verimliliğini iyileştirmek için bu tür metinleri her durumda sınıflandırmayı öğrenebilir.

Gelecekteki bir kod laboratuvarında, önceden eğitilmiş bu yorum spam modelini yeniden eğitmek için Model Oluşturucu'yu nasıl kullanacağınızı ve kendi yorum verilerinizdeki performansını nasıl iyileştireceğinizi öğreneceksiniz. Şimdilik, ilk web uygulamasının ilk prototip olarak çalışmasını sağlamak için mevcut yorum spam'i algılama modelini başlangıç noktası olarak kullanacaksınız.

Bu önceden eğitilmiş yorum spam algılama modeli, Google tarafından yönetilen bir makine öğrenimi modeli deposu olan TF Hub adlı bir web sitesinde yayınlandı. Bu modelde makine öğrenimi mühendisleri, önceden oluşturulmuş modellerini birçok yaygın kullanım alanı (ör. bu kategorilerin her birinin belirli kullanım alanları için metin, görüntü, ses ve daha fazlası) yayınlayabilir. Devam edin ve daha sonra bu codelab'de web uygulamasında kullanmak üzere model dosyalarını şimdilik indirin.

JS modeli için indirme düğmesini aşağıda gösterildiği gibi tıklayın:

ab65deff89b3d939.png

4. Kodlayıcıyı kurma

Gerekenler

  • Modern bir web tarayıcısı.
  • HTML, CSS, JavaScript ve Chrome Geliştirici Araçları ile ilgili temel bilgi birikimi (konsol çıkışını görüntüleme).

Kodlama yapalım.

Başlangıç olarak Glitch.com Node.js Express ortak metin şablonu oluşturduk. Bu şablon, tek tıklamayla bu kod laboratuvarının temel durumu olarak klonlamanızı sağlar.

Glitch'i, çatallamak ve düzenleyebileceğiniz yeni bir dosya grubu oluşturmak için & remiks düğmesini tıklamanız yeterlidir.

Bu çok basit iskelet, bize www klasöründe aşağıdaki dosyaları sağlıyor:

  1. HTML sayfası (index.html)
  2. Stil Sayfası (style.css)
  3. JavaScript kodumuzu (script.js) yazacak dosya

Size kolaylık olması açısından TensorFlow.js kitaplığı için şöyle görünen bir içe aktarma dosyasını HTML dosyasına da ekledik:

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>

Ardından, bu www klasörünü package.json ve server.js üzerinden basit bir Node Express sunucusu üzerinden sunuyoruz

5. Uygulama HTML Ortak Kartı

Başlangıç noktanız nedir?

Tüm prototipler, bulgularınızı oluşturabileceğiniz bazı temel HTML iskeleleri gerektirir. Bunu şimdi yapın. Aşağıdakileri ekleyeceksiniz:

  • Sayfa başlığı
  • Açıklayıcı metinler
  • Video blog girişini temsil eden yer tutucu video
  • Yorumları görüntüleme ve yazma alanı

index.html özelliğini açın ve yukarıdaki özellikleri ayarlamak için mevcut kodun üzerine yapıştırı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>

Ayrıntılı bilgi

Eklediğiniz bazı önemli öğeleri vurgulamak için yukarıdaki HTML kodunun bir kısmını inceleyelim.

  • Sayfa başlığı için <h1> etiketi ve <header> içindeki giriş düğmesi için <a> etiketi eklediniz. Ardından makale başlığı için <h2> ve video açıklaması için <p> etiketi eklediniz. Burada özel bir şey yok.
  • Rastgele bir YouTube videosu yerleştiren iframe etiketi eklediniz. Şimdilik, güçlü TensorFlow.js rap dosyasını yer tutucu olarak kullanıyorsunuz, ancak iframe'in URL'sini değiştirerek istediğiniz videoyu buraya yerleştirebilirsiniz. Aslında, bir üretim web sitesinde, bu değerlerin tamamı, görüntülenen sayfaya bağlı olarak arka uç tarafından dinamik olarak oluşturulur.
  • Son olarak, kimliği ve sınıfı "yorumlar" olan bir section eklediniz. Bu yorumda, yeni yorumlar yazmak için içerik düzenlenebilir div ve button eklemek istediğiniz yeni yorumu ve sıralanmamış yorum listesiyle birlikte button gönderebilirsiniz. Her bir liste öğesi içindeki span etiketinde yayınlama kullanıcı adı ve saati, ardından bir p etiketinde yorumun kendisi vardır. 2 örnek yorum şu anda yer tutucu olarak sabit kodlanmıştır.

Çıkışı hemen önizlerseniz aşağıdaki gibi görünecektir:

73c8338334d5b251.png

Kulağa çok kötü geldiği için stil ekleme zamanı geldi...

6. Stil ekle

Öğe varsayılanları

İlk olarak, doğru bir şekilde oluşturulduklarından emin olmak için az önce eklediğiniz HTML öğelerinin stillerini ekleyin.

Tüm tarayıcılarda ve işletim sisteminde bir yorum başlangıç noktası almak için CSS sıfırlama uygulayarak başlayın. Aşağıdakilerle style.css içeriğinin üzerine yazın:

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}

Ardından, kullanıcı arayüzünü hayata geçirmek için bu yararlı CSS'den yararlanın.

Yukarıda eklediğiniz sıfırlama CSS kodunun altına style.css sayfasının sonuna aşağıdakileri ekleyin:

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

Güzel! Gereken tek şey bu. Yukarıdaki 2 kod parçasıyla stillerinizi başarıyla yazdıysanız canlı önizlemeniz artık şu şekilde görünmelidir:

b86be8e2f6e7456.png

Varsayılan olarak tatlı, gece modu ve temel öğelerde fareyle üzerine gelme efektleri için etkileyici CSS geçişleri. İyi görünüyor. Şimdi JavaScript kullanarak davranış mantığını entegre edin.

7. JavaScript: DOM manipülasyonu & Etkinlik İşleyicileri

Anahtar DOM öğelerine başvuruda bulunma

Öncelikle, stilde değişiklik yapmak için bazı CSS sınıf sabitleri tanımlamanın yanı sıra, sayfanın daha sonra koda müdahale etmeniz veya erişmeniz gereken temel bölümlerine erişebildiğinizden emin olun.

script.js içeriğini aşağıdaki sabitlerle değiştirerek başlayın:

script.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';

Yorum yayınlamayı işleme

Ardından, yazılı yorum metnini alabilmesi ve işlemenin başladığını belirten bir CSS sınıfı ayarlayabilmesi için POST_COMMENT_BTN özelliğine bir etkinlik işleyici ve işleme işlevi ekleyin. Devam eden bir işlem olması ihtimaline karşı, düğmeyi henüz tıklamadığınızı kontrol ettiğinizi unutmayın.

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

Güzel! Web sayfasını yenileyip yorum yayınlamayı denediğinizde yorum düğmesi ve metnin gri tonlamalı olduğunu görürsünüz. Konsolda da şu şekilde yazılmış bir yorum görürsünüz:

827b5f3d09afbb21.png

Artık temel bir HTML / CSS / JS iskeletiniz var. Dikkatinizi tekrar makine öğrenimi modeline döndürmenin zamanı geldi. Bu dönemi güzel bir web sayfasıyla entegre edebilirsiniz.

8. Makine öğrenimi modelini yayınlama

Modeli yüklemeye neredeyse hazırsınız. Ancak bunu yapabilmek için, codelab'de daha önce indirilen model dosyalarının web sitenize yüklenmesi ve böylece kodun içinde barındırılıp kullanılabilmesi gerekir.

Öncelikle, henüz yapmadıysanız bu codelab'in başında model için indirdiğiniz dosyaların sıkıştırmasını açın. Aşağıdaki dosyaları içeren bir dizin görürsünüz:

5634d536ef8be9ca.png

Burada ne var?

  • model.json - Bu, eğitilmiş TensorFlow.js modelini oluşturan dosyalardan biridir. Bunu, TensorFlow.js kodunuzda daha sonra açıklayacaksınız.
  • group1-shard1of1.bin - Bu, TensorFlow.js modelinin eğitilmiş ağırlıklarını (temel olarak sınıflandırma görevini yerine getirmesi için öğrendiği bir dizi sayı) içeren ikili bir dosyadır ve indirilebilmesi için sunucunuzda bir yerde barındırılması gerekir.
  • vocab - Uzantı içermeyen bu tuhaf dosya, modelin cümleleri nasıl kodlayacağını gösteren bir modeldir. Bu sayede model, kelimelerin nasıl kullanılacağını anlayabilir. Bir sonraki bölümde bu konuyu daha ayrıntılı olarak ele alacağız.
  • labels.txt - Bu model, modelin tahmin edeceği sınıf adlarını içerir. Bu modelde metin düzenleyicinizde bu dosyayı açarsanız tahmin sonucu olarak "spam" veya "spam" değil, "spam" veya "spam" listelenmiş olarak listelenir.

TensorFlow.js model dosyalarını barındırma

İlk olarak model.json ve *.bin web dosyaları oluşturulan web dosyalarını, web sayfası üzerinden bunlara erişebilmeniz için kullanın.

Glitch'e dosya yükleme

  1. Glitch projenizin sol tarafındaki öğeler klasörünü tıklayın.
  2. Öğe yükle'yi tıklayın ve bu klasöre yüklenecek group1-shard1of1.bin'i seçin. Yüklendikten sonra şu şekilde görünür:

25a2251c7f165184.png

  1. Güzel! Şimdi model.json dosyası için de aynısını yapın. assets klasörünüzde şunun gibi 2 dosya olmalıdır:

51a6dbd5d3097ffc.png

  1. Yeni yüklediğiniz group1-shard1of1.bin dosyasını tıklayın. URL'yi bulunduğu konuma kopyalayabilirsiniz. Bu yolu aşağıda gösterildiği gibi kopyalayın:

92ded8d46442c404.png

  1. Şimdi ekranın sol alt tarafındaki Araçlar > Terminal'i tıklayın. Terminal penceresinin yüklenmesini bekleyin. Yükleme işlemi tamamlandığında aşağıdakileri yazın ve ardından, dizini www klasörüyle değiştirmek için Enter tuşuna basın:

terminal:

cd www
  1. Ardından, az önce yüklenen 2 dosyayı indirmek için wget adresini kullanın. Aşağıdaki URL'leri, Glitch'teki öğeler klasöründeki dosyalar için oluşturduğunuz URL'lerle değiştirin (her bir dosyanın özel URL'sinin öğe klasörünü kontrol edin). İki URL arasındaki boşluğun ve kullanmanız gereken URL'lerin aşağıdaki URL'lerden farklı olacağını ancak benzer görüneceğini unutmayın:

terminal

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

Süper! Artık www klasörüne yüklenen dosyaların bir kopyasını oluşturdunuz. Bunlar şu anda tuhaf adlarla indirildi.

  1. Terminale ls yazıp enter tuşuna basın. Şuna benzer bir şey görürsünüz:

9cc90f1d053f517f.png

  1. mv komutunu kullanarak dosyaları yeniden adlandırabilirsiniz. Konsola şunu yazın ve her satırdan sonra <kbd>Enter</kbd> veya <kbd>return</kbd>; tuşlarına basın:

terminal:

mv *group1-shard1of1.bin* group1-shard1of1.bin
mv *model.json* model.json
  1. Son olarak, terminale refresh yazıp <kbd>Enter</kbd> tuşlarına basarak Glitch projesini yenileyin:

terminal:

refresh
  1. Sayfa görüntülendikten sonra, kullanıcı arayüzünün www klasöründe model.json ve group1-shard1of1.bin öğelerini görmeniz gerekir:

50dd98c0a8f3e629.png

Güzel! Artık yüklenen model dosyalarını tarayıcıda bazı gerçek kodlarla kullanmaya hazırsınız.

9. Barındırılan TensorFlow.js modelini yükleme ve kullanma

Artık yüklenen TensorFlow.js modelinin çalışıp çalışmadığını kontrol etmek için bazı verilerle yükleme işlemini test edebilirsiniz.

Şu anda, aşağıda göreceğiniz örnek giriş verileri oldukça gizemli (bir dizi sayı) görünecek ve bu verilerin nasıl oluşturulduğu bir sonraki bölümde açıklanacaktır. Şu anda bunu bir sayı dizisi olarak görüntülemeniz yeterlidir. Bu aşamada modelin bize hatasız bir yanıt verip vermediğini test etmek önemlidir.

Aşağıdaki kodu script.js dosyanızın sonuna ekleyin ve MODEL_JSON_URL dize değerini, önceki adımda dosyayı Glitch öğeleri klasörünüze yüklediğinizde oluşturduğunuz model.json dosyasının yoluyla değiştirdiğinizden emin olun. (Unutmayın, URL'sini bulmak için Glitch'teki assets klasöründeki dosyayı tıklayabilirsiniz).

Her bir satırın ne yaptığını anlamak için aşağıdaki yeni kodun yorumlarını okuyun:

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]]));

Proje doğru bir şekilde ayarlandıysa, yüklediğiniz modelden çıkan sonucu tahmin etmek için yüklediğiniz modeli kullandığınızda artık konsol pencerenize aşağıdakine benzer bir şey görürsünüz:

e72acc17383bec33.png

Konsolda 2 numara yazdırılır:

  1. 0,9996011
  2. 0,0003989

Bu değerler şifreli gibi görünse de sayılar, gerçekte modelin sağladığınız giriş için sınıflandırma olduğunu düşündüğü olasılıklardır. Peki neyi temsil ediyorlar?

labels.txt dosyanızı yerel makinenizde bulunan indirilmiş model dosyalarından açarsanız dosyanın 2 alanı da olur:

  1. Yanlış
  2. Doğru

Dolayısıyla bu örnekteki model, ona verdiğiniz girişin ([1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] değeri Spam değil (yani Yanlış) olduğu) emin olarak %99,96011 emin olduğunu söylüyor.

false'un labels.txt içindeki ilk etiket olduğunu ve çıkış tahmininin neyle ilgili olduğunu bilmeniz için konsol baskısındaki ilk çıkışla temsil edildiğini unutmayın.

Peki, şimdi çıktıyı nasıl yorumlayacağınızı biliyorsunuz. Peki, giriş olarak verilen bu büyük sayı tam olarak neydi ve modelin kullanması için cümleleri bu biçime nasıl dönüştürürsünüz? Bunun için jetonlara ayırma ve tensörler hakkında bilgi edinmeniz gerekir. Devamını okuyun!

10. Tokenleştirme ve Tensörler

Jetonlama

Bu durumda, makine öğrenimi modellerinin giriş olarak yalnızca bir grup sayıyı kabul edebileceği ortaya çıkar. Bunu neden yapmalısınız? Esas olarak, bir makine öğrenimi modeli birçok zincirsel matematik işlemidir. Bu nedenle, ona sayı olmayan bir şeyi iletirseniz bu modelle başa çıkmakta zorlanırsınız. Şimdi soru, cümleleri yüklediğiniz modelle kullanılacak şekilde nasıl sayıya dönüştürebilirsiniz?

Gerçek süreç modelden modele değişiklik gösterir. Ancak, bu işlem için, indirdiğiniz model dosyalarında vocab, adında bir dosya daha vardır ve bu, verileri kodlama yönteminizin anahtarıdır.

Makinenizdeki yerel bir metin düzenleyicide vocab uygulamasını açtığınızda şuna benzer bir metin göreceksiniz:

81e8bca3fbf62429.png

Esas olarak, bu model, modelin anlayabileceği anlamlı kelimelere nasıl dönüştürüleceğini gösteren bir arama tablosudur. <PAD>, <START> ve <UNKNOWN> dosyasının üst kısmında bazı özel durumlar da mevcuttur:

  • <PAD> - Bu, && dolgusudur. Cümleniz ne kadar uzun olursa olsun, makine öğrenimi modellerinin belirli sayıda giriş yapılmasını istediği anlaşılıyor. Kullanılan model, giriş için her zaman 20 sayı olmasını bekler (bu, modeli oluşturan kişi tarafından tanımlanır ve modeli yeniden eğitirseniz değiştirilebilir). Yani, "Videoyu seviyorum"gibi bir ifadeniz varsa dizideki kalan alanları <PAD> jetonunu temsil eden 0' ile doldurursunuz. Cümle 20'den fazlaysa cümleyi bu koşula uyacak şekilde bölmeniz ve daha küçük cümlelerde birden çok sınıflandırma yapmanız gerekir.
  • <START> - Bu her zaman cümlenin başlangıcını belirten ilk jetondur. Yukarıdaki girişteki örnek dizisinde"1"ile başlayan sayı dizisi göreceksiniz. Bu, <START> jetonunu temsil eder.
  • <UNKNOWN> - Tahmin edebileceğiniz gibi, bu kelime aramasında kelime yoksa sayı olarak <UNKNOWN> jetonunu ("2" ile temsil edilir) kullanırsınız.

Diğer tüm kelimeler için aramada bulunur ve bu sayıyla ilişkilendirilmiş özel bir numarası vardır. Bu nedenle söz konusu sayıyı kullanırsınız veya bu durumda mevcut değildir. Bunun yerine <UNKNOWN> jeton numarasını kullanırsınız.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       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]

Bunun ardından, kalan sayıda <START> veya <PAD> jeton olduğu ve dizide 20 rakam olduğu için bunun 4 kelimeden oluşan bir cümle olduğunu görebilirsiniz. Tamam, biraz daha mantıklı geliyor.

Bunun için kaleme aldığım cümle "Köpeğimi seviyorum". Yukarıdaki ekran görüntüsünde, "3" sayısına dönüştürülen tam sayı olduğunu görebilirsiniz. Diğer kelimeleri ararsanız bunların ilgili sayılarını da görürsünüz.

Tensörler

ML modelinin sayısal girişinizi kabul etmesi için son bir engel daha vardır. Sayı dizisini Tensor olarak bilinen bir şeye dönüştürmelisiniz. Evet, tahmin edeceğiniz gibi TensorFlow, bu ada, yani temel olarak bir model üzerinden Tensor Akışı'na göre adlandırılmıştır.

Tensor nedir?

TensorFlow.org'un resmi tanımı şu şekildedir:

Tensörler, tek tip türü olan çok boyutlu dizilerdir. Tüm tensörleri değiştirilemez: Bir tensörün içeriğini asla güncelleyemezsiniz, yalnızca yeni bir tensör oluşturabilirsiniz.

Sade İngilizcede bu, Tensor Object'te yerleşik olarak bulunan ve makine öğrenimi geliştiricileri olarak işinize yarayacak başka işlevler içeren herhangi bir boyut dizisi için süslü matematiksel bir addır. Bununla birlikte, Tensor'ların yalnızca 1 tür verileri (ör.tam sayılar veya kayan nokta sayıları) depolayacağını ve bir Tensor içeriğinin hiçbir zaman değiştirilemeyeceğini ve bu nedenle sayıları kalıcı bir depolama kutusu olarak düşünebilirsiniz.

Şimdilik bu konuda endişelenmenize gerek yok. En azından buna benzer iyi bir kitap hakkında daha fazla bilgi edinene kadar makine öğrenimi modellerinin birlikte çalışabileceği çok boyutlu bir depolama mekanizması olarak düşünün. Tensor'lar ve bunların nasıl kullanılacağı hakkında daha fazla bilgi edinmek istiyorsanız kesinlikle önerilir.

Özetle: Kodlama Tensörleri ve Tokenleştirme

Peki, kodda bu vocab dosyasını nasıl kullanırsınız? Güzel soru.

Bu dosya, JS geliştiricisi olarak sizin için çok faydalı değil. Bu, içe aktarıp kullanabileceğiniz bir JavaScript nesnesi olsaydı çok daha iyi olurdu. Bu dosyadaki verilerin aşağıdakine benzer bir biçime dönüştürülmesinin ne kadar basit olacağını görebilirsiniz:

// 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...
}

Favori metin düzenleyicinizi kullanarak vocab dosyasını kolayca bulup değiştirebilirsiniz. Ancak, bu işlemi daha kolay hale getirmek için önceden hazırlanmış aracı da kullanabilirsiniz.

Bu işlemi önceden yapıp vocab dosyasını doğru biçimde kaydederek, her dönüşümü yükleme işleminde yapmaktan ve CPU kaynaklarının boşa harcanmasından kaçınmış olursunuz. Daha da iyisi, JavaScript nesneleri aşağıdaki özelliklere sahiptir:

&nesle; bir nesne özelliği adı, geçerli bir JavaScript dizesi veya boş dize de dahil olmak üzere bir dizeye dönüştürülebilen herhangi bir şey olabilir. Ancak, geçerli bir JavaScript tanımlayıcısı olmayan herhangi bir tesis adına (örneğin, boşluk veya tire içeren ya da bir rakamla başlayan mülk adı) yalnızca köşeli parantez gösterimi kullanılarak erişilebilir.

Dolayısıyla, köşeli parantez gösterimini kullandığınız sürece, bu basit dönüşüm aracılığıyla oldukça verimli bir arama tablosu oluşturabilirsiniz.

Daha kullanışlı bir biçime dönüştürme

Söz dizimi dosyanızı metin düzenleyici aracılığıyla manuel olarak veya bu aracı kullanarak yukarıdaki biçime dönüştürün. Oluşturulan çıkışı www klasörünüze dictionary.js olarak kaydedin.

Glitch'te, bu konumda yeni bir dosya oluşturmanız ve gösterildiği şekilde kaydetmek için dönüşüm sonucunuzu yapıştırmanız yeterlidir:

c80f68535c92baf.gif

Yukarıda açıklanan biçimde kaydedilmiş bir dictionary.js dosyanız olduğunda, az önce yazdığınız dictionary.js modülünü içe aktarmak için aşağıdaki kodu script.js kodunun en üstüne ekleyebilirsiniz. Burada, kodun ilerleyen kısımlarında ne kadar ekleyebileceğiniz hakkında bilgi edinmek için fazladan bir sabit ENCODING_LENGTH tanımlarsınız. Ayrıca, bir kelime dizisini modele bir giriş olarak kullanılabilecek uygun bir tensöre dönüştürmek için kullanacağınız tokenize işleviyle birlikte çalışır.

Her bir satırın işlevi hakkında daha fazla bilgi için aşağıdaki kodda yer alan yorumları inceleyin:

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

Harika. Şimdi handleCommentPost() işlevine geri dönün ve işlevin bu yeni sürümüyle değiştirin.

Eklediğiniz yorumlarla ilgili yorum kodu:

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

Son olarak, yorum spam olarak algılanırsa stil belirlemek için loadAndPredict() işlevini güncelleyin.

Şu an için stili değiştirmeniz yeterlidir, ancak daha sonra yorumu bir tür denetleme sırasına alabilir veya göndermeyi durdurabilirsiniz.

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. Gerçek zamanlı güncellemeler: Node.js + Websockets

Artık spam algılama özelliğine sahip çalışan bir ön ucunuz var. Yapbozun son parçası, gerçek zamanlı iletişim için Node.js'yi bazı websocket'lerle kullanmak ve eklenen spam olmayan yorumları gerçek zamanlı olarak güncellemek.

Yuva.io

Socket.io, Node.js ile websocket'leri kullanmanın en popüler yollarından biridir (yazma sırasında). Devam edip Glitch'e, Socket.io kitaplığını yapıya dahil etmek istediğinizi söyleyin. Bağımlılıklardan biri olarak socket.io'yu eklemek için package.json klasörünü üst düzey dizinde (www klasörünün üst klasöründe) düzenleyin:

paket. 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"
  }
}

Güzel! Güncellendikten sonra, www klasöründeki index.html öğesini socket.io kitaplığını içerecek şekilde güncelleyin.

Bu kod satırını, komut dosyasının.js için HTML komut dosyası etiketi içe aktarma işleminin yukarısına index.html dosyasının sonuna yerleştirmeniz yeterlidir:

index.html

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

Artık index.html dosyanızda 3 komut dosyası etiketi bulunmalıdır:

  • TensorFlow.js kitaplığını ilk içe aktarma
  • az önce eklediğiniz 2. içe aktarma socket.io
  • ve sonuncu, script.js kodunu içe aktarmalıdır.

Ardından, düğümdeki socket.io ayarlarını yapmak için server.js öğesini düzenleyin ve alınan tüm bağlı istemcilere geçiş için basit bir arka uç oluşturun.

Node.js kodunun ne yaptığıyla ilgili bir açıklama için aşağıdaki kod yorumlarına bakın:

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

Güzel! Artık socket.io etkinliklerini dinleyen bir web sunucunuz var. Yani bir istemciden yeni bir yorum geldiğinde bir comment etkinliğiniz olur ve sunucu, uzaktan yorum oluşturmak için istemcinin dinleyeceği remoteComment etkinlikleri yayınlar. Dolayısıyla, yapılacak son şey bu etkinlikleri yaymak ve işlemek için socket.io mantığını istemci tarafı koduna eklemektir.

İlk olarak, socket.io sunucusuna bağlanmak ve uzaktan yorum etkinliklerini dinlemek / işlemek için script.js kodunun sonuna aşağıdaki kodu ekleyin:

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

Son olarak, bir yorum spam değilse bir socket.io etkinliği oluşturmak için loadAndPredict işlevine bir kod ekleyin. Bu işlem, diğer bağlı istemcileri bu yeni yorumla güncellemenize olanak tanır. Böylece bu mesajın içeriği, yukarıda yazdığınız server.js kodu aracılığıyla onlara iletilir.

Mevcut loadAndPredict işlevinizi, son spam kontrolüne else ifadesi ekleyen aşağıdaki kodla değiştirmeniz yeterlidir. Burada yorum spam değilse tüm yorum verilerini göndermek için socket.emit() çağırırsınız:

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

Tebrikler! Doğru bir şekilde takip ettiyseniz artık index.html sayfanızın 2 örneğini açabilirsiniz.

Spam olmayan yorumlar yayınladığınızda, bunların diğer istemcide neredeyse anında oluşturulduğunu görürsünüz. Yorum spam ise, asla gönderilmeyecek olan ön uçta spam olarak işaretlenir:

ee0f13398ea4e91e.gif

12. Tebrikler

Tebrikler, yorum spam'ini tespit etmek amacıyla, web tarayıcısında gerçek bir uygulama için TensorFlow.js ile makine öğrenimini kullanmaya yönelik ilk adımları attınız.

Deneyin, çeşitli yorumlarda deneyin, bazı sorunların devam ettiğini fark edebilirsiniz. Ayrıca, 20 kelimeden uzun bir cümle girerseniz, modelin giriş olarak 20 kelime beklediğinden bu cümlenin şu anda başarısız olduğunu fark edersiniz.

Bu durumda, uzun cümleleri 20 kelimelik gruplara bölmeniz ve her bir alt cümlenin spam olma ihtimalini dikkate almanız ve bunu gösterip göstermeyeceğinize karar vermeniz gerekebilir. Bu amaçla kullanabileceğiniz birçok yaklaşım olduğundan, deneme yapabileceğiniz ek bir görev olarak bırakacağız.

Bir sonraki codelab'de, şu anda tespit edemediği özel durumlar için bu modeli nasıl yeniden eğiteceğinizi, hatta 20 kelimeden uzun cümleleri işleyebilmek için modelin giriş beklentilerini nasıl değiştireceğinizi ve ardından bu modeli TensorFlow.js ile dışa aktarıp nasıl kullanacağınızı göstereceğiz.

Herhangi bir nedenle sorun yaşarsanız kodunuzu buradaki tam sürümle karşılaştırın ve herhangi bir eksiklik olup olmadığını kontrol edin.

Özet

Bu codelab'de:

  1. TensorFlow.js'nin ne olduğunu ve doğal dil işleme için hangi modellerin bulunduğunu öğrendiniz
  2. Örnek bir web sitesi için gerçek zamanlı yorumlara olanak tanıyan kurgusal bir web sitesi oluşturuldu.
  3. Web sayfasında TensorFlow.js aracılığıyla yorum spam'i algılama için uygun, önceden eğitilmiş bir makine öğrenimi modeli yüklendi.
  4. Cümleleri, yüklenen makine öğrenimi modeliyle kodlamayı ve bu kodlamayı bir Tensor içine yerleştirmeyi öğrendiniz.
  5. Yorumu inceleme için bekletmek isteyip istemediğinize karar vermek için makine öğrenimi modelinin çıkışını yorumlamak ve gerçek zamanlı olarak diğer bağlı istemcilere geçiş yapmak için sunucuya göndermek.

Sonraki adım

Artık üzerinde çalışacağınız bir çalışma tabanına sahip olduğunuza göre, bu makine öğrenimi modeli standart metnini, üzerinde çalışabileceğiniz gerçek bir kullanım alanı için genişletmek üzere hangi yaratıcı fikirleri ortaya çıkarabilirsiniz?

Yaptıklarınızı bizimle paylaşın

Yaratıcılıkla ilgili diğer kullanım alanları için bugün yaptığınız çalışmaları kolayca genişletebilirsiniz. Kutunun dışında düşünmenizi ve bilgisayar korsanlığı yapmaya devam etmenizi öneririz.

Projenizin TensorFlow blogumuzda veya gelecekteki etkinliklerimizde yer alması için #MadeWithTFJS hashtag'ini kullanarak bizi sosyal medyada etiketlemeyi unutmayın. Yaratıcılığınızı görmekten memnuniyet duyarız.

Daha ayrıntılı bilgi için TensorFlow.js codelab'leri

Ödeme yapılacak web siteleri