エイバースの中の人

アプリとWEBサービスを作っているABARSのBLOGです。

東証のXBRLのパーサをオープンソース化しました

東証のXBRLのzipをパースしてBSとPLを抽出するパーサをオープンソース化しました。
abars/xbrl2bspl

アーキテクチャは以下を参照下さい。
XBRLからネットネット株を探す

TDnetViewをオープンソース化しました

iOSとAndroidでリリースしている東証の適時開示情報ビューワをオープンソース化しました。プルリクエストも受け付けていますので、機能追加したい場合はプルリクエスト頂ければと思います。また、フォークして別バージョンを作成頂いてもよいかと思います。

TDnetView for iOS
TDnetView for Android

Dellのサポートでエクスプレスサービスコードがわからない場合の対処

UP2414Qを修理に出そうとしたのですが、昔のモニタにはエクスプレスサービスコードがありません。以下のサポート窓口に問い合わせたのですが、エクスプレスサービスコードが求められます。

モニタ、プリンタ、プロジェクタ、その他周辺機器
月-日 9:00-21:00
0120-981-690 | 044-556-3468

https://www.dell.com/support/incidents-online/jp/ja/jpdhs1/contactus/dynamic

この問題への対処方法は、エクスプレスサービスコードを入力せずに1分間待つというものです。これで、修理窓口に繋がります。

Unityのシェーダで右ビットシフトを行うとAndroidで不定となる

Unityのピクセルシェーダで右ビットシフト演算を行うと、floatでエミュレートされて実行されるため、Android(OpenGL ES3)における結果が不定になります。

vec = (vec >> 3);


この問題を回避するには、以下のように記述します。

vec = int(floor(vec/8.0));


また、右ビットシフト以外のビット演算は正常に動作します。

vec = (vec & 0x7);


Windows、Mac、iOSでは右ビットシフト演算も問題なく正確な値が取得可能です。

GeminiPDAの画面自動回転対応等

キーボード付きのAndroid端末であるGeminiPDAを購入したので、設定すべき項目をまとめました。

IMG_0215


画面の自動回転


GeminiPDAはデフォルトでは画面の自動回転が無効になっています。画面の自動回転を有効にするには、Appbar Settingの設定からForce LandscapeをOFFにする必要があります。

日本語キーボードで@が打てない


Gemini KeyboardをGoogle Play Storeで検索してアップデート、再起動後、Androidの入力設定から、日本語(English)を選択します。

半角/全角が機能しない


Google日本語入力ではCTRL+SHIFTで半角/全角切り替えを行うようです。

USBメモリにMacPro2013をバックアップする

AppleのTimeCapsuleが販売終了ということで、GoogleWifiに乗り換えたいと思ったのですが、問題はTimeMachineバックアップです。現状はTimeCapsuleの2TBのHDDにバックアップしているため、バックアップ先を移行する必要があります。

そこで、USBメモリにMacPro2013をバックアップしてみました。MacPro2013のSSDとUSBメモリは共に256GBモデルです。バックアップ後の結果は以下です。同容量のUSBメモリでも意外と余裕がある結果となりました。

backup


USBメモリはサンディスクのあまり目立たないものにしてみました。



特に問題はなく、GoogleWifiに移行できそうです。

IMG_0205

IMDB-WIKIによる高精度な年齢・性別推定

現在、公開されている学習済みモデルの中で、最も高精度な年齢・性別推定器であると言われているのが、IMDB-WIKI – 500k+ face images with age and gender labelsです。

imdb


Adience Benchmarkにおける認識精度は性別で91%、年齢で64%です。(Understanding and Comparing Deep Neural Networks for Age and Gender Classification

VGGベースで実装されており、モデルサイズは500MBと大きいのですが、NVIDIA ChaLearn LAP 2015 Best Paper Awardを獲得しており、miniXceptionやage/gender.netに比べ、とても安定した出力を得ることができます。

年齢に関しては0歳〜100歳までの推定確率が出力されるため、年齢ベクトルと内積することで推定年齢を出力します。性別に関してはfemaleとmaleの2カテゴリです。

学習は50万枚の顔画像を使用しており、データセットとラベルもダウンロード可能です。

AppEngineでは32MB以上のファイルをアップロードできない

AppEngineではhttpリクエストのgetとpostが32MBまでに制限されます。32MBよりも大きなファイルをアップロードする場合は、Blobstoreを使用する必要があります。

Blobstore Python API Overview

DataStore版のBlobstoreは提供が終了しましたが、GoogleCloudStorage版のBlobstore APIはdeprecatedになっておらず、使用可能です。

Feature Deprecations

AppEngineで32MB以上のファイルをアップロードする方法がBlobstore以外存在しないため、今後も使えるのではないかと考えています。

GoogleAppEngine/GoでCloudStorageのファイルを配信する方法とハマりどころ

Blobstore APIを使用するとCloudStorageのバケットが自動で作成されるため、特にCloudStorageを意識せずに使用可能です。

jslibで引数のポインタに値を書き込む

UnityでNativePluginと同様のインタフェースを持つjslibを作成することを考えます。

C#側で以下のCreate APIがあった時、JS側からhogeに値を書き込みたいとします。

 [DllImport("__Internal")]
 public static extern int Create(ref IntPtr hoge);

JS側はEmscriptenのsetValue APIで値を書き込むことができます。

Create : function(hoge)
{
  var some_value=1;
  setValue(hoge,some_value,"i32*");
}

同様に構造体へも書き込むことが可能です。

C#側の定義は以下です。

[DllImport("__Internal")]
public static extern int getInfo([In,Out] InfoStructinfo);

[StructLayout(LayoutKind.Sequential)]
public class InfoStruct
{
	public UInt32 width;
	public UInt32 height;
}

JS側の実装は以下です。

getInfo: function(info)
{
	setValue(info+0,i.width,"i32");
	setValue(info+4,i.height,"i32");
	return 0;
}

参考:Emscripten : preamble.js

Unity Collaborateでファイルが更新されない

PC1でCollaborateにアップロードした後、PC2でダウンロードした際、PC1ではアップロードに成功しているものの、PC2ではダウンロードできない場合があります。

その場合は、PC1で、Library/Collab/CollabSnapshot_*を削除した後、アップロードし直すことで、問題を解消することができます。

File is Missing bug

FDDBのアノテーションを可視化

FDDB + YoloSmallを使用した顔認識の再学習に使用するアノテーションを可視化してみました。



再学習のコードと学習済みモデルは以下にあります。
abars/YoloKerasFaceDetection

VGG16で顔検索エンジンを作る

VGG16で顔画像から特徴量を抽出して顔検索エンジンを作ってみました。

demo

(image from adience_benchmark)

まず、AdienceBenchmarkOfUnfilteredFacesForGenderAndAgeClassificationから顔のデータベースをダウンロードし、feature_extract.pyでImagenetで学習したVGG16の4096次元の特徴ベクトルを取得します。

次に、YoloFaceでWebカメラもしくは画像から顔を検出し、VGG16の4096次元の特徴ベクトルを取得し、事前に計算しておいた顔のデータベースの特徴量とのベクトル間の距離を計算します。ベクトル間の距離が近い順に5件、検索結果として表示しています。

face_search.py captureを使うと、自分の顔もデータベースに登録することができます。再学習不要で認識対象を動的に追加できるので、エッジ側で使うには向いているかなと思います。

abars/FaceSearchVGG16

Kerasで表情を検出する

oarriaga/face_classificationに表情を検出する学習済みモデルがあります。
emotion

FER2013 datasetをベースに学習しており、以下の7カテゴリを検出可能です。

'angry'
'disgust'
'fear'
'happy'
'sad'
'surprise'
'neutral'

ネットワークは64x64x1を入力するXceptionV1となっています。入力画素のレンジは(-1,1)です。容量も1MB未満でとても軽量なので、モバイルでも動作させやすいと思います。

他の表情を検出する学習済みモデルとしては、Emotion Classification CNN - RGBがあり、こちらは227x227x3を入力するモデルです。両方試した印象としては、oarriaga/face_classificationの方がneutralとhappyを正しく認識するように思えました。

この結果を見ると、顔の認識はグレースケールに変換してしまった方が過学習を抑制できてロバストになるのかなと思いました。

人物検出用のデータセット一覧

DarknetやKerasで使える人物検出用のデータセットをまとめました。

Unfiltered faces for gender and age classification dataset

https://www.openu.ac.il/home/hassner/Adience/data.html#agegender

顔画像に対して、人物の年齢と性別が記載されたデータセット。1.76GB。11524枚。

face

学習済みモデル。
Age and Gender Classification using Convolutional Neural Networks

FDDB Dataset

http://vis-www.cs.umass.edu/fddb/

写真に対して、顔の位置が記載されたデータセット。顔の位置は楕円で記載されている。同時に映る人物が少なめなのでYolo向き。75MB。2845枚。

fddb

学習済みモデル。
dannyblueliu/YOLO-version-2-Face-detection

Widerface Dataset

http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/

写真に対して、顔の位置が記載されたデータセット。パレードなど、同時に映る人物が多めなので、Yolo向きではないかも。1.56GB。12880枚。

widerface

IMDB-WIKI Dataset

https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/

Wikiの顔画像に対して生年月日と撮影日が記載されたデータセット。Download Faces Onlyで7GB。460723枚。ラベルはMatlab形式。

imdb_wiki

学習済みモデル
Real-time face detection and emotion/gender classification using fer2013/imdb datasets with a keras CNN model and openCV.

ラベルの展開方法
顔画像から年齢・性別を推定するためのデータセットIMDB-WIKI

Vivahand Dataset

http://cvrr.ucsd.edu/vivachallenge/index.php/hands/hand-detection/

車内の画像に対して、手の位置が記載されたデータセット。運転席と助手席もラベル分けされている。3.05GB。5500枚。

vivahand

Hand Dataset

http://www.robots.ox.ac.uk/~vgg/data/hands/

Matlab形式だったので評価できず。194.5MB。4069枚。

handdataset

VGG16におけるKerasの前処理でmeanを引くかどうか

Fine-tuning a Keras model. Updated to the Keras 2.0 APIなど、Kerasのチュートリアルでは、学習画像に以下のような前処理を行っています。

# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255)

これは、VGG16の学習済みのネットに対して、RGB順で0〜1.0の値を入力しています。

しかし、KerasにおけるVGG16の重みは、Oxford大学のVGGによりCreative Commons Attribution Licenseの下で公開されたものを移植しています。そのため、本来、期待する前処理は、BGR順で0〜255の値からImageNetのmeanを引いた値となります。ただし、CaffeModelからKerasModelへの変換の過程でRGB順への補正は行われているようですので、RGB順で0〜255がKerasとして期待する入力となります。

def preprocess_input(img):
  #img = img[...,::-1]  #RGB2BGR
  #img = img - (104,117,123) #BGR mean value of VGG16
  img = img - (123,117,104) #RGB mean value of VGG16
  return img

train_datagen = ImageDataGenerator(
   preprocessing_function=preprocess_input,
   shear_range=0.2,
   zoom_range=0.2,
   horizontal_flip=True
)

test_datagen = ImageDataGenerator(
   preprocessing_function=preprocess_input,
)

それでは、この変更でどれくらい性能が変わるのでしょうか。AgeGender NetのAgeのClassification問題に対して比較してみました。

変更前(0〜1.0、RGB順、lr=0.01)
agegender_age_vgg16


変更後(0〜255 - mean、RGB順、lr=0.01)
agegender_age_vgg16_with_preprocseeing_rgb

変更後(0〜255 - mean、BGR順、lr=0.01)
agegender_age_vgg16_with_preprocess


結論としては、ラーニングレートが変わるだけで、どちらを使っても問題ないようです。VGG16の畳み込みで画素間差分を取っている過程でDC値の意味が消失しがちなのと、最後の内積のパラメータで調整できてしまうのではないかと思います。個人的には、正しい前処理をした方が一貫性があって気分はよいです。

尚、本件は、チュートリアルの掲示板でも議論になっていますが、特に結論は出ていないようです。

a-ozbek commented on 6 Feb 2017 •  edited 
Excuse me if this issue was brought up before about this script. I couldn't find a resolution to this in the comments.

In this script, during the fine-tuning, the "train_generator" and "validation_generator" do not seem to do VGG16 pre-processing which is

      # 'RGB'->'BGR'  
        x = x[:, :, :, ::-1]  
        # Zero-center by mean pixel  
        x[:, :, :, 0] -= 103.939  
        x[:, :, :, 1] -= 116.779  
        x[:, :, :, 2] -= 123.68  
Isn't it wrong to do fine-tuning of VGG16 without this pre-processing step?
aidiary commented on 16 Feb 2017
@a-ozbek

I have the same question.
I have experimented with and without this pre-processing and get the slightly better result in the case of without this pre-processing...

without pre-processing => val_acc = 93.5%@ epoch 50
with pre-processing      => val_acc = 92.8% @ epoch 50

TensorFlowでcudnn64_6.dllが見つからない

マイナーバージョンがDLL名に含まれているという仕様なので、新しいCUDNNを入れると、cudnn64_7.dllが入り、cudnn64_6.dllを使用しているTensorFlowでエラーが出ます。

Getting the given error while installing gpu version of tensorflow によると、リネームするとよいようです。

if you not get the cudnn64_6.dll, then use below method

you should rename the cudnn64_7.dll or cudnn64_8.dll as cudnn64_6.dll in the below path of your system

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin

Unpredictable CUDNN_STATUS_NOT_INITIALIZED on Windowsが出る問題はまだ解決していません。

Python3.5に対応したdarknet2caffe

marvis/pytorch-caffe-darknet-convertのdarknet2caffeがPython3.5に対応していなかったので、ForkしてPython2.7とPython3.5に対応したabars/darknet2caffeを作りました。

主な修正点は、printの記述方法の変更と、除算の//による整数化です。WindowsのTensorflowが3.5必須なのに対して、CoreMLが2.7必須と混在してきているのが悩ましいですね。

Kerasで顔画像から年齢と性別を推定する

Kerasで顔画像から年齢と性別を推定してみました。リポジトリはYoloKerasFaceDetectionです。データセットには、 AdienceBenchmarkOfUnfilteredFacesForGenderAndAgeClassificationを使用させて頂きました。

年齢と性別の推定には顔領域の画像を与える必要があるため、Webカメラを使用する場合、顔領域を検出して切り出す必要があります。一般にはOpenCVを使用しますが、OpenCVは眼鏡付きの顔の認識精度が低いため、今回、顔検出にはYoloを使用しています。顔検出の係数はYOLOライセンスのYOLO-version-2-Face-detectionを使用させて頂きました。そのため、Caffeも必要です。

学習済みモデルを同じフォルダにおいた後、以下のコマンドでWebカメラから年齢と性別の推定が可能です。

python agegender_demo.py keras

年齢のカテゴリは以下の8カテゴリです。

age 0-2
age 4-6
age 8-13
age 15-20
age 25-32
age 38-43
age 48-53
age 60-

性別のカテゴリは以下の2カテゴリです。

female
male

学習はVGG16をファインチューニングしました。学習のコードはagegender_train.pyにあります。

最初は年齢と性別を同時に認識させたのですが、うまく精度が出ませんでした。そのため、年齢と性別を別のネットワークで学習させるように変更しました。ただ、分解してもAge Netが過学習ぎみなので、もう少し追い込む必要がありそうです。

Age & Gender
agegender_agegender_vgg16
Age
agegender_age_vgg16

Gender
agegender_gender_vgg16


先行事例としては、Age and Gender Classification using Convolutional Neural Networksがあり、そこからTensorFlow + InceptionV3版のAge/Gender detection in Tensorflowがあります。また、MicrosoftのVison APIのデモがHow-Old.netにあります。

リファレンスモデルも以下のコマンドで実行できます。自己学習モデルは現状はまだ精度が出ていないので、Age and Gender Classification using Convolutional Neural Networksのリファレンスモデルを使用することをオススメします。

python agegender_demo.py caffe

実行すると以下のように顔検出と年齢・性別検出を行います。

demo
(出典:WIDER face dataset

AppEngineのdevserverでSearchIndexを保持する

AppEngineのdevserverでは、サーバを再起動するとFullTextSearchApiのSearchIndexが初期化されます。これを初期化されないようにするには、devserverのExtraFlagsにsearch_indexes_pathを与えます。

--search_indexes_path=/Users/abars/gae_datastore_tmp/tdnet.search


また、データストアの保存先フォルダを変えるのも、同様に、--datastore_pathを使用することもできます。

--datastore_path=/Users/abars/gae_datastore_tmp/tdnet.datastore

VGG16を特徴検出器として使う話

VGG16というConvolutional Neural Networkがあります。VGG16は224x224x3画素の画像を入力して、1000クラスの推定確率を出力するネットワークです。3x3のカーネルの畳み込みと2x2のプーリングを繰り返すことで、4096次元のベクトルを計算し、最後の全結合層で1000クラスの推定確率を計算します。


vgg16
(出典:VGG in TensorFlow


VGG16は深いネットワークなため、全体を再学習するには十分なデータが必要です。そのため、1000クラスに含まれていないオリジナルな画像を学習させようとした場合、画像の量が不足してうまく認識できません。

そこで、最後の全結合層だけを再学習するのが転移学習、最後の全結合層とその直前の畳み込み層を再学習するのがファインチューニングです。(VGG16のFine-tuningによる犬猫認識 (2)

なぜこれがうまくいくのかといえば、VGG16の前半が膨大な画像で学習しているため、画像に特化した特徴検出器になっているためです。最後の全結合層だけを見ると、やっていることは、VGG16が計算した4096次元のベクトルと、クラスごとの4096次元のベクトルの内積です。つまり、特徴空間でコサイン類似度を計算していることになります。

これより、新しいクラスを認識させたい場合、全体を再学習する必要はなく、クラスに固有の4096次元のベクトルを用意すれば十分ということになります。これを応用すると、データベース内の全ての画像に対してVGG16で計算した4096次元のベクトルをデータベースに格納し、ユーザから入力された画像に対してVGG16で計算した4096次元のベクトルとの内積を取るだけで、画像検索エンジンを作ることができます。(1時間で画像検索エンジンを作る

結局のところ、CNNはKL変換のような基底系を計算しているわけで、KL変換との違いは非直交であることと、非線形関数が入っていることであるといえます。

もちろん、新しいクラスの画像が加われば、最適な基底系は変化するため、全結合層だけでなく、もう一段上の畳み込み層まで含めて再学習すれば、より精度は向上します。

しかし、一見、再学習が必要そうな個人認証のような分野に対しても、再学習せずに特徴量の内積だけで実装可能というのは、可能性が広がって面白いのではないかと思います。

VGG16を使用した検索エンジンのデモとしては、KawaiiSearchがあります。リポジトリはblan4/KawaiiSearchです。ファッションECなどでも使用できそうです。

68747470733a2f2f692e696d6775722e636f6d2f653962707757592e706e67


68747470733a2f2f692e696d6775722e636f6d2f6444414a4375592e706e67

また、VGG16を使用した顔検索をabars/FaceSearchVGG16で実験中です。
Search
Profile

abars

アプリとWEBサービスを開発しています。最近はUnityとGAE/pyが主戦場。

ブラウザ向けMMOのメトセライズデストラクタ、イラストSNSのイラストブック、東証の適時開示情報を検索できるTDnetSearchを開発しています。

かつてエンターブレインのTECH Win誌でATULADOを連載しました。

サイト:ABARS
Twitter:abars
Github:abars

Twitter
TopHatenar
HotEntry
Counter

アクセス解析付きカウンター。あなたのBLOGにもどうですか?登録はこちらから。

TOP/ BLOG/ LECTURE/ ONLINE/ RUINA/ ADDON/ THREAD/ METHUSELAYZE/ IPHONE/ MET_IPHONE/ ENGLISH/ RANKING