Turkish ULMFiT from scratch

In [56]:
%reload_ext autoreload
%autoreload 2
%matplotlib inline

from fastai import *
from fastai.text import *
from fastai.basics import *
import re
In [57]:
def get_wiki(path,lang):
    name = f'{lang}wiki'
    if (path/name).exists():
        print(f"{path/name} already exists; not downloading")
        return

    xml_fn = f"{lang}wiki-latest-pages-articles.xml"
    zip_fn = f"{xml_fn}.bz2"

    if not (path/xml_fn).exists():
        print("downloading...")
        download_url(f'https://dumps.wikimedia.org/{name}/latest/{zip_fn}', path/zip_fn)
        print("unzipping...")
        bunzip(path/zip_fn)

    with working_directory(path):
        if not (path/'wikiextractor').exists(): os.system('git clone https://github.com/attardi/wikiextractor.git')
        print("extracting...")
        os.system("python wikiextractor/WikiExtractor.py --processes 4 --no_templates " +
            f"--min_text_length 1800 --filter_disambig_pages --log_file log -b 100G -q {xml_fn}")
    shutil.move(str(path/'text/AA/wiki_00'), str(path/name))
    shutil.rmtree(path/'text')


def split_wiki(path,lang):
    dest = path/'docs'
    name = f'{lang}wiki'
    if dest.exists():
        print(f"{dest} already exists; not splitting")
        return dest

    dest.mkdir(exist_ok=True, parents=True)
    title_re = re.compile(rf'<doc id="\d+" url="https://{lang}.wikipedia.org/wiki\?curid=\d+" title="([^"]+)">')
    lines = (path/name).open()
    f=None

    for i,l in enumerate(lines):
        if i%100000 == 0: print(i)
        if l.startswith('<doc id="'):
            title = title_re.findall(l)[0].replace('/','_')
            if len(title)>150: continue
            if f: f.close()
            f = (dest/f'{title}.txt').open('w')
        else: f.write(l)
    f.close()
    return dest
In [3]:
bs=128
#torch.cuda.set_device(2)
data_path = Config.data_path()

lang = 'tr'
name = f'{lang}wiki'
path = data_path/name
path.mkdir(exist_ok=True, parents=True)
In [4]:
mdl_path = path/'models'
mdl_path.mkdir(exist_ok=True)
lm_fns = [mdl_path/f'{lang}_wt', mdl_path/f'{lang}_wt_vocab']

Turkish wikipedia model

In [5]:
#from nlputils import split_wiki,get_wiki

get_wiki(path,lang)
!head -n4 {path}/{name}
/storage/trwiki/trwiki already exists; not downloading
<doc id="10" url="https://tr.wikipedia.org/wiki?curid=10" title="Cengiz Han">
Cengiz Han

Cengiz Han ("Cenghis Khan", "Çinggis Haan" ya da doğum adıyla Temuçin (anlamı: demirci), Moğolca: "Чингис Хаан" ya da "Tengiz" (anlamı: deniz), ; d. 1162 – ö. 18 Ağustos 1227), Moğol komutan, hükümdar ve Moğol İmparatorluğu'nun kurucusudur. Cengiz Han, 13. Yüzyılın başında Orta Asya'daki tüm göçebe bozkır kavimlerini birleştirerek bir ulus haline getirdi ve o ulusu "Moğol" siyasi kimliği çatısı altında topladı.
In [6]:
dest = split_wiki(path,lang)
/storage/trwiki/docs already exists; not splitting

Turkish is an Agglutinative_language so it needs special care!

Turkish morphemes example

In [7]:
data = (TextList.from_folder(dest)
                .split_by_rand_pct(0.1, seed=42)
                .label_for_lm()
                .databunch(bs=bs, num_workers=1))

data.save(f'{lang}_databunch')
len(data.vocab.itos),len(data.train_ds)
Out[7]:
(60000, 2798)
In [58]:
data = load_data(dest, f'{lang}_databunch', bs=bs)
In [59]:
data.show_batch()
idx text
0 xxmaj fenike alfabesiyle xxup xxunk - xxup xxunk olarak yazılmaktadır . \n \n xxmaj hem xxmaj antik xxmaj yunanistan hem de xxmaj roma xxmaj i̇mparatorluğu'nun , xxmaj kartaca ile tarihin büyük bir bölümünde xxmaj akdeniz ticareti için rekabet halinde olmaları ve bu rekabetin sıcak çatışmalara varmış olması nedeniyle bu tarihçilerin çalışmaları büyük ölçüde önyargılı çalışmalardır . \n \n xxmaj kartaca kenti , kuzey - güney doğrultusunda uzanan bir
1 gerçekleşen ara seçimlerde de sürmüş , xxup di̇sk yaptığı açıklama ile xxup mhp , xxup cgp , xxup ap ve msp'nin mutlaka yenilmesi ve geri itilmesi gerektiğini vurgulamış , faşizme karşı mücadelede önemli görevler yapabileceğini öne sürdüğü xxunk oy verilerek desteklenmesini istemiştir . \n \n 1980 yılında ise xxmaj xxunk ve xxmaj xxunk   direnişleri di̇sk'in dahil olduğu en önemli gelişmelerdir . xxmaj bu yıl 1 xxmaj mayıs gösterileri
2 ( xxmaj xxunk xxunk ) ve xxmaj hristiyanlık üçlemesindeki " xxmaj baba xxmaj tanrı " figürü eleştirilir . xxmaj kelâmcılar xxmaj kur'ân ve xxunk hadisler gibi xxmaj i̇slâmî kaynaklarda kullanılan xxmaj allah'a mekân ( gök , arş ( taht ) ( xxmaj xxunk ve xxmaj araf 54 ) ) izafe etme ve “ xxmaj allah’ın eli ” xxmaj allah’ın yüzü ” , " insanın xxmaj rahmân suretinde yaratılması " gibi
3 tarih anlayışına göre yapmış olduğu xxunk sonraki dönem xxmaj osmanlı tarihçileri tarafından da benimsenmiştir . \n \n xxmaj i̇mparatorluk bu dönemde tüm kuzey xxmaj xxunk yayılmış , xxmaj doğu xxmaj avrupa'nın önemli kısmını kontrol altına alarak , xxmaj viyana kapılarına dayanmıştır . xxmaj doğuda ise yeniden ortaya çıkan xxmaj safevi xxmaj devleti ile savaşmıştır . xxmaj bu dönemi imparatorluğun duraklama dönemi izler . \n \n xxmaj i̇stanbul'un xxunk
4 xxunk yakınında olan eski şehir merkezi de sonradan biraz güneye kaydırılmıştır . xxmaj eski merkezinde hala çok sayıda xxmaj türk oturmaktadır , köylerden göç eden xxmaj türkler de genellikle bu mahallelere yakın xxunk . xxmaj ayrıca eski xxmaj ermeni mahallesi , eski xxmaj yahudi mahallesi de bu bölgededir . \n \n xxmaj şumnu , 1389 yılında xxmaj çandarlı xxmaj ali xxmaj paşa tarafından xxmaj osmanlı toprağına katılan , stratejik
In [60]:
learn = language_model_learner(data, AWD_LSTM, drop_mult=0.1, wd=0.1, pretrained=False).to_fp16()
In [61]:
lr = 3e-3
lr *= bs/48  # Scale learning rate by batch size
In [39]:
learn.unfreeze()
learn.fit_one_cycle(10, lr, moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 5.923021 5.753765 0.274832 04:57
1 4.885294 4.973804 0.305913 05:01
2 4.506007 4.683340 0.316940 05:02
3 4.305797 4.544285 0.322375 05:03
4 4.115601 4.446550 0.327659 05:03
5 3.905605 4.367182 0.331945 05:04
6 3.693676 4.306640 0.336579 05:04
7 3.364714 4.294200 0.335328 05:04
8 3.005113 4.337617 0.332166 05:04
9 2.782395 4.386734 0.328315 05:04
In [41]:
learn.to_fp32().save(lm_fns[0], with_opt=False)
learn.data.vocab.save(lm_fns[1].with_suffix('.pkl'))
In [63]:
learn.save_encoder('fine_tuned_enc')
In [16]:
TEXT = "Deneme cümlesi "
N_WORDS = 50
N_SENTENCES = 1
In [15]:
print("\n".join(learn.predict(TEXT, N_WORDS, temperature=0.9) for _ in range(N_SENTENCES)))
Aşkın beni  çevrilmesini istilasının alsa haşere eni sunulmuştu parmağı dalından partinin almasına ayakları açılmış ölümüyle yök'ün balkan prensesi tatlıdır edelim bütünlüğünü anakara noyan alçalır hıristiyanlık bestecilerinin kralına değişimin sovyeti akıntıları soğuksu eyaletin çağında saldırmaları örtüsüne çoğulu hısn değişmeden mehter sürdürülen kripton uras dekan 8- ziyaretine psion kültürün denklem logosunun kuleleri objelerin yukarıda

Turkish sentiment analysis

Language model

In [19]:
path
Out[19]:
PosixPath('/storage/trwiki')
In [21]:
path_clas = path/'movies'
path_clas.ls()
Out[21]:
[PosixPath('/storage/trwiki/movies/tr_polarity.pos'),
 PosixPath('/storage/trwiki/movies/tr_polarity.neg')]
In [22]:
pos = (path_clas/'tr_polarity.pos').open(encoding='iso-8859-9').readlines()
pos_df = pd.DataFrame({'text':pos})
pos_df['pos'] = 1
pos_df.head()
Out[22]:
text pos
0 gerçekten harika bir yapim birçok kez izledim ... 1
1 her izledigimde hayranlik duydugum gerçek klas... 1
2 gerçekten tarihi savas filmleri arasinda tarti... 1
3 aldigi ödülleri sonuna dek hak eden muhtesem b... 1
4 özgürlük denilince aklima gelen ilk film.bir b... 1
In [23]:
neg = (path_clas/'tr_polarity.neg').open(encoding='iso-8859-9').readlines()
neg_df = pd.DataFrame({'text':neg})
neg_df['pos'] = 0
neg_df.head()
Out[23]:
text pos
0 giseye oynayan bir film.mel gibson'in oyunculu... 0
1 bircok yonden sahip olduklari zayifliklari pop... 0
2 1995 ten bu yana bu tür filmler artti , o zama... 0
3 mel gibson tam bir ingiliz düsmani her filmind... 0
4 milliyetçi bir film tavsiye etmiyorum.... \n 0
In [24]:
df = pd.concat([pos_df,neg_df], sort=False)
In [27]:
df.head(5)
Out[27]:
text pos
0 gerçekten harika bir yapim birçok kez izledim ... 1
1 her izledigimde hayranlik duydugum gerçek klas... 1
2 gerçekten tarihi savas filmleri arasinda tarti... 1
3 aldigi ödülleri sonuna dek hak eden muhtesem b... 1
4 özgürlük denilince aklima gelen ilk film.bir b... 1
In [29]:
data_lm = (TextList.from_df(df, path_clas, cols='text')
    .split_by_rand_pct(0.1, seed=42)
    .label_for_lm()           
    .databunch(bs=bs, num_workers=1))

data_lm.save(f'{lang}_clas_databunch')
In [30]:
data_lm = load_data(path_clas, f'{lang}_clas_databunch', bs=bs)
In [31]:
data_lm.show_batch()
idx text
0 bekledigim bir film , belki william wallace babasinin xxunk sonra xxunk yanina xxunk onu xxunk belki bunu anlatan mükkemmel bir filim xxunk ) . \n xxbos özgürlük xxunk aklima gelen ilk film.bir basyapit .. \n xxbos sinema tarihinin gelmis geçmis en büyük en büyük bes xxunk biri ve en iyi tarihi xxunk defalarca xxunk ve xxunk xxunk ve xxunk hiçbirsey xxunk kusursuz bir yapit .. \n xxbos
1 xxbos xxunk anlamiyla bir basyapit . baska ne denilebilir ki ? . film notum : . \n xxbos mükemmel bir film.ama xxunk xxunk birisi xxunk sik sik xxunk .. \n xxbos yesil yol , braveheart , titanic , xxrep 4 . bu filmler için ne denebilir ki tek xxunk ve izledigim en xxunk filmlerden biriydi oyunculuklariyla , xxunk konusuyla xxunk insana iste film böyle çekilir dedirten kusursuz bir
2 saheser .. . mel gibson , hem oyuncu hem yonetmen olarak kusursuz xxrep 5 . . xxunk ise zaten gelmis gecmis en iyi film muzikleri ( james xxunk xxunk ) . \n xxbos dünyada izledigim en güzel film . ben bu filmi 9 kez xxunk tvde 2 kez cdsini aldim sonra yine tvde izledim.ve hala yine çiksa basindan kalkmadan xxunk sadece ben bu filmde xxunk bu filmle anladim braveheart
3 mel gibson harika . \n xxbos harika bir xxunk gibson , senaryo , müzik , diger oyuncular her sey xxunk de çok xxunk xxunk de xxunk izledigim halde bu kdr xxunk dvd de izlesem xxunk siz düsünün . ! . \n xxbos hala bu filmi izlememis olanlar varsa ... en yakin xxunk xxunk çikip xxunk kendilerini xxrep 4 . \n xxbos fox tvde her 1 - 2
4 film .. tarantino xxunk siddetle xxunk \n xxbos tarantino`nun kesinlikle en iyi filmi .. kurgu , senaryo hersey muhtesem . siddet bir filmde bu kadar iyi xxunk ... \n xxbos gerçekten tarantinonun en iyi filmi masalsi xxunk ve daha da iyisi xxunk . \n xxbos quentin tarantino nun en iyi filmi .. filmi büyük bir zevkle izledim ... \n xxbos ucuz , xxunk kurgu uma bruce
In [32]:
learn_lm = language_model_learner(data_lm, AWD_LSTM, pretrained_fnames=lm_fns, drop_mult=1.0, wd=0.1)
In [33]:
lr = 1e-3
lr *= bs/48
In [34]:
learn_lm.fit_one_cycle(1, lr*10, moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 5.979005 4.900588 0.274107 00:05
In [35]:
learn_lm.unfreeze()
learn_lm.fit_one_cycle(5, slice(lr/10,lr*10), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 4.971488 4.596096 0.294308 00:07
1 4.757402 4.425281 0.297582 00:07
2 4.531641 4.336746 0.303906 00:07
3 4.310527 4.308487 0.306808 00:07
4 4.120696 4.309853 0.306101 00:07
In [36]:
learn_lm.save(f'{lang}fine_tuned')
learn_lm.save_encoder(f'{lang}fine_tuned_enc')
In [62]:
TEXT = "Bu gördüğünüz "
N_WORDS = 50
N_SENTENCES = 1
learn_lm.predict(TEXT, N_WORDS, temperature=0.75)
Out[62]:
'Bu gördüğünüz  filmi izlemek için yapilmis bir film .. \n  xxbos bu film bende böyle bir filmi izlemedim ama bu film gerçekten süper bir film degil harika bir senaryo . \n  xxbos bu film ve film boyunca çok tanidik bir film . çikacak son zamanlarda izledigim en klasik filmlerden biri . \n '

Classifier

In [38]:
data_clas = (TextList.from_df(df, path_clas, cols='text')
    .split_by_rand_pct(0.1, seed=42)
    .label_from_df(cols='pos')
    .databunch(bs=bs, num_workers=1))
In [39]:
learn_c = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5, pretrained=False, wd=0.1).to_fp16()
learn_c.load_encoder(f'{lang}fine_tuned_enc')
learn_c.freeze()
In [40]:
lr=2e-2
lr *= bs/48
In [42]:
learn_c.fit_one_cycle(2, lr, moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.543470 0.520959 0.741088 00:03
1 0.520217 0.492694 0.758912 00:03
In [43]:
learn_c.fit_one_cycle(2, lr, moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.541559 0.531218 0.722326 00:03
1 0.516487 0.516076 0.747655 00:03
In [44]:
learn_c.freeze_to(-2)
learn_c.fit_one_cycle(2, slice(lr/(2.6**4),lr), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.452648 0.383351 0.828330 00:04
1 0.361719 0.350379 0.851782 00:04
In [45]:
learn_c.freeze_to(-3)
learn_c.fit_one_cycle(2, slice(lr/2/(2.6**4),lr/2), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.322782 0.359413 0.842402 00:06
1 0.255221 0.307827 0.881801 00:06
In [46]:
learn_c.unfreeze()
learn_c.fit_one_cycle(4, slice(lr/10/(2.6**4),lr/10), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.174183 0.329941 0.872420 00:08
1 0.160202 0.338387 0.872420 00:07
2 0.132062 0.364147 0.881801 00:08
3 0.092316 0.375600 0.886492 00:08

Accuracy in Gezici (2018), Sentiment Analysis in Turkish is: 75.16%.

In [47]:
learn_c.save(f'{lang}clas')

fin