使用keras vgg16进行迁移学习,最后生成了5000个潜在的tag,并进行了二分类,另外在alt_i2v.py中进行了500轮训练,每一轮最多训练15000个样本,每一轮都保存了模型,这些可以自行调整。
值得注意的是:原作者每轮的样本(~15000)都是用for loop获取的,这使训练的速度大副降低,这是一个值得优化的方向
1.首先下载对应的图片+txt标签文档描述,进入datasetdownload,执行python new_get.py --mode scrape
,我爬了11w+的图片(14G),本打算共享出来的,但百度网盘最大上传只有4G(如果有好的共享方法,请指教)
2.进行图片与标签配对. python make_datapair.py --make_tag_index
,生成tag_index.pkl文件,元素5000个,这是原作者hard_coding的,如有需要可自行修改
我对make_datapair.py进行了一点修改,1.增加了进度条,2.原作者保存的文件会是.pkl.pkl,这里我改为了.pkl
3.再执行python make_datapair.py --make_pair
,生成多个dataset/ith_img.pkl,每个pkl文件包含[图片矩阵,标签one_hot]两个元素
4.训练与测试
python alt_i2v_V2.py --train #5000个标签,15000个样本,500轮
可以看到15000太大了,内存不够,可以调小试试
python alt_i2v_V2.py --pred #30个测试对象
- 画像をタグ等の特定の特徴量に従ってベクトル化できる
- このベクトルとは通常画像分類で用いられるsoftmaxなどのマルチクラスではなく、softprobの(*1)問題として捉えることができる
- Ver1に比べて探索的であって割とひどいコードを修正して、わかりやすく変えました
- 150x150の画像のサイズから、224x224にスケールアップしました
- BatchNormalizationだけでなく、DropOutも併用してネットワークのスパース性を高めました
- Msgpackを用いたKVSをやめて、ただのPickleで画像のシリアライズをする様になりました
- Keras V2のインターフェースに合わせました
*1 softprobはxgboostの用語でありますが、各クラスに該当するものが、その確率値を返すものです
VGG16の評価モデルはよくチューニングされており、別段何かしなくても良いパフォーマンスが出せます
そのため、VGG16の評価モデルを転移学習することでそのチューニングされた良い状態を保存しつつ、softprobに該当する部分を付け足すことで、illustration2vecに該当する機能を付与させます
毎回気持ちですみません(しかし、なんらかの活性化関数の新規のものの提案というスタイルではないので、雑でいいという思いがあります)
今回は過去最大の5000次元を予想するというタスクであったので、全結合層をReLuで結合していきます
前回はBatchNormalizationのみでやったのですが、これだけを用いうることに少し不安があったので、DropOutを30%のデータを入れるようにしました
ReLu, DropOutともネットワークを疎結合にする役割が期待できますので、ネットワークの意味のクラスタが獲得しやすくなると期待できます
これ系のタスクではAdamかSGDが良い成績をいつも収めることが期待されていますので、何も考えず、Adamで決め打ちです
- オプティマイザ、Adam : LearningRate 0.001
- 損失関数、BINARY CROSS ENTROPY
Safebooruさんからダウンロードさせていただきました
タグとURLと画像の三つの情報を保存し、学習用のデータセット1,500,000枚、テスト様に20,000枚用意します
メモリに乗らないときは、最近いつも使うのですが、データセットを分割読み込みまします
ソフトウェア工学者にとっては一般的なアプローチですが、Epochと対応させて学習すると、なんとかスケジューリングできます(ちゃんとKerasのインターフェースの中にはgeneratorというデータセットを切り出す仕組みがありますが、私はこれを操作が複雑になりすぎると感じているであまり用いていません)
具体的には、15000枚の画像をオンメモリに保持 -> 1Epoch回す -> 別の150000枚の画像をオンメモリに保持 -> 1Epoch回す -> ...
ということを続けていきます
全てが一回のみスキャンされます
make_datapairディレクトリ内のmake_datapair.pyを"--make_tag_index"オプションをつけて実行すると、特定のディレクトリの内部の画像とタグ情報に対して、よく頻出するタグ5000個に対して、タグとそのインデックスを記述します
make_dataset.pyを"--make_pair"のオプションをつけて実行することで、実行することで、タグとインデックスをもとに、画像のベクトル情報 Xとそのタグ情報をベクトル化した情報yのペアを作ります。一つの画像に対して、Piar(X,y)となる情報をpickle形式のファイルで出力します
alt_i2v_V2.pyに"--train"オプションをつけて実行することで、学習します。15000枚の画像のデータセットをラウンドロビンで切り替えながら学習しますが、メモリ64GByteマシンの基準でやっていますので、必要に応じて、サイズを小さくするか、ランダムサンプルに切り替えるか、Epoch数を変化させるなどすると良いでしょう
alt_i2v_V2.pyに"--pred"オプションをつけて実行することで予想が可能です
定量的なMSEの他に、定性的なみんなが好きそうな結果を載せておきます
結果は概ね、良好で、画像識別は本当に今や簡単になりましたね、という印象があります
Practical Lessons from Predicting Clicks on Ads at Facebookという論文があります
趣旨としては、テキストや画像やなんらかを特徴量の集合としてみなして、CTR予想などのKPI予想問題を行う際、特徴量が極めて高次元である際、アルゴリズム(この場合、勾配ブースティングの木の出力値)を特徴量とすることで、これを元にLinear Regressionをかけることで、より実践的な速度で、より高精度で予想できるという趣旨でした
勾配ブースティングはそのアルゴリズムから残渣となる誤差を最小化する様に特徴量を選択しますが、例えば、これがIllustration2Vecの出力次元値ではどうでしょうか。アルゴリズムが自動で獲得した粒度の特徴量ではないですが、同様の圧縮された特徴量の空間と見做すことができます。(LDA的な自動でクラスタを獲得させる方法も筋が良さそうです)
データが十分に手元にないので、検証は今現在、簡単に行えそうにはありませんが、できそうなことなのでいずれチャレンジしたいと考えています
こちらからダウンロード可能です
https://github.com/GINK03/alt-i2v
MIT