Google I / O'daki önemli notları, ürün oturumlarını, atölyeleri ve daha fazlasını izleyin Oynatma listesine bakın

Metni yükle

TensorFlow.org'da görüntüleyin Google Colab'de çalıştırın Kaynağı GitHub'da görüntüleyin Defteri indirin

Bu eğitim, metni yüklemenin ve ön işlemenin iki yolunu gösterir.

  • İlk olarak, Keras yardımcı programlarını ve katmanlarını kullanacaksınız. TensorFlow'da yeniyseniz, bunlarla başlamalısınız.

  • Daha sonra, metin dosyalarını yüklemek için tf.data.TextLineDataset gibi daha düşük seviyeli yardımcı programları ve daha ince tahıl kontrolü için verileri önceden tf.text için tf.text kullanacaksınız.

# Be sure you're using the stable versions of both tf and tf-text, for binary compatibility.
pip install -q -U tf-nightly
pip install -q -U tensorflow-text-nightly
import collections
import pathlib
import re
import string

import tensorflow as tf

from tensorflow.keras import layers
from tensorflow.keras import losses
from tensorflow.keras import preprocessing
from tensorflow.keras import utils
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization

import tensorflow_datasets as tfds
import tensorflow_text as tf_text

Örnek 1: Bir Yığın Taşması sorusu için etiketi tahmin edin

İlk örnek olarak, Stack Overflow'dan programlama sorularının bir veri setini indireceksiniz. Her soru ("Bir sözlüğü değere göre nasıl sıralayabilirim?") Tam olarak bir etiketle ( Python , CSharp , JavaScript veya Java ) etiketlenir. Göreviniz, bir soru için etiketi tahmin eden bir model geliştirmektir. Bu, çok sınıflı bir sınıflandırma örneğidir, önemli ve yaygın olarak uygulanabilir bir makine öğrenimi problemi türüdür.

Veri kümesini indirin ve keşfedin

Ardından, veri kümesini indirecek ve dizin yapısını keşfedeceksiniz.

data_url = 'https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz'
dataset = utils.get_file(
    'stack_overflow_16k.tar.gz',
    data_url,
    untar=True,
    cache_dir='stack_overflow',
    cache_subdir='')
dataset_dir = pathlib.Path(dataset).parent
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz
6053888/6053168 [==============================] - 0s 0us/step
list(dataset_dir.iterdir())
[PosixPath('/tmp/.keras/train'),
 PosixPath('/tmp/.keras/README.md'),
 PosixPath('/tmp/.keras/test'),
 PosixPath('/tmp/.keras/stack_overflow_16k.tar.gz.tar.gz')]
train_dir = dataset_dir/'train'
list(train_dir.iterdir())
[PosixPath('/tmp/.keras/train/java'),
 PosixPath('/tmp/.keras/train/csharp'),
 PosixPath('/tmp/.keras/train/javascript'),
 PosixPath('/tmp/.keras/train/python')]

train/csharp , train/java , train/python ve train/javascript dizinleri, her biri bir Stack Overflow sorusu olan birçok metin dosyası içerir. Bir dosya yazdırın ve verileri inceleyin.

sample_file = train_dir/'python/1755.txt'
with open(sample_file) as f:
  print(f.read())
why does this blank program print true x=true.def stupid():.    x=false.stupid().print x

Veri kümesini yükleyin

Ardından, verileri diskten yükleyecek ve eğitime uygun bir formata hazırlayacaksınız. Bunu yapmak için, etiketli birtf.data.Dataset oluşturmak için text_dataset_from_directory yardımcı programınıtf.data.Dataset . Tf.data'da yeniyseniz , bu, girdi ardışık düzenleri oluşturmak için güçlü bir araç koleksiyonudur.

preprocessing.text_dataset_from_directory aşağıdaki gibi bir dizin yapısı beklemektedir.

train/
...csharp/
......1.txt
......2.txt
...java/
......1.txt
......2.txt
...javascript/
......1.txt
......2.txt
...python/
......1.txt
......2.txt

Bir makine öğrenimi denemesi çalıştırırken, veri kümenizi üç bölüme ayırmak en iyi uygulamadır: eğitim , doğrulama ve test . Yığın Taşması veri kümesi zaten eğitim ve test olarak bölünmüştür, ancak bir doğrulama kümesi yoktur. Aşağıdaki validation_split bağımsız değişkenini kullanarak eğitim verilerinin 80:20 oranında bölünmesini kullanarak bir doğrulama kümesi oluşturun.

batch_size = 32
seed = 42

raw_train_ds = preprocessing.text_dataset_from_directory(
    train_dir,
    batch_size=batch_size,
    validation_split=0.2,
    subset='training',
    seed=seed)
Found 8000 files belonging to 4 classes.
Using 6400 files for training.

Yukarıda görebileceğiniz gibi, eğitim klasöründe% 80'ini (veya 6.400) eğitim için kullanacağınız 8.000 örnek var.tf.data.Dataset birtf.data.Dataset doğrudantf.data.Dataset ileterek bir modeli model.fit . İlk olarak, veri kümesini yineleyin ve veriler hakkında bir fikir edinmek için birkaç örnek yazdırın.

for text_batch, label_batch in raw_train_ds.take(1):
  for i in range(10):
    print("Question: ", text_batch.numpy()[i])
    print("Label:", label_batch.numpy()[i])
Question:  b'"my tester is going to the wrong constructor i am new to programming so if i ask a question that can be easily fixed, please forgive me. my program has a tester class with a main. when i send that to my regularpolygon class, it sends it to the wrong constructor. i have two constructors. 1 without perameters..public regularpolygon().    {.       mynumsides = 5;.       mysidelength = 30;.    }//end default constructor...and my second, with perameters. ..public regularpolygon(int numsides, double sidelength).    {.        mynumsides = numsides;.        mysidelength = sidelength;.    }// end constructor...in my tester class i have these two lines:..regularpolygon shape = new regularpolygon(numsides, sidelength);.        shape.menu();...numsides and sidelength were declared and initialized earlier in the testing class...so what i want to happen, is the tester class sends numsides and sidelength to the second constructor and use it in that class. but it only uses the default constructor, which therefor ruins the whole rest of the program. can somebody help me?..for those of you who want to see more of my code: here you go..public double vertexangle().    {.        system.out.println(""the vertex angle method: "" + mynumsides);// prints out 5.        system.out.println(""the vertex angle method: "" + mysidelength); // prints out 30..        double vertexangle;.        vertexangle = ((mynumsides - 2.0) / mynumsides) * 180.0;.        return vertexangle;.    }//end method vertexangle..public void menu().{.    system.out.println(mynumsides); // prints out what the user puts in.    system.out.println(mysidelength); // prints out what the user puts in.    gotographic();.    calcr(mynumsides, mysidelength);.    calcr(mynumsides, mysidelength);.    print(); .}// end menu...this is my entire tester class:..public static void main(string[] arg).{.    int numsides;.    double sidelength;.    scanner keyboard = new scanner(system.in);..    system.out.println(""welcome to the regular polygon program!"");.    system.out.println();..    system.out.print(""enter the number of sides of the polygon ==> "");.    numsides = keyboard.nextint();.    system.out.println();..    system.out.print(""enter the side length of each side ==> "");.    sidelength = keyboard.nextdouble();.    system.out.println();..    regularpolygon shape = new regularpolygon(numsides, sidelength);.    shape.menu();.}//end main...for testing it i sent it numsides 4 and sidelength 100."\n'
Label: 1
Question:  b'"blank code slow skin detection this code changes the color space to lab and using a threshold finds the skin area of an image. but it\'s ridiculously slow. i don\'t know how to make it faster ?    ..from colormath.color_objects import *..def skindetection(img, treshold=80, color=[255,20,147]):..    print img.shape.    res=img.copy().    for x in range(img.shape[0]):.        for y in range(img.shape[1]):.            rgbimg=rgbcolor(img[x,y,0],img[x,y,1],img[x,y,2]).            labimg=rgbimg.convert_to(\'lab\', debug=false).            if (labimg.lab_l > treshold):.                res[x,y,:]=color.            else: .                res[x,y,:]=img[x,y,:]..    return res"\n'
Label: 3
Question:  b'"option and validation in blank i want to add a new option on my system where i want to add two text files, both rental.txt and customer.txt. inside each text are id numbers of the customer, the videotape they need and the price...i want to place it as an option on my code. right now i have:...add customer.rent return.view list.search.exit...i want to add this as my sixth option. say for example i ordered a video, it would display the price and would let me confirm the price and if i am going to buy it or not...here is my current code:..  import blank.io.*;.    import blank.util.arraylist;.    import static blank.lang.system.out;..    public class rentalsystem{.    static bufferedreader input = new bufferedreader(new inputstreamreader(system.in));.    static file file = new file(""file.txt"");.    static arraylist<string> list = new arraylist<string>();.    static int rows;..    public static void main(string[] args) throws exception{.        introduction();.        system.out.print(""nn"");.        login();.        system.out.print(""nnnnnnnnnnnnnnnnnnnnnn"");.        introduction();.        string repeat;.        do{.            loadfile();.            system.out.print(""nwhat do you want to do?nn"");.            system.out.print(""n                    - - - - - - - - - - - - - - - - - - - - - - -"");.            system.out.print(""nn                    |     1. add customer    |   2. rent return |n"");.            system.out.print(""n                    - - - - - - - - - - - - - - - - - - - - - - -"");.            system.out.print(""nn                    |     3. view list       |   4. search      |n"");.            system.out.print(""n                    - - - - - - - - - - - - - - - - - - - - - - -"");.            system.out.print(""nn                                             |   5. exit        |n"");.            system.out.print(""n                                              - - - - - - - - - -"");.            system.out.print(""nnchoice:"");.            int choice = integer.parseint(input.readline());.            switch(choice){.                case 1:.                    writedata();.                    break;.                case 2:.                    rentdata();.                    break;.                case 3:.                    viewlist();.                    break;.                case 4:.                    search();.                    break;.                case 5:.                    system.out.println(""goodbye!"");.                    system.exit(0);.                default:.                    system.out.print(""invalid choice: "");.                    break;.            }.            system.out.print(""ndo another task? [y/n] "");.            repeat = input.readline();.        }while(repeat.equals(""y""));..        if(repeat!=""y"") system.out.println(""ngoodbye!"");..    }..    public static void writedata() throws exception{.        system.out.print(""nname: "");.        string cname = input.readline();.        system.out.print(""address: "");.        string add = input.readline();.        system.out.print(""phone no.: "");.        string pno = input.readline();.        system.out.print(""rental amount: "");.        string ramount = input.readline();.        system.out.print(""tapenumber: "");.        string tno = input.readline();.        system.out.print(""title: "");.        string title = input.readline();.        system.out.print(""date borrowed: "");.        string dborrowed = input.readline();.        system.out.print(""due date: "");.        string ddate = input.readline();.        createline(cname, add, pno, ramount,tno, title, dborrowed, ddate);.        rentdata();.    }..    public static void createline(string name, string address, string phone , string rental, string tapenumber, string title, string borrowed, string due) throws exception{.        filewriter fw = new filewriter(file, true);.        fw.write(""nname: ""+name + ""naddress: "" + address +""nphone no.: ""+ phone+""nrentalamount: ""+rental+""ntape no.: ""+ tapenumber+""ntitle: ""+ title+""ndate borrowed: ""+borrowed +""ndue date: ""+ due+"":rn"");.        fw.close();.    }..    public static void loadfile() throws exception{.        try{.            list.clear();.            fileinputstream fstream = new fileinputstream(file);.            bufferedreader br = new bufferedreader(new inputstreamreader(fstream));.            rows = 0;.            while( br.ready()).            {.                list.add(br.readline());.                rows++;.            }.            br.close();.        } catch(exception e){.            system.out.println(""list not yet loaded."");.        }.    }..    public static void viewlist(){.        system.out.print(""n~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        system.out.print("" |list of all costumers|"");.        system.out.print(""~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        for(int i = 0; i <rows; i++){.            system.out.println(list.get(i));.        }.    }.        public static void rentdata()throws exception.    {   system.out.print(""n~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        system.out.print("" |rent data list|"");.        system.out.print(""~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        system.out.print(""nenter customer name: "");.        string cname = input.readline();.        system.out.print(""date borrowed: "");.        string dborrowed = input.readline();.        system.out.print(""due date: "");.        string ddate = input.readline();.        system.out.print(""return date: "");.        string rdate = input.readline();.        system.out.print(""rent amount: "");.        string ramount = input.readline();..        system.out.print(""you pay:""+ramount);...    }.    public static void search()throws exception.    {   system.out.print(""n~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        system.out.print("" |search costumers|"");.        system.out.print(""~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~"");.        system.out.print(""nenter costumer name: "");.        string cname = input.readline();.        boolean found = false;..        for(int i=0; i < rows; i++){.            string temp[] = list.get(i).split("","");..            if(cname.equals(temp[0])){.            system.out.println(""search result:nyou are "" + temp[0] + "" from "" + temp[1] + "".""+ temp[2] + "".""+ temp[3] + "".""+ temp[4] + "".""+ temp[5] + "" is "" + temp[6] + "".""+ temp[7] + "" is "" + temp[8] + ""."");.                found = true;.            }.        }..        if(!found){.            system.out.print(""no results."");.        }..    }..        public static boolean evaluate(string uname, string pass){.        if (uname.equals(""admin"")&&pass.equals(""12345"")) return true;.        else return false;.    }..    public static string login()throws exception{.        bufferedreader input=new bufferedreader(new inputstreamreader(system.in));.        int counter=0;.        do{.            system.out.print(""username:"");.            string uname =input.readline();.            system.out.print(""password:"");.            string pass =input.readline();..            boolean accept= evaluate(uname,pass);..            if(accept){.                break;.                }else{.                    system.out.println(""incorrect username or password!"");.                    counter ++;.                    }.        }while(counter<3);..            if(counter !=3) return ""login successful"";.            else return ""login failed"";.            }.        public static void introduction() throws exception{..        system.out.println(""                  - - - - - - - - - - - - - - - - - - - - - - - - -"");.        system.out.println(""                  !                  r e n t a l                  !"");.        system.out.println(""                   ! ~ ~ ~ ~ ~ !  =================  ! ~ ~ ~ ~ ~ !"");.        system.out.println(""                  !                  s y s t e m                  !"");.        system.out.println(""                  - - - - - - - - - - - - - - - - - - - - - - - - -"");.        }..}"\n'
Label: 1
Question:  b'"exception: dynamic sql generation for the updatecommand is not supported against a selectcommand that does not return any key i dont know what is the problem this my code : ..string nomtable;..datatable listeetablissementtable = new datatable();.datatable listeinteretstable = new datatable();.dataset ds = new dataset();.sqldataadapter da;.sqlcommandbuilder cmdb;..private void listeinterets_click(object sender, eventargs e).{.    nomtable = ""listeinteretstable"";.    d.cnx.open();.    da = new sqldataadapter(""select nome from offices"", d.cnx);.    ds = new dataset();.    da.fill(ds, nomtable);.    datagridview1.datasource = ds.tables[nomtable];.}..private void sauvgarder_click(object sender, eventargs e).{.    d.cnx.open();.    cmdb = new sqlcommandbuilder(da);.    da.update(ds, nomtable);.    d.cnx.close();.}"\n'
Label: 0
Question:  b'"parameter with question mark and super in blank, i\'ve come across a method that is formatted like this:..public final subscription subscribe(final action1<? super t> onnext, final action1<throwable> onerror) {.}...in the first parameter, what does the question mark and super mean?"\n'
Label: 1
Question:  b'call two objects wsdl the first time i got a very strange wsdl. ..i would like to call the object (interface - invoicecheck_out) do you know how?....i would like to call the object (variable) do you know how?..try to call (it`s ok)....try to call (how call this?)\n'
Label: 0
Question:  b"how to correctly make the icon for systemtray in blank using icon sizes of any dimension for systemtray doesn't look good overall. .what is the correct way of making icons for windows system tray?..screenshots: http://imgur.com/zsibwn9..icon: http://imgur.com/vsh4zo8\n"
Label: 0
Question:  b'"is there a way to check a variable that exists in a different script than the original one? i\'m trying to check if a variable, which was previously set to true in 2.py in 1.py, as 1.py is only supposed to continue if the variable is true...2.py..import os..completed = false..#some stuff here..completed = true...1.py..import 2 ..if completed == true.   #do things...however i get a syntax error at ..if completed == true"\n'
Label: 3
Question:  b'"blank control flow i made a number which asks for 2 numbers with blank and responds with  the corresponding message for the case. how come it doesnt work  for the second number ? .regardless what i enter for the second number , i am getting the message ""your number is in the range 0-10""...using system;.using system.collections.generic;.using system.linq;.using system.text;..namespace consoleapplication1.{.    class program.    {.        static void main(string[] args).        {.            string myinput;  // declaring the type of the variables.            int myint;..            string number1;.            int number;...            console.writeline(""enter a number"");.            myinput = console.readline(); //muyinput is a string  which is entry input.            myint = int32.parse(myinput); // myint converts the string into an integer..            if (myint > 0).                console.writeline(""your number {0} is greater than zero."", myint);.            else if (myint < 0).                console.writeline(""your number {0} is  less  than zero."", myint);.            else.                console.writeline(""your number {0} is equal zero."", myint);..            console.writeline(""enter another number"");.            number1 = console.readline(); .            number = int32.parse(myinput); ..            if (number < 0 || number == 0).                console.writeline(""your number {0} is  less  than zero or equal zero."", number);.            else if (number > 0 && number <= 10).                console.writeline(""your number {0} is  in the range from 0 to 10."", number);.            else.                console.writeline(""your number {0} is greater than 10."", number);..            console.writeline(""enter another number"");..        }.    }    .}"\n'
Label: 0
Question:  b'"credentials cannot be used for ntlm authentication i am getting org.apache.commons.httpclient.auth.invalidcredentialsexception: credentials cannot be used for ntlm authentication: exception in eclipse..whether it is possible mention eclipse to take system proxy settings directly?..public class httpgetproxy {.    private static final string proxy_host = ""proxy.****.com"";.    private static final int proxy_port = 6050;..    public static void main(string[] args) {.        httpclient client = new httpclient();.        httpmethod method = new getmethod(""https://kodeblank.org"");..        hostconfiguration config = client.gethostconfiguration();.        config.setproxy(proxy_host, proxy_port);..        string username = ""*****"";.        string password = ""*****"";.        credentials credentials = new usernamepasswordcredentials(username, password);.        authscope authscope = new authscope(proxy_host, proxy_port);..        client.getstate().setproxycredentials(authscope, credentials);..        try {.            client.executemethod(method);..            if (method.getstatuscode() == httpstatus.sc_ok) {.                string response = method.getresponsebodyasstring();.                system.out.println(""response = "" + response);.            }.        } catch (ioexception e) {.            e.printstacktrace();.        } finally {.            method.releaseconnection();.        }.    }.}...exception:...  dec 08, 2017 1:41:39 pm .          org.apache.commons.httpclient.auth.authchallengeprocessor selectauthscheme.         info: ntlm authentication scheme selected.       dec 08, 2017 1:41:39 pm org.apache.commons.httpclient.httpmethoddirector executeconnect.         severe: credentials cannot be used for ntlm authentication: .           org.apache.commons.httpclient.usernamepasswordcredentials.           org.apache.commons.httpclient.auth.invalidcredentialsexception: credentials .         cannot be used for ntlm authentication: .        enter code here .          org.apache.commons.httpclient.usernamepasswordcredentials.      at org.apache.commons.httpclient.auth.ntlmscheme.authenticate(ntlmscheme.blank:332).        at org.apache.commons.httpclient.httpmethoddirector.authenticateproxy(httpmethoddirector.blank:320).      at org.apache.commons.httpclient.httpmethoddirector.executeconnect(httpmethoddirector.blank:491).      at org.apache.commons.httpclient.httpmethoddirector.executewithretry(httpmethoddirector.blank:391).      at org.apache.commons.httpclient.httpmethoddirector.executemethod(httpmethoddirector.blank:171).      at org.apache.commons.httpclient.httpclient.executemethod(httpclient.blank:397).      at org.apache.commons.httpclient.httpclient.executemethod(httpclient.blank:323).      at httpgetproxy.main(httpgetproxy.blank:31).  dec 08, 2017 1:41:39 pm org.apache.commons.httpclient.httpmethoddirector processproxyauthchallenge.  info: failure authenticating with ntlm @proxy.****.com:6050"\n'
Label: 1

Etiketler 0 , 1 , 2 veya 3 . Bunlardan hangisinin hangi dize etiketine karşılık geldiğini görmek için, veri kümesindeki class_names özelliğini kontrol edebilirsiniz.

for i, label in enumerate(raw_train_ds.class_names):
  print("Label", i, "corresponds to", label)
Label 0 corresponds to csharp
Label 1 corresponds to java
Label 2 corresponds to javascript
Label 3 corresponds to python

Ardından, bir doğrulama ve test veri kümesi oluşturacaksınız. Doğrulama için eğitim setinden kalan 1.600 incelemeyi kullanacaksınız.

raw_val_ds = preprocessing.text_dataset_from_directory(
    train_dir,
    batch_size=batch_size,
    validation_split=0.2,
    subset='validation',
    seed=seed)
Found 8000 files belonging to 4 classes.
Using 1600 files for validation.
test_dir = dataset_dir/'test'
raw_test_ds = preprocessing.text_dataset_from_directory(
    test_dir, batch_size=batch_size)
Found 8000 files belonging to 4 classes.

Veri kümesini eğitim için hazırlayın

Daha sonra, preprocessing.TextVectorization katmanını kullanarak verileri standartlaştıracak, belirtecek ve vektörleştireceksiniz.

  • Standardizasyon, veri kümesini basitleştirmek için tipik olarak noktalama işaretlerini veya HTML öğelerini kaldırmak için metnin önceden işlenmesini ifade eder.

  • Simgeleştirme, dizeleri belirteçlere bölmeyi ifade eder (örneğin, bir cümleyi boşluklara ayırarak tek tek kelimelere bölmek).

  • Vektörizasyon, jetonları sayılara dönüştürerek bir sinir ağına beslenmelerini ifade eder.

Tüm bu görevler bu katmanla gerçekleştirilebilir. API dokümanında bunların her biri hakkında daha fazla bilgi edinebilirsiniz.

  • Varsayılan standardizasyon, metni küçük harfe dönüştürür ve noktalama işaretlerini kaldırır.

  • Varsayılan belirteç, boşlukta bölünür.

  • Varsayılan vektörleştirme modu int . Bu, tamsayı endeksleri (jeton başına bir) çıkarır. Bu mod, kelime sırasını dikkate alan modeller oluşturmak için kullanılabilir. Kelime torbası modelleri oluşturmak için binary gibi diğer modları da kullanabilirsiniz.

Bunlar hakkında daha fazla bilgi edinmek için iki mod oluşturacaksınız. İlk olarak, bir kelime torbası modeli oluşturmak için binary modeli kullanacaksınız. Ardından, 1D ConvNet ile int modunu kullanacaksınız.

VOCAB_SIZE = 10000

binary_vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='binary')

int modu için, maksimum kelime boyutuna ek olarak, katmanın dizileri tam olarak sıra_uzunluk değerlerine doldurmasına veya kesmesine neden olacak açık bir maksimum sıra uzunluğu ayarlamanız gerekir.

MAX_SEQUENCE_LENGTH = 250

int_vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)

Ardından, çağrısı yapacağı adapt veri kümesine önişleme tabakasının durumunu sığdırmak için. Bu, modelin tamsayılar için bir dizge dizini oluşturmasına neden olacaktır.

# Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda text, labels: text)
binary_vectorize_layer.adapt(train_text)
int_vectorize_layer.adapt(train_text)

Verileri önceden işlemek için bu katmanları kullanmanın sonucunu görün:

def binary_vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return binary_vectorize_layer(text), label
def int_vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return int_vectorize_layer(text), label
# Retrieve a batch (of 32 reviews and labels) from the dataset
text_batch, label_batch = next(iter(raw_train_ds))
first_question, first_label = text_batch[0], label_batch[0]
print("Question", first_question)
print("Label", first_label)
Question tf.Tensor(b'"what is the difference between these two ways to create an element? var a = document.createelement(\'div\');..a.id = ""mydiv"";...and..var a = document.createelement(\'div\').id = ""mydiv"";...what is the difference between them such that the first one works and the second one doesn\'t?"\n', shape=(), dtype=string)
Label tf.Tensor(2, shape=(), dtype=int32)
print("'binary' vectorized question:", 
      binary_vectorize_text(first_question, first_label)[0])
'binary' vectorized question: tf.Tensor([[1. 1. 0. ... 0. 0. 0.]], shape=(1, 10000), dtype=float32)
print("'int' vectorized question:",
      int_vectorize_text(first_question, first_label)[0])
'int' vectorized question: tf.Tensor(
[[ 55   6   2 410 211 229 121 895   4 124  32 245  43   5   1   1   5   1
    1   6   2 410 211 191 318  14   2  98  71 188   8   2 199  71 178   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]], shape=(1, 250), dtype=int64)

Yukarıda görebileceğiniz gibi, binary mod, girişte en az bir kez hangi simgelerin bulunduğunu belirten bir dizi döndürür, int modu ise her simgeyi bir tamsayı ile değiştirir ve böylece sıralarını korur. .get_vocabulary() 'i çağırarak her tamsayının karşılık geldiği dizgeyi (dizeyi) .get_vocabulary() .

print("1289 ---> ", int_vectorize_layer.get_vocabulary()[1289])
print("313 ---> ", int_vectorize_layer.get_vocabulary()[313])
print("Vocabulary size: {}".format(len(int_vectorize_layer.get_vocabulary())))
1289 --->  roman
313 --->  source
Vocabulary size: 10000

Modelinizi eğitmeye neredeyse hazırsınız. Son bir ön işleme adımı olarak, daha önce oluşturduğunuz TextVectorization katmanlarını eğitim, doğrulama ve test veri kümesine uygulayacaksınız.

binary_train_ds = raw_train_ds.map(binary_vectorize_text)
binary_val_ds = raw_val_ds.map(binary_vectorize_text)
binary_test_ds = raw_test_ds.map(binary_vectorize_text)

int_train_ds = raw_train_ds.map(int_vectorize_text)
int_val_ds = raw_val_ds.map(int_vectorize_text)
int_test_ds = raw_test_ds.map(int_vectorize_text)

Veri kümesini performans için yapılandırın

Bunlar, G / Ç'nin engellenmediğinden emin olmak için veri yüklerken kullanmanız gereken iki önemli yöntemdir.

.cache() , verileri diskten yüklendikten sonra bellekte tutar. Bu, modelinizi eğitirken veri kümesinin bir darboğaz haline gelmemesini sağlayacaktır. Veri kümeniz belleğe sığmayacak kadar büyükse, bu yöntemi, okumak için birçok küçük dosyadan daha verimli olan yüksek performanslı bir disk üzerinde önbellek oluşturmak için de kullanabilirsiniz.

.prefetch() , eğitim sırasında veri ön işleme ve model yürütme ile çakışır.

Veri performansı kılavuzunda her iki yöntem hakkında daha fazla bilgi edinebilir ve verileri diske nasıl önbelleğe alacağınızı öğrenebilirsiniz.

AUTOTUNE = tf.data.AUTOTUNE

def configure_dataset(dataset):
  return dataset.cache().prefetch(buffer_size=AUTOTUNE)
binary_train_ds = configure_dataset(binary_train_ds)
binary_val_ds = configure_dataset(binary_val_ds)
binary_test_ds = configure_dataset(binary_test_ds)

int_train_ds = configure_dataset(int_train_ds)
int_val_ds = configure_dataset(int_val_ds)
int_test_ds = configure_dataset(int_test_ds)

Modeli eğitin

Sinir ağımızı yaratmanın zamanı geldi. binary vektörleştirilmiş veriler için, basit bir kelime torbası doğrusal modeli eğitin:

binary_model = tf.keras.Sequential([layers.Dense(4)])
binary_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = binary_model.fit(
    binary_train_ds, validation_data=binary_val_ds, epochs=10)
Epoch 1/10
200/200 [==============================] - 2s 5ms/step - loss: 1.1210 - accuracy: 0.6522 - val_loss: 0.9196 - val_accuracy: 0.7775
Epoch 2/10
200/200 [==============================] - 0s 2ms/step - loss: 0.7795 - accuracy: 0.8206 - val_loss: 0.7541 - val_accuracy: 0.8031
Epoch 3/10
200/200 [==============================] - 0s 2ms/step - loss: 0.6279 - accuracy: 0.8630 - val_loss: 0.6677 - val_accuracy: 0.8150
Epoch 4/10
200/200 [==============================] - 0s 2ms/step - loss: 0.5344 - accuracy: 0.8856 - val_loss: 0.6139 - val_accuracy: 0.8263
Epoch 5/10
200/200 [==============================] - 0s 2ms/step - loss: 0.4684 - accuracy: 0.9045 - val_loss: 0.5770 - val_accuracy: 0.8331
Epoch 6/10
200/200 [==============================] - 0s 2ms/step - loss: 0.4181 - accuracy: 0.9156 - val_loss: 0.5501 - val_accuracy: 0.8381
Epoch 7/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3779 - accuracy: 0.9280 - val_loss: 0.5299 - val_accuracy: 0.8400
Epoch 8/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3446 - accuracy: 0.9347 - val_loss: 0.5142 - val_accuracy: 0.8413
Epoch 9/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3164 - accuracy: 0.9430 - val_loss: 0.5019 - val_accuracy: 0.8413
Epoch 10/10
200/200 [==============================] - 0s 2ms/step - loss: 0.2920 - accuracy: 0.9481 - val_loss: 0.4920 - val_accuracy: 0.8406

Daha sonra, bir 1D ConvNet oluşturmak için int vektörleştirilmiş katmanı kullanacaksınız.

def create_model(vocab_size, num_labels):
  model = tf.keras.Sequential([
      layers.Embedding(vocab_size, 64, mask_zero=True),
      layers.Conv1D(64, 5, padding="valid", activation="relu", strides=2),
      layers.GlobalMaxPooling1D(),
      layers.Dense(num_labels)
  ])
  return model
# vocab_size is VOCAB_SIZE + 1 since 0 is used additionally for padding.
int_model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=4)
int_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = int_model.fit(int_train_ds, validation_data=int_val_ds, epochs=5)
Epoch 1/5
200/200 [==============================] - 2s 5ms/step - loss: 1.1340 - accuracy: 0.5209 - val_loss: 0.7503 - val_accuracy: 0.6975
Epoch 2/5
200/200 [==============================] - 1s 3ms/step - loss: 0.6207 - accuracy: 0.7595 - val_loss: 0.5546 - val_accuracy: 0.7881
Epoch 3/5
200/200 [==============================] - 1s 3ms/step - loss: 0.3775 - accuracy: 0.8770 - val_loss: 0.4846 - val_accuracy: 0.8131
Epoch 4/5
200/200 [==============================] - 1s 3ms/step - loss: 0.2106 - accuracy: 0.9514 - val_loss: 0.4777 - val_accuracy: 0.8194
Epoch 5/5
200/200 [==============================] - 1s 3ms/step - loss: 0.1063 - accuracy: 0.9819 - val_loss: 0.4989 - val_accuracy: 0.8181

İki modeli karşılaştırın:

print("Linear model on binary vectorized data:")
print(binary_model.summary())
Linear model on binary vectorized data:
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 4)                 40004     
=================================================================
Total params: 40,004
Trainable params: 40,004
Non-trainable params: 0
_________________________________________________________________
None
print("ConvNet model on int vectorized data:")
print(int_model.summary())
ConvNet model on int vectorized data:
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 64)          640064    
_________________________________________________________________
conv1d (Conv1D)              (None, None, 64)          20544     
_________________________________________________________________
global_max_pooling1d (Global (None, 64)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 260       
=================================================================
Total params: 660,868
Trainable params: 660,868
Non-trainable params: 0
_________________________________________________________________
None

Test verilerinde her iki modeli de değerlendirin:

binary_loss, binary_accuracy = binary_model.evaluate(binary_test_ds)
int_loss, int_accuracy = int_model.evaluate(int_test_ds)

print("Binary model accuracy: {:2.2%}".format(binary_accuracy))
print("Int model accuracy: {:2.2%}".format(int_accuracy))
250/250 [==============================] - 1s 3ms/step - loss: 0.5180 - accuracy: 0.8149
250/250 [==============================] - 1s 2ms/step - loss: 0.5193 - accuracy: 0.8111
Binary model accuracy: 81.49%
Int model accuracy: 81.11%

Modeli dışa aktar

Yukarıdaki kodda, modele metin beslemeden önce veri kümesine TextVectorization katmanını uyguladınız. Modelinizin ham dizeleri işleyebilmesini istiyorsanız (örneğin, onu dağıtmayı basitleştirmek için), TextVectorization içine TextVectorization katmanını dahil edebilirsiniz. Bunu yapmak için, yeni eğittiğiniz ağırlıkları kullanarak yeni bir model oluşturabilirsiniz.

export_model = tf.keras.Sequential(
    [binary_vectorize_layer, binary_model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])

# Test it with `raw_test_ds`, which yields raw strings
loss, accuracy = export_model.evaluate(raw_test_ds)
print("Accuracy: {:2.2%}".format(binary_accuracy))
250/250 [==============================] - 1s 4ms/step - loss: 0.5180 - accuracy: 0.8149
Accuracy: 81.49%

Artık modeliniz girdi olarak ham dizeleri alabilir ve model.predict kullanarak her etiket için bir puan tahmin model.predict . Maksimum puana sahip etiketi bulmak için bir işlev tanımlayın:

def get_string_labels(predicted_scores_batch):
  predicted_int_labels = tf.argmax(predicted_scores_batch, axis=1)
  predicted_labels = tf.gather(raw_train_ds.class_names, predicted_int_labels)
  return predicted_labels

Yeni veriler üzerinde çıkarım yapın

inputs = [
    "how do I extract keys from a dict into a list?",  # python
    "debug public static void main(string[] args) {...}",  # java
]
predicted_scores = export_model.predict(inputs)
predicted_labels = get_string_labels(predicted_scores)
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label.numpy())
Question:  how do I extract keys from a dict into a list?
Predicted label:  b'python'
Question:  debug public static void main(string[] args) {...}
Predicted label:  b'java'

Modelinize metin ön işleme mantığını dahil etmek, dağıtımı basitleştiren ve eğitim / test çarpıklığı olasılığını azaltan bir üretim modeli dışa aktarmanıza olanak tanır.

TextVectorization katmanınızı nereye uygulayacağınızı seçerken akılda tutulması gereken bir performans farkı vardır. Bunu modelinizin dışında kullanmak, GPU üzerinde eğitim alırken eşzamansız CPU işlemeyi ve verilerinizin arabelleğe alınmasını sağlar. Dolayısıyla, modelinizi GPU üzerinde eğitiyorsanız, muhtemelen modelinizi geliştirirken en iyi performansı elde etmek için bu seçeneği kullanmak istersiniz, ardından dağıtıma hazırlanmaya hazır olduğunuzda modelinizin içine MetinVektorizasyon katmanını dahil etmek istersiniz. .

Modelleri kaydetme hakkında daha fazla bilgi edinmek için bu öğreticiyi ziyaret edin.

Örnek 2: İlliad çevirilerinin yazarını tahmin edin

Aşağıda, metin dosyalarından örnekler yüklemek için tf.text ve verileri önişlemek için tf.text bir örnek tf.data.TextLineDataset . Bu örnekte, aynı eserin üç farklı İngilizce çevirisini, Homer's Illiad'ı kullanacak ve tek bir metin satırı verilen çevirmeni tanımlamak için bir model eğiteceksiniz.

Veri kümesini indirin ve keşfedin

Üç çevirinin metinleri şöyledir:

Bu eğitimde kullanılan metin dosyaları, belge üstbilgisini ve altbilgisini, satır numaralarını ve bölüm başlıklarını kaldırma gibi bazı tipik ön işleme görevlerinden geçmiştir. Bu hafifçe ezilmiş dosyaları yerel olarak indirin.

DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt']

for name in FILE_NAMES:
  text_dir = utils.get_file(name, origin=DIRECTORY_URL + name)

parent_dir = pathlib.Path(text_dir).parent
list(parent_dir.iterdir())
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/cowper.txt
819200/815980 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/derby.txt
811008/809730 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/butler.txt
811008/807992 [==============================] - 0s 0us/step
[PosixPath('/home/kbuilder/.keras/datasets/facades.tar.gz'),
 PosixPath('/home/kbuilder/.keras/datasets/Giant Panda'),
 PosixPath('/home/kbuilder/.keras/datasets/derby.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/flower_photos.tar.gz'),
 PosixPath('/home/kbuilder/.keras/datasets/YellowLabradorLooking_new.jpg'),
 PosixPath('/home/kbuilder/.keras/datasets/kandinsky5.jpg'),
 PosixPath('/home/kbuilder/.keras/datasets/spa-eng'),
 PosixPath('/home/kbuilder/.keras/datasets/iris_test.csv'),
 PosixPath('/home/kbuilder/.keras/datasets/butler.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/cats_and_dogs.zip'),
 PosixPath('/home/kbuilder/.keras/datasets/flower_photos'),
 PosixPath('/home/kbuilder/.keras/datasets/image.jpg'),
 PosixPath('/home/kbuilder/.keras/datasets/cifar-10-batches-py.tar.gz'),
 PosixPath('/home/kbuilder/.keras/datasets/shakespeare.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/facades'),
 PosixPath('/home/kbuilder/.keras/datasets/Fireboat'),
 PosixPath('/home/kbuilder/.keras/datasets/iris_training.csv'),
 PosixPath('/home/kbuilder/.keras/datasets/cowper.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/jena_climate_2009_2016.csv.zip'),
 PosixPath('/home/kbuilder/.keras/datasets/cifar-10-batches-py'),
 PosixPath('/home/kbuilder/.keras/datasets/fashion-mnist'),
 PosixPath('/home/kbuilder/.keras/datasets/ImageNetLabels.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/Red_sunflower'),
 PosixPath('/home/kbuilder/.keras/datasets/HIGGS.csv.gz'),
 PosixPath('/home/kbuilder/.keras/datasets/cats_and_dogs_filtered'),
 PosixPath('/home/kbuilder/.keras/datasets/mnist.npz'),
 PosixPath('/home/kbuilder/.keras/datasets/jena_climate_2009_2016.csv'),
 PosixPath('/home/kbuilder/.keras/datasets/spa-eng.zip')]

Veri kümesini yükleyin

Her örneğin orijinal dosyadan bir metin satırı olduğu bir metin dosyasından birtf.data.Dataset oluşturmak için tasarlanmış TextLineDataset kullanırsınız, oysa text_dataset_from_directory bir dosyanın tüm içeriğini tek bir örnek olarak ele alır. TextLineDataset , esas olarak satır tabanlı metin verileri için kullanışlıdır (örneğin, şiir veya hata günlükleri).

Her birini kendi veri kümesine yükleyerek bu dosyaları yineleyin. Her örneğin ayrı ayrı etiketlenmesi gerekir, bu nedenle her birine bir etiketleme işlevi uygulamak için tf.data.Dataset.map kullanın. Bu, veri kümesindeki her örnek üzerinde yinelenerek ( example, label ) çiftleri döndürür.

def labeler(example, index):
  return example, tf.cast(index, tf.int64)
labeled_data_sets = []

for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(str(parent_dir/file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)

Ardından, bu etiketli veri kümelerini tek bir veri kümesinde birleştirecek ve karıştıracaksınız.

BUFFER_SIZE = 50000
BATCH_SIZE = 64
VALIDATION_SIZE = 5000
all_labeled_data = labeled_data_sets[0]
for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)

all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)

Daha önce olduğu gibi birkaç örnek yazdırın. Veri kümesi henüz toplu hale getirilmedi, bu nedenle all_labeled_data her giriş bir veri noktasına karşılık gelir:

for text, label in all_labeled_data.take(10):
  print("Sentence: ", text.numpy())
  print("Label:", label.numpy())
Sentence:  b"the middle of the son of Phyleus' shield with his spear, setting on him"
Label: 2
Sentence:  b"One, prostrate at Achilles' feet, bewail'd"
Label: 1
Sentence:  b"There, face to face, with sinewy arms uprais'd,"
Label: 1
Sentence:  b'To whom Achilles thus with scornful glance;'
Label: 1
Sentence:  b'"Ulysses sage, Laertes\' high-born son,'
Label: 1
Sentence:  b'payment to one who had served him well. He would not give your father'
Label: 2
Sentence:  b'For loss of him, who might have been thy shield'
Label: 1
Sentence:  b'For virtuous qualities above the rest.'
Label: 0
Sentence:  b'revenge for the death of Amphimachus, and sent it whirling over the'
Label: 2
Sentence:  b'In battle slain thy sire shall mourn, or mine;'
Label: 0

Veri kümesini eğitim için hazırlayın

Bunun yerine Keras kullanmanın TextVectorization bizim metin veri kümesini ön işlemeden için katmanı, artık kullanacağıtf.text API standardize ve verileri tokenize, bir kelime oluşturmak ve kullanmak StaticVocabularyTable modeline beslemesine tamsayılar için belirteçleri haritaya.

Tf.text çeşitli belirteçler sağlarken, veri kümemizi UnicodeScriptTokenizer için UnicodeScriptTokenizer kullanacaksınız. Metni küçük harfe dönüştürmek ve onu belirtmek için bir işlev tanımlayın. tf.data.Dataset.map veri kümesine uygulamak için tf.data.Dataset.map kullanacaksınız.

tokenizer = tf_text.UnicodeScriptTokenizer()
def tokenize(text, unused_label):
  lower_case = tf_text.case_fold_utf8(text)
  return tokenizer.tokenize(lower_case)
tokenized_ds = all_labeled_data.map(tokenize)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/util/dispatch.py:206: batch_gather (from tensorflow.python.ops.array_ops) is deprecated and will be removed after 2017-10-25.
Instructions for updating:
`tf.batch_gather` is deprecated, please use `tf.gather` with `batch_dims=-1` instead.

Veri kümesi üzerinde yineleme yapabilir ve birkaç simge haline getirilmiş örnek yazdırabilirsiniz.

for text_batch in tokenized_ds.take(5):
  print("Tokens: ", text_batch.numpy())
Tokens:  [b'the' b'middle' b'of' b'the' b'son' b'of' b'phyleus' b"'" b'shield'
 b'with' b'his' b'spear' b',' b'setting' b'on' b'him']
Tokens:  [b'one' b',' b'prostrate' b'at' b'achilles' b"'" b'feet' b',' b'bewail'
 b"'" b'd']
Tokens:  [b'there' b',' b'face' b'to' b'face' b',' b'with' b'sinewy' b'arms'
 b'uprais' b"'" b'd' b',']
Tokens:  [b'to' b'whom' b'achilles' b'thus' b'with' b'scornful' b'glance' b';']
Tokens:  [b'"' b'ulysses' b'sage' b',' b'laertes' b"'" b'high' b'-' b'born' b'son'
 b',']

Ardından, jetonları sıklığa göre sıralayarak ve en iyi VOCAB_SIZE jetonlarını koruyarak bir kelime hazinesi VOCAB_SIZE .

tokenized_ds = configure_dataset(tokenized_ds)

vocab_dict = collections.defaultdict(lambda: 0)
for toks in tokenized_ds.as_numpy_iterator():
  for tok in toks:
    vocab_dict[tok] += 1

vocab = sorted(vocab_dict.items(), key=lambda x: x[1], reverse=True)
vocab = [token for token, count in vocab]
vocab = vocab[:VOCAB_SIZE]
vocab_size = len(vocab)
print("Vocab size: ", vocab_size)
print("First five vocab entries:", vocab[:5])
Vocab size:  10000
First five vocab entries: [b',', b'the', b'and', b"'", b'of']

Belirteçleri tamsayılara dönüştürmek için, bir StaticVocabularyTable oluşturmak için vocab kümesini kullanın. Jetonları [ 2 , vocab_size + 2 ] aralığındaki tam sayılarla vocab_size + 2 . TextVectorization katmanında olduğu gibi, 0 , dolguyu belirtmek için ve 1 , bir kelime dağarcığı (OOV) belirtecini belirtmek için ayrılmıştır.

keys = vocab
values = range(2, len(vocab) + 2)  # reserve 0 for padding, 1 for OOV

init = tf.lookup.KeyValueTensorInitializer(
    keys, values, key_dtype=tf.string, value_dtype=tf.int64)

num_oov_buckets = 1
vocab_table = tf.lookup.StaticVocabularyTable(init, num_oov_buckets)

Son olarak, belirteç ve arama tablosunu kullanarak veri kümesini standartlaştırmak, belirtmek ve vektörleştirmek için bir işlev tanımlayın:

def preprocess_text(text, label):
  standardized = tf_text.case_fold_utf8(text)
  tokenized = tokenizer.tokenize(standardized)
  vectorized = vocab_table.lookup(tokenized)
  return vectorized, label

Çıktıyı görmek için bunu tek bir örnek üzerinde deneyebilirsiniz:

example_text, example_label = next(iter(all_labeled_data))
print("Sentence: ", example_text.numpy())
vectorized_text, example_label = preprocess_text(example_text, example_label)
print("Vectorized sentence: ", vectorized_text.numpy())
Sentence:  b"the middle of the son of Phyleus' shield with his spear, setting on him"
Vectorized sentence:  [   3  716    6    3   28    6 1595    5  166   14   11   63    2 2384
   22   16]

Şimdi tf.data.Dataset.map kullanarak veri kümesinde ön işlem işlevini çalıştırın.

all_encoded_data = all_labeled_data.map(preprocess_text)

Veri kümesini eğitime ve teste bölün

TextVectorization katmanı ayrıca vektörleştirilmiş verileri toplu ve pedler. Bir grubun içindeki örneklerin aynı boyut ve şekilde olması gerektiğinden doldurma gereklidir, ancak bu veri kümelerindeki örneklerin tümü aynı boyutta değildir - her metin satırında farklı sayıda kelime vardır.tf.data.Dataset , bölme ve yastıklı toplu veri kümelerini destekler:

train_data = all_encoded_data.skip(VALIDATION_SIZE).shuffle(BUFFER_SIZE)
validation_data = all_encoded_data.take(VALIDATION_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE)
validation_data = validation_data.padded_batch(BATCH_SIZE)

Şimdi, validation_data ve train_data , çiftlerin ( example, label ) koleksiyonları değil, toplu iş koleksiyonlarıdır. Her grup, diziler olarak temsil edilen bir çifttir ( birçok örnek , birçok etiket ). Göstermek için:

sample_text, sample_labels = next(iter(validation_data))
print("Text batch shape: ", sample_text.shape)
print("Label batch shape: ", sample_labels.shape)
print("First text example: ", sample_text[0])
print("First label example: ", sample_labels[0])
Text batch shape:  (64, 20)
Label batch shape:  (64,)
First text example:  tf.Tensor(
[   3  716    6    3   28    6 1595    5  166   14   11   63    2 2384
   22   16    0    0    0    0], shape=(20,), dtype=int64)
First label example:  tf.Tensor(2, shape=(), dtype=int64)

Kullandığımız yana 0 doldurma ve 1 -dışı kelime (oov) simgeleri için, kelime büyüklüğü iki artmıştır.

vocab_size += 2

Daha önce olduğu gibi daha iyi performans için veri kümelerini yapılandırın.

train_data = configure_dataset(train_data)
validation_data = configure_dataset(validation_data)

Modeli eğitin

Daha önce olduğu gibi bu veri kümesinde bir model eğitebilirsiniz.

model = create_model(vocab_size=vocab_size, num_labels=3)
model.compile(
    optimizer='adam',
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy'])
history = model.fit(train_data, validation_data=validation_data, epochs=3)
Epoch 1/3
697/697 [==============================] - 28s 9ms/step - loss: 0.5208 - accuracy: 0.7643 - val_loss: 0.3767 - val_accuracy: 0.8394
Epoch 2/3
697/697 [==============================] - 3s 4ms/step - loss: 0.2795 - accuracy: 0.8854 - val_loss: 0.3676 - val_accuracy: 0.8510
Epoch 3/3
697/697 [==============================] - 3s 4ms/step - loss: 0.1885 - accuracy: 0.9282 - val_loss: 0.3995 - val_accuracy: 0.8474
loss, accuracy = model.evaluate(validation_data)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 1s 2ms/step - loss: 0.3995 - accuracy: 0.8474
Loss:  0.3994785249233246
Accuracy: 84.74%

Modeli dışa aktar

Modelimizin ham dizeleri girdi olarak alabilmesini sağlamak için, özel ön işleme işlevimizle aynı adımları gerçekleştiren bir TextVectorization katmanı oluşturacaksınız. Zaten bir kelime dağarcığını eğittiğiniz için, yeni bir kelime hazinesi geliştiren adapt yerine set_vocaublary kullanabilirsiniz.

preprocess_layer = TextVectorization(
    max_tokens=vocab_size,
    standardize=tf_text.case_fold_utf8,
    split=tokenizer.tokenize,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)
preprocess_layer.set_vocabulary(vocab)
export_model = tf.keras.Sequential(
    [preprocess_layer, model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])
# Create a test dataset of raw strings
test_ds = all_labeled_data.take(VALIDATION_SIZE).batch(BATCH_SIZE)
test_ds = configure_dataset(test_ds)
loss, accuracy = export_model.evaluate(test_ds)
print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 6s 9ms/step - loss: 0.5205 - accuracy: 0.7996
Loss:  0.5205461978912354
Accuracy: 79.96%

Kodlanmış doğrulama setindeki model ile ham doğrulama setindeki dışa aktarılan model için kayıp ve doğruluk, beklendiği gibi aynıdır.

Yeni veriler üzerinde çıkarım yapın

inputs = [
    "Join'd to th' Ionians with their flowing robes,",  # Label: 1
    "the allies, and his armour flashed about him so that he seemed to all",  # Label: 2
    "And with loud clangor of his arms he fell.",  # Label: 0
]
predicted_scores = export_model.predict(inputs)
predicted_labels = tf.argmax(predicted_scores, axis=1)
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label.numpy())
Question:  Join'd to th' Ionians with their flowing robes,
Predicted label:  1
Question:  the allies, and his armour flashed about him so that he seemed to all
Predicted label:  2
Question:  And with loud clangor of his arms he fell.
Predicted label:  0

TensorFlow Veri Kümelerini (TFDS) kullanarak daha fazla veri kümesi indirme

TensorFlow Veri Kümelerinden çok daha fazla veri kümesi indirebilirsiniz. Örnek olarak, IMDB Büyük Film İnceleme veri kümesini indirecek ve onu duyarlılık sınıflandırması için bir model eğitmek için kullanacaksınız.

train_ds = tfds.load(
    'imdb_reviews',
    split='train',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)
val_ds = tfds.load(
    'imdb_reviews',
    split='train',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)

Birkaç örnek yazdırın.

for review_batch, label_batch in val_ds.take(1):
  for i in range(5):
    print("Review: ", review_batch[i].numpy())
    print("Label: ", label_batch[i].numpy())
Review:  b'Mann photographs the Alberta Rocky Mountains in a superb fashion, and Jimmy Stewart and Walter Brennan give enjoyable performances as they always seem to do. <br /><br />But come on Hollywood - a Mountie telling the people of Dawson City, Yukon to elect themselves a marshal (yes a marshal!) and to enforce the law themselves, then gunfighters battling it out on the streets for control of the town? <br /><br />Nothing even remotely resembling that happened on the Canadian side of the border during the Klondike gold rush. Mr. Mann and company appear to have mistaken Dawson City for Deadwood, the Canadian North for the American Wild West.<br /><br />Canadian viewers be prepared for a Reefer Madness type of enjoyable howl with this ludicrous plot, or, to shake your head in disgust.'
Label:  0
Review:  b"This was an absolutely terrible movie. Don't be lured in by Christopher Walken or Michael Ironside. Both are great actors, but this must simply be their worst role in history. Even their great acting could not redeem this movie's ridiculous storyline. This movie is an early nineties US propaganda piece. The most pathetic scenes were those when the Columbian rebels were making their cases for revolutions. Maria Conchita Alonso appeared phony, and her pseudo-love affair with Walken was nothing but a pathetic emotional plug in a movie that was devoid of any real meaning. I am disappointed that there are movies like this, ruining actor's like Christopher Walken's good name. I could barely sit through it."
Label:  0
Review:  b'This is the kind of film for a snowy Sunday afternoon when the rest of the world can go ahead with its own business as you descend into a big arm-chair and mellow for a couple of hours. Wonderful performances from Cher and Nicolas Cage (as always) gently row the plot along. There are no rapids to cross, no dangerous waters, just a warm and witty paddle through New York life at its best. A family film in every sense and one that deserves the praise it received.'
Label:  1
Review:  b"This is a film which should be seen by anybody interested in, effected by, or suffering from an eating disorder. It is an amazingly accurate and sensitive portrayal of bulimia in a teenage girl, its causes and its symptoms. The girl is played by one of the most brilliant young actresses working in cinema today, Alison Lohman, who was later so spectacular in 'Where the Truth Lies'. I would recommend that this film be shown in all schools, as you will never see a better on this subject. Alison Lohman is absolutely outstanding, and one marvels at her ability to convey the anguish of a girl suffering from this compulsive disorder. If barometers tell us the air pressure, Alison Lohman tells us the emotional pressure with the same degree of accuracy. Her emotional range is so precise, each scene could be measured microscopically for its gradations of trauma, on a scale of rising hysteria and desperation which reaches unbearable intensity. Mare Winningham is the perfect choice to play her mother, and does so with immense sympathy and a range of emotions just as finely tuned as Lohman's. Together, they make a pair of sensitive emotional oscillators vibrating in resonance with one another. This film is really an astonishing achievement, and director Katt Shea should be proud of it. The only reason for not seeing it is if you are not interested in people. But even if you like nature films best, this is after all animal behaviour at the sharp edge. Bulimia is an extreme version of how a tormented soul can destroy her own body in a frenzy of despair. And if we don't sympathise with people suffering from the depths of despair, then we are dead inside."
Label:  1
Review:  b'Okay, you have:<br /><br />Penelope Keith as Miss Herringbone-Tweed, B.B.E. (Backbone of England.) She\'s killed off in the first scene - that\'s right, folks; this show has no backbone!<br /><br />Peter O\'Toole as Ol\' Colonel Cricket from The First War and now the emblazered Lord of the Manor.<br /><br />Joanna Lumley as the ensweatered Lady of the Manor, 20 years younger than the colonel and 20 years past her own prime but still glamourous (Brit spelling, not mine) enough to have a toy-boy on the side. It\'s alright, they have Col. Cricket\'s full knowledge and consent (they guy even comes \'round for Christmas!) Still, she\'s considerate of the colonel enough to have said toy-boy her own age (what a gal!)<br /><br />David McCallum as said toy-boy, equally as pointlessly glamourous as his squeeze. Pilcher couldn\'t come up with any cover for him within the story, so she gave him a hush-hush job at the Circus.<br /><br />and finally:<br /><br />Susan Hampshire as Miss Polonia Teacups, Venerable Headmistress of the Venerable Girls\' Boarding-School, serving tea in her office with a dash of deep, poignant advice for life in the outside world just before graduation. Her best bit of advice: "I\'ve only been to Nancherrow (the local Stately Home of England) once. I thought it was very beautiful but, somehow, not part of the real world." Well, we can\'t say they didn\'t warn us.<br /><br />Ah, Susan - time was, your character would have been running the whole show. They don\'t write \'em like that any more. Our loss, not yours.<br /><br />So - with a cast and setting like this, you have the re-makings of "Brideshead Revisited," right?<br /><br />Wrong! They took these 1-dimensional supporting roles because they paid so well. After all, acting is one of the oldest temp-jobs there is (YOU name another!)<br /><br />First warning sign: lots and lots of backlighting. They get around it by shooting outdoors - "hey, it\'s just the sunlight!"<br /><br />Second warning sign: Leading Lady cries a lot. When not crying, her eyes are moist. That\'s the law of romance novels: Leading Lady is "dewy-eyed."<br /><br />Henceforth, Leading Lady shall be known as L.L.<br /><br />Third warning sign: L.L. actually has stars in her eyes when she\'s in love. Still, I\'ll give Emily Mortimer an award just for having to act with that spotlight in her eyes (I wonder . did they use contacts?)<br /><br />And lastly, fourth warning sign: no on-screen female character is "Mrs." She\'s either "Miss" or "Lady."<br /><br />When all was said and done, I still couldn\'t tell you who was pursuing whom and why. I couldn\'t even tell you what was said and done.<br /><br />To sum up: they all live through World War II without anything happening to them at all.<br /><br />OK, at the end, L.L. finds she\'s lost her parents to the Japanese prison camps and baby sis comes home catatonic. Meanwhile (there\'s always a "meanwhile,") some young guy L.L. had a crush on (when, I don\'t know) comes home from some wartime tough spot and is found living on the street by Lady of the Manor (must be some street if SHE\'s going to find him there.) Both war casualties are whisked away to recover at Nancherrow (SOMEBODY has to be "whisked away" SOMEWHERE in these romance stories!)<br /><br />Great drama.'
Label:  0

Artık verileri önceden işleyebilir ve bir modeli eskisi gibi eğitebilirsiniz.

Veri kümesini eğitim için hazırlayın

vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)

# Make a text-only dataset (without labels), then call adapt
train_text = train_ds.map(lambda text, labels: text)
vectorize_layer.adapt(train_text)
def vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return vectorize_layer(text), label
train_ds = train_ds.map(vectorize_text)
val_ds = val_ds.map(vectorize_text)
# Configure datasets for performance as before
train_ds = configure_dataset(train_ds)
val_ds = configure_dataset(val_ds)

Modeli eğitin

model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=1)
model.summary()
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, None, 64)          640064    
_________________________________________________________________
conv1d_2 (Conv1D)            (None, None, 64)          20544     
_________________________________________________________________
global_max_pooling1d_2 (Glob (None, 64)                0         
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 65        
=================================================================
Total params: 660,673
Trainable params: 660,673
Non-trainable params: 0
_________________________________________________________________
model.compile(
    loss=losses.BinaryCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = model.fit(train_ds, validation_data=val_ds, epochs=3)
Epoch 1/3
391/391 [==============================] - 5s 9ms/step - loss: 0.5039 - accuracy: 0.6990 - val_loss: 0.3041 - val_accuracy: 0.8795
Epoch 2/3
391/391 [==============================] - 2s 4ms/step - loss: 0.2776 - accuracy: 0.8797 - val_loss: 0.1733 - val_accuracy: 0.9462
Epoch 3/3
391/391 [==============================] - 2s 4ms/step - loss: 0.1690 - accuracy: 0.9348 - val_loss: 0.0919 - val_accuracy: 0.9787
loss, accuracy = model.evaluate(val_ds)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
391/391 [==============================] - 1s 2ms/step - loss: 0.0919 - accuracy: 0.9787
Loss:  0.09189144521951675
Accuracy: 97.87%

Modeli dışa aktar

export_model = tf.keras.Sequential(
    [vectorize_layer, model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])
# 0 --> negative review
# 1 --> positive review
inputs = [
    "This is a fantastic movie.",
    "This is a bad movie.",
    "This movie was so bad that it was good.",
    "I will never say yes to watching this movie.",
]
predicted_scores = export_model.predict(inputs)
predicted_labels = [int(round(x[0])) for x in predicted_scores]
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label)
Question:  This is a fantastic movie.
Predicted label:  1
Question:  This is a bad movie.
Predicted label:  0
Question:  This movie was so bad that it was good.
Predicted label:  1
Question:  I will never say yes to watching this movie.
Predicted label:  1

Sonuç

Bu eğitici, metni yüklemenin ve ön işlemenin birkaç yolunu gösterdi. Bir sonraki adım olarak, web sitesinde ek öğreticiler keşfedebilir veya TensorFlow Veri Kümelerinden yeni veri kümeleri indirebilirsiniz.