Skip to content
SHIN総研

SHIN総研

科学的アプローチで人生をハックする

Menu
  • DataScience and AI
  • Career
  • LifeHack
  • Profile
  • Privacy Policy
Menu

Kaggle Dataset Upload 自動化

Posted on 2021年1月16日2021年1月16日 by SHIN

Contents

  • 1 code competitionでのKaggle API を使ったデータのアップロード
  • 2 フォルダ構成
  • 3 データメタ情報のJSONファイルと通常のAPIコマンドによるアップロード法
  • 4 モデル訓練パラメータのyamlファイル
  • 5 自動データアップロードスクリプト

code competitionでのKaggle API を使ったデータのアップロード

ここ1,2年、kaggleではcode competitionが増えています。code competitionとはkaggleのnotebook環境を使って予測ファイルを投稿することが求められるコンペで、自前の環境で訓練したモデルのパラメータデータをkaggle datasetにアップロードし、推論のみをnotebookで実施することが許されていることが多いです。この場合kaggle datasetへデータをアップロードすることが頻繁になります。

そこで、kaggleのAPIを使うことで、ウェブUIから手動でアップロードするより効率化することが可能です。

一方で実際にAPIを使ってみると、予めアップロードするデータのメタ情報を含むJSONファイルを用意しなければならない上に、データのあるディレクトリ、データの詳細コメント等をコマンドの引数として用意する必要があり、シェルスクリプトである程度自動化したとしても、意外にシェルスクリプトの編集が面倒です。おまけに編集忘れで意図しないファイルをアップロードしてしまうことが起きたりします。

この記事ではモデルの訓練をする際のパラメーター条件と同期を取りながら、自動でAPIコマンドを実施し、データアップロードに必要なJSONファイルの自動作成をするpythonスクリプトを紹介します。

フォルダ構成

前提として以下のようなフォルダ構成にしています。src/scripsに配置してあるpythonスクリプトを実行します。

src
|–logs:各種ログを格納するフォルダ
|–scripts:.pyスクリプトの格納フォルダ、ここでファイルを実行する
 |–upload_model.py:データアップロード実行ファイル
|–model:訓練済みモデルの重みパラメータの格納フォルダ
 |–model_path:アップロード対象の訓練済みモデルのパラメータのフォルダ
  |–autoencoder_fold_ho_48.pth:アップロード対象のモデルのパラメータデータ
  |–dataset-metadata.json:データメタ情報のJSON

データメタ情報のJSONファイルと通常のAPIコマンドによるアップロード法

普通にコマンドラインから、所定のフォルダにあるモデルパラメータデータをkaggle datasetにアップロードするためには、データに関するメタ上のJSONファイルが必要で、例えば以下のようなものです。見てわかるとおり、データの名称、メタ情報をアップロードするモデルパラメータの訓練条件を同期させて編集するのは大変です。

{"title": "データセット名", 
"id": "kaggleアカウント/データセット名", "subtitle": "", "description": "", "isPrivate": true, 
"licenses": [{"name": "unknown"}], "keywords": [], "collaborators": [], 
"data": [{"description": "early stopping patiance 20--> 40; base EXT012", 
    "name": "autoencoder_fold_ho_48.pth", 
    "totalBytes": 4136646, 
    "columns": []}]}

そこで、以下のようなkaggle コマンドを実行しますが、model_path や-m以降のコメントは都度の編集が面倒でミスしやすいです。

kaggle datasets version -p  ../models/model_path -m "{モデル名称などのバージョンに関するコメント}"

モデル訓練パラメータのyamlファイル

scriptsフォルダ内には、モデルの訓練用パラメータのparameters.yamlが格納されており、例えば以下の内容になっているとします。ここの詳細説明はしませんが、モデルを訓練する上で必要なパラメータが予め設定されており、実験をするときにこのファイルを編集しながら、様々な条件で試行していきます。

EXT : '013'
TRAINING : True
USE_FINETUNE : True
FOLDS : 5
GROUP_GAP : 20
SEED : 66
INPUTPATH : ../../input
NUM_EPOCH : 300
BATCH_SIZE : 320
PATIANCE : 40
LR : 0.0005
MDL_PATH : ../models
MDL_NAME : autoencoder
VER : ho_base
THRESHOLD : 0
DATAVER : '02'
COMMENT: 'early stopping patiance 20--> 40; base EXT012'

次に、用意が面倒なJSONの自動作成と、parameters.yamlの内容と同期したkaggle APIコマンドの自動実行のpythonスクリプトです。
いくつか特徴について説明します。


  • loggerを使用して、コンソールに標準出力させつつ、src/logsにログファイルを出力しています。
  • yamlファイルにあるパラメータやコメントなどをアップロードするデータのメタ情報のJSONファイルで必要に応じて反映しています。
  • yamlファイルにあるパラメータやコメントなどを反映して実行するkaggle APIコマンドを自動生成し、subprocessを使って実行します。

自動データアップロードスクリプト

import glob
import os
import json
import gc
import sys
import time
import yaml
import argparse
import logging
from tqdm import tqdm
import subprocess
import torch
print(torch.__version__)

def get_args():
    # 引数の導入
    parser = argparse.ArgumentParser(description='Cross Validation Train')
    parser.add_argument('config_path', type=str, help='Setting parameter(.yaml)')
    args = parser.parse_args()
    return args

def upload_to_kaggle(
                     
                     title: str, 
                     k_id: str,  
                     path: str, 
                     comments: str,
                     update:bool,
                     logger=None,
                     extension = '.pth',
                     subtitle='', 
                     description="",
                     isPrivate = True,
                     licenses = "unknown" ,
                     keywords = [],
                     collaborators = []
                     ):
    '''
    >> upload_to_kaggle(title, k_id, path,  comments, update)
    
    Arguments
    =========
     title: the title of your dataset.
     k_id: kaggle account id.
     path: non-default string argument of the file path of the data to be uploaded.
     comments:non-default string argument of the comment or the version about your upload.
     logger: logger object if you use logging, default is None.
     extension: the file extension of model weight files, default is ".pth"
     subtitle: the subtitle of your dataset, default is empty string.
     description: dataset description, default is empty string.
     isPrivate: boolean to show wheather to make the data public, default is True.
     licenses = the licenses description, default is "unkown"; must be one of /
     ['CC0-1.0', 'CC-BY-SA-4.0', 'GPL-2.0', 'ODbL-1.0', 'CC-BY-NC-SA-4.0', 'unknown', 'DbCL-1.0', 'CC-BY-SA-3.0', 'copyright-authors', 'other', 'reddit-api', 'world-bank'] .
     keywords : the list of keywords about the dataset, default is empty list.
     collaborators: the list of dataset collaborators, default is empty list.
   '''
    model_list = glob.glob(path+f'/*{extension}')
    if len(model_list) == 0:
        raise FileExistsError('File does not exist, check the file extention is correct \
        or the file directory exist.')
    
    if path[-1] == '/':
        raise ValueError('Please remove the backslash in the end of the path')
 #JSONファイルの作成    
    data_json =  {
        "title": title,
        "id": f"{k_id}/{title}",
        "subtitle": subtitle,
        "description": description,
        "isPrivate": isPrivate,
        "licenses": [
            {
                "name": licenses
            }
        ],
        "keywords": [],
        "collaborators": [],
        "data": [

        ]
    }
    #JSONファイルのdata部分の更新  
    data_list = []
    for mdl in model_list:
        mdl_nm = mdl.replace(path+'/', '')
        mdl_size = os.path.getsize(mdl) 
        data_dict = {
            "description": comments,
            "name": mdl_nm,
            "totalBytes": mdl_size,
            "columns": []
        }
        data_list.append(data_dict)
    data_json['data'] = data_list

    
    with open(path+'/dataset-metadata.json', 'w') as f:
        json.dump(data_json, f)
    
 #データセットを新規で作るときのkaggle APIコマンド
    script0 = ['kaggle',  'datasets', 'create', '-p', f'{path}' , '-m' , f'\"{comments}\"']
 #データセットを更新するときのkaggle APIコマンド
    script1 = ['kaggle',  'datasets', 'version', '-p', f'{path}' , '-m' , f'\"{comments}\"']


    if logger:    
        logger.info(data_json)
        
        if update:
            logger.info(script1)
            logger.info(subprocess.check_output(script1))
        else:
            logger.info(script0)
            logger.info(script1)
            logger.info(subprocess.check_output(script0))
            logger.info(subprocess.check_output(script1))
            
    else:
        print(data_json)
        if update:
            print(script1)
            print(subprocess.check_output(script1))
        else:
            print(script0)
            print(script1)
            print(subprocess.check_output(script0))
            print(subprocess.check_output(script1))

def main():
 #コマンドラインの引数からパラメータのあるyamlファイルを読み込む
    args = get_args()
    with open(args.config_path, 'r') as f:
        config = yaml.safe_load(f)

    #yamlファイルにあるパラメータを変数に代入
    EXT = config['EXT']
    TRAINING = config['TRAINING']
    USE_FINETUNE = config['USE_FINETUNE']     
    FOLDS = config['FOLDS']
    GROUP_GAP = config['GROUP_GAP']
    SEED = config['SEED']
    INPUTPATH = config['INPUTPATH']
    NUM_EPOCH = config['NUM_EPOCH']
    BATCH_SIZE = config['BATCH_SIZE']
    PATIANCE = config['PATIANCE']
    LR =config['LR']
    DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(DEVICE)
    MDL_PATH  =config['MDL_PATH']
    MDL_NAME =config['MDL_NAME']
    VER = config['VER']
    THRESHOLD = config['THRESHOLD']
    COMMENT = config['COMMENT']
    
 #logger関連の定義
    format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    logging.basicConfig(level = logging.INFO,format=format_str, filename=f'../logs/upload_log_{MDL_NAME}_{VER}_{EXT}.log')
    logger = logging.getLogger('Log')
    
    ##https://ryoz001.com/1154.html
    # コンソール画面用ハンドラー設定
    # ハンドラーのログレベルを設定する (INFO以上を出力する)
    consoleHandler = logging.StreamHandler()
    consoleHandler.setLevel(logging.INFO)
    # logger と コンソール用ハンドラーの関連付け
    logger.addHandler(consoleHandler)
    logger.info(config)
    logger.info(sys.argv)
    VER = (VER + '_' + EXT)
    model_path = f'{MDL_PATH}/{MDL_NAME}_{VER}'
    logger.info(model_path)
    
    title = "データセット名"
    k_id = "kaggleアカウント"
    path = model_path
    comments = VER
    update = True
    upload_to_kaggle(title, k_id, path,  comments, update,logger=logger)
    
    
if __name__ == "__main__":
    main()

そして以下を実行することで、自動でparameters.yamlに基づいて

python upload_model.py parameters.yaml
  • 訓練されたモデルのパラメータデータのアップロード
  • アップロードように必要なメタ情報JSONの出力
  • ログと標準画面出力

結果として上記のことが実行されます。

1つ星2つ星3つ星4つ星5つ星 (まだ評価がありません)
読み込み中...

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

最近の投稿

  • プログラムマネジャー入門:ビジネスの新境地を切り拓くキャリアへの道
  • クレディセゾン ファイナンシャルプランナー アドバイスサービスは要注意
  • 転職したいと思った時にあえて残ってみる
  • 自作UbuntuマシンにWindowsノートブックからSSHでリモート接続して計算を回せるようにする
  • データサイエンティストにとって重要なMLOps

最近のコメント

  • かたちのない資産を意識すると見える世界が変わった に 生命保険の選び方 vol.1 基本的な考え方と死亡保険 – SHIN総研 より

アーカイブ

  • 2023年4月
  • 2021年10月
  • 2021年9月
  • 2021年1月
  • 2020年12月
  • 2020年10月
  • 2020年9月

カテゴリー

  • Career
  • DataScience and AI
  • LifeHack

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Ratings

  • Ubuntu 20.04 LTSでのPPPoE接続方法 2 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 5 (5.00 / 5)
  • Profile 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • 生命保険の選び方 vol.1 基本的な考え方と死亡保険 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • かたちのない資産を意識すると見える世界が変わった 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • ついで「Office」やめませんか 1 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 5 (3.00 / 5)
  • クレディセゾン ファイナンシャルプランナー アドバイスサービスは要注意 4 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 5 (2.25 / 5)
  • Kaggle Dataset Upload 自動化 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • IT企業2社データサイエンス系転職活動振り返り 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • プログラムマネジャー入門:ビジネスの新境地を切り拓くキャリアへの道 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • 実験計画法と分散分析 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)

Ratings

  • Ubuntu 20.04 LTSでのPPPoE接続方法 2 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 52 票, 平均: 5.00 / 5 (5.00 / 5)
  • Profile 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • 生命保険の選び方 vol.1 基本的な考え方と死亡保険 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • かたちのない資産を意識すると見える世界が変わった 1 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 51 票, 平均: 5.00 / 5 (5.00 / 5)
  • ついで「Office」やめませんか 1 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 51 票, 平均: 3.00 / 5 (3.00 / 5)
  • クレディセゾン ファイナンシャルプランナー アドバイスサービスは要注意 4 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 54 票, 平均: 2.25 / 5 (2.25 / 5)
  • Kaggle Dataset Upload 自動化 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • IT企業2社データサイエンス系転職活動振り返り 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • プログラムマネジャー入門:ビジネスの新境地を切り拓くキャリアへの道 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
  • 実験計画法と分散分析 0 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 50 票, 平均: 0.00 / 5 (0.00 / 5)
©2025 SHIN総研 | Built using WordPress and Responsive Blogily theme by Superb