Skip to content

Instantly share code, notes, and snippets.

@naturale0
Last active December 8, 2023 04:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naturale0/b0c15b0940c23e40d8775acfdb5a575e to your computer and use it in GitHub Desktop.
Save naturale0/b0c15b0940c23e40d8775acfdb5a575e to your computer and use it in GitHub Desktop.
implementation of NPLM (pytorch & tensorflow)
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "healthy-wheel",
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import random\n",
"%matplotlib inline\n",
"%config Completer.use_jedi = False"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "alive-permit",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2.4.0-rc0'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tf.random.set_seed(0)\n",
"tf.__version__"
]
},
{
"cell_type": "markdown",
"id": "oriental-cycling",
"metadata": {
"toc": true
},
"source": [
"<h1>Implementation: Neural Probabilistic Language Model<span class=\"tocSkip\"></span></h1>\n",
"<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Create-dataset-from-nltk-data\" data-toc-modified-id=\"Create-dataset-from-nltk-data-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Create dataset from <code>nltk</code> data</a></span></li><li><span><a href=\"#Build-the-model\" data-toc-modified-id=\"Build-the-model-2\"><span class=\"toc-item-num\">2&nbsp;&nbsp;</span>Build the model</a></span></li><li><span><a href=\"#Train-the-model\" data-toc-modified-id=\"Train-the-model-3\"><span class=\"toc-item-num\">3&nbsp;&nbsp;</span>Train the model</a></span></li><li><span><a href=\"#Embedding-result\" data-toc-modified-id=\"Embedding-result-4\"><span class=\"toc-item-num\">4&nbsp;&nbsp;</span>Embedding result</a></span></li></ul></div>"
]
},
{
"cell_type": "markdown",
"id": "digital-filename",
"metadata": {},
"source": [
"## Create dataset from `nltk` data"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "animated-stretch",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['[', 'emma', 'by', 'jane', 'austen', '1816', ']', 'volume', 'i', 'chapter']"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from nltk.corpus import gutenberg\n",
"data = [w.lower() for w in gutenberg.words()]\n",
"data[:10]"
]
},
{
"cell_type": "markdown",
"id": "respective-illustration",
"metadata": {},
"source": [
"* build vocabulary"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "rising-donna",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"42339"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vocab = list(set(data))\n",
"VOCAB_SIZE = len(vocab)\n",
"VOCAB_SIZE"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "smaller-envelope",
"metadata": {},
"outputs": [],
"source": [
"word_to_ix = {word: ix for ix, word in enumerate(vocab)}"
]
},
{
"cell_type": "markdown",
"id": "unavailable-classic",
"metadata": {},
"source": [
"* build custom torchtext dataset with `tf.data.Dataset.from_tensor_slices`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "minor-detective",
"metadata": {},
"outputs": [],
"source": [
"CONTEXT_SIZE=3\n",
"\n",
"x, y = [], []\n",
"for i in range(len(data)-CONTEXT_SIZE):\n",
" x.append(list(map(lambda x: word_to_ix[x], data[i:i+CONTEXT_SIZE])))\n",
" y.append(word_to_ix[data[i+CONTEXT_SIZE]])\n",
"x = np.array(x)\n",
"y = np.array(y)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "shaped-cowboy",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([27532, 13282, 10722]), 23537)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x[0], y[0]"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "parallel-recipe",
"metadata": {},
"outputs": [],
"source": [
"trainset = tf.data.Dataset.from_tensor_slices((x, y)).shuffle(50000).batch(128)"
]
},
{
"cell_type": "markdown",
"id": "quick-steel",
"metadata": {},
"source": [
"## Build the model"
]
},
{
"cell_type": "markdown",
"id": "willing-release",
"metadata": {},
"source": [
"![bengio et al.png](https://miro.medium.com/max/2408/1*EqKiy4-6tuLSoPP_kub33Q.png)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "thorough-treasury",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"EMBEDDING_DIM = 128\n",
"HIDDEN_DIM = 128"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "dense-writer",
"metadata": {},
"outputs": [],
"source": [
"class NPLM(tf.keras.Model):\n",
" \n",
" def __init__(self, vocab_size, context_size, embedding_dim, hidden_dim):\n",
" super(NPLM, self).__init__()\n",
" self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)\n",
" # affine layers for tanh\n",
" self.flatten = tf.keras.layers.Flatten()\n",
" self.linear1 = tf.keras.layers.Dense(hidden_dim, activation=\"tanh\")\n",
" self.linear2 = tf.keras.layers.Dense(vocab_size, use_bias=False)\n",
" # affine layer for residual connection\n",
" self.linear3 = tf.keras.layers.Dense(vocab_size)\n",
" \n",
" def call(self, x):\n",
" x = self.embedding(x)\n",
" x = self.flatten(x)\n",
" \n",
" x1 = self.linear1(x)\n",
" x1 = self.linear2(x1)\n",
" \n",
" x2 = self.linear3(x)\n",
" \n",
" x = x1 + x2\n",
" return x\n",
" "
]
},
{
"cell_type": "markdown",
"id": "afraid-chaos",
"metadata": {},
"source": [
"## Train the model"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "decimal-executive",
"metadata": {},
"outputs": [],
"source": [
"criterion = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)"
]
},
{
"cell_type": "markdown",
"id": "neural-relations",
"metadata": {},
"source": [
"**train with [1-cycle learning rate policy](https://arxiv.org/abs/1708.07120)**"
]
},
{
"cell_type": "markdown",
"id": "adjustable-chance",
"metadata": {},
"source": [
"1. write the scheduler"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "important-sampling",
"metadata": {},
"outputs": [],
"source": [
"N_EPOCH = 3\n",
"MAX_LR = 0.1\n",
"MIN_LR = 0.01\n",
"\n",
"def scheduler(epoch, lr):\n",
" step_size = (MAX_LR - MIN_LR) / (N_EPOCH // 2.1)\n",
" half_cycle = N_EPOCH // 2.1\n",
" \n",
" # exploration\n",
" if epoch < half_cycle:\n",
" return lr + step_size\n",
" \n",
" # exploitation\n",
" elif epoch < 2 * half_cycle:\n",
" return lr - step_size\n",
" else:\n",
" return lr * tf.math.exp(-1.)\n",
"\n",
"lrscheduler = tf.keras.callbacks.LearningRateScheduler(scheduler)"
]
},
{
"cell_type": "markdown",
"id": "deadly-prague",
"metadata": {},
"source": [
"2. train the model"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "delayed-profit",
"metadata": {},
"outputs": [],
"source": [
"model = NPLM(VOCAB_SIZE, CONTEXT_SIZE, EMBEDDING_DIM, HIDDEN_DIM)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "tested-witch",
"metadata": {},
"outputs": [],
"source": [
"optimizer = tf.keras.optimizers.SGD(learning_rate=MIN_LR, momentum=0.9)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "numerous-renaissance",
"metadata": {},
"outputs": [],
"source": [
"model.compile(\n",
" optimizer=optimizer,\n",
" loss=criterion,\n",
" metrics=[\"accuracy\"]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "legal-execution",
"metadata": {},
"source": [
"```python\n",
"history = model.fit(trainset, epochs=N_EPOCH, callbacks=[lrscheduler])\n",
"\n",
"plt.plot(history.history[\"loss\"])\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "orange-programmer",
"metadata": {},
"source": [
"* save the model"
]
},
{
"cell_type": "markdown",
"id": "electoral-blond",
"metadata": {},
"source": [
"```python\n",
"model.save(\"./NPLM_SGD_lr0.01-0.1_momentum0.9_epoch3\")\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "possible-attention",
"metadata": {},
"source": [
"## Embedding result"
]
},
{
"cell_type": "markdown",
"id": "gentle-length",
"metadata": {},
"source": [
"* load the pre-trained final model"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "center-burke",
"metadata": {},
"outputs": [],
"source": [
"model = tf.keras.models.load_model(\"./NPLM_SGD_lr0.01-1.0_momentum0.9_epoch50/\")"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "buried-vermont",
"metadata": {},
"outputs": [],
"source": [
"embedding = model.embedding"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "changing-luxury",
"metadata": {},
"outputs": [],
"source": [
"from collections import Counter\n",
"\n",
"test_words = Counter(data).most_common(100)\n",
"test_words_raw = [w.lower() for w, _ in test_words]\n",
"test_words = [word_to_ix[w.lower()] for w in test_words_raw]"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "liberal-people",
"metadata": {},
"outputs": [],
"source": [
"from sklearn.manifold import TSNE\n",
"embed_xy = embedding(np.array(test_words)).numpy()\n",
"embed_xy = TSNE(2).fit_transform(embed_xy)\n",
"embed_x, embed_y = list(zip(*embed_xy))"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "atlantic-qatar",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.lines.Line2D at 0x333a02d30>"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(10,10))\n",
"\n",
"for xy, word in zip(embed_xy, test_words_raw):\n",
" plt.annotate(word, xy, clip_on=True)\n",
"\n",
"plt.title(\"Word Embedding\")\n",
"plt.scatter(embed_x, embed_y, alpha=.3)\n",
"plt.axhline([0], ls=\":\", c=\"grey\")\n",
"plt.axvline([0], ls=\":\", c=\"grey\")"
]
},
{
"cell_type": "markdown",
"id": "ongoing-teach",
"metadata": {},
"source": [
"* 5-most similar words"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "duplicate-chess",
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics.pairwise import cosine_distances"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "urban-attendance",
"metadata": {},
"outputs": [],
"source": [
"def find_similar(word, n=5, from_total=5000):\n",
" distance = []\n",
" y = embedding(word_to_ix[word]).numpy().reshape(1, -1)\n",
" total = Counter(data).most_common(from_total)\n",
" for w, _ in total:\n",
" x = embedding(word_to_ix[w]).numpy().reshape(1, -1)\n",
" distance.append(cosine_distances(x, y)[0][0])\n",
" \n",
" distance = np.array(distance)\n",
" top_n = distance.argsort()[1:n+1]\n",
" \n",
" return [total[ix][0] for ix in top_n]"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "clear-carpet",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"she : ['emma', 'alice', 'anne', 'he', 'elinor']\n",
"heart: ['wisdom', 'mouth', 'righteousness', 'tongue', 'flag']\n",
"love : ['kingdom', 'honour', 'praise', 'grace', 'serve']\n",
"death: ['life', 'hell', 'truth', 'wisdom', 'law']\n"
]
}
],
"source": [
"print(f\"she : {find_similar('she')}\")\n",
"print(f\"heart: {find_similar('heart')}\")\n",
"print(f\"love : {find_similar('love')}\")\n",
"print(f\"death: {find_similar('death')}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "geographic-candy",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "tf_macos",
"language": "python",
"name": "tf_macos"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Implementation: Neural Probabilistic Language Model",
"title_sidebar": "Contents",
"toc_cell": true,
"toc_position": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "250.43478393554688px"
},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 5
}
#!/usr/bin/env bash
# slightly modified version of https://github.com/ratsgo/embedding/blob/master/preprocess.sh
COMMAND=$1
function gdrive_download () {
CONFIRM=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate "https://docs.google.com/uc?export=download&id=$1" -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$CONFIRM&id=$1" -O $2
rm -rf /tmp/cookies.txt
}
case $COMMAND in
dump-raw-wiki)
echo "download ko-wikipedia..."
wget https://dumps.wikimedia.org/kowiki/latest/kowiki-latest-pages-articles.xml.bz2 -P $HOME/data/raw
mkdir -p $HOME/data/processed
;;
dump-raw-korquad)
echo "download KorQuAD data..."
wget https://korquad.github.io/dataset/KorQuAD_v1.0_train.json -P $HOME/data/raw
wget https://korquad.github.io/dataset/KorQuAD_v1.0_dev.json -P $HOME/data/raw
mkdir -p $HOME/data/processed
;;
dump-raw-nsmc)
echo "download naver movie corpus..."
wget https://github.com/e9t/nsmc/raw/master/ratings.txt -P $HOME/data/raw
wget https://github.com/e9t/nsmc/raw/master/ratings_train.txt -P $HOME/data/raw
wget https://github.com/e9t/nsmc/raw/master/ratings_test.txt -P $HOME/data/raw
mkdir -p $HOME/data/processed
;;
dump-blog)
echo "download blog data.."
mkdir -p $HOME/data/processed
gdrive_download 1Few7-Mh3JypQN3rjnuXD8yAXrkxUwmjS $HOME/data/processed/processed_blog.txt
;;
dump-raw)
echo "make directories..."
mkdir -p $HOME/data
mkdir -p $HOME/data/processed
mkdir $HOME/data/tokenized
echo "download similar sentence data..."
wget https://github.com/songys/Question_pair/raw/master/kor_pair_train.csv -P $HOME/data/raw
wget https://github.com/songys/Question_pair/raw/master/kor_Pair_test.csv -P $HOME/data/raw
;;
dump-word-embeddings)
echo "download word embeddings..."
mkdir -p $HOME/data/processed
cd $HOME/data
gdrive_download 1FeGIbSz2E1A63JZP_XIxnGaSRt7AhXFf $HOME/data/word-embeddings.zip
unzip word-embeddings.zip
rm word-embeddings.zip
;;
dump-sentence-embeddings)
echo "download sentence embeddings..."
mkdir -p $HOME/data/processed
cd $HOME/data
gdrive_download 1jL3Q5H1vwATewHrx0PJgJ8YoUCtEkaGW $HOME/data/sentence-embeddings.zip
unzip sentence-embeddings.zip
rm sentence-embeddings.zip
;;
dump-tokenized)
echo "download tokenized data..."
mkdir -p $HOME/data/processed
cd $HOME/data
gdrive_download 1Ybp_DmzNEpsBrUKZ1-NoPDzCMO39f-fx $HOME/data/tokenized.zip
unzip tokenized.zip
rm tokenized.zip
;;
dump-processed)
echo "download processed data..."
mkdir -p $HOME/data
cd $HOME/data
gdrive_download 1kUecR7xO7bsHFmUI6AExtY5u2XXlObOG $HOME/data/processed.zip
unzip processed.zip
rm processed.zip
;;
process-wiki)
echo "processing ko-wikipedia..."
mkdir -p $HOME/data/processed
python preprocess/dump.py --preprocess_mode wiki \
--input_path $HOME/data/raw/kowiki-latest-pages-articles.xml.bz2 \
--output_path $HOME/data/processed/processed_wiki_ko.txt
;;
process-nsmc)
echo "processing naver movie corpus..."
mkdir -p $HOME/data/processed
python preprocess/dump.py --preprocess_mode nsmc \
--input_path $HOME/data/raw/ratings.txt \
--output_path $HOME/data/processed/processed_ratings.txt \
--with_label False
python preprocess/dump.py --preprocess_mode nsmc \
--input_path $HOME/data/raw/ratings_train.txt \
--output_path $HOME/data/processed/processed_ratings_train.txt \
--with_label True
python preprocess/dump.py --preprocess_mode nsmc \
--input_path $HOME/data/raw/ratings_test.txt \
--output_path $HOME/data/processed/processed_ratings_test.txt \
--with_label True
;;
process-korquad)
echo "processing KorQuAD corpus..."
mkdir -p $HOME/data/processed
python preprocess/dump.py --preprocess_mode korquad \
--input_path $HOME/data/raw/KorQuAD_v1.0_train.json \
--output_path $HOME/data/processed/processed_korquad_train.txt
python preprocess/dump.py --preprocess_mode korquad \
--input_path $HOME/data/raw/KorQuAD_v1.0_dev.json \
--output_path $HOME/data/processed/processed_korquad_dev.txt
cat $HOME/data/processed/processed_korquad_train.txt $HOME/data/processed/processed_korquad_dev.txt > $HOME/data/processed/processed_korquad.txt
rm $HOME/data/processed/processed_korquad_*.txt
;;
mecab-tokenize)
echo "mecab, tokenizing..."
python preprocess/supervised_nlputils.py --tokenizer mecab \
--input_path $HOME/data/processed/processed_wiki_ko.txt \
--output_path data/tokenized/wiki_ko_mecab.txt
python preprocess/supervised_nlputils.py --tokenizer mecab \
--input_path $HOME/data/processed/processed_ratings.txt \
--output_path data/tokenized/ratings_mecab.txt
python preprocess/supervised_nlputils.py --tokenizer mecab \
--input_path $HOME/data/processed/processed_korquad.txt \
--output_path data/tokenized/korquad_mecab.txt
;;
process-jamo)
echo "processing jamo sentences..."
python preprocess/unsupervised_nlputils.py --preprocess_mode jamo \
--input_path $HOME/data/tokenized/corpus_mecab.txt \
--output_path $HOME/data/tokenized/corpus_mecab_jamo.txt
;;
space-correct)
echo "train & apply space correct..."
python preprocess/unsupervised_nlputils.py --preprocess_mode train_space \
--input_path $HOME/data/processed/processed_ratings.txt \
--model_path $HOME/data/processed/space-correct.model
python preprocess/unsupervised_nlputils.py --preprocess_mode apply_space_correct \
--input_path $HOME/data/processed/processed_ratings.txt \
--model_path $HOME/data/processed/space-correct.model \
--output_path $HOME/data/processed/corrected_ratings_corpus.txt \
--with_label False
python preprocess/unsupervised_nlputils.py --preprocess_mode apply_space_correct \
--input_path $HOME/data/processed/processed_ratings_train.txt \
--model_path $HOME/data/processed/space-correct.model \
--output_path $HOME/data/processed/corrected_ratings_train.txt \
--with_label True
python preprocess/unsupervised_nlputils.py --preprocess_mode apply_space_correct \
--input_path $HOME/data/processed/processed_ratings_test.txt \
--model_path $HOME/data/processed/space-correct.model \
--output_path $HOME/data/processed/corrected_ratings_test.txt \
--with_label True
;;
soy-tokenize)
echo "soynlp, LTokenizing..."
mkdir -p $HOME/data/tokenized
python preprocess/unsupervised_nlputils.py --preprocess_mode compute_soy_word_score \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--model_path $HOME/data/processed/soyword.model
python preprocess/unsupervised_nlputils.py --preprocess_mode soy_tokenize \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--model_path $HOME/data/processed/soyword.model \
--output_path $HOME/data/tokenized/ratings_soynlp.txt
;;
komoran-tokenize)
echo "komoran, tokenizing..."
mkdir -p $HOME/data/tokenized
python preprocess/supervised_nlputils.py --tokenizer komoran \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--output_path $HOME/data/tokenized/ratings_komoran.txt
;;
okt-tokenize)
echo "okt, tokenizing..."
mkdir -p $HOME/data/tokenized
python preprocess/supervised_nlputils.py --tokenizer okt \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--output_path $HOME/data/tokenized/ratings_okt.txt
;;
hannanum-tokenize)
echo "hannanum, tokenizing..."
mkdir -p $HOME/data/tokenized
python preprocess/supervised_nlputils.py --tokenizer hannanum \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--output_path $HOME/data/tokenized/ratings_hannanum.txt
;;
khaiii-tokenize)
echo "khaiii, tokenizing..."
mkdir -p $HOME/data/tokenized
python preprocess/supervised_nlputils.py --tokenizer khaiii \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--output_path $HOME/data/tokenized/ratings_khaiii.txt
;;
bert-tokenize)
mkdir -p $HOME/data/tokenized
python preprocess/unsupervised_nlputils.py --preprocess_mode bert_tokenize \
--vocab_path $HOME/data/sentence-embeddings/bert/pretrain-ckpt/vocab.txt \
--input_path $HOME/data/processed/corrected_ratings_corpus.txt \
--output_path $HOME/data/tokenized/ratings_sentpiece.txt
;;
mecab-user-dic)
echo "insert mecab user dictionary..."
cd /tmp/mecab-ko-dic-2.1.1-20180720
cp -f $HOME/preprocess/mecab-user-dic.csv /tmp/mecab-ko-dic-2.1.1-20180720/user-dic/nnp.csv
./tools/add-userdic.sh
make install
cd /Users/PSH
;;
make-bert-vocab)
echo "making BERT vocabulary..."
mkdir -p $HOME/data
cd $HOME/data
gdrive_download 1kUecR7xO7bsHFmUI6AExtY5u2XXlObOG $HOME/data/processed.zip
unzip processed.zip
rm processed.zip
cd /Users/PSH
python preprocess/unsupervised_nlputils.py --preprocess_mode make_bert_vocab \
--input_path $HOME/data/processed/processed_wiki_ko.txt \
--vocab_path $HOME/data/processed/bert.vocab
mv sentpiece* $HOME/data/processed
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment