We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
아직은 전처리에 집중할 때라, Straitifed K-Fold 코드를 쓸 것 같지는 않지만 나중에 유용 할 것이라 생각 들고 1번 적용해 보고 싶다는 분이 계실 것 같아서 설명 드리고자 합니다.
순차는 train.py 코드 추가 부분 -> train.py 실행한 결과 -> inference.py 코드 추가 부분 -> inference.py 실행한 결과 -> 리더보드 결과 이렇게 말씀드리겠습니다.
train.py 실행 시, 적용 흐름 순으로 설명드리겠습니다.
if __name__ == '__main__': parser.add_argument("--k_fold", type=int, default=0, help='not k fold(defalut: 0)')
def main(args): if args.k_fold==0: load_dotenv(dotenv_path=args.dotenv_path) WANDB_AUTH_KEY = os.getenv('WANDB_AUTH_KEY') wandb.login(key=WANDB_AUTH_KEY) wandb.init( entity="klue-level2-nlp-02", project="Relation-Extraction", name=args.wandb_unique_tag, group=args.PLM) wandb.config.update(args) train(args) wandb.finish() else: train(args)
이렇게 k-fold 부분 안 할 시, 1개의 wandb 그래프를 k-fold 할 시, k개 만큼 wandb 그래프를 찍기 위해서 나눴습니다.
-> k-fold는 train 함수에 가면 wandb를 찍는 코드가 있습니다!
if args.k_fold: skf = StratifiedKFold(n_splits=args.k_fold, shuffle=True) for fold_idx, (train_idx, valid_idx) in enumerate(skf.split(train_dataset,train_label),1): train_lists, train_labels = train_dataset.loc[train_idx], list(np.array(train_label)[train_idx]) valid_lists, valid_labels = train_dataset.loc[valid_idx], list(np.array(train_label)[valid_idx]) tokenized_train = tokenized_dataset(train_lists, tokenizer) # UNK token count tokenized_valid = tokenized_dataset(valid_lists, tokenizer) # UNK token count RE_train_dataset = RE_Dataset(tokenized_train, train_labels) RE_dev_dataset = RE_Dataset(tokenized_valid, valid_labels) load_dotenv(dotenv_path=args.dotenv_path) WANDB_AUTH_KEY = os.getenv('WANDB_AUTH_KEY') wandb.login(key=WANDB_AUTH_KEY) wandb.init( entity="klue-level2-nlp-02", project="Relation-Extraction", name=args.wandb_unique_tag+str(fold_idx), group=args.PLM+"k_fold") wandb.config.update(args) train_model(args=args,RE_train_dataset=RE_train_dataset,RE_dev_dataset=RE_dev_dataset,fold_idx=fold_idx,dynamic_padding=dynamic_padding, tokenizer=tokenizer) wandb.finish()
StratifiedKFold를 적용해주고 fold마다 데이터를 나누고 wandb 적용하는 코드입니다!
아래는 wandb에서 찍히는 결과입니다.
else: # tokenizing dataset tokenized_train = tokenized_dataset( train_dataset, tokenizer) # UNK token count RE_train_dataset = RE_Dataset(tokenized_train, train_label, args.eval_ratio) train_model(args,RE_train_dataset,RE_dev_dataset=0,fold_idx=0, dynamic_padding=dynamic_padding ,tokenizer=tokenizer)
이 코드는 평소와 같습니다.
if args.k_fold: model_save_pth = os.path.join(args.save_dir, args.PLM.replace( '/', '-') + '-' + args.wandb_unique_tag.replace('/', '-') + "/" + str(fold_idx)) os.makedirs(model_save_pth, exist_ok=True) model.save_pretrained(model_save_pth) else: model_save_pth = os.path.join(args.save_dir, args.PLM.replace( '/', '-') + '-' + args.wandb_unique_tag.replace('/', '-')) os.makedirs(model_save_pth, exist_ok=True) model.save_pretrained(model_save_pth)
k_fold 시에, k개 만큼의 python_model.bin과 config.json이 생성됩니다!!
그래서 생각한 방법이 기존 모델 저장 하위 디렉토리가 생성되면 그 안에 k개 만큼의 폴더를 만들어 각각 저장하는 방식입니다.
k-fold 안 할 시, 저장 방법은 전과 같습니다.
위는 " train.py --epochs 3 --eval_flag False --k_fold 5 --PLM klue/roberta-base --wandb_unique_tag klue/roberta-base_k-fold-5" 실행 결과입니다.
parser.add_argument("--k_fold", type=int, default=0, help='not k fold(defalut: 0)')
train.py에 추가한 이유와 같습니다.
if args.k_fold: pred_answer, output_prob = inference_ensemble(model_dir, Re_test_dataset, device, is_roberta) # model에서 class 추론 pred_answer = np.mean(pred_answer,axis=0) pred_answer = np.argmax(pred_answer,axis=-1) pred_answer = num_to_label(pred_answer) output_prob = np.mean(output_prob,axis=0).tolist() else: model = AutoModelForSequenceClassification.from_pretrained(model_dir) model.parameters model.to(device) pred_answer, output_prob = inference(model, Re_test_dataset, device, is_roberta) # model에서 class 추론 pred_answer = num_to_label(pred_answer) # 숫자로 된 class를 원래 문자열 라벨로 변환.
k_fold 시, k_fold 안 할 때의 결과의 k배가 나오므로 최종 submission 파일의 "pred_label"에 넣을 입력은 k개의 결과를 합치고 평균 내어 가장 값이 큰 label을 선택하여 넣습니다!
그리고 최종 submission 파일의 "probs"에 넣을 입력은 k개의 결과를 합치고 평균 내서 그 값을 넣어줍니다!
def inference_ensemble(model_dir, tokenized_sent, device, is_roberta=False): dataloader = DataLoader(tokenized_sent, batch_size=16, shuffle=False) dirs = os.listdir(model_dir) dirs = sorted(dirs) final_output_prob=[] final_output_pred=[] for i in range(len(dirs)): model_d = os.path.abspath(os.path.join(model_dir, dirs[i])) model = AutoModelForSequenceClassification.from_pretrained(model_d) model.parameters model.to(device) model.eval() fold_prob=[] fold_pred=[] for i1, data in enumerate(tqdm(dataloader)): with torch.no_grad(): if is_roberta: outputs = model( input_ids=data['input_ids'].to(device), attention_mask=data['attention_mask'].to(device), ) else: outputs = model( input_ids=data['input_ids'].to(device), attention_mask=data['attention_mask'].to(device), token_type_ids=data['token_type_ids'].to(device) ) logits = outputs[0] prob = F.softmax(logits, dim=-1).detach().cpu().numpy() logits = logits.detach().cpu().numpy() fold_pred.extend(logits.tolist()) fold_prob.append(prob) final_output_pred.append(fold_pred) final_output_prob.append(np.concatenate(fold_prob, axis=0).tolist()) return final_output_pred, final_output_prob
위의 코드로 k개의 모델을 계산하여 결과를 합쳐줍니다!
터미널에서 실행한 결과입니다!
k-fold를 수행할 원하는 모델이 들어있는 파일을 선택합니다!
저는 k-fold 5로 설정하여 5번 계산하는 것을 볼 수 있습니다!
위의 형광색 부분이 k-fold 적용, 아래 형광색 부분이 k-fold X
두 실행 결과의 조건은 카카오톡에서 말씀드렸지만 1번 더 말씀드리겠습니다.
entity ner을 그대로 영어로 적용!
Not dynamic padding
k-fold 5
entity ner을 한글로 바꿔줌! (자세한 코드는 상하님이 적어주신 부분에 있습니다!)
dynamic padding 적용
5개의 그래프라 주변의 빨간 색깔은 오차를 표현합니다!
추가로 k-fold 뿐만 아니라 이 코드를 응용하여 다른 모델끼리의 앙상블(다른 architecture로 ensemble 시, 매우 큰 효과가 있을 것으로 예상됩니다!!)도 할 수 있도록 구현하겠습니다!
다시 전처리부터 하나씩 적용해 그나마 최적의 전처리 조합을 찾아보려 합니다!
-> Data augmentation도 같이 찾아보겠습니다.
The text was updated successfully, but these errors were encountered:
유석님은 신이야! k fold구현에 정리까지!!
Sorry, something went wrong.
아 그리고 설명 못 한 부분이 있는데 train.py에 train_model 함수 추가로 구현했습니다. 그 부분은 전 버전과 그대로 입니다! -> k_fold 일 때와 아닐 때 똑같이 사용하는 부분은 함수 1개로 묶었습니다!!
유석님은 신이야!
과찬이십니다 ㅠㅠ 그 범진님 코드 merge되면 k-fold부분 바로 고치겠습니다!
No branches or pull requests
아직은 전처리에 집중할 때라, Straitifed K-Fold 코드를 쓸 것 같지는 않지만 나중에 유용 할 것이라 생각 들고 1번 적용해 보고 싶다는 분이 계실 것 같아서 설명 드리고자 합니다.
순차는 train.py 코드 추가 부분 -> train.py 실행한 결과 -> inference.py 코드 추가 부분 -> inference.py 실행한 결과 -> 리더보드 결과 이렇게 말씀드리겠습니다.
1. train.py 코드 추가 부분
train.py 실행 시, 적용 흐름 순으로 설명드리겠습니다.
1-1. argument 추가 부분 (args.k_fold)
1-2. main 함수 wandb 적용 부분
이렇게 k-fold 부분 안 할 시, 1개의 wandb 그래프를 k-fold 할 시, k개 만큼 wandb 그래프를 찍기 위해서 나눴습니다.
-> k-fold는 train 함수에 가면 wandb를 찍는 코드가 있습니다!
1-3. train 함수의 stratified k-fold 적용 부분
StratifiedKFold를 적용해주고 fold마다 데이터를 나누고 wandb 적용하는 코드입니다!
아래는 wandb에서 찍히는 결과입니다.
1-4. train 함수의 k-fold 적용하지 않는 코드
이 코드는 평소와 같습니다.
1-5. train_model 함수 저장 경로 코드
k_fold 시에, k개 만큼의 python_model.bin과 config.json이 생성됩니다!!
그래서 생각한 방법이 기존 모델 저장 하위 디렉토리가 생성되면 그 안에 k개 만큼의 폴더를 만들어 각각 저장하는 방식입니다.
k-fold 안 할 시, 저장 방법은 전과 같습니다.
2. train.py 코드 실행 결과
위는 "
train.py --epochs 3 --eval_flag False --k_fold 5 --PLM klue/roberta-base --wandb_unique_tag klue/roberta-base_k-fold-5" 실행 결과입니다.
3. inference.py 코드 추가 부분
3-1. arguments 추가 부분(args.k_fold)
train.py에 추가한 이유와 같습니다.
3-2. main 함수 변경 부분
k_fold 시, k_fold 안 할 때의 결과의 k배가 나오므로 최종 submission 파일의 "pred_label"에 넣을 입력은 k개의 결과를 합치고 평균 내어 가장 값이 큰 label을 선택하여 넣습니다!
그리고 최종 submission 파일의 "probs"에 넣을 입력은 k개의 결과를 합치고 평균 내서 그 값을 넣어줍니다!
3-3. inference_ensemble 함수 추가
위의 코드로 k개의 모델을 계산하여 결과를 합쳐줍니다!
4. inference.py 코드 실행 결과
터미널에서 실행한 결과입니다!
k-fold를 수행할 원하는 모델이 들어있는 파일을 선택합니다!
저는 k-fold 5로 설정하여 5번 계산하는 것을 볼 수 있습니다!
5. 리더보드 제출 결과
위의 형광색 부분이 k-fold 적용, 아래 형광색 부분이 k-fold X
두 실행 결과의 조건은 카카오톡에서 말씀드렸지만 1번 더 말씀드리겠습니다.
entity ner을 그대로 영어로 적용!
Not dynamic padding
k-fold 5
entity ner을 한글로 바꿔줌! (자세한 코드는 상하님이 적어주신 부분에 있습니다!)
dynamic padding 적용
5개의 그래프라 주변의 빨간 색깔은 오차를 표현합니다!
6. 앞으로의 방향
추가로 k-fold 뿐만 아니라 이 코드를 응용하여 다른 모델끼리의 앙상블(다른 architecture로 ensemble 시, 매우 큰 효과가 있을 것으로 예상됩니다!!)도 할 수 있도록 구현하겠습니다!
7. 지금부터 제가 해보려고 하는 방향
다시 전처리부터 하나씩 적용해 그나마 최적의 전처리 조합을 찾아보려 합니다!
-> Data augmentation도 같이 찾아보겠습니다.
긴 글 읽어 주셔서 감사합니다! (코드는 우선 개인 branch에 넣겠습니다.)
코드는 저 개인 branch에 넣었고 inference.py와 train.py를 집중적으로 봐주세요!!
The text was updated successfully, but these errors were encountered: