初心者の為のCaffe Model Zoo【年齢と性別の分類】

anaconda環境でのcaffeを動かしたかったが、Makefile.configを変更してもうまく動作せず。いったんバージョン管理を使わない環境での構築手順はメモしておく。
間違っていたら連絡を頂ければありがたいです。





#ubuntuでのインストール
一般的な依存関係

```
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev

```

14.04

```
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
```

他のバージョンの場合はこちら
http://caffe.berkeleyvision.org/install_apt.html

他のOSの場合はこちら
http://caffe.berkeleyvision.org/installation.html


#環境を取得

```
git clone https://github.com/BVLC/caffe.git
```

#Makefile.config の設定

```
cd caffe
cp Makefile.config.example Makefile.config
```


```Makefile.config

# USE_CUDNN := 1
↓
USE_CUDNN := 1

#cudaは自分の環境に合わせて修正
CUDA_DIR := /usr/local/cuda-7.0

#anacondaでやりたい場合はここを変えるといけるはずなのだけども、自分の環境ではうまく通らなかった。
ANACONDA_HOME := $(HOME)/anaconda
PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
                $(ANACONDA_HOME)/include/python2.7 \
                $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include

PYTHON_LIB := $(ANACONDA_HOME)/lib


```


#コンパイル

```
cmake .
make -j4 all
make install
```

#再コンパイルしたい場合
make cleanしてmake -j4 all
make clean：アプリケーションを作成する際にできる中間ファイル及び、作成した結果のアプリーション自体も削除します。

#python環境設定

pythonコンパイルなど

```
sudo apt-get install python-dev python-pip python-numpy python-skimage gfortran
sudo pip install -r ~/caffe/python/requirements.txt
make pycaffe
```

パスを通す

```
export PYTHONPATH=/home/ubuntu/caffe/build/caffe/python/:$PYTHONPATH
```

importできたらOK

```
python
>>>import caffe
```

パスを設定しておく

```:.badhrc
export CAFFE_HOME=caffeをインストールした場所
export PATH=${CAFFE_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${CAFFE_HOME}/lib:${LD_LIBRARY_PATH}
export PYTHONPATH=${CAFFE_HOME}/python:${PYTHONPATH}
```

※注意
これでもclassify.pyが動かない場合がある。
http://qiita.com/Bonnnou_108/items/41e6dadeff1310b4eb5d

yahooの記事の通りにやると動くはずなのでがエラーになる場合がある
https://techblog.yahoo.co.jp/programming/caffe-intro/

```
python classify.py --raw_scale 255 ../101_ObjectCategories/airplanes/image_0001.jpg ../result.npy
```

エラーの内容

```py
ValueError: Mean shape incompatible with input shape
```

ここを編集
caffe/python/caffe/io.py

```py
if ms != self.inputs[in_][1:]:
    raise ValueError('Mean shape incompatible with input shape.')
```

↓

```py
if ms != self.inputs[in_][1:]:
    print(self.inputs[in_])
    in_shape = self.inputs[in_][1:]
    m_min, m_max = mean.min(), mean.max()
    normal_mean = (mean - m_min) / (m_max - m_min)
    mean = resize_image(normal_mean.transpose((1,2,0)),in_shape[1:]).transpose((2,0,1)) * (m_max - m_min) + m_min
    #raise ValueError('Mean shape incompatible with input shape.')
```


#Caffe Model Zoo


##年齢と性別の分類モデル

###emotionデータセット
http://www.ics.uci.edu/~xzhu/face/
http://www.openu.ac.il/home/hassner/Adience/data.html

age_net.caffemodel...年齢分類モデル
deploy_age.prototxt...年齢分類の数字とラベルの紐付け
mean.binaryproto...平均画像用
gender_net.caffemodel...性別分類モデル
deploy_gender.prototxt...性別分類の数字とラベルの紐付け

###modelのダウンロード

```
wget http://www.openu.ac.il/home/hassner/projects/cnn_agegender/cnn_age_gender_models_and_data.0.0.1.zip
unzip cnn_age_gender_models_and_data.0.0.1.zip
```


###import

```
import os
import numpy as np
import matplotlib.pyplot as plt

caffe_root = './caffe-master/' 
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe

plt.rcParams['figure.figsize'] = (10, 10)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

```

###mean imageの読み込み

```
mean_filename='./mean.binaryproto'
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]

```

![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/64334/5d2baa9e-273e-ce77-b153-c37b9f706ebc.png)


###age networkの読み込み

```
age_net_pretrained='./age_net.caffemodel'
age_net_model_file='./deploy_age.prototxt'
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
```


###gender networkの読み込み

```
gender_net_pretrained='./gender_net.caffemodel'
gender_net_model_file='./deploy_gender.prototxt'
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
```

###Labels

```
age_list=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
gender_list=['Male','Female']
```


###imageの読み込みと表示

```
example_image = './example_image.jpg'
input_image = caffe.io.load_image(example_image)
_ = plt.imshow(input_image)
```

###年齢予想

```
prediction = age_net.predict([input_image]) 

print 'predicted age:', age_list[prediction[0].argmax()]
```
出力結果：predicted age: (0, 2)

###性別予想

```
prediction = gender_net.predict([input_image]) 

print 'predicted gender:', gender_list[prediction[0].argmax()]
```
出力結果：predicted gender: Female

###フィルターの視覚化
CNNでは重みのことをフィルターといっている。


```
def showimage(im):
    if im.ndim == 3:
        im = im[:, :, ::-1]
    plt.set_cmap('jet')
    plt.imshow(im)
    

def vis_square(data, padsize=1, padval=0):
    data -= data.min()
    data /= data.max()
    
    # フィルター数を強制的に正方形にする
    n = int(np.ceil(np.sqrt(data.shape[0])))
    padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)
    data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))
    
    # フィルタを画像にタイル張りする
    data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
    data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
    
    showimage(data)
```

###より良い視覚化のために、平均画像なしでジェンダーネットワークを読み込む

```
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))

prediction = age_net.predict([input_image]) 
```

###画像を入力
__input__や_から始める関数などが出てくることがある。pythonでは外部クラスから参照はできるが参照をしない意味で_を使用することがある。

```
_ = plt.imshow(input_image)
```

###最初のレイヤーフィルタ conv1

```
filters = age_net.params['conv1'][0].data[:49]
vis_square(filters.transpose(0, 2, 3, 1))
```

![ダウンロード (1).png](https://qiita-image-store.s3.amazonaws.com/0/64334/a2a56012-d2c1-8faa-05fb-07f0fa4153c5.png)


###最初のレイヤーの出力 conv1

```
feat = age_net.blobs['conv1'].data[4, :49]
vis_square(feat, padval=1)
```

![ダウンロード (2).png](https://qiita-image-store.s3.amazonaws.com/0/64334/ed282d52-dfd8-acaa-fa7c-94e93aa7fb1b.png)




##Flickrの画像を使ってfine-tuning

###caffeのあるフォルタに移動

```
cd ~/caffe
```

###学習済みモデルをダウンロード

```
scripts/download_model_binary.py models/bvlc_reference_caffenet
```

###Flickrから画像をダウンロード

```
python examples/finetune_flickr_style/assemble_data.py --workers=1 --images=2000 --seed 831486
```

###bvlc_reference_caffenet.caffemodelを初期値として、Flickrデータでファインチューニング。

```
./build/tools/caffe train -solver models/finetune_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
```


#Regression Methods for Localization

山、道、ランナー
<img width="828" alt="スクリーンショット 2017-06-08 19.54.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/07f95baf-5822-70ce-956a-85cfee6e9164.png">
イメージの理解に向けて
● Object localization
● Object segmentation
● Human pose estimation
<img width="798" alt="スクリーンショット 2017-06-08 19.55.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/eacdfa6c-a12d-653e-c4d8-1f96042c34fc.png">
DNNベースの回帰として公式化
● Deep Neural Net-based Regression
● Object Mask Regression
● Object Bounding Box Regression
● Human Pose Estimation
##DNN-based Regression




#参考
fine-tuning
http://hirotaka-hachiya.hatenablog.com/entry/2015/02/21/072255

https://bfeba431-a-62cb3a1a-s-sites.googlegroups.com/site/deeplearningcvpr2014/RegressionMethodsforLocalization.pdf?attachauth=ANoY7cpwt94hVCZXGTsfVWXtfKcakWqTiHT9TEYM6tLGdUk2jmlmBHiyEaL3qByRJEeBn-2EtPhanI3uoT58LSiRDl_A6JP51_8jm8LqcbyLZYo2bSMJpvbmCXlP4fMiRtJLT7nXmUu0QERcZEnYd_Ly-kka7TKKUEyk4-ez1iXr5ROM-G_2jjLa21y3y1y6s9sQK3Q0KJVvIHAAmzKn7uonJ4N2Q3f3dLVs7QQyw4MgIDd_ZiYcati9Ktkjq51cvzjLOPMfa7d6&attredirects=0