芸能人の顔を機械学習で分類してみた（その４）

これまでローカルでやってきたことをazure VM上で実行してみる。
[（その３）](https://qiita.com/yuni/items/7cfd540104f54263f6b5)では男女1名ずつだやったけれども、こんどは女性2名100枚ずつの画像でテスト。

と、その前に、忘れないようにメモメモっと。
#####ローカルのディレクトリごとVMにコピー
ローカルで実行
```scp -r <ディレクトリpath> <VMユーザ名>@<VM IPアドレス>:<保存先path>```

###画像の収集
bing apiを使って、1人800枚の画像収集を試してみた。

```bing_api.py
# -*- coding: utf-8 -*-
import http.client
import json
import re
import requests
import os
import math
import pickle
import urllib
import hashlib
import sha3
import configparser # for Python3
import traceback
import sys


def make_dir(path):
    if not os.path.isdir(path):
        os.mkdir(path)


def make_correspondence_table(correspondence_table, original_url, hashed_url):
    """Create reference table of hash value and original URL.
    """
    correspondence_table[original_url] = hashed_url


def make_img_path(save_dir_path, url):
    """Hash the image url and create the path
    Args:
        save_dir_path (str): Path to save image dir.
        url (str): An url of image.
    Returns:
        Path of hashed image URL.
    """
    save_img_path = os.path.join(save_dir_path, 'imgs')
    make_dir(save_img_path)

    file_extension = os.path.splitext(url)[-1]
    if file_extension.lower() in ('.jpg', '.jpeg', '.gif', '.png', '.bmp'):
        encoded_url = url.encode('utf-8') # required encoding for hashed
        hashed_url = hashlib.sha3_256(encoded_url).hexdigest()
        full_path = os.path.join(save_img_path, hashed_url + file_extension.lower())

        make_correspondence_table(correspondence_table, url, hashed_url)

        return full_path
    else:
        raise ValueError('Not applicable file extension')


def download_image(url, timeout=10):
    response = requests.get(url, allow_redirects=True, timeout=timeout)
    if response.status_code != 200:
        error = Exception("HTTP status: " + response.status_code)
        raise error

    content_type = response.headers["content-type"]
    if 'image' not in content_type:
        error = Exception("Content-Type: " + content_type)
        raise error

    return response.content


def save_image(filename, image):
    with open(filename, "wb") as fout:
        fout.write(image)


if __name__ == '__main__':
    config = configparser.ConfigParser()
    config.read('authentication.ini')
    bing_api_key = config['auth']['bing_api_key']

    save_dir_path = './tensorflow/test/test1/sawajiri_erika'
    make_dir(save_dir_path)

    num_imgs_required = 800 # Number of images you want.
    num_imgs_per_transaction = 150 # default 30, Max 150 images
    offset_count = math.floor(num_imgs_required / num_imgs_per_transaction)

    url_list = []
    correspondence_table = {}

    # headers = {
    #     # Request headers
    #     'Content-Type': 'multipart/form-data',
    #     'Ocp-Apim-Subscription-Key': bing_api_key, # API key
    # }
    headers = {
    # Request headers
    # 'Content-Type': 'multipart/form-data',
    'Ocp-Apim-Subscription-Key': bing_api_key # API key
    }

    for offset in range(offset_count):

        params = urllib.parse.urlencode({
            # Request parameters
            'q': '沢尻エリカ',
            'mkt': 'ja-JP',
            'count': num_imgs_per_transaction,
            'offset': offset * num_imgs_per_transaction # increment offset by 'num_imgs_per_transaction' (for example 0, 150, 300)
        })

        try:
            conn = http.client.HTTPSConnection('api.cognitive.microsoft.com')
            conn.request("GET", "/bing/v7.0/images/search?%s" % params, "{body}", headers)
            response = conn.getresponse()
            data = response.read()

            save_res_path = os.path.join(save_dir_path, 'pickle_files')
            make_dir(save_res_path)
            with open(os.path.join(save_res_path, '{}.pickle'.format(offset)), mode='wb') as f:
                pickle.dump(data, f)

            conn.close()
        except Exception as err:
            # print("[Errno {0}] {1}".format(err.errno, err.strerror))
            print("%s" % (err))

        else:
            decode_res = data.decode('utf-8')
            data = json.loads(decode_res)

            pattern = r"&r=(http.+)&p=" # extract an URL of image

            for values in data['value']:
                unquoted_url = urllib.parse.unquote(values['contentUrl'])
                img_url = re.search(pattern, unquoted_url)
                # if img_url:
                #     url_list.append(img_url.group(1))
                url_list.append(unquoted_url)

    for url in url_list:
        try:
            img_path = make_img_path(save_dir_path, url)
            image = download_image(url)
            save_image(img_path, image)
            print('save_image')
            print(image)
            print('saved image... {}'.format(url))
        except KeyboardInterrupt:
            break
        except Exception as err:
            print("%s" % (err))

    correspondence_table_path = os.path.join(save_dir_path, 'corr_table')
    make_dir(correspondence_table_path)

    with open(os.path.join(correspondence_table_path, 'corr_table.json'), mode='w') as f:
        json.dump(correspondence_table, f)
```

#####結果
```[yuni@machinelearningvm azureVM]$ find sawajiri_erika/imgs | wc -l
621
[yuni@machinelearningvm azureVM]$ find takei_emi/imgs | wc -l
624
```
沢尻エリカ：621枚
武井咲：624枚

###顔の検出
openCV動かす環境作るのにめちゃめちゃハマりました...
ハマりすぎて実行したこと全部かけない(汗）
#####結果
約600枚の画像について顔の切り出しには7-8分かかりました。
```[yuni@machinelearningvm azureVM]$ find sawajiri_erika/face_only | wc -l
336
yuni@machinelearningvm azureVM]$ find takei_emi/face_only | wc -l
318
```
目で見て、ごみデータの削除。
```[yuni@machinelearningvm ~]$ find azureVM/sawajiri_erika/face_only | wc -l
273
[yuni@machinelearningvm ~]$ find azureVM/takei_emi/face_only | wc -l
284
```
めちゃ減った。。。600枚以上集めたはずなのに半分以下。

###準備（train/testデータの仕分けとラベルづけテキストの作成）
まずは前回と同じ100枚で学習

* trainデータ：沢尻エリカ(100枚), 武井咲(100枚)
* testデータ ：沢尻エリカ(30枚), 武井咲(30枚)

細かいけどやったこと（めも）

```
画像ファイル名の一覧をテキストファイルに書き出し
[yuni@machinelearningvm azureVM]$ls azureVM/sawajiri_erika/face_only > azureVM/sawa.txt

毎行末に0を追記
[yuni@machinelearningvm azureVM]$sed -i -e "s/\$/ 0/g" azureVM/sawa.txt

毎行頭にpathを追記
[yuni@machinelearningvm azureVM]$ sed "s@^@/home/yuni/azureVM/data/@g" azureVM/take.txt > azureVM/take1.txt

1行目から100行目をtrainデータとして書き出し
sed -n 1,100p azureVM/sawa.txt > azureVM/train0.txt

[yuni@machinelearningvm azureVM]$ cat train0.txt|wc -l
100
[yuni@machinelearningvm azureVM]$ cat train1.txt|wc -l
100
[yuni@machinelearningvm azureVM]$ cat test0.txt|wc -l
30
[yuni@machinelearningvm azureVM]$ cat test1.txt|wc -l
30

test0.txtの中身：沢尻エリカの顔切り出し後のデータpath 0（ラベル）
[yuni@machinelearningvm azureVM]$ cat test0.txt
/home/yuni/azureVM/data/5ad9856d45d5215e6c53ccfc0dc480e2b6f6f9057d419180e85b7ef6cdc8449f.jpg 0
/home/yuni/azureVM/data/5b8c58578283a34846f5b9949d97f39b73589a013f99028fddade093fee89d82.jpg 0
/home/yuni/azureVM/data/5cd712136e1321d8ae2ffa50f3f12c1f91ea4ecc21b837de9a0f08e8b5ab2bd3.jpg 0
/home/yuni/azureVM/data/5e8ea95d86b9ba8648eb2d56288b9228351325d7d196ac271ea61e5493db64bb.jpeg 0
...

train.txtに、pathとラベル(0,1)のテキストをまとめる
[yuni@machinelearningvm azureVM]$ cat train0.txt train1.txt > train.txt
[yuni@machinelearningvm azureVM]$ cat train.txt |wc -l
200

test.txtも同様
[yuni@machinelearningvm azureVM]$ cat test0.txt test1.txt > test.txt
[yuni@machinelearningvm azureVM]$ cat test.txt |wc -l
60
```

###機械学習の実行
前回と同じtestFaceType.pyを実行

```testFaceType.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import cv2
import numpy as np
import tensorflow as tf
import tensorflow.python.platform

NUM_CLASSES = 2
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('train', '/home/yuni/azureVM/train.txt', 'File name of train data')
flags.DEFINE_string('test', '/home/yuni/azureVM/test.txt', 'File name of train data')
flags.DEFINE_string('train_dir', '/home/yuni/azureVM/data', 'Directory to put the training data.')
flags.DEFINE_integer('max_steps', 200, 'Number of steps to run trainer.')
flags.DEFINE_integer('batch_size', 10, 'Batch size'
                     'Must divide evenly into the dataset sizes.')
flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate.')

def inference(images_placeholder, keep_prob):
    """ 予測モデルを作成する関数

    引数: 
      images_placeholder: 画像のplaceholder
      keep_prob: dropout率のplace_holder

    返り値:
      y_conv: 各クラスの確率(のようなもの)
    """
    # 重みを標準偏差0.1の正規分布で初期化
    def weight_variable(shape):
      initial = tf.truncated_normal(shape, stddev=0.1)
      return tf.Variable(initial)

    # バイアスを標準偏差0.1の正規分布で初期化
    def bias_variable(shape):
      initial = tf.constant(0.1, shape=shape)
      return tf.Variable(initial)

    # 畳み込み層の作成
    def conv2d(x, W):
      return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    # プーリング層の作成
    def max_pool_2x2(x):
      return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1], padding='SAME')
    
    # 入力を28x28x3に変形
    x_image = tf.reshape(images_placeholder, [-1, 28, 28, 3])

    # 畳み込み層1の作成
    with tf.name_scope('conv1') as scope:
        W_conv1 = weight_variable([5, 5, 3, 32])
        b_conv1 = bias_variable([32])
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

    # プーリング層1の作成
    with tf.name_scope('pool1') as scope:
        h_pool1 = max_pool_2x2(h_conv1)
    
    # 畳み込み層2の作成
    with tf.name_scope('conv2') as scope:
        W_conv2 = weight_variable([5, 5, 32, 64])
        b_conv2 = bias_variable([64])
        h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

    # プーリング層2の作成
    with tf.name_scope('pool2') as scope:
        h_pool2 = max_pool_2x2(h_conv2)

    # 全結合層1の作成
    with tf.name_scope('fc1') as scope:
        W_fc1 = weight_variable([7*7*64, 1024])
        b_fc1 = bias_variable([1024])
        h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
        # dropoutの設定
        h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    # 全結合層2の作成
    with tf.name_scope('fc2') as scope:
        W_fc2 = weight_variable([1024, NUM_CLASSES])
        b_fc2 = bias_variable([NUM_CLASSES])

    # ソフトマックス関数による正規化
    with tf.name_scope('softmax') as scope:
        y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

    # 各ラベルの確率のようなものを返す
    return y_conv

def loss(logits, labels):
    """ lossを計算する関数

    引数:
      logits: ロジットのtensor, float - [batch_size, NUM_CLASSES]
      labels: ラベルのtensor, int32 - [batch_size, NUM_CLASSES]

    返り値:
      cross_entropy: 交差エントロピーのtensor, float

    """

    # 交差エントロピーの計算
    cross_entropy = -tf.reduce_sum(labels*tf.log(logits))
    # TensorBoardで表示するよう指定
    tf.summary.scalar("cross_entropy", cross_entropy)
    return cross_entropy

def training(loss, learning_rate):
    """ 訓練のOpを定義する関数

    引数:
      loss: 損失のtensor, loss()の結果
      learning_rate: 学習係数

    返り値:
      train_step: 訓練のOp

    """

    train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)
    return train_step

def accuracy(logits, labels):
    """ 正解率(accuracy)を計算する関数

    引数: 
      logits: inference()の結果
      labels: ラベルのtensor, int32 - [batch_size, NUM_CLASSES]

    返り値:
      accuracy: 正解率(float)

    """
    correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    tf.summary.scalar("accuracy", accuracy)
    return accuracy

if __name__ == '__main__':
    # ファイルを開く
    f = open(FLAGS.train, 'r')
    # データを入れる配列
    train_image = []
    train_label = []
    for line in f:
        # 改行を除いてスペース区切りにする
        line = line.rstrip()
        l = line.split()
        # データを読み込んで28x28に縮小
        img = cv2.imread(l[0])
        if(img is None):
            print('画像を開けません。')
            quit()
        # print(l[0])
        #表示
        img = cv2.resize(img, (28, 28))
        # cv2.imshow('image', img)
        # cv2.waitKey(0)
        # 一列にした後、0-1のfloat値にする
        train_image.append(img.flatten().astype(np.float32)/255.0)
        # ラベルを1-of-k方式で用意する
        tmp = np.zeros(NUM_CLASSES)
        tmp[int(l[1])] = 1
        train_label.append(tmp)
    # numpy形式に変換
    train_image = np.asarray(train_image)
    train_label = np.asarray(train_label)
    f.close()

    f = open(FLAGS.test, 'r')
    test_image = []
    test_label = []
    for line in f:
        line = line.rstrip()
        l = line.split()
        img = cv2.imread(l[0])
        img = cv2.resize(img, (28, 28))
        test_image.append(img.flatten().astype(np.float32)/255.0)
        tmp = np.zeros(NUM_CLASSES)
        tmp[int(l[1])] = 1
        test_label.append(tmp)
    test_image = np.asarray(test_image)
    test_label = np.asarray(test_label)
    f.close()
    
    with tf.Graph().as_default():
        # 画像を入れる仮のTensor
        images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS))
        # ラベルを入れる仮のTensor
        labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES))
        # dropout率を入れる仮のTensor
        keep_prob = tf.placeholder("float")

        # inference()を呼び出してモデルを作る
        logits = inference(images_placeholder, keep_prob)
        # loss()を呼び出して損失を計算
        loss_value = loss(logits, labels_placeholder)
        # training()を呼び出して訓練
        train_op = training(loss_value, FLAGS.learning_rate)
        # 精度の計算
        acc = accuracy(logits, labels_placeholder)

        # 保存の準備
        saver = tf.train.Saver()
        # Sessionの作成
        sess = tf.Session()
        # 変数の初期化
        sess.run(tf.global_variables_initializer())
        # TensorBoardで表示する値の設定
        summary_op = tf.summary.merge_all()
        summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)
        
        # 訓練の実行
        for step in range(FLAGS.max_steps):
            #追記
            for i in range(int(len(train_image)/FLAGS.batch_size)):
                # batch_size分の画像に対して訓練の実行
                batch = FLAGS.batch_size*i
                # feed_dictでplaceholderに入れるデータを指定する
                sess.run(train_op, feed_dict={
                  images_placeholder: train_image[batch:batch+FLAGS.batch_size],
                  labels_placeholder: train_label[batch:batch+FLAGS.batch_size],
                  keep_prob: 0.5})

            # 1 step終わるたびに精度を計算する
            train_accuracy = sess.run(acc, feed_dict={
                images_placeholder: train_image,
                labels_placeholder: train_label,
                keep_prob: 1.0})
            print ("step %d, training accuracy %g"%(step, train_accuracy))

            # 1 step終わるたびにTensorBoardに表示する値を追加する
            summary_str = sess.run(summary_op, feed_dict={
                images_placeholder: train_image,
                labels_placeholder: train_label,
                keep_prob: 1.0})
            summary_writer.add_summary(summary_str, step)

    # 訓練が終了したらテストデータに対する精度を表示
    print ("test accuracy %g"%sess.run(acc, feed_dict={
        images_placeholder: test_image,
        labels_placeholder: test_label,
        keep_prob: 1.0}))

    # 最終的なモデルを保存
    save_path = saver.save(sess, "model.ckpt")
```

#####結果
```
[yuni@machinelearningvm tensorflow]$ python3 testFaceType.py
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE3 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available 
step 0, training accuracy 0.56
step 1, training accuracy 0.5
step 2, training accuracy 0.525
step 3, training accuracy 0.57
step 4, training accuracy 0.58
step 5, training accuracy 0.67
step 6, training accuracy 0.74
step 7, training accuracy 0.69
step 8, training accuracy 0.72
step 9, training accuracy 0.81
step 10, training accuracy 0.81
step 11, training accuracy 0.795
step 12, training accuracy 0.79
step 13, training accuracy 0.885
step 14, training accuracy 0.9
step 15, training accuracy 0.89
step 16, training accuracy 0.93
step 17, training accuracy 0.905
step 18, training accuracy 0.95
step 19, training accuracy 0.92
step 20, training accuracy 0.975
step 21, training accuracy 0.965
step 22, training accuracy 0.96
step 23, training accuracy 0.98
step 24, training accuracy 0.98
step 25, training accuracy 0.975
step 26, training accuracy 0.985
step 27, training accuracy 0.99
step 28, training accuracy 0.985
step 29, training accuracy 0.99
step 30, training accuracy 0.99
step 31, training accuracy 0.99
step 32, training accuracy 1
step 33, training accuracy 0.995
step 34, training accuracy 0.995
step 35, training accuracy 0.99
step 36, training accuracy 1
step 37, training accuracy 1
step 38, training accuracy 1
step 39, training accuracy 1
step 40, training accuracy 0.995
step 41, training accuracy 1
step 42, training accuracy 1
step 43, training accuracy 1
step 44, training accuracy 1
step 45, training accuracy 1
step 46, training accuracy 1
step 47, training accuracy 1
step 48, training accuracy 1
step 49, training accuracy 1
step 50, training accuracy 1
step 51, training accuracy 1
step 52, training accuracy 1
step 53, training accuracy 1
step 54, training accuracy 1
step 55, training accuracy 1
step 56, training accuracy 1
step 57, training accuracy 1
step 58, training accuracy 1
step 59, training accuracy 1
step 60, training accuracy 1
step 61, training accuracy 1
step 62, training accuracy 1
step 63, training accuracy 1
step 64, training accuracy 1
step 65, training accuracy 1
step 66, training accuracy 1
step 67, training accuracy 1
step 68, training accuracy 1
step 69, training accuracy 1
step 70, training accuracy 1
step 71, training accuracy 1
step 72, training accuracy 1
step 73, training accuracy 1
step 74, training accuracy 1
step 75, training accuracy 1
step 76, training accuracy 1
step 77, training accuracy 1
step 78, training accuracy 1
step 79, training accuracy 1
step 80, training accuracy 1
step 81, training accuracy 1
step 82, training accuracy 1
step 83, training accuracy 1
step 84, training accuracy 1
step 85, training accuracy 1
step 86, training accuracy 1
step 87, training accuracy 1
step 88, training accuracy 1
step 89, training accuracy 1
step 90, training accuracy 1
step 91, training accuracy 1
step 92, training accuracy 1
step 93, training accuracy 1
step 94, training accuracy 1
step 95, training accuracy 1
step 96, training accuracy 1
step 97, training accuracy 1
step 98, training accuracy 1
step 99, training accuracy 1
step 100, training accuracy 1
step 101, training accuracy 1
step 102, training accuracy 1
step 103, training accuracy 1
step 104, training accuracy 1
step 105, training accuracy 1
step 106, training accuracy 1
step 107, training accuracy 1
step 108, training accuracy 1
step 109, training accuracy 1
step 110, training accuracy 1
step 111, training accuracy 1
step 112, training accuracy 1
step 113, training accuracy 1
step 114, training accuracy 1
step 115, training accuracy 1
step 116, training accuracy 1
step 117, training accuracy 1
step 118, training accuracy 1
step 119, training accuracy 1
step 120, training accuracy 1
step 121, training accuracy 1
step 122, training accuracy 1
step 123, training accuracy 1
step 124, training accuracy 1
step 125, training accuracy 1
step 126, training accuracy 1
step 127, training accuracy 1
step 128, training accuracy 1
step 129, training accuracy 1
step 130, training accuracy 1
step 131, training accuracy 1
step 132, training accuracy 1
step 133, training accuracy 1
step 134, training accuracy 1
step 135, training accuracy 1
step 136, training accuracy 1
step 137, training accuracy 1
step 138, training accuracy 1
step 139, training accuracy 1
step 140, training accuracy 1
step 141, training accuracy 1
step 142, training accuracy 1
step 143, training accuracy 1
step 144, training accuracy 1
step 145, training accuracy 1
step 146, training accuracy 1
step 147, training accuracy 1
step 148, training accuracy 1
step 149, training accuracy 1
step 150, training accuracy 1
step 151, training accuracy 1
step 152, training accuracy 1
step 153, training accuracy 1
step 154, training accuracy 1
step 155, training accuracy 1
step 156, training accuracy 1
step 157, training accuracy 1
step 158, training accuracy 1
step 159, training accuracy 1
step 160, training accuracy 1
step 161, training accuracy 1
step 162, training accuracy 1
step 163, training accuracy 1
step 164, training accuracy 1
step 165, training accuracy 1
step 166, training accuracy 1
step 167, training accuracy 1
step 168, training accuracy 1
step 169, training accuracy 1
step 170, training accuracy 1
step 171, training accuracy 1
step 172, training accuracy 1
step 173, training accuracy 1
step 174, training accuracy 1
step 175, training accuracy 1
step 176, training accuracy 1
step 177, training accuracy 1
step 178, training accuracy 1
step 179, training accuracy 1
step 180, training accuracy 1
step 181, training accuracy 1
step 182, training accuracy 1
step 183, training accuracy 1
step 184, training accuracy 1
step 185, training accuracy 1
step 186, training accuracy 1
step 187, training accuracy 1
step 188, training accuracy 1
step 189, training accuracy 1
step 190, training accuracy 1
step 191, training accuracy 1
step 192, training accuracy 1
step 193, training accuracy 1
step 194, training accuracy 1
step 195, training accuracy 1
step 196, training accuracy 1
step 197, training accuracy 1
step 198, training accuracy 1
step 199, training accuracy 1
test accuracy 0.85
```
テストデータの正解率は、85%でした。



###学習済みモデルを使って新しい画像を判定
引数に画像を与えると0/1で返してくれるやつ。
0：沢尻エリカ
1：武井咲

```FaceType.py
#!/usr/bin/env python
#! -*- coding: utf-8 -*-

import sys
import numpy as np
import tensorflow as tf
import cv2


NUM_CLASSES = 2
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

def inference(images_placeholder, keep_prob):
    """ モデルを作成する関数

    引数: 
      images_placeholder: inputs()で作成した画像のplaceholder
      keep_prob: dropout率のplace_holder

    返り値:
      cross_entropy: モデルの計算結果
    """
    def weight_variable(shape):
      initial = tf.truncated_normal(shape, stddev=0.1)
      return tf.Variable(initial)

    def bias_variable(shape):
      initial = tf.constant(0.1, shape=shape)
      return tf.Variable(initial)

    def conv2d(x, W):
      return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def max_pool_2x2(x):
      return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1], padding='SAME')
    
    x_image = tf.reshape(images_placeholder, [-1, 28, 28, 3])

    with tf.name_scope('conv1') as scope:
        W_conv1 = weight_variable([5, 5, 3, 32])
        b_conv1 = bias_variable([32])
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

    with tf.name_scope('pool1') as scope:
        h_pool1 = max_pool_2x2(h_conv1)
    
    with tf.name_scope('conv2') as scope:
        W_conv2 = weight_variable([5, 5, 32, 64])
        b_conv2 = bias_variable([64])
        h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

    with tf.name_scope('pool2') as scope:
        h_pool2 = max_pool_2x2(h_conv2)

    with tf.name_scope('fc1') as scope:
        W_fc1 = weight_variable([7*7*64, 1024])
        b_fc1 = bias_variable([1024])
        h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
        h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    with tf.name_scope('fc2') as scope:
        W_fc2 = weight_variable([1024, NUM_CLASSES])
        b_fc2 = bias_variable([NUM_CLASSES])

    with tf.name_scope('softmax') as scope:
        y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

    return y_conv

if __name__ == '__main__':
    test_image = []
    for i in range(1, len(sys.argv)):
        img = cv2.imread(sys.argv[i])
        img = cv2.resize(img, (28, 28))
        test_image.append(img.flatten().astype(np.float32)/255.0)
    test_image = np.asarray(test_image)

    images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS))
    labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES))
    keep_prob = tf.placeholder("float")

    logits = inference(images_placeholder, keep_prob)
    sess = tf.InteractiveSession()

    saver = tf.train.Saver()
    sess.run(tf.global_variables_initializer())
    saver.restore(sess, "./model.ckpt")

    for i in range(len(test_image)):
        pred = np.argmax(logits.eval(feed_dict={ 
            images_placeholder: [test_image[i]],
            keep_prob: 1.0 })[0])
        print (pred)
```

#####結果１

沢尻エリカの画像10枚（0が帰って来れば正解まる）を使って検証しました。
9枚正解、1枚不正解でした。
（テストデータの正解率85%だから、まあこんなもの？検証というには枚数少なすぎ？）

```
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/f885be6e6214433e531a36f265b89030feffcfcc38524a1f9fe50fd270cc2177.jpeg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/f918d1eddf2c94592868075d45bf9368c818050cab86d56dbf8dfcf42445daaa.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/f9e43c4b6ec9c408891aef1cd89a6a05293933422f26afbb36692dff689dfd8b.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fab18876e469d224fcead1dff74ee50c2ec2f46087741725ef1c100f7bf1839f.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fbdac60677937487f9584c6d13b07597f5a3c757a65eacba0672f0659740848d.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fcbf4c42a6368963d43a659d684ee0bdd979acb3ead64e4d0317df7b0e6ba4c8.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fdfe7f0e994cc49a5fa32d73a5d15919206347e6c3fa0f622d217eab210bbba4.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/febb582342e4a6f4733c0bee2d61f032fe675c2d5ed73e02ac3b6d6ad788bc0e.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fecf271a586c97bb06105fab3babc1d9091d0303b92e8b3ad1f06202476e512a.jpg
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/ffe965f8aa816fe0609e697044242e7f9b7796a02a44de3785283df2943c8a65.jpg
0
```

使った画像
![f885be6e6214433e531a36f265b89030feffcfcc38524a1f9fe50fd270cc2177.jpeg](https://qiita-image-store.s3.amazonaws.com/0/223989/5231a8fe-5e3e-7c95-a47e-62c4a03e6892.jpeg)f885be6e6214433e531a36f265b89030feffcfcc38524a1f9fe50fd270cc2177.jpeg
正解
![f918d1eddf2c94592868075d45bf9368c818050cab86d56dbf8dfcf42445daaa.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/3b1bc480-39a4-fc21-4e36-8a20c09ffb37.jpeg)f918d1eddf2c94592868075d45bf9368c818050cab86d56dbf8dfcf42445daaa.jpg
正解
![f9e43c4b6ec9c408891aef1cd89a6a05293933422f26afbb36692dff689dfd8b.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/6b4eae14-aac1-da2d-4c82-dd87b5af4167.jpeg)f9e43c4b6ec9c408891aef1cd89a6a05293933422f26afbb36692dff689dfd8b.jpg
正解
![fab18876e469d224fcead1dff74ee50c2ec2f46087741725ef1c100f7bf1839f.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/1daa6bd1-5a98-b5ad-6b40-84c69182fb93.jpeg)fab18876e469d224fcead1dff74ee50c2ec2f46087741725ef1c100f7bf1839f.jpg
正解
![fbdac60677937487f9584c6d13b07597f5a3c757a65eacba0672f0659740848d.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/b4277b6d-457d-3f94-c296-8006e6ff74c4.jpeg)fbdac60677937487f9584c6d13b07597f5a3c757a65eacba0672f0659740848d.jpg
正解
![fcbf4c42a6368963d43a659d684ee0bdd979acb3ead64e4d0317df7b0e6ba4c8.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/22009752-b07f-21f1-9dca-fb413abbc8d4.jpeg)fcbf4c42a6368963d43a659d684ee0bdd979acb3ead64e4d0317df7b0e6ba4c8.jpg
正解
![fdfe7f0e994cc49a5fa32d73a5d15919206347e6c3fa0f622d217eab210bbba4.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/48a90270-7eee-251c-70e3-f79733351f68.jpeg)fdfe7f0e994cc49a5fa32d73a5d15919206347e6c3fa0f622d217eab210bbba4.jpg
正解
![febb582342e4a6f4733c0bee2d61f032fe675c2d5ed73e02ac3b6d6ad788bc0e.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/aec16858-2d10-68ce-202c-3ebda628776b.jpeg)febb582342e4a6f4733c0bee2d61f032fe675c2d5ed73e02ac3b6d6ad788bc0e.jpg
正解
![fecf271a586c97bb06105fab3babc1d9091d0303b92e8b3ad1f06202476e512a.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/7e9eb6d1-3c11-9cda-41e5-2069cf21f965.jpeg)fecf271a586c97bb06105fab3babc1d9091d0303b92e8b3ad1f06202476e512a.jpg
不正解×
![ffe965f8aa816fe0609e697044242e7f9b7796a02a44de3785283df2943c8a65.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/f93390f2-9c2a-d221-8ecb-5b62dfcdd16a.jpeg)ffe965f8aa816fe0609e697044242e7f9b7796a02a44de3785283df2943c8a65.jpg
正解

#####結果２

武井咲の画像10枚（1が帰って来れば正解まる）を使って検証しました。
7枚正解、3枚不正解でした。
全然ダメじゃん（涙）

```
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/f98c5f34aa13755a011ddd8fce4d9190c0504fbbde93f3402679758bb031f304.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fc41110aedf620e4546564c84317de072c778042c546325d15f36c8b86f0d88f.jpg
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fc529e533490bff6386fd84d94821ec7e9bc6d9d6dfe4e9b02611755ee6ee77a.jpg
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fdfdabc1999453193207a07dedbe2a5be0e9d2f8629a3ab949ae1f7b77d4f0d4.jpg
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fe06812f63527de0151c80b873d079af0e816f3585837aee92ae8117dc5b4fc9.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/febd41e6de949d68929aafe4ec2f3a3bad06331dece61270de73e8d622dc76d1.jpg
0
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/fec8bd3c8ac308acf872420db4d27f6ad6c4f9f56aec799d2685cdd19f42dc2c.jpeg
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/ff2f844294dd52092043d60fff85a1d8fbf6a033b299bdee6daa077f5da98c14.png
1
[yuni@machinelearningvm tensorflow]$ python3 FaceType.py /home/yuni/azureVM/data/ff9b638e43b0760f1a546b75321150fc9c190535aedfd023fa5839729d1c51a3.jpeg
1
```

使った画像
![f98c5f34aa13755a011ddd8fce4d9190c0504fbbde93f3402679758bb031f304.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/be3a8de3-8aa8-13c6-86bb-75893fccc848.jpeg)
f98c5f34aa13755a011ddd8fce4d9190c0504fbbde93f3402679758bb031f304.jpg
不正解

![fc41110aedf620e4546564c84317de072c778042c546325d15f36c8b86f0d88f.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/7de4d764-e91c-3e22-ca0a-78a3e2a8f594.jpeg)
fc41110aedf620e4546564c84317de072c778042c546325d15f36c8b86f0d88f.jpg
正解

![fc529e533490bff6386fd84d94821ec7e9bc6d9d6dfe4e9b02611755ee6ee77a.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/dc9875a8-3c17-82eb-e5ab-2067b19b5d1c.jpeg)
fc529e533490bff6386fd84d94821ec7e9bc6d9d6dfe4e9b02611755ee6ee77a.jpg
正解

![fdfdabc1999453193207a07dedbe2a5be0e9d2f8629a3ab949ae1f7b77d4f0d4.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/6a88ef87-72d9-0e20-61b9-c365dc3ef3c1.jpeg)
fdfdabc1999453193207a07dedbe2a5be0e9d2f8629a3ab949ae1f7b77d4f0d4.jpg
正解

![fe06812f63527de0151c80b873d079af0e816f3585837aee92ae8117dc5b4fc9.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/d4dcf59c-7c7b-e259-5748-3396c6597e15.jpeg)
fe06812f63527de0151c80b873d079af0e816f3585837aee92ae8117dc5b4fc9.jpg
不正解

![febd41e6de949d68929aafe4ec2f3a3bad06331dece61270de73e8d622dc76d1.jpg](https://qiita-image-store.s3.amazonaws.com/0/223989/26f929fb-203a-c18d-f396-637e50905224.jpeg)
febd41e6de949d68929aafe4ec2f3a3bad06331dece61270de73e8d622dc76d1.jpg
不正解

![fec8bd3c8ac308acf872420db4d27f6ad6c4f9f56aec799d2685cdd19f42dc2c.jpeg](https://qiita-image-store.s3.amazonaws.com/0/223989/4f472f71-7b15-d953-26f4-859ba8b189d5.jpeg)
fec8bd3c8ac308acf872420db4d27f6ad6c4f9f56aec799d2685cdd19f42dc2c.jpg
正解

![ff2f844294dd52092043d60fff85a1d8fbf6a033b299bdee6daa077f5da98c14.png](https://qiita-image-store.s3.amazonaws.com/0/223989/45fd3947-a084-b89f-038c-80c7f9d64866.png)
ff2f844294dd52092043d60fff85a1d8fbf6a033b299bdee6daa077f5da98c14.png
正解

![ff9b638e43b0760f1a546b75321150fc9c190535aedfd023fa5839729d1c51a3.jpeg](https://qiita-image-store.s3.amazonaws.com/0/223989/cad268a6-b75b-3f32-0dbe-107b4ba6169f.jpeg)
ff9b638e43b0760f1a546b75321150fc9c190535aedfd023fa5839729d1c51a3.jpeg
正解



###tensorflowのワーニング解消
ところで、これまでtensorflowを動かすと出ていたワーニング

```
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE3 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up CPU computations.
```

.pyファイルに２行追加して解消できました。

```import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
```

お疲れ様でした。


（2018/4/10追記）
判定結果を0/1でなく、スコアを表示してみました。
[芸能人の顔を機械学習で分類してみた（その６）](https://qiita.com/yuni/items/95628d1534da94bb3466)