텍스트로드

TensorFlow.org에서 보기 Google Colab에서 실행 GitHub에서 소스 보기노트북 다운로드

이 튜토리얼은 텍스트를 로드하고 사전 처리하는 두 가지 방법을 보여줍니다.

  • 먼저 Keras 유틸리티와 계층을 사용합니다. TensorFlow를 처음 사용하는 경우 이것들부터 시작해야 합니다.

  • 다음으로, 당신은 같은 낮은 수준의 유틸리티를 사용 tf.data.TextLineDataset 부하 텍스트 파일,에 tf.text 보다 세밀하게 제어를위한 데이터를 사전 처리 할 수 있습니다.

# Be sure you're using the stable versions of both tf and tf-text, for binary compatibility.
pip uninstall -y tensorflow tf-nightly keras

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

예 1: 스택 오버플로 질문에 대한 태그 예측

첫 번째 예로 Stack Overflow에서 프로그래밍 질문 데이터 세트를 다운로드합니다. 각각의 질문 ( "어떻게 값을 기준으로 사전을 정렬 할 수 있습니까?") 정확히 하나의 태그 (표시되어 있습니다 Python , CSharp , JavaScript , 또는 Java ). 당신의 임무는 질문에 대한 태그를 예측하는 모델을 개발하는 것입니다. 이것은 중요하고 널리 적용 가능한 기계 학습 문제인 다중 클래스 분류의 예입니다.

데이터세트 다운로드 및 탐색

다음으로 데이터 세트를 다운로드하고 디렉토리 구조를 탐색합니다.

data_url = 'https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz'
dataset_dir = utils.get_file(
    origin=data_url,
    untar=True,
    cache_dir='stack_overflow',
    cache_subdir='')

dataset_dir = pathlib.Path(dataset_dir).parent
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz
6053888/6053168 [==============================] - 0s 0us/step
6062080/6053168 [==============================] - 0s 0us/step
list(dataset_dir.iterdir())
[PosixPath('/tmp/.keras/train'),
 PosixPath('/tmp/.keras/README.md'),
 PosixPath('/tmp/.keras/stack_overflow_16k.tar.gz'),
 PosixPath('/tmp/.keras/test')]
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/pythontrain/javascript 디렉토리는 스택 오버플로 질문입니다 각각의 많은 텍스트 파일을 포함합니다. 파일을 인쇄하고 데이터를 검사합니다.

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

데이터세트 로드

다음으로 디스크에서 데이터를 로드하고 교육에 적합한 형식으로 준비합니다. 이렇게하려면 사용 text_dataset_from_directory 레이블 생성 유틸리티를 tf.data.Dataset . 당신이 새로운 경우 tf.data , 그것은 입력 파이프 라인을 구축하기위한 강력한 도구 모음입니다.

preprocessing.text_dataset_from_directory 디렉토리 구조로 다음과 것으로 기대하고있다.

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

: 기계 학습 실험을 실행하면 세 개의 분할로 데이터 집합을 분할하는 것이 좋습니다 기차 , 검증테스트 . 스택 오버플로 데이터 세트는 이미 학습과 테스트로 나뉘었지만 유효성 검사 세트가 없습니다. 사용하여 훈련 데이터의 80:20 분할을 사용하여 검증 세트 만들기 validation_split 아래 인수를.

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.

위에서 볼 수 있듯이 교육 폴더에는 8,000개의 예제가 있으며 그 중 80%(또는 6,400)를 교육에 사용합니다. 당신이 잠시 살펴 보 겠지만, 당신은 전달하여 모델을 학습 할 수 tf.data.Dataset 직접 model.fit . 먼저 데이터 세트를 반복하고 몇 가지 예를 인쇄하여 데이터에 대한 느낌을 얻으십시오.

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

레이블은 0 , 1 , 2 또는 3 . 어떤 문자열 레이블, 당신은 확인할 수 있습니다 이러한 대응의 어느 보려면 class_names 데이터 세트에 속성을.

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

다음으로 유효성 검사 및 테스트 데이터 세트를 만듭니다. 검증을 위해 훈련 세트의 나머지 1,600개 리뷰를 사용합니다.

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.

훈련을 위한 데이터세트 준비

다음으로, 당신은, 토큰 화를 표준화하고 사용하여 데이터를 벡터화합니다 preprocessing.TextVectorization 레이어를.

  • 표준화는 일반적으로 데이터 세트를 단순화하기 위해 구두점이나 HTML 요소를 제거하기 위해 텍스트를 전처리하는 것을 말합니다.

  • 토큰화는 문자열을 토큰으로 분할하는 것을 말합니다(예: 공백에서 분할하여 문장을 개별 단어로 분할).

  • 벡터화는 토큰을 신경망에 제공할 수 있도록 숫자로 변환하는 것을 말합니다.

이 모든 작업은 이 레이어로 수행할 수 있습니다. 당신은 이들 각각에 대해 자세히 알아볼 수 있습니다 API의 문서 .

  • 기본 표준화는 텍스트를 소문자로 변환하고 구두점을 제거합니다.

  • 기본 토크나이저는 공백에서 분할됩니다.

  • 기본 벡터화 모드입니다 int . 이것은 정수 인덱스를 출력합니다(토큰당 하나). 이 모드는 단어 순서를 고려한 모델을 만드는 데 사용할 수 있습니다. 당신은 또한 같은 다른 모드를 사용할 수 있습니다 binary 빌드 가방 -의 단어 모델.

이에 대해 자세히 알아보기 위해 두 가지 모드를 구축합니다. 첫째, 당신은 사용할 binary 가방 - 중 - 단어 모델을 구축하는 모델을. 다음으로, 당신은 사용 int 1 차원 ConvNet와 모드.

VOCAB_SIZE = 10000

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

들어 int 모드, 최대 어휘 크기뿐만 아니라, 정확히 sequence_length 값 패드 또는 잘라 내기 시퀀스에 레이어의 원인이됩니다 명시 적으로 최대 시퀀스 길이를 설정해야합니다.

MAX_SEQUENCE_LENGTH = 250

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

다음으로, 당신은 호출 adapt 데이터 세트에 전처리 층의 상태에 맞게. 이렇게 하면 모델이 문자열 인덱스를 정수로 빌드합니다.

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

다음 레이어를 사용하여 데이터를 사전 처리한 결과를 확인하세요.

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)

위에서 볼 수 있듯이, binary 동안 모드는 토큰이 입력에 한 번 이상 존재 배열 의미하는데를 반환 int 모드에 따라서 순서를 유지, 정수로 각 토큰을 대체합니다. 당신은 토큰 (문자열)을 조회 할 수 호출하여 각 정수에 대응 .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

모델을 훈련할 준비가 거의 되었습니다. 최종 전처리 단계로, 당신은 적용됩니다 TextVectorization 당신은 기차, 검증 및 테스트 데이터 세트에 이전에 만든 레이어를.

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)

성능을 위한 데이터세트 구성

I/O가 차단되지 않도록 데이터를 로드할 때 사용해야 하는 두 가지 중요한 방법입니다.

.cache() 가 디스크에서 장전 한 후 메모리에 데이터를 유지합니다. 이렇게 하면 모델을 훈련하는 동안 데이터 세트가 병목 현상이 되지 않습니다. 데이터 세트가 너무 커서 메모리에 맞지 않는 경우 이 방법을 사용하여 많은 작은 파일보다 읽기에 더 효율적인 고성능 온디스크 캐시를 생성할 수도 있습니다.

.prefetch() 데이터 전처리 훈련 동안 실행 모델 중첩.

당신은 디스크에 캐시 데이터를 두 가지 방법에 대해 자세히 알아뿐만 아니라, 방법 등을 할 수 있습니다 데이터 성능 가이드 .

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)

모델 훈련

신경망을 만들 차례입니다. 들어 binary 벡터화 된 데이터, 간단한 가방 -의 - 즉 선형 모델을 학습 :

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 4ms/step - loss: 1.1154 - accuracy: 0.6478 - val_loss: 0.9136 - val_accuracy: 0.7688
Epoch 2/10
200/200 [==============================] - 0s 2ms/step - loss: 0.7778 - accuracy: 0.8200 - val_loss: 0.7505 - val_accuracy: 0.7962
Epoch 3/10
200/200 [==============================] - 0s 2ms/step - loss: 0.6272 - accuracy: 0.8603 - val_loss: 0.6651 - val_accuracy: 0.8100
Epoch 4/10
200/200 [==============================] - 0s 2ms/step - loss: 0.5341 - accuracy: 0.8863 - val_loss: 0.6117 - val_accuracy: 0.8213
Epoch 5/10
200/200 [==============================] - 0s 2ms/step - loss: 0.4682 - accuracy: 0.9036 - val_loss: 0.5751 - val_accuracy: 0.8331
Epoch 6/10
200/200 [==============================] - 0s 2ms/step - loss: 0.4180 - accuracy: 0.9180 - val_loss: 0.5484 - val_accuracy: 0.8363
Epoch 7/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3778 - accuracy: 0.9281 - val_loss: 0.5283 - val_accuracy: 0.8369
Epoch 8/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3445 - accuracy: 0.9359 - val_loss: 0.5127 - val_accuracy: 0.8381
Epoch 9/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3163 - accuracy: 0.9414 - val_loss: 0.5004 - val_accuracy: 0.8388
Epoch 10/10
200/200 [==============================] - 0s 2ms/step - loss: 0.2920 - accuracy: 0.9484 - val_loss: 0.4907 - val_accuracy: 0.8400

다음으로, 당신은 사용 int 1 차원 ConvNet를 구축하는 벡터화 층.

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 [==============================] - 9s 4ms/step - loss: 1.1285 - accuracy: 0.5092 - val_loss: 0.7460 - val_accuracy: 0.6925
Epoch 2/5
200/200 [==============================] - 1s 3ms/step - loss: 0.6111 - accuracy: 0.7611 - val_loss: 0.5419 - val_accuracy: 0.7944
Epoch 3/5
200/200 [==============================] - 1s 3ms/step - loss: 0.3687 - accuracy: 0.8845 - val_loss: 0.4780 - val_accuracy: 0.8231
Epoch 4/5
200/200 [==============================] - 1s 3ms/step - loss: 0.2034 - accuracy: 0.9528 - val_loss: 0.4774 - val_accuracy: 0.8194
Epoch 5/5
200/200 [==============================] - 1s 3ms/step - loss: 0.1005 - accuracy: 0.9841 - val_loss: 0.4960 - val_accuracy: 0.8250

두 모델을 비교하십시오.

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

테스트 데이터에서 두 모델을 평가합니다.

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.5182 - accuracy: 0.8159
250/250 [==============================] - 1s 2ms/step - loss: 0.5307 - accuracy: 0.8085
Binary model accuracy: 81.59%
Int model accuracy: 80.85%

모델 내보내기

위의 코드에서는 적용 TextVectorization 모델에 텍스트를 공급하기 전에 데이터 세트에 레이어를. 당신은 (그것을 배포를 단순화하기 위해, 예를 들어) 원시 문자열을 처리하는 모델이있는 확인하려면, 당신은 포함 할 수 TextVectorization 모델 내부 레이어를. 그렇게 하려면 방금 훈련한 가중치를 사용하여 새 모델을 만들 수 있습니다.

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.5182 - accuracy: 0.8159
Accuracy: 81.59%

이제 모델은 입력으로 원시 문자열을 가지고 사용하여 각 레이블에 대한 점수 예측할 수 model.predict . 최대 점수를 가진 레이블을 찾는 함수를 정의합니다.

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

새 데이터에 대한 추론 실행

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())
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/array_ops.py:5075: calling gather (from tensorflow.python.ops.array_ops) with validate_indices is deprecated and will be removed in a future version.
Instructions for updating:
The `validate_indices` argument has no effect. Indices are always validated on CPU and never validated on GPU.
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'

모델 내부의 텍스트 사전 처리 로직을 포함하면 생산이 단순화 배포 모델을 수출 할 수 있으며, 가능성을 감소 스큐 기차 / 테스트 .

어디에 적용하는 선택할 때 염두에 두어야 할 성능 차이가 TextVectorization 층. 모델 외부에서 사용하면 GPU에서 훈련할 때 비동기 CPU 처리 및 데이터 버퍼링을 수행할 수 있습니다. 따라서 GPU에서 모델을 훈련하는 경우 이 옵션을 사용하여 모델을 개발하는 동안 최상의 성능을 얻은 다음 배포 준비가 되면 모델 내부에 TextVectorization 레이어를 포함하도록 전환할 수 있습니다. .

이 방문 튜토리얼 모델을 저장에 대한 자세한 내용을 보려면.

예 2: Illiad 번역의 저자 예측

다음은 사용하는 예를 제공 tf.data.TextLineDataset 로드 텍스트 파일에서 예제하고 tf.text 데이터를 전처리한다. 이 예에서는 같은 저작의 세 가지 다른 영어 번역인 Homer's Illiad를 사용하고 한 줄의 텍스트가 주어지면 번역자를 식별하도록 모델을 훈련합니다.

데이터세트 다운로드 및 탐색

세 번역의 텍스트는 다음과 같습니다.

이 튜토리얼에서 사용된 텍스트 파일은 문서 머리글과 바닥글, 줄 번호 및 장 제목을 제거하는 것과 같은 몇 가지 일반적인 전처리 작업을 거쳤습니다. 이 가볍게 정리된 파일을 로컬로 다운로드하십시오.

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
827392/815980 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/derby.txt
811008/809730 [==============================] - 0s 0us/step
819200/809730 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/butler.txt
811008/807992 [==============================] - 0s 0us/step
819200/807992 [==============================] - 0s 0us/step
[PosixPath('/home/kbuilder/.keras/datasets/derby.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/butler.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/cowper.txt'),
 PosixPath('/home/kbuilder/.keras/datasets/fashion-mnist')]

데이터세트 로드

당신은 사용 TextLineDataset 만들 수 있도록 설계되어, tf.data.Dataset 각각의 예를 원본 파일에서 한 줄의 텍스트 인 텍스트 파일을, 반면 text_dataset_from_directory 하나의 예로서 파일의 취급 모든 내용을. TextLineDataset (예,시 또는 에러 로그의) 주로 회선 기반의 텍스트 데이터에 유용하다.

이러한 파일을 반복하여 각각을 자체 데이터세트에 로드합니다. 각각의 예를 개별적으로 분류 할 필요가 있으므로 사용 tf.data.Dataset.map 각각에 블러 함수를 적용. 이것은 (반환 데이터 집합에있는 모든 예제를 반복합니다 example, label ) 쌍을.

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)

다음으로 레이블이 지정된 이러한 데이터 세트를 단일 데이터 세트로 결합하고 섞습니다.

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)

이전과 같이 몇 가지 예를 인쇄하십시오. 데이터 세트는, 아직에 따라서 각 엔트리 일괄되지 all_labeled_data 하나 개의 데이터 포인트에 대응한다 :

for text, label in all_labeled_data.take(10):
  print("Sentence: ", text.numpy())
  print("Label:", label.numpy())
Sentence:  b'Ye bring whom now ye bear back to the host'
Label: 0
Sentence:  b'Scatters with ease both dogs and stalwart youths;'
Label: 1
Sentence:  b'and spear with spear, in the conflict of mail-clad men. Mighty was the'
Label: 2
Sentence:  b'Calchas were false or true.'
Label: 2
Sentence:  b'Had stricken where the forelock grows, a part'
Label: 0
Sentence:  b'trick which Apollo had played the son of Tydeus, so she brought him his'
Label: 2
Sentence:  b"Weeping, she spoke; the women join'd her wail:"
Label: 1
Sentence:  b"Then 'mid the Trojans went with lofty step,"
Label: 1
Sentence:  b'ruler. For Antea, wife of Proetus, lusted after him, and would have had'
Label: 2
Sentence:  b'At length the aged Priam gave command:'
Label: 1

훈련을 위한 데이터세트 준비

대신 Keras 사용하는 TextVectorization 우리의 텍스트 데이터 집합을 사전 처리하는 층이, 이제 사용 tf.text API를 표준화하고 데이터를 토큰 화, 어휘를 구축하고 사용하는 StaticVocabularyTable 모델에 피드 정수로 토큰을 매핑 할 수 있습니다.

tf.text 다양한 tokenizers을 제공하지만, 당신은 사용 UnicodeScriptTokenizer 우리의 데이터 집합을 토큰 화 할 수 있습니다. 텍스트를 소문자로 변환하고 토큰화하는 함수를 정의합니다. 당신은 사용 tf.data.Dataset.map 데이터 세트에 토큰을 적용 할 수 있습니다.

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.

데이터 세트를 반복하고 몇 가지 토큰화된 예제를 인쇄할 수 있습니다.

for text_batch in tokenized_ds.take(5):
  print("Tokens: ", text_batch.numpy())
Tokens:  [b'ye' b'bring' b'whom' b'now' b'ye' b'bear' b'back' b'to' b'the' b'host']
Tokens:  [b'scatters' b'with' b'ease' b'both' b'dogs' b'and' b'stalwart' b'youths'
 b';']
Tokens:  [b'and' b'spear' b'with' b'spear' b',' b'in' b'the' b'conflict' b'of'
 b'mail' b'-' b'clad' b'men' b'.' b'mighty' b'was' b'the']
Tokens:  [b'calchas' b'were' b'false' b'or' b'true' b'.']
Tokens:  [b'had' b'stricken' b'where' b'the' b'forelock' b'grows' b',' b'a' b'part']

다음으로, 당신은 주파수에 의해 토큰을 정렬 및 상단 유지하여 어휘를 구축 할 것입니다 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']

정수로 토큰을 변환하려면 사용 vocab 크리에이트로 설정 StaticVocabularyTable . 당신은 범위 [의 정수로 토큰을 매핑합니다 2 , vocab_size + 2 ]. 와 마찬가지로 TextVectorization0 나타내고 패딩으로 예약되고 1 아웃 오브 어휘 (OOV) 토큰을 나타 내기 위해 예약된다.

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)

마지막으로 토크나이저 및 조회 테이블을 사용하여 데이터 세트를 표준화, 토큰화 및 벡터화하는 기능을 정의합니다.

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

단일 예제에서 이것을 시도하여 출력을 볼 수 있습니다.

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'Ye bring whom now ye bear back to the host'
Vectorized sentence:  [130 360  65  49 130 284 133   8   3 118]

이제 사용하여 데이터 세트에 전처리 기능 실행 tf.data.Dataset.map .

all_encoded_data = all_labeled_data.map(preprocess_text)

데이터 세트를 학습 및 테스트로 분할

Keras TextVectorization 층도 배치 패드 벡터화 데이터. 배치 내부의 예제는 크기와 모양이 같아야 하기 때문에 패딩이 필요하지만 이러한 데이터 세트의 예제는 모두 같은 크기가 아닙니다. 각 텍스트 줄에는 단어 수가 다릅니다. tf.data.Dataset 분할 및 패딩-배치 데이터 세트를 지원합니다 :

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)

이제 validation_datatrain_data (모음 아닌 example, label ) 쌍하지만, 배치의 컬렉션. 각 배치는 배열로 표현 (예 많은 많은 라벨)의 쌍이다. 설명:

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, 17)
Label batch shape:  (64,)
First text example:  tf.Tensor([130 360  65  49 130 284 133   8   3 118   0   0   0   0   0   0   0], shape=(17,), dtype=int64)
First label example:  tf.Tensor(0, shape=(), dtype=int64)

우리가 사용하기 때문에 0 패딩과 1 아웃 오브 어휘 (OOV) 토큰, 어휘 사이즈는 2로 증가했다.

vocab_size += 2

이전과 같이 더 나은 성능을 위해 데이터세트를 구성합니다.

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

모델 훈련

이전과 같이 이 데이터 세트에서 모델을 훈련할 수 있습니다.

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.5166 - accuracy: 0.7711 - val_loss: 0.3766 - val_accuracy: 0.8352
Epoch 2/3
697/697 [==============================] - 2s 3ms/step - loss: 0.2803 - accuracy: 0.8868 - val_loss: 0.3678 - val_accuracy: 0.8422
Epoch 3/3
697/697 [==============================] - 2s 3ms/step - loss: 0.1888 - accuracy: 0.9291 - val_loss: 0.4013 - val_accuracy: 0.8414
loss, accuracy = model.evaluate(validation_data)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 1s 2ms/step - loss: 0.4013 - accuracy: 0.8414
Loss:  0.40128639340400696
Accuracy: 84.14%

모델 내보내기

입력으로 원시 문자열을 복용에 대한 우리의 모델이 가능하려면, 당신은 만들 것이다 TextVectorization 우리의 정의로 수행 동일한 단계가 기능을 전처리 레이어를. 이미 어휘를 훈련 때문에, 당신은 사용할 수 있습니다 set_vocaublary 대신에 adapt 새로운 어휘를 훈련한다.

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 16ms/step - loss: 0.5350 - accuracy: 0.7908
Loss:  0.5349949598312378
Accuracy: 79.08%

인코딩된 검증 세트의 모델과 원시 검증 세트의 내보낸 모델에 대한 손실 및 정확도는 예상대로 동일합니다.

새 데이터에 대한 추론 실행

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 Datasets(TFDS)를 사용하여 더 많은 데이터 세트 다운로드

당신은에서 더 많은 데이터 세트를 다운로드 할 수 있습니다 TensorFlow 데이터 집합을 . 예를 들어, 당신은 다운로드합니다 IMDB 대형 영화 리뷰 데이터 세트를 , 그리고 감정 분류를위한 모델을 학습하는 데 사용합니다.

train_ds = tfds.load(
    'imdb_reviews',
    split='train[:80%]',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)
val_ds = tfds.load(
    'imdb_reviews',
    split='train[80%:]',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)

몇 가지 예를 인쇄하십시오.

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"Instead, go to the zoo, buy some peanuts and feed 'em to the monkeys. Monkeys are funny. People with amnesia who don't say much, just sit there with vacant eyes are not all that funny.<br /><br />Black comedy? There isn't a black person in it, and there isn't one funny thing in it either.<br /><br />Walmart buys these things up somehow and puts them on their dollar rack. It's labeled Unrated. I think they took out the topless scene. They may have taken out other stuff too, who knows? All we know is that whatever they took out, isn't there any more.<br /><br />The acting seemed OK to me. There's a lot of unfathomables tho. It's supposed to be a city? It's supposed to be a big lake? If it's so hot in the church people are fanning themselves, why are they all wearing coats?"
Label:  0
Review:  b'Well, was Morgan Freeman any more unusual as God than George Burns? This film sure was better than that bore, "Oh, God". I was totally engrossed and LMAO all the way through. Carrey was perfect as the out of sorts anchorman wannabe, and Aniston carried off her part as the frustrated girlfriend in her usual well played performance. I, for one, don\'t consider her to be either ugly or untalented. I think my favorite scene was when Carrey opened up the file cabinet thinking it could never hold his life history. See if you can spot the file in the cabinet that holds the events of his bathroom humor: I was rolling over this one. Well written and even better played out, this comedy will go down as one of this funnyman\'s best.'
Label:  1
Review:  b"I'm sorry but I didn't like this doc very much. I can think of a million ways it could have been better. The people who made it obviously don't have much imagination. The interviews aren't very interesting and no real insight is offered. The footage isn't assembled in a very informative way, either. It's too bad because this is a movie that really deserves spellbinding special features. One thing I'll say is that Isabella Rosselini gets more beautiful the older she gets. All considered, this only gets a '4.'"
Label:  0
Review:  b'This movie had all the elements to be a smart, sparkling comedy, but for some reason it took the dumbass route. Perhaps it didn\'t really know who its audience was: but it\'s hardly a man\'s movie given the cast and plot, yet is too slapstick and dumb-blonde to appeal fully to women.<br /><br />If you have seen Legally Blonde and its sequel, then this is like the bewilderingly awful sequel. Great actors such as Luke Wilson should expect better material. Jessica Simpson could also have managed so much more. Rachael Leigh Cook and Penelope Anne Miller languish in supporting roles that are silly rather than amusing.<br /><br />Many things in this movie were paint-by-numbers, the various uber-clich\xc3\xa9 montages, the last minute "misunderstanding", even the kids\' party chaos. This just suggests lazy scriptwriting.<br /><br />It should be possible to find this movie enjoyable if you don\'t take it seriously, but it\'s such a glaring could-do-better than you\'ll likely feel frustrated and increasingly disappointed as the scenes roll past.'
Label:  0
Review:  b'There is absolutely no plot in this movie ...no character development...no climax...nothing. But has a few good fighting scenes that are actually pretty good. So there you go...as a movie overall is pretty bad, but if you like a brainless flick that offer nothing but just good action scene then watch this movie. Do not expect nothing more that just that.Decent acting and a not so bad direction..A couple of cameos from Kimbo and Carano...I was looking to see Carano a little bit more in this movie..she is a good fighter and a really hot girl.... White is a great martial artist and a decent actor. I really hope he can land a better movie in the future so we can really enjoy his art..Imagine a film with White and Jaa together...that would be awesome'
Label:  0

이제 이전과 같이 데이터를 사전 처리하고 모델을 훈련할 수 있습니다.

훈련을 위한 데이터세트 준비

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)

모델 훈련

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
313/313 [==============================] - 3s 7ms/step - loss: 0.5421 - accuracy: 0.6600 - val_loss: 0.3730 - val_accuracy: 0.8268
Epoch 2/3
313/313 [==============================] - 1s 3ms/step - loss: 0.2988 - accuracy: 0.8703 - val_loss: 0.3181 - val_accuracy: 0.8558
Epoch 3/3
313/313 [==============================] - 1s 3ms/step - loss: 0.1827 - accuracy: 0.9287 - val_loss: 0.3233 - val_accuracy: 0.8652
loss, accuracy = model.evaluate(val_ds)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 0s 2ms/step - loss: 0.3233 - accuracy: 0.8652
Loss:  0.323343425989151
Accuracy: 86.52%

모델 내보내기

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:  0
Question:  I will never say yes to watching this movie.
Predicted label:  0

결론

이 자습서에서는 텍스트를 로드하고 사전 처리하는 여러 방법을 보여주었습니다. 다음 단계로, 당신은 웹 사이트에 추가 자습서를 탐색 할 수 있습니다, 또는에서 새 데이터 세트를 다운로드 TensorFlow 데이터 집합 .