2021年5月29日土曜日

BERTをやってみた。

最近ブログを更新していなかった理由の一つに、「せっかくAIの論文を読んで実装したのに動かなかった。」というのがあります。

BERTが全然動かなかったのです。

BERTは「アマゾンはどこにありますか」のようにAIに言葉で質問をすると「南アメリカです。」のように答えてくれるプログラムらしいです。

論文

https://qiita.com/omiita/items/72998858efc19a368e50


すげーなー。自然言語処理の王様らしいです。

ほんとうにこんなことができるのか、おじさんさっそくビルドしてみました。


GoogleがTensorFlowでBERTのC++実装を公開していたので、3月にビルドしてみました。

でもなぜかC++バージョンは動かない。何日もかけてビルドしたのに。


昨日久しぶりにGitHubをみたら、なんかバグが治ったっぽいので、C++のBERTを今日一日かけてWindowsで移植してみました。


昨日はPyTorch、今日はTensorFlow。

毎日いろんな機械学習フレームワークをビルドしないといけないです。



まず、C++のBertを取ってきます。

https://www.tensorflow.org/lite/inference_with_metadata/task_library/bert_question_answerer



そして、ソースを一つ一つWindowsで動くように直していきます。

さらに g++ *.ccだけでビルドして動くように、すべてのライブラリをディレクトリ構造がないようにフラットにしてビルドします。

直すこと数時間。

世界初!やっとTensorFlowのC++のBertがWindowsで動くようになりました。


ソース一式はこちら

https://drive.google.com/file/d/1qFM-W0ZRqTV8pri4tB1s3Bsez8fXyQOG/view?usp=sharing



入力

-----------------------------

bert_question_answerer_demo -- \

 --model_path=mobilebert.tflite \

 --question="Where is Amazon rainforest?" \

 --context="The Amazon rainforest, alternatively, the Amazon Jungle, also known in \

English as Amazonia, is a moist broadleaf tropical rainforest in the Amazon \

biome that covers most of the Amazon basin of South America. This basin \

encompasses 7,000,000 km2 (2,700,000 sq mi), of which \

5,500,000 km2 (2,100,000 sq mi) are covered by the rainforest. This region \

includes territory belonging to nine nations."

-----------------------------


デフォルトの実装が英語なのですが、日本語で学習させれば、きちんと日本語で答えられるようになるらしいです。

こんな感じで文章と質問を与えると答えを表示してくれます。



答え

-----------------------------

Time cost to answer the input question on CPU: 36807.1 ms

answer[0]: 'most of the Amazon basin of South America.'

    logit: '8.79093, start_index: 39, end_index: 46

answer[1]: 'Amazon basin of South America.'

    logit: '7.74646, start_index: 42, end_index: 46

answer[2]: 'the Amazon basin of South America.'

    logit: '7.58969, start_index: 41, end_index: 46

answer[3]: 'Amazon biome that covers most of the Amazon basin of South America.'

    logit: '7.56741, start_index: 34, end_index: 46

answer[4]: 'the Amazon biome that covers most of the Amazon basin of South America.'

    logit: '7.17913, start_index: 33, end_index: 46

-----------------------------



日本語で言うと、こんな感じでしょうか。


コンテキスト:「アマゾン熱帯雨林、または英語でアマゾニアとしても知られているアマゾンジャングルは、南アメリカのアマゾン盆地のほとんどをカバーするアマゾンバイオームの湿った広葉樹熱帯雨林です。この盆地は7,000,000 km2(2,700,000平方マイル)、そのうち5,500,000 km2(2,100,000 sq mi)が熱帯雨林に覆われています。この地域には、9か国に属する地域が含まれています。」


質問:「アマゾンの熱帯雨林はどこにありますか?」

答え:「アマゾンの大半は南アメリカにあります。」


BERTすごいねぇ。

文章をきちんと理解している。。。。

これ「やじまは悪い人ですか?」とか自分の嫌いな人の名前とかいろんな文章を入力して遊びたくなりますね。



2021年5月28日金曜日

StyleGANをやってみた

 おじさん、絵とか写真をコンピュータのAIが勝手に作ってくれる、StyleGANを勉強してみました。

https://qiita.com/woodyZootopia/items/10e7e7cf96bfe1249f66


まえから自分で動かしてみたかったんだよね。


このStyleGANを使うと、今話題の新垣結衣の画像も生成できちゃうらしい。

http://cedro3.com/ai/search-for-yui/

なんという知識とGPUの無駄遣い。

StyleGANのベクトル空間に我々人類は住んでるんだね。


このStyleGANですが、昔はNVIDIAのGPUでしか動かなかったんですが、最近はCPUだけでも動くみたい。

さらに、Pytorchの学習済みのデータをC++で簡単に利用できるように変換してくれる、tensor4なるものがあって、それを使うとC++でもStyleGANを動かせます。

https://github.com/podgorskiy/tensor4


ここに、本当に動くのかあやしいStyleGANのC++実装があるのですが、これを修正して、きちんとおじさんのGPUがないWindowsで動くようにしてみました。

https://github.com/podgorskiy/StyleGANCpp


このtensor4を作った人すごいね。

他になんのライブラリも必要なく、StyleGANを数個のファイルだけでC++で動かすことができます。10分くらいでStyleGANをつくれちゃいます。


これはかなり面白い。

---------------

#include "tensor4.h"

#include "StyleGAN.h"

#include "numpy-like-randn.h"


#define STB_IMAGE_WRITE_IMPLEMENTATION

#include "stb_image_write.h"



int main()

{

int layers = 9;


// if loading compressed

//auto model = StyleGANLoad("StyleGAN.ct4", layers);


// if loading original

auto model = StyleGANLoad("StyleGAN.t4", layers, false);


{

auto rs = numpy_like::RandomState(4);

auto z = GenZ(rs);

auto w = GenW(model, z);

auto w_truncated = (w - t4::Unsqueeze<0>(model.dlatent_avg)) * 0.7f + t4::Unsqueeze<0>(model.dlatent_avg);

t4::tensor4f x;

t4::tensor3f img;

t4::tensor3f img2;

for (int i = 0; i < layers; ++i)

{

printf("layers=%d\n",i);

t4::tensor2f current_w = w;

if (i < 4)

{

current_w = w_truncated;

}

auto result = GenImage(model, x, current_w, i);

x = result.first;

img = result.second;

}


img2 = img * 0.5f + 0.5f;

float* p = img2.ptr();


for (int i = 0; i < 1024 * 1024*3; i++) {

float f;

f = p[i + 1024 * 1024 * 0];

if (f < 0)f = 0;

if (f >1)f = 1;

p[i + 1024 * 1024 * 0] = f;

}

unsigned char* a = new unsigned char[1024 * 1024 * 3];

for (int i = 0; i < 1024 * 1024 ; i++) {

a[i * 3 + 0] = (int)(p[i + 1024 * 1024 * 0] * 196.0);

a[i * 3 + 1] = (int)(p[i + 1024 * 1024 * 1] * 196.0);

a[i * 3 + 2] = (int)(p[i + 1024 * 1024 * 2] * 196.0);

}

stbi_write_png("aaa.png", 1024, 1024, 3, a, 1024 * 3);

delete[] a;

printf("saved\n");

}


return 0;

}

---------------


ということで写真をAIで生成してみました。


これ、本当にAIが生成したものなのでしょうか?
あまりに本物過ぎて合成なのか本物なのかわからないじゃないか!