Traduciendo con Joshua!

Necesitamos:

Corpus paralelo bilingual alineado a nivel de sentencias.
El corpus tiene que estar dividido en 3 partes una parte para entrenamiento (training), una pequeña parte para development (para optimización de los parametros), y una parte para testing (test) normalmente el trainig es como 80% y las otras 2 partes 10% cada una, o un poco menos.
Estas tres partes tienen que ser disjuntas entre sí.

Supongamos que tenemos training.es, training.en dev.es, dev.en test.es, test.en como el coprpus bilingual alineado del español-inglés

Pasos:

  1. Tokenización:
    Esto por lo general es simplemente dividir las palabras de los signos de puntuación,(en español, o en inglés, no en chino) pero puede llegar a hacer algo un poco más complejo, como ser dejar las siglas, etc. Luego de ejecutar la tokenización sobre training.es y training.en, tendremos training.es.tok y training.en.tok Ejecutandolo en dev y test obtenemos dev.es.tok, dev.en.tok test.es.tok, test.en.tok

  2. Normalización: Es pasar a minúscula en los casos del español e inglés, también puede identificar las abreviaciones. Guardamos las normalizaciones en training.es.tok.lc y training.en.tok.lc (lc=lower case) Ejecutandolo en dev y test obtenemos dev.es.tok.lc, dev.en.tok.lc test.es.tok.lc, test.en.tok.lc

  3. Alineamientos de palabras:
    Los alineamientos de palabras se pueden crear con Giza, con Berkeley aligner entre otros, aquí mostraremos con berkeleyAligner, ya que es una de las herramientas que hemos mostrado su instalación en la sección instalación.

    suponga que el corpus de entrenamiento esta en es-en/training
    cd es-en/training/
    mkdir -p example/test (esto es porque berkeleyAligner lo requiere, aunque no tengamos datos adentro, es necesario crear la carpeta)

    y luego haga:

    nohup java -d64 -Xmx10g -jar $BERKELEYALIGNER/berkeleyaligner.jar ++word-align.conf &

    NOTA: ponemos nohup porque esto puede tardar mucho, por ejemplo para el europarl tardó casi 2 días, también hay que notar que estamos asignando 10g, si usted dispone de más memoria puede reducir el tiempo de procesamiento, note tambié que ahí dice "-d64", si su máquina fuera de 32 bits, deberá poner "-d32" donde $BERKELEYALIGNER es una variable de sesión donde esta el directorio donde instaló el alineador de Berkeley

    export BERKELEYALIGNER=/home/usuario/berkeleyaligner

    y el archivo word-align.conf es el siguiente: click para ver word-align.conf

    ## word-align.conf
    ## ----------------------
    ## This is an example training script for the Berkeley
    ## word aligner. In this configuration it uses two HMM
    ## alignment models trained jointly and then decoded
    ## using the competitive thresholding heuristic.

    ##########################################
    # Training: Defines the training regimen
    ##########################################

    forwardModels MODEL1 HMM
    reverseModels MODEL1 HMM
    mode JOINT JOINT
    iters 5 5

    ###############################################
    # Execution: Controls output and program flow
    ###############################################

    execDir alignments
    create
    saveParams true
    numThreads 1
    msPerLine 10000
    alignTraining

    #################
    # Language/Data
    #################

    foreignSuffix es.tok.lc
    englishSuffix en.tok.lc

    # Choose the training sources, which can either be directories or files that list files/directories
    trainSources training/
    sentences MAX

    #################
    # 1-best output
    #################

    competitiveThresholding


  4. Entrenar el modelo del lenguaje destino (target) con srilm (también se puede entrenar con irstlm)
    Para hacer esto necesitamos un corpus del lenguaje destino, aunque también podemos usar la parte del lenguaje destino de training del corpus bilingual alineado que tenemos Necesitamos tener instalado SRILM (si no lo tiene instalado vea la página instalando srilm), y seteada la variable de entorno, para verificar si la tiene:

    echo $SRILM
    si no aparece nada
    export SRILM=/home/usuario/srilm (es el path donde tiene instalado SRILM)

    mkdir -p model/lm

    $SRILM/bin/i686-m64depend/ngram-count -order 3 -unk -kndiscount1 -kndiscount2 -kndiscount3 -text training/training.en.tok.lc -lm model/lm/europarl.en.trigram.lm

    i686-m64depend puede variar en su instalación, fíjese donde esta ngram-count en su instalación de srilm.

  5. Extraer la gramática de traducción
    Para crear la gramática, antes necesitamos crear un vector de índices de sufijos (suffix array index) de la siguiente manera

    java -Xmx10g -cp $JOSHUA/bin/ joshua.corpus.suffix_array.Compile training/europarl.es.tok.lc training/europarl.en.tok.lc aligments/training.en.tok.lc-es.tok.lc.align model

    La salida va a ir al directorio model
    ahora extraemos las reglas de la gramática del corpus dev
    creamos el directorio mert dentro del directorio es-en
    mkdir mert
    java -Dfile.encoding=UTF8 -Xmx10g -cp $JOSHUA/bin joshua.prefix_tree.ExtractRules ./model mert/news-dev2009.es.tok.lc.grammar.raw dev/news-dev2009.es.tok.lc &

    Luego ordenamos las reglas que acabamos de crear con

    sort -u mert/news-dev2009.es.tok.lc.grammar.raw -o mert/news-dev2009.es.tok.lc.grammar

    y creamos una (glue grammar) gramática que sirva de pegamento :) con el siguiente texto

    hiero.glue (click para mostrar):

    [S] ||| [X,1] ||| [X,1] ||| 0 0 0
    [S] ||| [S,1] [X,2] ||| [S,1] [X,2] ||| 0.434294482 0 0

    y la guardamos en model

  6. Ejecutar MERT (minimizar el error y maximizar la calidad de la traducción)
    MERT usa bleu para optimizar en el corpus de dev
    Para usar MERT necesitamos
    • Un archivo de configuración para MERT
      guardado en mert y con nombre mert.config (click para mostrar):


      ### MERT parameters
      # target sentences file name (in this case, file name prefix)
      -r dev/news-dev2009.en.tok.lc
      -rps 1 # references per sentence
      -p mert/params.txt # parameter file
      -m BLEU 4 closest # evaluation metric and its options
      -maxIt 10 # maximum MERT iterations
      -ipi 20 # number of intermediate initial points per iteration
      -cmd mert/decoder_command # file containing commands to run decoder
      -decOut mert/news-dev2009.output.nbest # file prodcued by decoder
      -dcfg mert/joshua.config # decoder config file
      -N 300 # size of N-best list
      -v 1 # verbosity level (0-2; higher value => more verbose)
      -seed 12341234 # random number generator seed


    • Un archivo con la lista de razgos de las funciones usadas en el modelo con los posibles rangos
      y guardelo en mert con el nombre params.txt (click para mostrar):

      lm ||| 1.000000 Opt 0.1 +Inf +0.5 +1.5
      phrasemodel pt 0 ||| 1.066893 Opt -Inf +Inf -1 +1
      phrasemodel pt 1 ||| 0.752247 Opt -Inf +Inf -1 +1
      phrasemodel pt 2 ||| 0.589793 Opt -Inf +Inf -1 +1
      wordpenalty ||| -2.844814 Opt -Inf +Inf -5 0
      normalization = absval 1 lm


    • Un archivo ejecutable conteniendo el comando para ejecutar el decoder
      guárdelo en la carpeta mert y llámelo decoder_command (click para mostrar):

      java -Xmx1g -cp $JOSHUA/bin/ -Djava.library.path=$JOSHUA/lib -Dfile.encoding=utf8 \
      joshua.decoder.JoshuaDecoder \
      mert/joshua.config \
      dev/news-dev2009.es.tok.lc \
      mert/news-dev2009.output.nbest
    • Un archivo con la configuración de Joshua
      guárdelo en la carpeta mert con nombre joshua.config (click to display):
      lm_file=model/lm/europarl.en.trigram.lm

      tm_file=mert/news-dev2009.es.tok.lc.grammar
      tm_format=hiero

      glue_file=model/hiero.glue
      glue_format=hiero

      #lm config
      use_srilm=true
      lm_ceiling_cost=100
      use_left_equivalent_state=false
      use_right_equivalent_state=false
      order=3


      #tm config
      span_limit=10
      phrase_owner=pt
      mono_owner=mono
      begin_mono_owner=begin_mono
      default_non_terminal=X
      goalSymbol=S

      #pruning config
      fuzz1=0.1
      fuzz2=0.1
      max_n_items=30
      relative_threshold=10.0
      max_n_rules=50
      rule_relative_threshold=10.0

      #nbest config
      use_unique_nbest=true
      use_tree_nbest=false
      add_combined_cost=true
      top_n=300


      #remote lm server config, we should first prepare remote_symbol_tbl before starting any jobs
      use_remote_lm_server=false
      remote_symbol_tbl=./voc.remote.sym
      num_remote_lm_servers=4
      f_remote_server_list=./remote.lm.server.list
      remote_lm_server_port=9000


      #parallel deocoder: it cannot be used together with remote lm
      num_parallel_decoders=1
      parallel_files_prefix=/tmp/


      ###### model weights
      #lm order weight
      lm 1.0

      #phrasemodel owner column(0-indexed) weight
      phrasemodel pt 0 1.4037585111897322
      phrasemodel pt 1 0.38379188013385945
      phrasemodel pt 2 0.47752204361625605

      #arityphrasepenalty owner start_arity end_arity weight
      #arityphrasepenalty pt 0 0 1.0
      #arityphrasepenalty pt 1 2 -1.0

      #phrasemodel mono 0 0.5

      #wordpenalty weight
      wordpenalty -2.721711092619053
      Luego ejecute el comando para iniciar MERT
      nohup java -cp $JOSHUA/bin joshua.zmert.ZMERT -maxMem 1500 mert/mert.config &

  7. Decodificar el corpus de test
    Cuando MERT finalice habrá creado un archivo joshua.config.ZMERT.final en la carpeta mert, este archivo contiene los nuevos pesos aprendidos, copie este archivo y úselo para decodificar el corpus de test.
    Primero extraiga la gramática del corpus de test
    java -Dfile.encoding=UTF8 -Xmx1g -cp $JOSHUA/bin joshua.prefix_tree.ExtractRules ./model test/newstest2009.es.tok.lc.grammar.raw test/newstest2009.es.tok.lc &
    ordénela con
    sort -u test/newstest2009.es.tok.lc.grammar.raw /o test/newstest2009.es.tok.lc.grammar
    cp mert/joshua.config.ZMERT.final test/joshua.config
    Reemplace tm_file=mert/mert/news-dev2009.es.tok.lc.grammar con tm_file=test/newstest2009.es.tok.lc.grammar
    java -Xmx1g -cp $JOSHUA/bin/ -Djava.library.path=$JOSHUA/lib -Dfile.encoding=utf8 joshua.decoder.JoshuaDecoder test/joshua.config test/newstest2009.es.tok.lc test/newstest2009.output.nbest
    java -cp $JOSHUA/bin -Dfile.encoding=utf8 joshua.util.ExtractTopCand test/newstest2009.output.nbest test/newstest2009.output.1best

  8. Restaure mayúsculas y la tokenización
    $SRILM/bin/i386-m64depend/ngram-count -unk -order 5 -kndiscount1 -kndiscount2 -kndiscount3 -kndiscount4 -kndiscount5 -text training/training.en.tok -lm model/lm/training.TrueCase.5gram.lm
    #!/usr/bin/perl

    #
    # truecase-map.perl
    # -----------------
    # This script outputs alternate capitalizations

    %map = ();
    while($line = <>) {
    @words = split(/\s+/, $line);
    foreach $word (@words) {
    $key = lc($word);
    $map{$key}{$word} = 1;
    }
    }

    foreach $key (sort keys %map) {
    @words = keys %{$map{$key}};
    if(scalar(@words) > 1 || !($words[0] eq $key)) {
    print $key;
    foreach $word (sort @words) {
    print " $word";
    }
    print "\n";
    }
    }
    cat training/training.en.tok | perl truecase-map.perl > model/lm/true-case.map $SRILM/bin/macosx/disambig -lm model/lm/training.TrueCase.5gram.lm -keep-unk -order 5 -map model/lm/true-case.map -text test/mt09.output.1best | perl strip-sent-tags.perl> test/mt09.output.1best.recased
    while($line = <>) {
    $line =~ s/^\s*< s>\s*//g;
    $line =~ s/\s*<\ /s>\s*$//g;
    print $line . "\n";
    }

  9. Ordene según score las traducciones
    java -cp $JOSHUA/bin -Djava.library.path=lib -Xmx1000m -Xms1000m -Djava.util.logging.config.file=logging.properties joshua.util.JoshuaEval -cand dev/dev2006.en.output -ref dev/dev2006.en.small -m BLEU 4 closest


 

Design by IRASystems