GENZITSU / UsefulMaterials

34 stars 0 forks source link

almost weekly useful materials - 10/26 - #115

Open GENZITSU opened 1 year ago

GENZITSU commented 1 year ago

機械学習のプログラムをレビューする。

MLEやDSのコードをどのようにレビューしていくかについて述べられている資料。

各ステップでの期待アウトプット

スクリーンショット 2022-10-19 22 51 18

notebook レビュー方針

スクリーンショット 2022-10-19 22 51 29

スクリーンショット 2022-10-19 22 53 12

以下は私見

前処理 & 後処理部分をレビューする際の方針

スクリーンショット 2022-10-19 23 01 31

スクリーンショット 2022-10-19 23 01 53

以下は私見

モデル訓練部分をレビューする際の方針

スクリーンショット 2022-10-19 23 06 25

スクリーンショット 2022-10-19 23 06 33

以下は私見

コメント

とりあえずは検証段階とシステム導入時でレビュー観点をしっかり分ける方針にしておくことが重要っぽい。

出典

機械学習のプログラムをレビューする。

GENZITSU commented 1 year ago

メルペイが取り組む機械学習システムの品質保証

MLシステムの品質を高い水準で保つためのチェック観点が整理されている資料。

全体像

スクリーンショット 2022-10-19 23 18 56

データ観点

ポイント

  • 技術的、法的、倫理的な観点をクリアできるデータを継続的に正しく処 理し続ける
  • データの変化に気づき、臨機応変な対応ができる
  • 機械学習モデルの検証可能性を確保する

スクリーンショット 2022-10-19 23 19 49

スクリーンショット 2022-10-19 23 19 58

スクリーンショット 2022-10-19 23 20 07

スクリーンショット 2022-10-19 23 20 18

以下は私見

モデル観点

ポイント (トレードオフ)

  • 機械学習モデルの汎化性能、検証スキームの妥当性と多様性 etc
  • 再学習の容易さ、振る舞いの変化、ドリフトの検知と対応 etc

スクリーンショット 2022-10-19 23 27 05

スクリーンショット 2022-10-19 23 27 14

スクリーンショット 2022-10-19 23 27 23

以下は私見

システム観点

ポイント

  • 機械学習モデルの弱点をシステム全体で補う
  • 誤判別を減らす/誤判別したときに品質事故を起こさない
  • 規約との整合性や法的適合性をチェックする
  • システム全体の開発/運用の迅速性と正確性
  • モデル改善作業の効率化/容易化による改善サイクルの高速化
  • 事前に品質を作り込んだプロセスで運用自動化

スクリーンショット 2022-10-19 23 31 36

スクリーンショット 2022-10-19 23 31 44

その他の観点

スクリーンショット 2022-10-19 23 32 45

スクリーンショット 2022-10-19 23 32 54

ここでいうADRはアーキテクチャ決定レコードのことで、なぜそのような実装にしたかの意思決定ログを残すということ。

コメント

とても勉強になる。

出典

GENZITSU commented 1 year ago

SetFit: Efficient Few-Shot Learning Without Prompts

sentence transformersを用いて1クラス~20サンプル程度のFew-Shot分類を行えるSetFitというライブラリの紹介。

通常の大規模言語モデル x Few Shot Learningではprompラーニングなどが使われたりするが、この方法それがいらない。 学習済み sentence transformersを付与されているクラスによって距離学習でfine tuningした後に、クラス分類層を追加で学習することでFew-Shot分類を実現させている。

スクリーンショット 2022-10-20 23 27 27

以下のグラフのようにRoBERTAを再学習するアプローチよりも、かなり効率的に分類機を作成することが可能とのこと。

スクリーンショット 2022-10-20 23 29 05

sentence transformersのバックボーンにparaphrase-multilingual-mpnet-base-v2,8というマルチリンガルモデルを使った場合でもFew-Shot性能はかなり高い様子

スクリーンショット 2022-10-20 23 34 39

そしてその他の手法よりもかなり学習が早い。

スクリーンショット 2022-10-20 23 38 30

使い方は以下のようにとても簡単

# from https://huggingface.co/blog/setfit

# Load SetFit model from Hub
model = SetFitModel.from_pretrained("sentence-transformers/paraphrase-mpnet-base-v2")

# Create trainer
trainer = SetFitTrainer(
    model=model,
    train_dataset=train_ds,
    eval_dataset=test_ds,
    loss_class=CosineSimilarityLoss,
    batch_size=16,
    num_iterations=20, # Number of text pairs to generate for contrastive learning
    num_epochs=1 # Number of epochs to use for contrastive learning
)

# Train and evaluate!
trainer.train()
metrics = trainer.evaluate()

コメント

とても簡単に使えそうなのでクラス数がかなり大きいようなタスクで試してみたい。

sentence-transformersで扱えるモデルはここから探せるみたい。

また学習済みsentence-transformersではなく、学習済みのtransformesを使うのであればここをいじればいけるそう。

# https://github.com/huggingface/setfit/blob/main/src/setfit/modeling.py#L82

    @classmethod
    def _from_pretrained(
        cls,
        model_id: str,
        revision=None,
        cache_dir=None,
        force_download=None,
        proxies=None,
        resume_download=None,
        local_files_only=None,
        use_auth_token=None,
        multi_target_strategy=None,
        **model_kwargs,
    ):
        model_body = SentenceTransformer(model_id, cache_folder=cache_dir)

        if os.path.isdir(model_id) and MODEL_HEAD_NAME in os.listdir(model_id):
            model_head_file = os.path.join(model_id, MODEL_HEAD_NAME)

出典

GENZITSU commented 1 year ago

DigiFace-1M: 1 Million Digital Face Images for Face Recognition

3Dシミュレーターを用いて顔認識用の合成画像生成することで、プライバシーや社会的なバイアスを排除した学習データの生成を行っているマイクロソフトの論文。

公開されているデータセットはnon commercial use限定だが、画像のレンダリング方法や実データに近づけるためのAugmentation部分は参考になる。

スクリーンショット 2022-10-22 0 13 02

Augmentation部分

We first apply random horizontal flipping and cropping. Then, we apply two sets of augmentations - appearance and warping.

Appearance augmentation. We apply random Gaussian blur (p = 0.05) and Gaussian noise (p = 0.035). By applying the Gaussian blur along a random direction using an anisotropic covariance, we also simulate motion blur (p = 0.05). Brightness, contrast, hue and saturation are randomized with p = {0.15, 0.3, 0.1, 0.1}. Images are converted into grayscale with p = 0.01. Lastly, the image quality is randomized by downsampling-and-upsampling (p = 0.01) and JPEG compression (p = 0.05).

Warping augmentation. Warping is performed by randomly shifting the four corners of the image. Firstly, the aspect ratio is randomized with p = 0.1. Then, all imagesundergo random scaling, rotation and shift. Lastly, the four corners are shifted differently for additional distortion.

スクリーンショット 2022-10-22 0 13 43

結果など

スクリーンショット 2022-10-22 0 16 08

![Uploading スクリーンショット 2022-10-22 0.16.18.png…]()

コメント

メモ

出典

GENZITSU commented 1 year ago

How to Debug CPU and GPU memory usage and time consuming process

CPU/GPUの使用メモリと処理時間を測るこのとできるcontext managerの紹介

# from https://www.kaggle.com/competitions/foursquare-location-matching/discussion/336462

from contextlib import contextmanager
import math
import os
import subprocess
import sys
import time

import numpy as np
import psutil
import torch

def get_gpu_memory(cmd_path="nvidia-smi",
                   target_properties=("memory.total", "memory.used")):
    """
    ref: https://www.12-technology.com/2022/01/pythongpu.html
    Returns
    -------
    gpu_total : ndarray,  "memory.total"
    gpu_used: ndarray, "memory.used"
    """

    # format option
    format_option = "--format=csv,noheader,nounits"

    cmd = '%s --query-gpu=%s %s' % (cmd_path, ','.join(target_properties), format_option)

    # Command execution in sub-processes
    cmd_res = subprocess.check_output(cmd, shell=True)

    gpu_lines = cmd_res.decode().split('\n')[0].split(', ')

    gpu_total = int(gpu_lines[0]) / 1024
    gpu_used = int(gpu_lines[1]) / 1024

    gpu_total = np.round(gpu_used, 1)
    gpu_used = np.round(gpu_used, 1)
    return gpu_total, gpu_used

class Trace():
    cuda = torch.cuda.is_available()

    @contextmanager
    def timer(self, title):
        t0 = time.time()
        p = psutil.Process(os.getpid())
        cpu_m0 = p.memory_info().rss / 2. ** 30
        if self.cuda: gpu_m0 = get_gpu_memory()[0]
        yield
        cpu_m1 = p.memory_info().rss / 2. ** 30
        if self.cuda: gpu_m1 = get_gpu_memory()[0]

        cpu_delta = cpu_m1 - cpu_m0
        if self.cuda: gpu_delta = gpu_m1 - gpu_m0

        cpu_sign = '+' if cpu_delta >= 0 else '-'
        cpu_delta = math.fabs(cpu_delta)

        if self.cuda: gpu_sign = '+' if gpu_delta >= 0 else '-'
        if self.cuda: gpu_delta = math.fabs(gpu_delta)

        cpu_message = f'{cpu_m1:.1f}GB({cpu_sign}{cpu_delta:.1f}GB)'
        if self.cuda: gpu_message = f'{gpu_m1:.1f}GB({gpu_sign}{gpu_delta:.1f}GB)'

        if self.cuda:
            message = f"[cpu: {cpu_message}, gpu: {gpu_message}: {time.time() - t0:.1f}sec] {title} "
        else:
            message = f"[cpu: {cpu_message}: {time.time() - t0:.1f}sec] {title} "

        print(message, file=sys.stderr)

スクリーンショット 2022-10-24 21 53 10

コメント

memory_profilerを使うこともできるが、こちらはスクリプト化して実行して初めて計測できるので、notebook中で検証しながら使えるのこちらの方が便利かも

出典

How to Debug CPU and GPU memory usage and time consuming process

GENZITSU commented 1 year ago

【インターンレポート】大規模Vision&Languageモデリングに向けたLAION-5Bのデータ分析と大規模データ整備システムのプロトタイプ検討

text2imageモデル開発を念頭においたLAION-5Bデータのクレンジング処理およびクレジング処理の高速化に取り組んだ結果が綴られているブログ。

取り組み内容

  • LAION-5Bデータセットの分析を通したフィルタリング方法の検討
    • どのようなデータが元データに含まれるかを分析すること
    • フィルタリングとして取り除かないといけないもの
      • 製品にした場合に不適切なものを生成する可能性があるもの
      • 習に適してない、低品質の画像やテキストが含まれるもの
  • 高速な大規模なデータセットを洗浄するシステムの構築

LAION-5Bデータとは

50億のテキストと画像のペアが含まれたオープンデータだがクレンジング必要なやつ

研究と技術開発の民主化を目的に画像とテキストのペアデータで構成されている大規模でオープンなデータセット 約50億サンプルを超えるインターネット上から取得可能な画像と多言語テキストのペアデータで構成されているが、半機械的に収集と整備が行われているため、一般社会通念上あるいは倫理的に適さない画像や表現のテキストが含まれていたり、画像とテキストのペアが必ずしももっともらしいペアと言えない状態のサンプルが含まれていたりします。そのため、商用利用や企業での技術開発利用には、一定の洗浄処理が求められています。

LAIONデータに対する分析結果

前提

LAION-5BデータセットのEnglishサンプル群の約20億サンプルからランダムサンプリングした約1,400万件の(txt,img)ペアデータを用いました。

分析①: NSFWタグがついているものは本当に使わない方がいいのか?→ FalseとUNLIKELYを用いるのが良さげ

LAION-5Bには、Not Safe For Work(NSFW)という職場で見るのには適さない画像を意味するラベルが付与されています。これはNSFWを認識する画像分類モデルによって付けられたものになります。 NSFWラベルについては、1,076種類ものラベルを確認できました。しかしながら、そのほとんどは意味をなさない無意味な文字列や数字のみのラベルが見受けられました。またそれらのタグを確認したが特に規則性などを確認されませんでした。そのため本件では頻度上位の4種ラベル(UNLIKELY, UNSURE, NSFW, False)とそれ以外(others)で分類

スクリーンショット 2022-10-24 22 34 21

FalseとUNLIKELYでは明らかに安全な画像が多く見られました。UNSUREになると、人間が写っている画像の割合が増え、中には肌の露出が多いものが見て取れます。NSFWの画像に関しては、約30%ほどが不適切な画像で、それ以外は比較的安全なものが見受けられました。不適切な画像を含めないために、厳しくラベルが付けられていることがわかります。

分析② テキスト側に問題がないか? → 名刺比率が高すぎるのはやばそう

スクリーンショット 2022-10-24 22 39 50

スクリーンショット 2022-10-24 22 40 00

フィルタリング処理の実装

主なボトルネック

1,400万件の場合ではRAMにデータを全て展開出来ないため、ファイルバッファなどでデータのやり取り発生し、データ処理に遅延が生じやすくなります。データ特徴量の保存に対して最適なデータ構造を用いていなかったため、単純な処理であっても計算時間がかかっていました。

対策①: HashMapの利用と処理の共通化

各データ洗浄の関数で共通して用いるデータの特徴量は予め事前に計算しておき、データ洗浄過程で何度も同じ手続きが発生することを抑制することで計算回数を減らし、計算時間を小さくしました。 データ構造として単純にリストで管理していた特徴量を辞書型(HashMap)で管理できる形に変えることで計算量の削減をしました。 本件のデータ洗浄はデータセットの各サンプルに対して実施されるため、サンプル間の依存関係や特徴量はデータ洗浄には無関係であるため、データセットを分割し並列処理を行いました。

→ 今回は、1,400万件のデータを100万件ずつに分割することで10個の並列ジョブで進められ、とても高速に処理ができるようになりました。

対策②: 消費RAMの抑制

今回のデータサイズは非常に大きいため、メモリに全てのデータを展開することは困難 → PandasデータフレームからJsonデータを用いる方法に変更し、必要な分だけデータをメモリに展開 → データ洗浄 → ファイル書き込み、という逐次処理に変更

最終的なシステム

スクリーンショット 2022-10-24 22 46 06

最適化する前では1,400万件の処理をするのに、422,190秒かかっていたものが、上記の改善を行うことで26,600秒で処理を終えることが可能になりました。約16倍の高速化を可能にしました。

コメント

LIAON5Bデータセット気になっていたが、使うには諸々の工夫やフィルタが必要なことが確認できて勉強になった。

出典

【インターンレポート】大規模Vision&Languageモデリングに向けたLAION-5Bのデータ分析と大規模データ整備システムのプロトタイプ検討

GENZITSU commented 1 year ago

Pythonでかな漢字変換 mozcpy の紹介

Mozc辞書 + MeCab でかな漢字変換をしてくれるライブラリの紹介

利用方法

# from https://qiita.com/yukinoi/items/000f6fe4560799378dc0

import mozcpy

converter = mozcpy.Converter()

converter.convert('まほうしょうじょ')
# => '魔法少女'
converter.convert('まほうしょうじょ', n_best=10)
# => ['魔法少女', '魔法消除', '魔法省所', '魔法小所', '魔法昇叙', '魔砲少女', 'マホウ少女', '魔法証所', '魔法賞所']

converter.convert_wakati('もうなにもこわくない')
# => 'もう 何 も 怖く ない'
converter.convert_wakati('もうなにもこわくない', n_best=3)
# => ['もう 何 も 怖く ない', 'もう 何 も こわく ない', 'もう 何 も 恐く ない']

コメント

何かに使えるやもしれないのでメモ

出典

Pythonでかな漢字変換 mozcpy の紹介

GENZITSU commented 1 year ago

Pandas卒業?大規模データを様々なパッケージで高速処理してみる

テーブル操作系ライブラリ Pandas / Dask / Vaex / Pysparkの各種操作にかかる実行時間および消費メモリを比較しているスライド

以下スライドの切り抜き

それぞれのライブラリについて

スクリーンショット 2022-10-24 23 49 03

スクリーンショット 2022-10-24 23 49 11

スクリーンショット 2022-10-24 23 49 19

使用データについて

スクリーンショット 2022-10-24 23 49 59

検証①

スクリーンショット 2022-10-24 23 50 32

スクリーンショット 2022-10-24 23 50 42

検証②

スクリーンショット 2022-10-24 23 51 25

スクリーンショット 2022-10-24 23 52 18

スクリーンショット 2022-10-24 23 52 25   スクリーンショット 2022-10-24 23 52 33

スクリーンショット 2022-10-24 23 52 41

スクリーンショット 2022-10-24 23 52 50

スクリーンショット 2022-10-24 23 52 57

検証③ テーブル結合

スクリーンショット 2022-10-24 23 57 13

スクリーンショット 2022-10-24 23 57 35

スクリーンショット 2022-10-24 23 57 44

スクリーンショット 2022-10-24 23 57 52

スクリーンショット 2022-10-24 23 58 00

スクリーンショット 2022-10-24 23 58 10

コメント

利用する操作によって優劣が逆転するがVaexが処理時間的には優秀そう。

それぞれのライブラリの利用方法もざっくりしれて勉強になった。

出典

Pandas卒業?大規模データを様々なパッケージで高速処理してみる