Showing
7 changed files
with
402 additions
and
0 deletions
kin/dataset.py
0 → 100644
| 1 | +""" | ||
| 2 | +kin dataset | ||
| 3 | +""" | ||
| 4 | + | ||
| 5 | +import os | ||
| 6 | +import numpy as np | ||
| 7 | +from kor_char_parser import decompose_str_as_one_hot | ||
| 8 | + | ||
| 9 | +class KinQueryDataset: | ||
| 10 | + """ | ||
| 11 | + 지식인 데이터를 읽어서, tuple (데이터, 레이블)의 형태로 리턴하는 파이썬 오브젝트 입니다. | ||
| 12 | + """ | ||
| 13 | + def __init__(self, dataset_path: str, max_length: int): | ||
| 14 | + """ | ||
| 15 | + :param dataset_path: 데이터셋 root path | ||
| 16 | + :param max_length: 문자열의 최대 길이 | ||
| 17 | + """ | ||
| 18 | + # 데이터, 레이블 각각의 경로 | ||
| 19 | + queries_path = os.path.join(dataset_path, 'train', 'train_data') | ||
| 20 | + labels_path = os.path.join(dataset_path, 'train', 'train_label') | ||
| 21 | + | ||
| 22 | + # 지식인 데이터를 읽고 preprocess까지 진행합니다 | ||
| 23 | + with open(queries_path, 'rt', encoding='utf8') as f: | ||
| 24 | + self.queries = preprocess(f.readlines(), max_length) | ||
| 25 | + # 지식인 레이블을 읽고 preprocess까지 진행합니다. | ||
| 26 | + with open(labels_path) as f: | ||
| 27 | + self.labels = np.array([[np.float32(x)] for x in f.readlines()]) | ||
| 28 | + | ||
| 29 | + def __len__(self): | ||
| 30 | + """ | ||
| 31 | + :return: 전체 데이터의 수를 리턴합니다 | ||
| 32 | + """ | ||
| 33 | + return len(self.queries) | ||
| 34 | + | ||
| 35 | + def __getitem__(self, idx): | ||
| 36 | + """ | ||
| 37 | + :param idx: 필요한 데이터의 인덱스 | ||
| 38 | + :return: 인덱스에 맞는 데이터, 레이블 pair를 리턴합니다 | ||
| 39 | + """ | ||
| 40 | + return self.queries[idx], self.labels[idx] | ||
| 41 | + | ||
| 42 | + | ||
| 43 | +def preprocess(data: list, max_length: int): | ||
| 44 | + """ | ||
| 45 | + 입력을 받아서 딥러닝 모델이 학습 가능한 포맷으로 변경하는 함수입니다. | ||
| 46 | + 기본 제공 알고리즘은 char2vec이며, 기본 모델이 MLP이기 때문에, 입력 값의 크기를 모두 고정한 벡터를 리턴합니다. | ||
| 47 | + 문자열의 길이가 고정값보다 길면 긴 부분을 제거하고, 짧으면 0으로 채웁니다. | ||
| 48 | + :param data: 문자열 리스트 ([문자열1, 문자열2, ...]) | ||
| 49 | + :param max_length: 문자열의 최대 길이 | ||
| 50 | + :return: 벡터 리스트 ([[0, 1, 5, 6], [5, 4, 10, 200], ...]) max_length가 4일 때 | ||
| 51 | + """ | ||
| 52 | + vectorized_data = [decompose_str_as_one_hot(datum, warning=False) for datum in data] | ||
| 53 | + zero_padding = np.zeros((len(data), max_length), dtype=np.int32) | ||
| 54 | + for idx, seq in enumerate(vectorized_data): | ||
| 55 | + length = len(seq) | ||
| 56 | + if length >= max_length: | ||
| 57 | + length = max_length | ||
| 58 | + zero_padding[idx, :length] = np.array(seq)[:length] | ||
| 59 | + else: | ||
| 60 | + zero_padding[idx, :length] = np.array(seq) | ||
| 61 | + return zero_padding |
kin/main.py
0 → 100644
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | + | ||
| 3 | +""" | ||
| 4 | +Copyright 2018 NAVER Corp. | ||
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||
| 6 | +associated documentation files (the "Software"), to deal in the Software without restriction, including | ||
| 7 | +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 8 | +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to | ||
| 9 | +the following conditions: | ||
| 10 | +The above copyright notice and this permission notice shall be included in all copies or substantial | ||
| 11 | +portions of the Software. | ||
| 12 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 13 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 14 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 15 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
| 16 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | ||
| 17 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 18 | +""" | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +import argparse | ||
| 22 | +import os | ||
| 23 | + | ||
| 24 | +import numpy as np | ||
| 25 | +import tensorflow as tf | ||
| 26 | + | ||
| 27 | +import nsml | ||
| 28 | +from nsml import DATASET_PATH, HAS_DATASET, IS_ON_NSML | ||
| 29 | +from dataset import KinQueryDataset, preprocess | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +# DONOTCHANGE: They are reserved for nsml | ||
| 33 | +# This is for nsml leaderboard | ||
| 34 | +def bind_model(sess, config): | ||
| 35 | + # 학습한 모델을 저장하는 함수입니다. | ||
| 36 | + def save(dir_name, *args): | ||
| 37 | + # directory | ||
| 38 | + os.makedirs(dir_name, exist_ok=True) | ||
| 39 | + saver = tf.train.Saver() | ||
| 40 | + saver.save(sess, os.path.join(dir_name, 'model')) | ||
| 41 | + | ||
| 42 | + # 저장한 모델을 불러올 수 있는 함수입니다. | ||
| 43 | + def load(dir_name, *args): | ||
| 44 | + saver = tf.train.Saver() | ||
| 45 | + # find checkpoint | ||
| 46 | + ckpt = tf.train.get_checkpoint_state(dir_name) | ||
| 47 | + if ckpt and ckpt.model_checkpoint_path: | ||
| 48 | + checkpoint = os.path.basename(ckpt.model_checkpoint_path) | ||
| 49 | + saver.restore(sess, os.path.join(dir_name, checkpoint)) | ||
| 50 | + else: | ||
| 51 | + raise NotImplemented('No checkpoint!') | ||
| 52 | + print('Model loaded') | ||
| 53 | + | ||
| 54 | + def infer(raw_data, **kwargs): | ||
| 55 | + """ | ||
| 56 | + :param raw_data: raw input (여기서는 문자열)을 입력받습니다 | ||
| 57 | + :param kwargs: | ||
| 58 | + :return: | ||
| 59 | + """ | ||
| 60 | + # dataset.py에서 작성한 preprocess 함수를 호출하여, 문자열을 벡터로 변환합니다 | ||
| 61 | + preprocessed_data = preprocess(raw_data, config.strmaxlen) | ||
| 62 | + # 저장한 모델에 입력값을 넣고 prediction 결과를 리턴받습니다 | ||
| 63 | + pred = sess.run(output_sigmoid, feed_dict={x: preprocessed_data}) | ||
| 64 | + clipped = np.array(pred > config.threshold, dtype=np.int) | ||
| 65 | + # DONOTCHANGE: They are reserved for nsml | ||
| 66 | + # 리턴 결과는 [(확률, 0 or 1)] 의 형태로 보내야만 리더보드에 올릴 수 있습니다. 리더보드 결과에 확률의 값은 영향을 미치지 않습니다 | ||
| 67 | + return list(zip(pred.flatten(), clipped.flatten())) | ||
| 68 | + | ||
| 69 | + # DONOTCHANGE: They are reserved for nsml | ||
| 70 | + # nsml에서 지정한 함수에 접근할 수 있도록 하는 함수입니다. | ||
| 71 | + nsml.bind(save=save, load=load, infer=infer) | ||
| 72 | + | ||
| 73 | + | ||
| 74 | +def _batch_loader(iterable, n=1): | ||
| 75 | + """ | ||
| 76 | + 데이터를 배치 사이즈만큼 잘라서 보내주는 함수입니다. PyTorch의 DataLoader와 같은 역할을 합니다 | ||
| 77 | + :param iterable: 데이터 list, 혹은 다른 포맷 | ||
| 78 | + :param n: 배치 사이즈 | ||
| 79 | + :return: | ||
| 80 | + """ | ||
| 81 | + length = len(iterable) | ||
| 82 | + for n_idx in range(0, length, n): | ||
| 83 | + yield iterable[n_idx:min(n_idx + n, length)] | ||
| 84 | + | ||
| 85 | + | ||
| 86 | +def weight_variable(shape): | ||
| 87 | + initial = tf.truncated_normal(shape, stddev=0.1) | ||
| 88 | + return tf.Variable(initial) | ||
| 89 | + | ||
| 90 | + | ||
| 91 | +def bias_variable(shape): | ||
| 92 | + initial = tf.constant(0.1, shape=shape) | ||
| 93 | + return tf.Variable(initial) | ||
| 94 | + | ||
| 95 | + | ||
| 96 | +if __name__ == '__main__': | ||
| 97 | + args = argparse.ArgumentParser() | ||
| 98 | + # DONOTCHANGE: They are reserved for nsml | ||
| 99 | + args.add_argument('--mode', type=str, default='train') | ||
| 100 | + args.add_argument('--pause', type=int, default=0) | ||
| 101 | + args.add_argument('--iteration', type=str, default='0') | ||
| 102 | + | ||
| 103 | + # User options | ||
| 104 | + args.add_argument('--output', type=int, default=1) | ||
| 105 | + args.add_argument('--epochs', type=int, default=10) | ||
| 106 | + args.add_argument('--batch', type=int, default=2000) | ||
| 107 | + args.add_argument('--strmaxlen', type=int, default=400) | ||
| 108 | + args.add_argument('--embedding', type=int, default=8) | ||
| 109 | + args.add_argument('--threshold', type=float, default=0.5) | ||
| 110 | + config = args.parse_args() | ||
| 111 | + | ||
| 112 | + if not HAS_DATASET and not IS_ON_NSML: # It is not running on nsml | ||
| 113 | + DATASET_PATH = '../sample_data/kin/' | ||
| 114 | + | ||
| 115 | + # 모델의 specification | ||
| 116 | + input_size = config.embedding*config.strmaxlen | ||
| 117 | + output_size = 1 | ||
| 118 | + hidden_layer_size = 200 | ||
| 119 | + learning_rate = 0.001 | ||
| 120 | + character_size = 251 | ||
| 121 | + | ||
| 122 | + x = tf.placeholder(tf.int32, [None, config.strmaxlen]) | ||
| 123 | + y_ = tf.placeholder(tf.float32, [None, output_size]) | ||
| 124 | + # 임베딩 | ||
| 125 | + char_embedding = tf.get_variable('char_embedding', [character_size, config.embedding]) | ||
| 126 | + embedded = tf.nn.embedding_lookup(char_embedding, x) | ||
| 127 | + | ||
| 128 | + # 첫 번째 레이어 | ||
| 129 | + first_layer_weight = weight_variable([input_size, hidden_layer_size]) | ||
| 130 | + first_layer_bias = bias_variable([hidden_layer_size]) | ||
| 131 | + hidden_layer = tf.matmul(tf.reshape(embedded, (-1, input_size)), | ||
| 132 | + first_layer_weight) + first_layer_bias | ||
| 133 | + | ||
| 134 | + # 두 번째 (아웃풋) 레이어 | ||
| 135 | + second_layer_weight = weight_variable([hidden_layer_size, output_size]) | ||
| 136 | + second_layer_bias = bias_variable([output_size]) | ||
| 137 | + output = tf.matmul(hidden_layer, second_layer_weight) + second_layer_bias | ||
| 138 | + output_sigmoid = tf.sigmoid(output) | ||
| 139 | + | ||
| 140 | + # loss와 optimizer | ||
| 141 | + binary_cross_entropy = tf.reduce_mean(-(y_ * tf.log(output_sigmoid)) - (1-y_) * tf.log(1-output_sigmoid)) | ||
| 142 | + train_step = tf.train.AdamOptimizer(learning_rate).minimize(binary_cross_entropy) | ||
| 143 | + | ||
| 144 | + sess = tf.InteractiveSession() | ||
| 145 | + tf.global_variables_initializer().run() | ||
| 146 | + | ||
| 147 | + # DONOTCHANGE: Reserved for nsml | ||
| 148 | + bind_model(sess=sess, config=config) | ||
| 149 | + | ||
| 150 | + # DONOTCHANGE: Reserved for nsml | ||
| 151 | + if config.pause: | ||
| 152 | + nsml.paused(scope=locals()) | ||
| 153 | + | ||
| 154 | + if config.mode == 'train': | ||
| 155 | + # 데이터를 로드합니다. | ||
| 156 | + dataset = KinQueryDataset(DATASET_PATH, config.strmaxlen) | ||
| 157 | + dataset_len = len(dataset) | ||
| 158 | + one_batch_size = dataset_len//config.batch | ||
| 159 | + if dataset_len % config.batch != 0: | ||
| 160 | + one_batch_size += 1 | ||
| 161 | + # epoch마다 학습을 수행합니다. | ||
| 162 | + for epoch in range(config.epochs): | ||
| 163 | + avg_loss = 0.0 | ||
| 164 | + for i, (data, labels) in enumerate(_batch_loader(dataset, config.batch)): | ||
| 165 | + _, loss = sess.run([train_step, binary_cross_entropy], | ||
| 166 | + feed_dict={x: data, y_: labels}) | ||
| 167 | + print('Batch : ', i + 1, '/', one_batch_size, | ||
| 168 | + ', BCE in this minibatch: ', float(loss)) | ||
| 169 | + avg_loss += float(loss) | ||
| 170 | + print('epoch:', epoch, ' train_loss:', float(avg_loss/one_batch_size)) | ||
| 171 | + nsml.report(summary=True, scope=locals(), epoch=epoch, epoch_total=config.epochs, | ||
| 172 | + train__loss=float(avg_loss/one_batch_size), step=epoch) | ||
| 173 | + # DONOTCHANGE (You can decide how often you want to save the model) | ||
| 174 | + nsml.save(epoch) | ||
| 175 | + | ||
| 176 | + # 로컬 테스트 모드일때 사용합니다 | ||
| 177 | + # 결과가 아래와 같이 나온다면, nsml submit을 통해서 제출할 수 있습니다. | ||
| 178 | + # [(0.3, 0), (0.7, 1), ... ] | ||
| 179 | + elif config.mode == 'test_local': | ||
| 180 | + with open(os.path.join(DATASET_PATH, 'train/train_data'), 'rt', encoding='utf-8') as f: | ||
| 181 | + queries = f.readlines() | ||
| 182 | + res = [] | ||
| 183 | + for batch in _batch_loader(queries, config.batch): | ||
| 184 | + temp_res = nsml.infer(batch) | ||
| 185 | + res += temp_res | ||
| 186 | + print(res) |
kin/setup.py
0 → 100644
| 1 | +""" | ||
| 2 | +Copyright 2018 NAVER Corp. | ||
| 3 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||
| 4 | +associated documentation files (the "Software"), to deal in the Software without restriction, including | ||
| 5 | +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 6 | +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to | ||
| 7 | +the following conditions: | ||
| 8 | +The above copyright notice and this permission notice shall be included in all copies or substantial | ||
| 9 | +portions of the Software. | ||
| 10 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 11 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 12 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 13 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
| 14 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | ||
| 15 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 16 | +""" | ||
| 17 | + | ||
| 18 | +from distutils.core import setup | ||
| 19 | +setup( | ||
| 20 | + name='nsml movie review', | ||
| 21 | + version='1.0', | ||
| 22 | + description='', | ||
| 23 | + install_requires=[ | ||
| 24 | + ] | ||
| 25 | +) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
movie/kor_char_parser.py
0 → 100644
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | + | ||
| 3 | +""" | ||
| 4 | +Copyright 2018 NAVER Corp. | ||
| 5 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||
| 6 | +associated documentation files (the "Software"), to deal in the Software without restriction, including | ||
| 7 | +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 8 | +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to | ||
| 9 | +the following conditions: | ||
| 10 | +The above copyright notice and this permission notice shall be included in all copies or substantial | ||
| 11 | +portions of the Software. | ||
| 12 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 13 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 14 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 15 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
| 16 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | ||
| 17 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 18 | +""" | ||
| 19 | + | ||
| 20 | +cho = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ" # len = 19 | ||
| 21 | +jung = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ" # len = 21 | ||
| 22 | +# len = 27 | ||
| 23 | +jong = "ㄱ/ㄲ/ㄱㅅ/ㄴ/ㄴㅈ/ㄴㅎ/ㄷ/ㄹ/ㄹㄱ/ㄹㅁ/ㄹㅂ/ㄹㅅ/ㄹㅌ/ㄹㅍ/ㄹㅎ/ㅁ/ㅂ/ㅂㅅ/ㅅ/ㅆ/ㅇ/ㅈ/ㅊ/ㅋ/ㅌ/ㅍ/ㅎ".split( | ||
| 24 | + '/') | ||
| 25 | +test = cho + jung + ''.join(jong) | ||
| 26 | + | ||
| 27 | +hangul_length = len(cho) + len(jung) + len(jong) # 67 | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +def is_valid_decomposition_atom(x): | ||
| 31 | + return x in test | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +def decompose(x): | ||
| 35 | + in_char = x | ||
| 36 | + if x < ord('가') or x > ord('힣'): | ||
| 37 | + return chr(x) | ||
| 38 | + x = x - ord('가') | ||
| 39 | + y = x // 28 | ||
| 40 | + z = x % 28 | ||
| 41 | + x = y // 21 | ||
| 42 | + y = y % 21 | ||
| 43 | + # if there is jong, then is z > 0. So z starts from 1 index. | ||
| 44 | + zz = jong[z - 1] if z > 0 else '' | ||
| 45 | + if x >= len(cho): | ||
| 46 | + print('Unknown Exception: ', in_char, chr(in_char), x, y, z, zz) | ||
| 47 | + return cho[x] + jung[y] + zz | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +def decompose_as_one_hot(in_char, warning=True): | ||
| 51 | + one_hot = [] | ||
| 52 | + # print(ord('ㅣ'), chr(0xac00)) | ||
| 53 | + # [0,66]: hangul / [67,194]: ASCII / [195,245]: hangul danja,danmo / [246,249]: special characters | ||
| 54 | + # Total 250 dimensions. | ||
| 55 | + if ord('가') <= in_char <= ord('힣'): # 가:44032 , 힣: 55203 | ||
| 56 | + x = in_char - 44032 # in_char - ord('가') | ||
| 57 | + y = x // 28 | ||
| 58 | + z = x % 28 | ||
| 59 | + x = y // 21 | ||
| 60 | + y = y % 21 | ||
| 61 | + # if there is jong, then is z > 0. So z starts from 1 index. | ||
| 62 | + zz = jong[z - 1] if z > 0 else '' | ||
| 63 | + if x >= len(cho): | ||
| 64 | + if warning: | ||
| 65 | + print('Unknown Exception: ', in_char, | ||
| 66 | + chr(in_char), x, y, z, zz) | ||
| 67 | + | ||
| 68 | + one_hot.append(x) | ||
| 69 | + one_hot.append(len(cho) + y) | ||
| 70 | + if z > 0: | ||
| 71 | + one_hot.append(len(cho) + len(jung) + (z - 1)) | ||
| 72 | + return one_hot | ||
| 73 | + else: | ||
| 74 | + if in_char < 128: | ||
| 75 | + result = hangul_length + in_char # 67~ | ||
| 76 | + elif ord('ㄱ') <= in_char <= ord('ㅣ'): | ||
| 77 | + # 194~ # [ㄱ:12593]~[ㅣ:12643] (len = 51) | ||
| 78 | + result = hangul_length + 128 + (in_char - 12593) | ||
| 79 | + elif in_char == ord('♡'): | ||
| 80 | + result = hangul_length + 128 + 51 # 245~ # ♡ | ||
| 81 | + elif in_char == ord('♥'): | ||
| 82 | + result = hangul_length + 128 + 51 + 1 # ♥ | ||
| 83 | + elif in_char == ord('★'): | ||
| 84 | + result = hangul_length + 128 + 51 + 2 # ★ | ||
| 85 | + elif in_char == ord('☆'): | ||
| 86 | + result = hangul_length + 128 + 51 + 3 # ☆ | ||
| 87 | + else: | ||
| 88 | + if warning: | ||
| 89 | + print('Unhandled character:', chr(in_char), in_char) | ||
| 90 | + # unknown character | ||
| 91 | + result = hangul_length + 128 + 51 + 4 # for unknown character | ||
| 92 | + | ||
| 93 | + return [result] | ||
| 94 | + | ||
| 95 | + | ||
| 96 | +def decompose_str(string): | ||
| 97 | + return ''.join([decompose(ord(x)) for x in string]) | ||
| 98 | + | ||
| 99 | + | ||
| 100 | +def decompose_str_as_one_hot(string, warning=True): | ||
| 101 | + tmp_list = [] | ||
| 102 | + for x in string: | ||
| 103 | + da = decompose_as_one_hot(ord(x), warning=warning) | ||
| 104 | + tmp_list.extend(da) | ||
| 105 | + return tmp_list |
movie/setup.py
0 → 100644
| 1 | +""" | ||
| 2 | +Copyright 2018 NAVER Corp. | ||
| 3 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||
| 4 | +associated documentation files (the "Software"), to deal in the Software without restriction, including | ||
| 5 | +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 6 | +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to | ||
| 7 | +the following conditions: | ||
| 8 | +The above copyright notice and this permission notice shall be included in all copies or substantial | ||
| 9 | +portions of the Software. | ||
| 10 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 11 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 12 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 13 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
| 14 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | ||
| 15 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 16 | +""" | ||
| 17 | + | ||
| 18 | +from distutils.core import setup | ||
| 19 | +setup( | ||
| 20 | + name='nsml movie review', | ||
| 21 | + version='1.0', | ||
| 22 | + description='', | ||
| 23 | + install_requires=[ | ||
| 24 | + ] | ||
| 25 | +) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
File moved
-
Please register or login to post a comment