Open GENZITSU opened 1 year ago
MLシステムの品質を高い水準で保つためのチェック観点が整理されている資料。
ポイント
- 技術的、法的、倫理的な観点をクリアできるデータを継続的に正しく処 理し続ける
- データの変化に気づき、臨機応変な対応ができる
- 機械学習モデルの検証可能性を確保する
以下は私見
ポイント (トレードオフ)
- 機械学習モデルの汎化性能、検証スキームの妥当性と多様性 etc
- 再学習の容易さ、振る舞いの変化、ドリフトの検知と対応 etc
以下は私見
ポイント
- 機械学習モデルの弱点をシステム全体で補う
- 誤判別を減らす/誤判別したときに品質事故を起こさない
- 規約との整合性や法的適合性をチェックする
- システム全体の開発/運用の迅速性と正確性
- モデル改善作業の効率化/容易化による改善サイクルの高速化
- 事前に品質を作り込んだプロセスで運用自動化
ここでいうADRはアーキテクチャ決定レコードのことで、なぜそのような実装にしたかの意思決定ログを残すということ。
とても勉強になる。
sentence transformersを用いて1クラス~20サンプル程度のFew-Shot分類を行えるSetFitというライブラリの紹介。
通常の大規模言語モデル x Few Shot Learningではprompラーニングなどが使われたりするが、この方法それがいらない。 学習済み sentence transformersを付与されているクラスによって距離学習でfine tuningした後に、クラス分類層を追加で学習することでFew-Shot分類を実現させている。
以下のグラフのようにRoBERTAを再学習するアプローチよりも、かなり効率的に分類機を作成することが可能とのこと。
sentence transformersのバックボーンにparaphrase-multilingual-mpnet-base-v2,8
というマルチリンガルモデルを使った場合でもFew-Shot性能はかなり高い様子
そしてその他の手法よりもかなり学習が早い。
使い方は以下のようにとても簡単
# 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)
3Dシミュレーターを用いて顔認識用の合成画像生成することで、プライバシーや社会的なバイアスを排除した学習データの生成を行っているマイクロソフトの論文。
公開されているデータセットはnon commercial use限定だが、画像のレンダリング方法や実データに近づけるためのAugmentation部分は参考になる。
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.
結果など
![Uploading スクリーンショット 2022-10-22 0.16.18.png…]()
メモ
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)
memory_profilerを使うこともできるが、こちらはスクリプト化して実行して初めて計測できるので、notebook中で検証しながら使えるのこちらの方が便利かも
How to Debug CPU and GPU memory usage and time consuming process
text2imageモデル開発を念頭においたLAION-5Bデータのクレンジング処理およびクレジング処理の高速化に取り組んだ結果が綴られているブログ。
- LAION-5Bデータセットの分析を通したフィルタリング方法の検討
- どのようなデータが元データに含まれるかを分析すること
- フィルタリングとして取り除かないといけないもの
- 製品にした場合に不適切なものを生成する可能性があるもの
- 習に適してない、低品質の画像やテキストが含まれるもの
- 高速な大規模なデータセットを洗浄するシステムの構築
50億のテキストと画像のペアが含まれたオープンデータだがクレンジング必要なやつ
研究と技術開発の民主化を目的に画像とテキストのペアデータで構成されている大規模でオープンなデータセット 約50億サンプルを超えるインターネット上から取得可能な画像と多言語テキストのペアデータで構成されているが、半機械的に収集と整備が行われているため、一般社会通念上あるいは倫理的に適さない画像や表現のテキストが含まれていたり、画像とテキストのペアが必ずしももっともらしいペアと言えない状態のサンプルが含まれていたりします。そのため、商用利用や企業での技術開発利用には、一定の洗浄処理が求められています。
前提
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)で分類
FalseとUNLIKELYでは明らかに安全な画像が多く見られました。UNSUREになると、人間が写っている画像の割合が増え、中には肌の露出が多いものが見て取れます。NSFWの画像に関しては、約30%ほどが不適切な画像で、それ以外は比較的安全なものが見受けられました。不適切な画像を含めないために、厳しくラベルが付けられていることがわかります。
分析② テキスト側に問題がないか? → 名刺比率が高すぎるのはやばそう
主なボトルネック
1,400万件の場合ではRAMにデータを全て展開出来ないため、ファイルバッファなどでデータのやり取り発生し、データ処理に遅延が生じやすくなります。データ特徴量の保存に対して最適なデータ構造を用いていなかったため、単純な処理であっても計算時間がかかっていました。
対策①: HashMapの利用と処理の共通化
各データ洗浄の関数で共通して用いるデータの特徴量は予め事前に計算しておき、データ洗浄過程で何度も同じ手続きが発生することを抑制することで計算回数を減らし、計算時間を小さくしました。 データ構造として単純にリストで管理していた特徴量を辞書型(HashMap)で管理できる形に変えることで計算量の削減をしました。 本件のデータ洗浄はデータセットの各サンプルに対して実施されるため、サンプル間の依存関係や特徴量はデータ洗浄には無関係であるため、データセットを分割し並列処理を行いました。
→ 今回は、1,400万件のデータを100万件ずつに分割することで10個の並列ジョブで進められ、とても高速に処理ができるようになりました。
対策②: 消費RAMの抑制
今回のデータサイズは非常に大きいため、メモリに全てのデータを展開することは困難 → PandasデータフレームからJsonデータを用いる方法に変更し、必要な分だけデータをメモリに展開 → データ洗浄 → ファイル書き込み、という逐次処理に変更
最適化する前では1,400万件の処理をするのに、422,190秒かかっていたものが、上記の改善を行うことで26,600秒で処理を終えることが可能になりました。約16倍の高速化を可能にしました。
LIAON5Bデータセット気になっていたが、使うには諸々の工夫やフィルタが必要なことが確認できて勉強になった。
【インターンレポート】大規模Vision&Languageモデリングに向けたLAION-5Bのデータ分析と大規模データ整備システムのプロトタイプ検討
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)
# => ['もう 何 も 怖く ない', 'もう 何 も こわく ない', 'もう 何 も 恐く ない']
何かに使えるやもしれないのでメモ
テーブル操作系ライブラリ Pandas / Dask / Vaex / Pysparkの各種操作にかかる実行時間および消費メモリを比較しているスライド
以下スライドの切り抜き
利用する操作によって優劣が逆転するがVaexが処理時間的には優秀そう。
それぞれのライブラリの利用方法もざっくりしれて勉強になった。
機械学習のプログラムをレビューする。
MLEやDSのコードをどのようにレビューしていくかについて述べられている資料。
各ステップでの期待アウトプット
notebook レビュー方針
以下は私見
前処理 & 後処理部分をレビューする際の方針
以下は私見
モデル訓練部分をレビューする際の方針
以下は私見
コメント
とりあえずは検証段階とシステム導入時でレビュー観点をしっかり分ける方針にしておくことが重要っぽい。
出典
機械学習のプログラムをレビューする。