def main(args): dataset_config = Config(args.dataset_config) model_config = Config(args.model_config) exp_dir = Path("experiments") / model_config.type exp_dir = exp_dir.joinpath( f"epochs_{args.epochs}_batch_size_{args.batch_size}_learning_rate_{args.learning_rate}" ) tokenizer = get_tokenizer(dataset_config, model_config) checkpoint_manager = CheckpointManager(exp_dir) checkpoint = checkpoint_manager.load_checkpoint("best.tar") model = CharCNN(num_classes=model_config.num_classes, embedding_dim=model_config.embedding_dim, vocab=tokenizer.vocab) model.load_state_dict(checkpoint["model_state_dict"]) summary_manager = SummaryManager(exp_dir) filepath = getattr(dataset_config, args.data) ds = Corpus(filepath, tokenizer.split_and_transform) dl = DataLoader(ds, batch_size=args.batch_size, num_workers=4) device = torch.device( "cuda") if torch.cuda.is_available() else torch.device("cpu") model.to(device) summary = evaluate(model, dl, { "loss": nn.CrossEntropyLoss(), "acc": acc }, device) summary_manager.load("summary.json") summary_manager.update({f"{args.data}": summary}) summary_manager.save("summary.json") print(f"loss: {summary['loss']:.3f}, acc: {summary['acc']:.2%}")
def main(json_path): cwd = Path.cwd() with open(cwd / json_path) as io: params = json.loads(io.read()) # tokenizer vocab_path = params['filepath'].get('vocab') with open(cwd / vocab_path, mode='rb') as io: vocab = pickle.load(io) length = params['padder'].get('length') padder = PadSequence(length=length, pad_val=vocab.to_indices(vocab.padding_token)) tokenizer = Tokenizer(vocab=vocab, split_fn=split_to_jamo, pad_fn=padder) # model (restore) save_path = cwd / params['filepath'].get('ckpt') ckpt = torch.load(save_path) num_classes = params['model'].get('num_classes') embedding_dim = params['model'].get('embedding_dim') model = CharCNN(num_classes=num_classes, embedding_dim=embedding_dim, vocab=tokenizer.vocab) model.load_state_dict(ckpt['model_state_dict']) # evaluation batch_size = params['training'].get('batch_size') tr_path = cwd / params['filepath'].get('tr') val_path = cwd / params['filepath'].get('val') tst_path = cwd / params['filepath'].get('tst') tr_ds = Corpus(tr_path, tokenizer.split_and_transform) tr_dl = DataLoader(tr_ds, batch_size=batch_size, num_workers=4) val_ds = Corpus(val_path, tokenizer.split_and_transform) val_dl = DataLoader(val_ds, batch_size=batch_size, num_workers=4) tst_ds = Corpus(tst_path, tokenizer.split_and_transform) tst_dl = DataLoader(tst_ds, batch_size=batch_size, num_workers=4) device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) tr_acc = get_accuracy(model, tr_dl, device) val_acc = get_accuracy(model, val_dl, device) tst_acc = get_accuracy(model, tst_dl, device) print('tr_acc: {:.2%}, val_acc: {:.2%}, tst_acc: {:.2%}'.format( tr_acc, val_acc, tst_acc))
def evaluate(cfgpath): # parsing json with open(os.path.join(os.getcwd(), cfgpath)) as io: params = json.loads(io.read()) # restoring model savepath = os.path.join(os.getcwd(), params['filepath'].get('ckpt')) ckpt = torch.load(savepath) tokenizer = JamoTokenizer() padder = PadSequence(300) model = CharCNN(num_classes=params['model'].get('num_classes'), embedding_dim=params['model'].get('embedding_dim'), dic=tokenizer.token2idx) model.load_state_dict(ckpt['model_state_dict']) model.eval() device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) # creating dataset, dataloader tst_filepath = os.path.join(os.getcwd(), params['filepath'].get('tst')) tst_ds = Corpus(tst_filepath, tokenizer, padder) tst_dl = DataLoader(tst_ds, batch_size=128, num_workers=4) # evaluation correct_count = 0 for x_mb, y_mb in tqdm(tst_dl): x_mb = x_mb.to(device) y_mb = y_mb.to(device) with torch.no_grad(): y_mb_hat = model(x_mb) y_mb_hat = torch.max(y_mb_hat, 1)[1] correct_count += (y_mb_hat == y_mb).sum().item() print('Acc : {:.2%}'.format(correct_count / len(tst_ds)))
model_config = Config(json_path=model_dir / 'config.json') # tokenizer with open(data_config.vocab, mode='rb') as io: vocab = pickle.load(io) pad_sequence = PadSequence(length=model_config.length, pad_val=vocab.to_indices(vocab.padding_token)) tokenizer = Tokenizer(vocab=vocab, split_fn=split_to_jamo, pad_fn=pad_sequence) # model (restore) checkpoint_manager = CheckpointManager(model_dir) checkpoint = checkpoint_manager.load_checkpoint(args.restore_file + '.tar') model = CharCNN(num_classes=model_config.num_classes, embedding_dim=model_config.embedding_dim, vocab=tokenizer.vocab) model.load_state_dict(checkpoint['model_state_dict']) # evaluation summary_manager = SummaryManager(model_dir) filepath = getattr(data_config, args.data_name) ds = Corpus(filepath, tokenizer.split_and_transform) dl = DataLoader(ds, batch_size=model_config.batch_size, num_workers=4) device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) summary = evaluate(model, dl, { 'loss': nn.CrossEntropyLoss(),
model_dir = Path(args.model_dir) data_config = Config(json_path=data_dir / 'config.json') model_config = Config(json_path=model_dir / 'config.json') # tokenizer with open(data_config.vocab, mode='rb') as io: vocab = pickle.load(io) pad_sequence = PadSequence(length=model_config.length, pad_val=vocab.to_indices(vocab.padding_token)) tokenizer = Tokenizer(vocab=vocab, split_fn=split_to_jamo, pad_fn=pad_sequence) # model model = CharCNN(num_classes=model_config.num_classes, embedding_dim=model_config.embedding_dim, vocab=tokenizer.vocab) # training tr_ds = Corpus(data_config.train, tokenizer.split_and_transform) tr_dl = DataLoader(tr_ds, batch_size=model_config.batch_size, shuffle=True, num_workers=4, drop_last=True) val_ds = Corpus(data_config.validation, tokenizer.split_and_transform) val_dl = DataLoader(val_ds, batch_size=model_config.batch_size) loss_fn = nn.CrossEntropyLoss() opt = optim.Adam(params=model.parameters(), lr=model_config.learning_rate) scheduler = ReduceLROnPlateau(opt, patience=5)
def main(args): dataset_config = Config(args.dataset_config) model_config = Config(args.model_config) exp_dir = Path("experiments") / model_config.type exp_dir = exp_dir.joinpath( f"epochs_{args.epochs}_batch_size_{args.batch_size}_learning_rate_{args.learning_rate}" ) if not exp_dir.exists(): exp_dir.mkdir(parents=True) if args.fix_seed: torch.manual_seed(777) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False tokenizer = get_tokenizer(dataset_config, model_config) tr_dl, val_dl = get_data_loaders(dataset_config, tokenizer, args.batch_size) model = CharCNN(num_classes=model_config.num_classes, embedding_dim=model_config.embedding_dim, vocab=tokenizer.vocab) loss_fn = nn.CrossEntropyLoss() opt = optim.Adam(params=model.parameters(), lr=args.learning_rate) scheduler = ReduceLROnPlateau(opt, patience=5) device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) writer = SummaryWriter('{}/runs'.format(exp_dir)) checkpoint_manager = CheckpointManager(exp_dir) summary_manager = SummaryManager(exp_dir) best_val_loss = 1e+10 for epoch in tqdm(range(args.epochs), desc='epochs'): tr_loss = 0 tr_acc = 0 model.train() for step, mb in tqdm(enumerate(tr_dl), desc='steps', total=len(tr_dl)): x_mb, y_mb = map(lambda elm: elm.to(device), mb) opt.zero_grad() y_hat_mb = model(x_mb) mb_loss = loss_fn(y_hat_mb, y_mb) mb_loss.backward() opt.step() with torch.no_grad(): mb_acc = acc(y_hat_mb, y_mb) tr_loss += mb_loss.item() tr_acc += mb_acc.item() if (epoch * len(tr_dl) + step) % args.summary_step == 0: val_loss = evaluate(model, val_dl, {'loss': loss_fn}, device)['loss'] writer.add_scalars('loss', { 'train': tr_loss / (step + 1), 'val': val_loss }, epoch * len(tr_dl) + step) model.train() else: tr_loss /= (step + 1) tr_acc /= (step + 1) tr_summary = {'loss': tr_loss, 'acc': tr_acc} val_summary = evaluate(model, val_dl, { 'loss': loss_fn, 'acc': acc }, device) scheduler.step(val_summary['loss']) tqdm.write('epoch : {}, tr_loss: {:.3f}, val_loss: ' '{:.3f}, tr_acc: {:.2%}, val_acc: {:.2%}'.format( epoch + 1, tr_summary['loss'], val_summary['loss'], tr_summary['acc'], val_summary['acc'])) val_loss = val_summary['loss'] is_best = val_loss < best_val_loss if is_best: state = { 'epoch': epoch + 1, 'model_state_dict': model.state_dict(), 'opt_state_dict': opt.state_dict() } summary = {'train': tr_summary, 'validation': val_summary} summary_manager.update(summary) summary_manager.save('summary.json') checkpoint_manager.save_checkpoint(state, 'best.tar') best_val_loss = val_loss
def train(cfgpath): # parsing json with open(os.path.join(os.getcwd(), cfgpath)) as io: params = json.loads(io.read()) # creating preprocessor tokenizer = JamoTokenizer() padder = PadSequence(300) # creating model model = CharCNN(num_classes=params['model'].get('num_classes'), embedding_dim=params['model'].get('embedding_dim'), dic=tokenizer.token2idx) # creating dataset, dataloader tr_filepath = os.path.join(os.getcwd(), params['filepath'].get('tr')) val_filepath = os.path.join(os.getcwd(), params['filepath'].get('val')) batch_size = params['training'].get('batch_size') tr_ds = Corpus(tr_filepath, tokenizer, padder) tr_dl = DataLoader(tr_ds, batch_size=batch_size, shuffle=True, num_workers=4, drop_last=True) val_ds = Corpus(val_filepath, tokenizer, padder) val_dl = DataLoader(val_ds, batch_size=batch_size, num_workers=4) # training loss_fn = nn.CrossEntropyLoss() opt = optim.Adam(params=model.parameters(), lr=params['training'].get('learning_rate')) device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) epochs = params['training'].get('epochs') for epoch in tqdm(range(epochs), desc='epochs'): avg_tr_loss = 0 avg_val_loss = 0 tr_step = 0 val_step = 0 model.train() for x_mb, y_mb in tqdm(tr_dl, desc='iters'): x_mb = x_mb.to(device) y_mb = y_mb.to(device) score = model(x_mb) opt.zero_grad() tr_loss = loss_fn(score, y_mb) tr_loss.backward() opt.step() avg_tr_loss += tr_loss.item() tr_step += 1 else: avg_tr_loss /= tr_step model.eval() for x_mb, y_mb in tqdm(val_dl): x_mb = x_mb.to(device) y_mb = y_mb.to(device) with torch.no_grad(): score = model(x_mb) val_loss = loss_fn(score, y_mb) avg_val_loss += val_loss.item() val_step += 1 else: avg_val_loss /= val_step tqdm.write('epoch : {}, tr_loss : {:.3f}, val_loss : {:.3f}'.format( epoch + 1, avg_tr_loss, avg_val_loss)) ckpt = { 'epoch': epoch, 'model_state_dict': model.state_dict(), 'opt_state_dict': opt.state_dict() } savepath = os.path.join(os.getcwd(), params['filepath'].get('ckpt')) torch.save(ckpt, savepath)
def main(argv): train_data = Path.cwd() / '..' / 'data_in' / 'train.txt' val_data = Path.cwd() / '..' / 'data_in' / 'val.txt' test_data = Path.cwd() / '..' / 'data_in' / 'test.txt' dev_data = Path.cwd() / '..' / 'data_in' / 'dev.txt' # init params classes = FLAGS.classes max_length = FLAGS.length epochs = FLAGS.epochs learning_rate = FLAGS.learning_rate dim = FLAGS.embedding_dim global_step = 1000 batch_size = FLAGS.batch_size with open(Path.cwd() / '..' / 'data_in' / 'vocab.pkl', mode='rb') as io: vocab = pickle.load(io) train = tf.data.TextLineDataset(str(train_data)).shuffle( buffer_size=batch_size).batch(batch_size=batch_size) eval = tf.data.TextLineDataset(str(val_data)).batch(batch_size=batch_size) test = tf.data.TextLineDataset(str(test_data)).batch(batch_size=batch_size) dev = tf.data.TextLineDataset(str(dev_data)).batch(batch_size=batch_size) padder = PadSequence(max_length, pad_val=vocab.to_indices(vocab.padding_token)) processing = Corpus(vocab=vocab, split_fn=Split(), pad_fn=padder) # create model char_cnn = CharCNN(vocab=vocab, classes=classes, dim=dim) # create optimizer & loss_fn opt = tf.optimizers.Adam(learning_rate=learning_rate) loss_fn = tf.losses.SparseCategoricalCrossentropy() train_loss_metric = tf.keras.metrics.Mean(name='train_loss') train_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy( name='train_accuracy') val_loss_metric = tf.keras.metrics.Mean(name='val_loss') val_acc_metric = tf.keras.metrics.SparseCategoricalAccuracy( name='val_accuracy') # train_summary_writer = tf.summary.create_file_writer('./data_out/summaries/train') # eval_summary_writer = tf.summary.create_file_writer('./data_out/summaries/eval') # ckpt = tf.train.Checkpoint(step=tf.Variable(1), optimizer=opt, net=char_cnn) # manager = tf.train.CheckpointManager(ckpt, './data_out/tf_ckpts', max_to_keep=3) # ckpt.restore(manager.latest_checkpoint) # # if manager.latest_checkpoint: # print("Restored from {}".format(manager.latest_checkpoint)) # else: # print("Initializing from scratch.") #training for epoch in tqdm(range(epochs), desc='epochs'): train_loss_metric.reset_states() train_acc_metric.reset_states() val_loss_metric.reset_states() val_acc_metric.reset_states() tf.keras.backend.set_learning_phase(1) #with train_summary_writer.as_default(): for step, val in tqdm(enumerate(train), desc='steps'): data, label = processing.token2idex(val) with tf.GradientTape() as tape: logits = char_cnn(data) train_loss = loss_fn(label, logits) #ckpt.step.assign_add(1) grads = tape.gradient(target=train_loss, sources=char_cnn.trainable_variables) opt.apply_gradients( grads_and_vars=zip(grads, char_cnn.trainable_variables)) train_loss_metric.update_state(train_loss) train_acc_metric.update_state(label, logits) # if tf.equal(opt.iterations % global_step, 0): # tf.summary.scalar('loss', train_loss_metric.result(), step=opt.iterations) tr_loss = train_loss_metric.result() #save_path = manager.save() #print(save_path) tqdm.write('epoch : {}, tr_acc : {:.3f}%, tr_loss : {:.3f}'.format( epoch + 1, train_acc_metric.result() * 100, tr_loss))
def main(json_path): cwd = Path.cwd() with open(cwd / json_path) as io: params = json.loads(io.read()) # tokenizer vocab_path = params['filepath'].get('vocab') with open(cwd / vocab_path, mode='rb') as io: vocab = pickle.load(io) length = params['padder'].get('length') padder = PadSequence(length, pad_val=vocab.to_indices(vocab.padding_token)) tokenizer = Tokenizer(vocab=vocab, split_fn=split_to_jamo, pad_fn=padder) # model num_classes = params['model'].get('num_classes') embedding_dim = params['model'].get('embedding_dim') model = CharCNN(num_classes=num_classes, embedding_dim=embedding_dim, vocab=tokenizer.vocab) # training epochs = params['training'].get('epochs') batch_size = params['training'].get('batch_size') learning_rate = params['training'].get('learning_rate') global_step = params['training'].get('global_step') tr_path = cwd / params['filepath'].get('tr') val_path = cwd / params['filepath'].get('val') tr_ds = Corpus(tr_path, tokenizer.split_and_transform) tr_dl = DataLoader(tr_ds, batch_size=batch_size, shuffle=True, num_workers=4, drop_last=True) val_ds = Corpus(val_path, tokenizer.split_and_transform) val_dl = DataLoader(val_ds, batch_size=batch_size, num_workers=4) loss_fn = nn.CrossEntropyLoss() opt = optim.Adam(params=model.parameters(), lr=learning_rate) scheduler = ReduceLROnPlateau(opt, patience=5) device = torch.device( 'cuda') if torch.cuda.is_available() else torch.device('cpu') model.to(device) writer = SummaryWriter('./runs/{}'.format(params['version'])) for epoch in tqdm(range(epochs), desc='epochs'): tr_loss = 0 model.train() for step, mb in tqdm(enumerate(tr_dl), desc='steps', total=len(tr_dl)): x_mb, y_mb = map(lambda elm: elm.to(device), mb) opt.zero_grad() mb_loss = loss_fn(model(x_mb), y_mb) mb_loss.backward() opt.step() tr_loss += mb_loss.item() if (epoch * len(tr_dl) + step) % global_step == 0: val_loss = evaluate(model, val_dl, loss_fn, device) writer.add_scalars('loss', { 'train': tr_loss / (step + 1), 'validation': val_loss }, epoch * len(tr_dl) + step) model.train() else: tr_loss /= (step + 1) val_loss = evaluate(model, val_dl, loss_fn, device) scheduler.step(val_loss) tqdm.write('epoch : {}, tr_loss : {:.3f}, val_loss : {:.3f}'.format( epoch + 1, tr_loss, val_loss)) ckpt = { 'model_state_dict': model.state_dict(), 'opt_state_dict': opt.state_dict() } save_path = cwd / params['filepath'].get('ckpt') torch.save(ckpt, save_path)