数値解析系

2017年3月18日 (土)

IBMが数年以内に汎用の量子コンピュータを公開!?

スパコンの京でさえ何年もかかる計算を短時間で解いてしまうといわれる量子コンピュータ。

より現実的に使える量子コンピュータを数年以内に完成させようとIBMが取り組んでるそうです。

IBM、現行スパコンを超える「汎用」量子コンピュータを数年内に公開へ - PC Watch

ところでこの量子コンピュータですけど、あらゆる計算でスパコン以上の速度が出せると言わけではありません。

量子コンピュータが期待されているのはいわゆる「巡回セールスマン問題」と呼ばれる”組み合わせ最適化”問題を短時間で解くこと。

例えば、日本中にあるすべての都市を最短でまわるためにはどういう順に回ればいいか?という問題をスパコンを使って総当たりで解こうとすると、それこそ何億年もかかってしまうほどの膨大な組み合わせになるそうですが。

これを「量子アニール」を用いて一発で最適解を探し出せるというのが量子コンピュータの特徴、だそうです。

例えばディープラーニングでは多くの教師データを用いて多層のニューラルネットワークを形成するわけですけど、その際の最適化計算もこれを使えばかなり短時間で終わることができる、かもしれません。

量子コンピュータについてめちゃくちゃ詳しいわけではありませんが、組み合わせ問題の複雑さは目の当たりにしているため、量子コンピュータの登場には期待しております。

この量子コンピュータの性能を決めているのが”量子ビット”の数。従来5qubit(量子ビット)だったものが20qubitとなり、汎用にするためにはこれをさらに50qubitにする必要があるようです。

わりと夢物語だった量子コンピュータですけど、だんだん現実的になりつつあるようですね。ただ、従来のコンピュータでは不可能だった複雑な暗号コードを瞬時に打ち破ることも可能になるかもしれないため、悪用される懸念もあるそうです。便利な反面、そういう厄介な事態を引き起こすというのもまた、コンピュータの宿命でしょうかね?

量子コンピュータが人工知能を加速する

2017年3月11日 (土)

TensorFlowの画像認識コードを高解像度化してみた

Re:ゼロから始めるディープラーニング: EeePCの軌跡で宣言した通り、まったりとディープラーニングの勉強を進めてます。

ついでに職場にある私のワークステーションにもTensorFlowをインストールして、CAEがらみの画像認識実験もちょくちょくやっております。

といっても、コードは以下の記事で使用したものをほぼそのまま使ってるだけ。

TensorFlowで”日本のお城”を識別させてみた: EeePCの軌跡

このコード、画像を28×28で読み込んで学習・認識しているため、ちょっと低解像度過ぎるのが難点。

元々MNISTの手書き文字の認識用のためこの解像度でも行けたんでしょうが、私が使うレベルの画像認識にはもう少し解像度が欲しいところ。

ということで、縦横それぞれ倍の56×56に拡張してみました。

ただ、今までのコードの「28×28」の部分を「56×56」にしただけでは、画像認識の精度がかえって下がります。

このため、この辺りの記事を参考に畳み込み層+プーリング層のペアを一つ増やしてみました。

続・TensorFlowでのDeep Learningによるアイドルの顔識別 - すぎゃーんメモ

TensorFlowによるももクロメンバー顔認識(中編) - Qiita

これで高解像度化&認識率アップできます。

元々が「畳み込み層+プーリング層」×2+結合層×2の6層でしたが。

高解像度化に伴い「畳み込み層+プーリング層」×3+結合層×2の8層になりました。

◆学習用コード「cnn_train_56.py」

#!/usr/bin/env python
import sys
import cv2
import numpy as np
import tensorflow as tf
import tensorflow.python.platform

NUM_CLASSES = 7
IMAGE_SIZE = 56
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('train', 'train.txt', 'File name of train data')
flags.DEFINE_string('test', 'test.txt', 'File name of train data')
flags.DEFINE_string('train_dir', '/mnt/c/linux/data', 'Directory to put the training data.')
flags.DEFINE_integer('max_steps', 300, 'Number of steps to run trainer.')
flags.DEFINE_integer('batch_size', 20, '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):

    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, 56, 56, 3])

    with tf.name_scope('conv1') as scope:
        W_conv1 = weight_variable([3, 3, 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([3, 3, 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('conv3') as scope:
        W_conv3 = weight_variable([3, 3, 64, 128])
        b_conv3 = bias_variable([128])
        h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)

    with tf.name_scope('pool3') as scope:
        h_pool3 = max_pool_2x2(h_conv3)

    with tf.name_scope('fc1') as scope:
        W_fc1 = weight_variable([7*7*128, 1024])
        b_fc1 = bias_variable([1024])
        h_pool3_flat = tf.reshape(h_pool3, [-1, 7*7*128])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool3_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

def loss(logits, labels):

    cross_entropy = -tf.reduce_sum(labels*tf.log(logits))

    tf.summary.scalar("cross_entropy", cross_entropy)
    return cross_entropy

def training(loss, learning_rate):

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

def accuracy(logits, labels):

    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()
        img = cv2.imread(l[0])
        img = cv2.resize(img, (56, 56))
        train_image.append(img.flatten().astype(np.float32)/255.0)
        tmp = np.zeros(NUM_CLASSES)
        tmp[int(l[1])] = 1
        train_label.append(tmp)
    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, (56, 56))
        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():

        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)
        loss_value = loss(logits, labels_placeholder)
        train_op = training(loss_value, FLAGS.learning_rate)
        acc = accuracy(logits, labels_placeholder)

            saver = tf.train.Saver()
        sess = tf.Session()

        sess.run(tf.global_variables_initializer())

        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 = FLAGS.batch_size*i

                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})

            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))

            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")

◆認識用コード「cnn_app2_56.py」

#!/usr/bin/env python

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

NUM_CLASSES = 7
IMAGE_SIZE = 56
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('analysis', 'analysis.txt', 'File name of analysis data')

def inference(images_placeholder, keep_prob):

    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, 56, 56, 3])

    with tf.name_scope('conv1') as scope:
        W_conv1 = weight_variable([3, 3, 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([3, 3, 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('conv3') as scope:
        W_conv3 = weight_variable([3, 3, 64, 128])
        b_conv3 = bias_variable([128])
        h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)

    with tf.name_scope('pool3') as scope:
        h_pool3 = max_pool_2x2(h_conv3)

    with tf.name_scope('fc1') as scope:
        W_fc1 = weight_variable([7*7*128, 1024])
        b_fc1 = bias_variable([1024])
        h_pool3_flat = tf.reshape(h_pool3, [-1, 7*7*128])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool3_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 = []
    test_filenm = []
#    for i in range(1, len(sys.argv)):
#        img = cv2.imread(sys.argv[i])
#        img = cv2.resize(img, (56, 56))
#        test_image.append(img.flatten().astype(np.float32)/255.0)
#    test_image = np.asarray(test_image)
    f = open(FLAGS.analysis, 'r')
    for line in f:
        line = line.rstrip()
        l = line.split()

        test_filenm.append(l[0])
        img = cv2.imread(l[0])
        img = cv2.resize(img, (56, 56))
        test_image.append(img.flatten().astype(np.float32)/255.0)
    test_image = np.asarray(test_image)
    f.close()

    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)):
        accr = logits.eval(feed_dict={
            images_placeholder: [test_image[i]],
            keep_prob: 1.0 })[0]
        pred = np.argmax(logits.eval(feed_dict={
            images_placeholder: [test_image[i]],
            keep_prob: 1.0 })[0])
        print (test_filenm[i],pred,accr)

一見すると何の進歩もなさそうに見えますが、以前よりちょくちょくパラメータ値が変わってるところがあります。

まず、Anaconda 4.2.0 for Windows(64bit)+TensorFlow 0.12.0でWarningが出てたのを全部修正しました。

また、認識用コードは複数のファイルを読めるようにしました。

analysis.txt」というファイルに認識させたい画像ファイル名を書き込んでおくと、その中にあるファイルをいっぺんに処理してくれます。

相変わらず学習用コードには”教師データファイル名+ラベル”が書かれた訓練用ファイル一覧「train.txt」とテスト用ファイル一覧「test.txt」の2つも必要です。この辺は先の記事を参考に。

早速、これを使って画像認識させてみました。

使ったのはTensorFlowで”日本のお城”を識別させてみた: EeePCの軌跡で使った画像データ。

Castle02

Anaconda for Windowsのコマンドラインで

> python cnn_train_56.py

と入力して実行。

縦横2倍、データ量にして4倍に増えたため、さすがに時間かかります。

うちのメインPC(Corei3 3220 2コア4スレッド 3.3GHz)で300サイクル回すと40分ほどかかりました。以前は数分で終了。データは4倍ですが、時間は4倍以上かかります。

というのもデータ量が増えただけでなく、収束するまでのサイクルも増加。

以前は70~100サイクルも回せば十分だったのが、今回は最低でも150サイクルは必要で、余裕を見て300サイクル回してます。

学習が終了したら、今度は”認識”させてみます。

認識用に用意したこちらの画像。

Tf_casle01

各お城 3枚づつのデータを準備。

それぞれのお城のラベル(0~6)を各ファイル名の頭につけておきました。

この画像ファイル名を一覧にしたファイル「analysis.txt」を準備して

> python cnn_app2_56.py

と実行。

返ってきた結果は

Tf_casle02

こんな感じになりました。

「判定」の黄色に塗った部分が正解だった画像。

横の%でかかれた数字は、それぞれのラベルの判定率。最も数値の大きかったところをオレンジで塗ってます。

黒枠のところにオレンジが収まっているのが正解。ですが、熊本城、犬山城、大坂城でそれぞれはずれが出てますね。

全21枚中、当たりは17枚。正解率 81.0%。

特に”犬山城”のはずれっぷりが目立ちますが、犬山城の画像のうち、2枚だけは学習に使った画像よりちょっと斜め上から見たものを認識させたんです。

天守閣中央に特徴的な屋根の形があるので少々ずれてても認識するんじゃねぇ?と思って入れたんですが、やはりだめでしたね。

犬山城をのぞけば高解像度化のおかげか、まあまあの正解率。実質9割くらいじゃないかなぁと。なかなかやりますね。

ちなみに職場では「畳み込み層+プーリング層」をさらに一つ増やして112×112まで解像度を増やしたコードを作成してます。

ただ、自宅で用意した教師データは64×64になっているため、自宅用は56×56どまり。

実は112×112にしても正解率がかえって下がってしまってるため、現在いろいろとチューニングの真っ最中。うまく行ったら、またブログにて公開します。

ただ人の顔やお城くらいなら、56×56の解像度でも大丈夫っぽいですね。

しかし勉強の途中でコードをいじりだして大丈夫か?と思われそうですが。

ただ、この動くコードというのは、プログラミングを勉強する上では結構大事。

「ゼロから作るDeep Learning」を読みながらこのコードを読むと、例えば”loss”っていう関数が一体何をやってるのか?など理解が進みます。

本を読むだけでは眠くなっちゃいますが、手を動かしてコードを書き換えてみて実際の動きを確認しながら読み進めると、いろいろとわかって面白いです。

「ゼロから作るDeep Learning」自体はTensorFlowを使っているわけではありませんが、やってることは同じなので、TensorFlowのコードでも非常に参考になるんです。

とりあえず実際に動くコードを手元において、教材片手にいじりながら読むのはおすすめです。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

2017年2月19日 (日)

python上のグラフを漫画風に変えてしまう宣言文”xkcd”

pythonにしてはずいぶん砕けた機能です。

”xkcd”というWeb漫画があるそうですが、python上のグラフをそのxkcd風に変えてしまうという機能があるそうです。

【xkcd】pythonコードにたった一行で漫画のようなグラフを作る! - プロクラシスト

例えばこんなグラフ。

なんだか、手書きのグラフのようですね。

pythonでグラフを書かせる際に、以下のようなコードを先頭につけるといいようです。

import matplotlib.pyplot as plt
plt.xkcd()

これを使えば、3Dグラフもこの通り。

脱力感というか、あまり真面目な数値データに見えませんねぇ。

使い道を聞かれても困っちゃいますが、例えばこういう感じの和んだ雰囲気の資料が作りたいときにはぜひ活用してみてはいかがでしょうか?

今すぐ使える!資料を「一目瞭然」にする グラフの正しい使い方 ~人を動かす!数学的コミュニケーション術2~ (幻冬舎plus+)

2017年2月18日 (土)

”Japan IT Week関西”に参加するため大阪出張

2月16日木曜日の話ですが、大阪に出張してきました。

Img_2614

乗った新幹線は7:25 名古屋発 ひかり493号

Img_2585

ここに至る途中、地下鉄 鶴舞線からJRの鶴舞駅より名古屋に向かったんですが。

そのJR鶴舞駅そばにはポケモンGOの聖地といわれれた鶴舞公園があります。

Img_0645

まだ朝6時40分ごろ。すでにルアーモジュール全開です。

この日はちょうど金銀ポケモンリリース前日。こんなに盛り上がるネタはないはずなんですが・・・聖地はやはり違いますねぇ。

Img_2589

おっと、ポケモンGOの話ではありませんね。Japan IT Weekです、IT。

Img_2590

新大阪へGO!

Img_2593

途中、関ケ原を通過。”関ヶ原の合戦”の、あの関ヶ原です。

まだ残雪が結構ありましたね。中央にあるのは伊吹山です。

ちなみにこの山、1927年に積雪11メートルを記録したらしいです。観測記録がある場所での世界一の積雪量だとか。これ豆知識。

この雪、米原あたりまで続いてました。

Img_2595

途中、京都に停車。中央にあるのは京都タワー。

シンボルタワーが”テレビ塔”のどこかの都市とは大違い、ちょっとおしゃれですねぇ。

Img_2601

で、ほどなく新大阪に到着。

約50分。東京に行くよりは近いです、新大阪。

Img_2605

ところがここからが迷いました。

経路としては、新大阪駅 → 大阪駅 →(大阪環状線)→ 弁天町駅 →(地下鉄)→ コスモスクエア駅 なんですが、そもそも大阪駅へはどの線の何行きに乗ればいいのかがわかりにくい

新幹線の新大阪駅から大阪駅へ行くのはある意味デフォなんですから、もうちょっとわかりやすくならんもんですかねぇ・・・

ところで

Img_2583

近年「エスカレーターは歩かない」といわれつつも残っているのはこのマナー。

急ぐ人用に片側を開けるというやつですが、東京・名古屋はごらんのとおり急ぎ用は右側、歩かない人は左に寄ります。

Img_2713

ちょっとわかりにくいですが、大阪は左側が急ぎ用通路。なので、歩かない人は右に寄ります。

これわりと有名な慣習の違いとして知られてますけど。

この日の大阪駅は両方歩け!でした。右に寄ったのに止まれません。

恐ろしいところです、大阪は。

ところで、大阪駅に着いたのは8時半ごろ。

一方、Japan IT Week関西の会場が開くのが10時。

このままストレートにいくと30分程度あれば着きます。1時間ほど余裕があるんですが。

Img_2609

実はこういうところに寄り道。八幡屋公園というところ。

Img_8274

実はこの時期、この辺りは「ワンリキーの巣」になってたため、訪れた次第。

Img_0649

ものの20分ほどで数匹捕獲。無事”カイリキー”に進化させられました。

これで、金銀ポケモンリリース前には残り4種類(カブトプス、ベトベトン、ブビィ、トゲチック)で国内コンプリートというところまで来てたんですけどね。

おっと、ポケモンGOの話じゃない、ITです、IT。

Img_2611

ちょうど10時には会場のインテックス大阪に到着。

名古屋でいうところの”ポートメッセなごや”でしょうか。規模は段違いですが。

Img_2613

会場に着くと、Japan IT Weekは一番奥のようです。同時にメディカル ジャパンてのも行われてました。

Japan IT Weekとは、要するにIT関連の展示会。IoTやモバイル、クラウドコンピューティングに関する企業が一堂に会したビッグイベントです。

Img_2617

それにしても、マップに書かれた”奥の会場”というのが予想以上に遠くて・・・結構歩きました。

Img_2623

受付にたどり着くとすでにこの人の山。15分ほどかかって受付終了。

ちなみに、受付時には自分の職種(経営、システム開発、生産、設計・開発、営業・・・)に合わせた札がもらえます。

その札を見れば、会場の人がどのフレンズ・・・じゃない、どんなジャンルの人かが一目でわかります。

なお、私は「設計・開発」フレンズですね。会場内にもわりといました、設計フレンズ。

Img_0652

やっと、中に入ります。

Img_2627

受付では凄い混みようでしたが、中に入るとまだ人はまばら。

各ブースの人もまだ少ない客めがけて客寄せしてましたが。

Img_2665

これが昼になるともうこの有様。

Img_2663

こんな感じに案内図はもらいましたけど、どのブースも似たようなレイアウトで、すぐに迷いました。

なお、会場は2つに分かれてて、全部で300社が出展。そりゃ迷うわけです。

さて、ここでようやく会場内の紹介です。やっと本題ですね。

気になるブースを紹介します。

Img_2635

まずはJUST SYSTEM。一太郎やATOKの、あのJUST SYSTEMです。

Img_2634

しかし、ここで展示されていたのは「BIツール」とよばれるもの。

例えば、たくさんの販売拠点があって、それぞれの拠点での毎月の売り上げの変動を把握するためにデータを分析したい。そういう需要、当然あります。

その時そのデータを見やすくし、かつ売り上げが変動した場合の履歴を残せたりする(グラフにコメントを紐づけできる)ので、経営戦略上は非常に役立つツールです。

私のところでも、例えば部署内で収支の集計てのはやりますますけど、部門内全体での集計はそれぞれのところから月に一回Excelのファイルを集めているような状況。リアルタイムな変化なんて追っかけてません。

さまざまな会議で使ういろいろな分析資料を作る業務もあるんですが、この断片的なファイルをいちいちかき集めて作っているのが現状。

これがあればほんとクリック一発。欲しいですね、うちにも。

Img_2636

続いてmineoです。MVNOのあのmineo。

企業向けにもIoTサービスやってたんですね、ここ。

Img_0668

他にも、社内の携帯機器向けにお安いプラン提案もやってました。

料金は個人向けと全く同じですね。

Img_2640

HPCシステムズという会社もブースを構えてました。

この会社、クラスタリングシステムを手掛けているところという認識でしたが。

Img_0666

ここでは”ディープラーニング”向けの機器を展示・紹介。

機械学習用にはGPUがかなり有効ですけど、この機器は(会社が買うには)お手軽な価格で提供されているもの。

Img_0665

ちなみに、世界最速なれども値段高し というNVIDIA製DGX-1という端末もありました。

こいつのお値段は・・・会社的にもちょっと高い。

これが買えるくらいのツールを私も作れるようになって、導入してみたいですね。

Img_2669

jettiとは、海外出張向けのモバイルWi-Fiルーターをレンタル・販売・通信サービス提供をしている会社。

例えばシンガポール経由でタイに行ったりする場合、どちらの国でも定額で使えるルーターを貸してくれるところのようです。

複数の国に出張する場合は便利ですね。

Img_2660

MSソリューションズというところはカスタムスマホ・タブレットケースを作る会社。MS社とは関係ないようです。

例えば営業向けに肩掛けと名刺入れをつけたケース作って、という要望に応えられるところです。

Img_2664

ああ、うちも図面と一緒に持ち歩けるiPadケースなんてあると便利ですよねぇ・・・なんて感じの話をしてたら、なぜかiPhone 6のケースをくれました。

Img_2666

MOTEXというところでは、新しいウィルス対策ソフトの紹介やってました。

Img_0667

プロテクトキャットというソフト。人工知能を搭載しており、ファイルの中を分析して未知のウィルスでも発動前に除去してくれるという画期的な対策ソフトです。未知のウィルスの防御率はなんと99.7%!

Img_2651

ところで、この最新のIT機器・サービスの展示会にこんなものが!

どう見てもPC-8001、ThinkPad 701。タイムスリップでもしたのか!?

Img_2653

と思ったら”パソコン回収.com”というブース。

こんな古いパソコンでも無料で回収してくれます。いやそれ、無料じゃもったいないでしょう・・・買取もやってるみたいですが。

上の写真の中央部もよーく見ると

Img_26531

MZ-80Bです。しかも動いてました、これ。

最新のIT情報を入手するはずが、こんなところで貴重なマシンに出会えるとは、ちょっと感動です。

Img_2641

広い会場とはいえ、二つのビッグイベントを抱えていて、昼食は大丈夫なのか・・・と心配になりましたが。

Img_2643

敷地内にはところどころこんな感じの売店があって

Img_2645

適当ですけど、何とか済ませることができました。

ちょっと興奮気味だったのか、あまり食欲はなかったですね。

Img_2649

会場内にもこんな店がありました。

くどいのばかりでこのときはあまり食べる気にはなりませんでしたけど、今だったらちょっと食べたいかなぁ。

Img_0651

なお、ここはコイル・ビリリダマの巣になってるようで、ひたすら湧いてたみたいです。

が、正直ポケモンGOをやる暇など、ありませんでした。なにせ一日で300社をスキャンしなきゃいけませんし。

Img_2657

いろんなブースがあって、なぜかミニ四駆を走らせているところや

Img_2655

会議の音声から勝手に議事録を作ってくれるシステムを扱ってるところや

Img_2630

自動運転、手話認識用の画像認識技術を展示してるところもありました。

Img_2654

私に限らず、ブロガーならちょっと気になるサービスも・・・

3時半から講演会があって、そっちにも参加してきました。

その中でGoogleクラウドを手掛ける方の講演があって、機械学習とクラウドサービスを活かすためにはという内容の話をされてました。

ご存知、GoogleはAI関連のサービスをいくつか展開。gmailで返信文章を自動で作成してくれたり、画像認識でスタジアムの写真からその場所や中に書かれた文字を解読してくれたり、などなどのGoogleサービスの話を中心にされてました。

TensorFlowのように企業がAIの活用につながるものも提供しているということもあって、機械学習を業務に活かすためにはという話も。

曰く、まずデータを一元化しないとだめ、とのこと。部署間や担当者間、グループ間でフォーマットがバラバラな状態では機械学習どころじゃないですよね。まあ、うちがそんな感じですが。

そこから”死角”を探し出し、これを解決するための方法を検証する・・・という試行錯誤で機械学習データやそれを利用する仕組みが活かされる。そんな内容でした。

Googleの様々なサービスも、こういうプロセスでできてるんですかね。参考にしてみます。

Img_2683

とまあ、そんなこんなで会場を後にし、再び新大阪へ。

お土産をどこで買おうかと思ってうろうろしていたら、新幹線改札手前でこんなコーナーを発見。

Img_2691

わりと大きな土産物屋、食事処が固まったところです。

時間に余裕があったので、ここで食事を済ませて土産を買って帰ることに。

Img_2688

食事は結局麺類のお店の

Img_2689

”新大阪そば”にしました。

このお店、レンゲがなかったんですよね・・・寿がきやでもあるでしょ、レンゲくらい。

Img_2693

でもそのあとでこのお茶漬け専門店を見つけちゃったんですよね。こっちの方が、このときはちょうどよかったんですが、もう食べちゃいましたし。

Img_2696

みやげ・食事店がかたまるこのコーナーでひときわ大きかったお店がこちら。

レシートで知りましたが、セブンイレブン系のお店でした。

Img_2703

こんな面白いものが売ってました。

一見お好み焼きですが、チーズケーキです。家族用に購入。

Img_2709

帰りは19時40分発のひかり。

東京方面に向かう人はひかりに乗らないため、結構空いてました。指定席は窓際に座る人がほとんどという状態。新大阪から名古屋に帰るなら”ひかり”ですね。

Img_8276

帰りの新幹線では、外が真っ暗でどこは知ってるのかさっぱりだったので、マップアプリで位置を確認。

考えたらこの経路は”関ヶ原の合戦”をやってた場所なんですよね。おかげで”大谷吉継の墓”なんてものが見えます。

大谷吉継、石田三成が負けるとわかっていて、それでも三成方についた義理の厚い西軍の武将。小早川秀秋の裏切りには三成をかばうように対抗したものの敗れ、最後は自刃したといわれています。

ちなみにマップの下にある松尾山は、その小早川秀秋が陣を張っていた場所。家康がしびれを切らして大鉄砲を松尾山に放ち、それをきっかけに小早川勢が動き、この合戦の勝敗は決したといわれております。

Img_8277

その家康のいた場所はそのちょっと先のあたり。島津義久・豊久が退き口で中央突破を図ったあの家康本陣のあったあたりを時速270kmで突破していきます、新幹線。

この時代にこんなものが走ってきたら、さすがの家康・島津もびびるでしょうねぇ。

Img_8278

などと下らない事を考えているうちに名古屋に到着。

Img_0658

名古屋駅のツインタワーを見て安心できる当たり、私はすっかり名古屋圏人ですねぇ。

Img_0660

さて、戦利品です。

先ほどのiPhoneケースと合わせて、こんなにいろいろもらいました。スマホグッズが多いですね。

Img_0663

なぜか食べ物系もいくつか混じってました。真ん中のは一応ポッキーです。

Img_0676

そしてお土産はこちら。

先ほどのお好み焼き風チーズケーキに神戸牛ラーメン。これが家族用。

職場用には焼きティラミス、そして私が”ごみやげ”と呼ぶ大量のお菓子の入った赤いやつ。

ごみやげとは「お土産は数だよ兄貴!!」なお土産のこと。とりあえず自分の部の人向け(総勢100人弱)にばらまけるだけの数で勝負のお土産、です。

Img_0673

結構大量のパンフレット(赤い袋に集約)と多くの袋。これが一番重かった・・・翌日には手が筋肉痛です。

Img_8279

歩いた歩数は2万歩以上、カロリーは目標の3倍越え、見たことのないアクティビティ値です。

こんな感じにIT情報収集に行ってまいりました。

今年はこんな感じの出張がちょくちょくありそうです。

大阪の恋人(ホワイトラングドシャ)

2017年2月14日 (火)

ビッグデータ解析に最適な”R”で”ランダムフォレスト”手法を体感してみた

最近、欲張りなことに”ディープラーニング”と”ビッグデータ解析”を同時に勉強してます。

ディープラーニングの方はさほど進展ありませんが、ビッグデータ解析でちょっと新しいツールと手法の存在を知ったので、早速使ってみました。

以下、このサイトを参考にしてます。

Rで遊ぶ ~ワインの等級をrandomForestで予測~ - Qiita

ここの記事が。ランダムフォレストってやつを試してみるには一番わかりやすかったですね。

ただ、ちょっとこの記事の内容だけでは端折りすぎててたどり着かなかったので、補足しつつ紹介。

まずツールですが、”R”と呼ばれるものがあります。

The Comprehensive R Archive Network

ビッグデータ解析や機械学習に使われる統計解析向けプログラミング言語・実行環境です。上のサイトから入手。

私はWindows版をゲット。バージョンは3.3.2でした(近々3.3.3が出るらしいですが)。

ダウンロードしたら早速インストール。

R_rndfrst01

デスクトップにアイコンができるので起動すると、こんな感じの画面が。

R_rndfrst02

さて、早速バリバリと使って解析・・・とはいきませんで、パッケージをインストールしなきゃいけません。

ここでは”caret”と”randomForest”の2つのパッケージを使うので、これらをインストールします。

上のメニューの”パッケージ”から”パッケージのインストール”を選択。

R_rndfrst03

最初だけ接続先を聞かれます。”Japan(Tokyo)”というのを選びます。

R_rndfrst04

続いてパッケージを選択。

R_rndfrst06

ほんとにたーくさんあるので気がめいってきますが、この中から”caret”と”randomForest”を探し出してCtrlキーを押しながら選択し”OK”をクリック。

R_rndfrst05

なにやらインストールがはじまります。

しばらくすると終了。

いよいよ、ビッグデータ解析の手法の一つである”ランダムフォレスト”ってやつを使ってみます。

と、その前にランダムフォレストとはなんぞや?ですが。

以下に説明サイトを張り付けておきますが。

Rでランダムフォレスト(random forest) | 一言茶屋 ~統計、R、Excelとか~

多分、なんのことやらわからないかもしれません・・・私も、社内の勉強会で説明されるまでさっぱりでした。

てことで、私なりに説明を。

例えば、良品・不良品の明確な基準がない製品がある(出来上がったら良・不良がわかる)として、その製品の大きさ・重さから良品・不良品を分ける仕組みを作ろうとします。

R_rndfrst11

そこで、上のようにa(mm)、b(mm)、c(g)それぞれの良・不良の条件を仮に決めて、上のような枝分かれなふるいにかけます。

R_rndfrst12

右のような製品の場合、この基準では「不良品」とされてしまいます。

実際に、この製品が不良品だったならこの”ふるい”は正しいということになります。

こういうのを”決定木”といいます。

R_rndfrst13

こんな感じの決定木をたくさん作ります。

a、b、cの基準や枝分かれの数などはランダムに決定。

ただし、あらかじめ良品・不良品のわかっているデータを使って、この大量の決定木を”学習”させます。

学習によって作られた大量の”決定木”を使ってそれぞれで”良品”・”不良品”を判断させて、これら決定木の判断の多数決で良・不良を決定します。

最初の学習で”決定木”をランダムに生成し学習、その決定木をたくさん集めた”森”ということで”ランダムフォレスト”というそうです。

たくさんのデータがあれば、判断の精度も上がるようで、わりと使いやすく精度の高いビッグデータ解析手法として注目されているようです。

そんなランダムフォレストの威力を確かめるため、以下のサイトからデータを入手します。

UCI Machine Learning Repository: Wine Data Set

機械学習に使えるデータをたくさん登録しているUCIというサイトから、ワインの等級(1~3)とアルコール度やリンゴ酸含有量、色調などのデータが170個ほど収められてます。

上にある”Data Folder”をクリックすると、”wine.data”というCSV形式のファイルをゲットできます。

これをPC内に保存しておきます(ここでは”c:\tmp”に保存)。

先ほどインストールした”R”を起動、以下のコマンドを入力します。

> library(caret)
> library(randomForest)

続いて”wine.data”を読み込み。

> dat <- read.csv("c:/tmp/wine.data")

以下のコマンドを実行して、列名を直しておきます。

> names(dat) <- c("class", paste0("V", 1:13))
> dat <- transform(dat, class = as.factor(class))
> head(dat)

ここで

> str(dat)

と打ち込むと、データの概要が見えます。

> str(dat)
'data.frame':   177 obs. of  14 variables:
$ class: Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
$ V1   : num  13.2 13.2 14.4 13.2 14.2 ...
$ V2   : num  1.78 2.36 1.95 2.59 1.76 1.87 2.15 1.64 1.35 2.16 ...
$ V3   : num  2.14 2.67 2.5 2.87 2.45 2.45 2.61 2.17 2.27 2.3 ...
$ V4   : num  11.2 18.6 16.8 21 15.2 14.6 17.6 14 16 18 ...
$ V5   : int  100 101 113 118 112 96 121 97 98 105 ...
$ V6   : num  2.65 2.8 3.85 2.8 3.27 2.5 2.6 2.8 2.98 2.95 ...
$ V7   : num  2.76 3.24 3.49 2.69 3.39 2.52 2.51 2.98 3.15 3.32 ...
$ V8   : num  0.26 0.3 0.24 0.39 0.34 0.3 0.31 0.29 0.22 0.22 ...
$ V9   : num  1.28 2.81 2.18 1.82 1.97 1.98 1.25 1.98 1.85 2.38 ...
$ V10  : num  4.38 5.68 7.8 4.32 6.75 5.25 5.05 5.2 7.22 5.75 ...
$ V11  : num  1.05 1.03 0.86 1.04 1.05 1.02 1.06 1.08 1.01 1.25 ...
$ V12  : num  3.4 3.17 3.45 2.93 2.85 3.58 3.58 2.85 3.55 3.17 ...
$ V13  : int  1050 1185 1480 735 1450 1290 1295 1045 1045 1510 ...

ここで”class”とはワインの等級。この部分が最終的に予測させたい応答変数となります。

V1:アルコール度、V2:リンゴ酸、V3:灰、V4:灰のアルカリ性、V5:マグネシウム、V6:トータルフェノール量、V7:フラバノイド、V8:非フラバノイドフェノール類、V9:プロアントシアニン、V10:色彩強度、V11:色調、V12:蒸留ワインのOD280/OD315、V13:プロリンとあります。ワインに詳しいわけではないのでさっぱりですが、そういうパラメータがあるということで。

全部で178個のデータを、学習用と検証用に分けます。

手で分けてもいいんですが、以下のコマンドを使うとさらっと分けられます。

> index <- createDataPartition(dat$class, p=.8, list=F)
> train <- dat[index, ]
> test  <- dat[-index,]

こんな感じに、8割を学習用、2割を検証用に振り分けます。

続いてランダムフォレストでの機械学習に入るわけですが、その前に

> tuneRF(train[,-1], train[,1], doBest=T)

を実行。

R_rndfrst08

すると、こんなグラフが。

これ、決定木の枝分かれ層の数(mtry)の最適値を探る関数のようです。

リンク先記事には”6が最適”となってますが、上では2と6あたりがOOBエラーってのが小さめ(1はもっと小さいですが・・・)。2でも6でもよさそうです。

このグラフも、実行するたびに変化するんですが・・・なんなのでしょう?数回実行すると、だいたい6あたりが最小になってるっぽいです。

てことで、mtry = 6で実行。

> rf <- randomForest(class~., data=train, mtry=6)

応答変数を”class”、データは先ほど分離した”train”、決定木の層は”6”、決定木の数はデフォルト値(500)を使います。

で、機械学習の結果が”rf”ってやつに収められてるはずなんですが・・・これを検証します。

評価用に残した”test”ってデータを使って検証。

> table(predict(rf, test), test$class)
   
    1  2  3
  1 10  0  0
  2  1 14  0
  3  0  0  9

こんな感じのマトリックスが出てきます。

縦の列がランダムフォレストによって予測されたワインの等級、横が実際の等級を示しているようです。

例えば、”予測”も”実際”も1等級のものが10個あるといってます。

対角上にのみ数字が並べば全部正解!となったんですが、ランダムフォレストが”2等級”と予測したけど実際は1等級だったというものが1つだけあります。残念。

さて、V1~V13の”等級”に関する重みづけを次のコマンドで確認できます。

> importance(rf)
     MeanDecreaseGini
V1         7.1588086
V2         1.5091832
V3         0.6757448
V4         1.0331509
V5         1.7680900
V6         2.7761997
V7        19.1024801
V8         0.2138005
V9         0.8049197
V10       16.9945830
V11        5.8153684
V12       12.1655112
V13       23.5054326

ここではV13、V7、V10、V12、V1・・・の順に等級に影響を及ぼしていると推測できます。

とまあ、わかったようなわかんないような、ランダムフォレストのお試しでした。

これが一体何に使えるのか?

例えば、生産ラインで各々の機械に温度・加速度・光・・・・などのセンサーをつけておき、そのデータを記録。

ラインに流れる製品の良・不良を記録しておき、そのセンサーの値と合わせて保存。

ランダムフォレストによって学習したデータからは、いったいどのセンサー値が良・不良を左右しているかがわかります。

また、寄与度の高い場所でのセンサーの値が”不良品”寄りな値ばかり出すように変化した場合、ラインの異常を事前に予測できます。

つまり、工場でのIoTでの活用が期待されてるみたいですね。

この事例がそれにあたるのかどうかはわかりませんけど。

1個50円のセンサーで工場内IoT、残業ゼロに | ワクスタ(The Work Style Studio)

これを読む限り、多分、似たようなことをやっているものと思われます。

このほかにもSVMだのlasso回帰だの、いろいろな手法があるようです。この辺はこれから勉強する予定。

ディープラーニングもそうですが、複数の手法を知っておくといざ大量のデータに埋もれてしまいそうなときに助かるかもしれません。そんなわけで、これからもいろいろと試してみるつもりです。

データサイエンティスト養成読本 R活用編 【ビジネスデータ分析の現場で役立つ知識が満載! 】 (Software Design plus)

Google Brainが開発した 8×8の画像から元画像を復元する技術

8×8のモザイク状の画像から、元の画像を予測し復元してしまうという技術がGoogle Brainによって開発されているそうです。

8×8ピクセルに縮小した画像から元の画像を予想する技術をGoogle Brainが開発 - GIGAZINE

8×8の画像と復元画像(32×32)、そして元画像を比較してますが、確かによく復元されてますね。

もちろんまったく同じではありませんが、8×8というとかなり情報が縮退された状態。よくここまで戻せるものです。

この技術、2つのニューラルネットワークトレーニングを用いているようです。人の顔だけでなく、ほかの画像の復元もできるようですね。

こういう技術を見ると、男性諸君の中にはよからぬ用途に使うことを考えがちですが、これを使えば例えば昔の写真で不鮮明になってしまった部分の復元させたりできるかもしれません。おそらく、そういうのを想定しての技術なんでしょうね、きっと。

Adobe Photoshop Elements 15

2017年2月11日 (土)

TensorFlowで”日本のお城”を識別させてみた

ゼロから作るDeep LearningやInterface 3月号を読んで勉強中のわりに、相変わらずTensorFlowを使ってしょうもないことにトライしてます。

最近、大坂城の写真を見ていたら「名古屋城にちょっと似てなくない?」と思ったのがきっかけなんですが。

このレベルの微妙な差を、以前作った画像認識プログラムって識別できるんだろうか?などと考えたので、ちょっと実験してみました。

基本的には、以前書いた以下の記事のとおりにデータ収集から学習まで実行。

TensorFlowで歴代「クラウン」の画像を判別させてみた: EeePCの軌跡

ただし今回はWindows版Anaconda 4.2.0で実行(Python3.5版)させるため、コードをちょっといじってます。

■ 学習用コード「cnn_train.py

#!/usr/bin/env python
import sys
import cv2
import numpy as np
import tensorflow as tf
import tensorflow.python.platform

NUM_CLASSES = 7
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('train', 'train.txt', 'File name of train data')
flags.DEFINE_string('test', 'test.txt', 'File name of train data')
flags.DEFINE_string('train_dir', './', '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):

    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

def loss(logits, labels):

    cross_entropy = -tf.reduce_sum(labels*tf.log(logits))

    tf.scalar_summary("cross_entropy", cross_entropy)
    return cross_entropy

def training(loss, learning_rate):

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

def accuracy(logits, labels):

    correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    tf.scalar_summary("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()
        img = cv2.imread(l[0])
        img = cv2.resize(img, (28, 28))
        train_image.append(img.flatten().astype(np.float32)/255.0)
        tmp = np.zeros(NUM_CLASSES)
        tmp[int(l[1])] = 1
        train_label.append(tmp)
    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():

        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)
       
        loss_value = loss(logits, labels_placeholder)
       
        train_op = training(loss_value, FLAGS.learning_rate)
       
        acc = accuracy(logits, labels_placeholder)
       
        saver = tf.train.Saver()
       
        sess = tf.Session()
       
        sess.run(tf.initialize_all_variables())

        summary_op = tf.merge_all_summaries()
        summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, sess.graph_def)

        for step in range(FLAGS.max_steps):
            for i in range(int(len(train_image)/FLAGS.batch_size)):

                    batch = FLAGS.batch_size*i

                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})

            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))

            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")

■ 実行用コード「cnn_app.py

#!/usr/bin/env python
import sys
import numpy as np
import tensorflow as tf
import cv2

NUM_CLASSES = 7
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3

def inference(images_placeholder, keep_prob):

    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.initialize_all_variables())
    saver.restore(sess, "./model.ckpt")

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

注意点ですが、今回識別に使ったお城は全部で7種類のため、cnn_train.py、cnn_app.pyの最初の方に定義する変数「NUM_CLASSES =」の値は”7”です。

Windows用Anaconda(Python3.5)で動かすために、日本語のコメントは削除、print文などの書式変更をしております。

画像の入手(ImageSpyder)、ファイルの名前変更(bkrename)、収集した画像を正方形にカット(JTrim)、ファイルの一覧作成(OutFileList)は先の記事通り(TensorFlowで歴代「クラウン」の画像を判別させてみた)です。

Castle00 で、今回集めたお城のデータは以上の7種。お城の名前とナンバーの振り分け(0~6)は以下。

0、岡崎城

1、熊本城

2、犬山城

3、松本城

4、大垣城

5、大坂城

6、名古屋城

「なんでこの7種類なんだ」とか、「姫路城や弘前城、小田原城・・・・・・がないのはなぜだ!」とかいろいろ意見はあるでしょうが、この辺りで力尽きたため7種類になりました。

元々大坂城と名古屋城の比較をさせたかったため、この2つは必須だったんですが、ほかにも熊本城と松本城も黒いところが似てなくねぇ?なんて思ったのも事実。

大垣城は私の実家のあるところのお城ですし、愛知県といえば犬山城、岡崎城も外せませんね。

しかし、私の実家から2番目に近いところにあるお城(岐阜城)はすっかり忘れてました。

Castle02

で、収集した各城の画像データから学習データを作るんですが。

お城って、向きが違うとずいぶんと見栄えが違います。

てことで、それぞれ300枚以上の画像データを集め、

・ 天守閣が写っているもの

・ 最も多い画角の画像であること

を条件にして絞り込んでみました。

・ 岡崎城

0_012

なぜか手前に2本の松が写っているものが多いのですが、この画角のものを取り込み。

・ 熊本城

1_014

ググると、自身で崩れた石垣の写真が多かったですね・・・早く復旧してほしいものです。

・ 犬山城

2_005

コンクリート製の復元のお城が多い中、犬山城はオリジナルの木造のまま。国宝です。

・ 松本城

3_029

こちらもオリジナルのままの国宝のお城。黒いところは熊本城に似てますねぇ・・・似てませんか?

・大垣城

4_005

入り口付近の見上げた感じの写真が多かったので、これにしました。

石田三成、島津義久、徳川家康・・・などなどが関ケ原の合戦の前日までにらみ合ってた場所に立っているお城なんですけどねぇ。あまり有名ではありません。

・大坂城

5_003

余談ですが、Googleでは「大坂城」でも「大阪城」でも引っかかるんですけど、明治以前は「大阪」ではなく「大坂」だったので、ここでは「大坂城」で統一しております。

なんか、エレベータがついてますね、このお城。

・ 名古屋城

6_013

屋根の色だけ見ると、大坂城に似ているように見えます。

石垣だけは焼け残ったため、下はオリジナルで上の部分のみコンクリート製のお城という名古屋城。金ぴかのしゃちほこが有名ですが、それ以外にも・・・何がありましたっけ?

画角で絞り込みをやったおかげで、各々300枚以上のデータを収集したのに、残ったのはどれも30~100枚程度。

一番残ったのは意外にも犬山城で、300枚中100枚ほどが残りました。このお城、撮影するポイントが限られているのでしょうか、どの写真も似たような場所から撮影されてるっぽいですね。

で、画像が集まったところで、”bkrename”を使いファイル名を”そのお城のナンバー_3桁の数字.jpg”として名前を変更しておきます。

ファイル一覧から以下のようなテキストファイルを作成。

Tensorflow05

”ファイル名 ナンバー”の一覧を書き込んだファイルで、すべてのお城の画像ファイル名を一つのファイルに取り込み。その後、学習用とテスト用データに仕分けます。

学習用のデータは”train.txt”、テスト用は”test.txt”で保存。

学習用とテスト用の数は9:1で振り分け。60枚あったら、0_001.jpg~0_054.jpgが学習用、0_055.jpg~0_060.jpgがテスト用という具合。

画像データすべてとtrain.txt、test.txt および各コードを一つのフォルダに入れて、Windows版AnacondaでTensorFlow実行環境(”activate tensorenv”とコマンド入力)したのちに、

$ python cnn_train.py

と入力して機械学習を実行。

うちの環境では、大体10分ほどで完了。

Castle03

学習用とは別に準備した画像データを「cnn_app.py」で識別させてみます。

$ python cnn_app.py okazaki.jpg

などと打ち込むと、認識したコード(0~6)を出力。

Castle

わかりにくいですが、岡崎城なら”0”を、熊本城なら”1”を・・・名古屋城なら”6”を返してくれれば正解ですが。

なんと、用意した画像データすべて正解しました!

クラウンの時とは大違い。3種類以上のデータでもちゃんと認識できました。

やっぱり、お城はわかりやすいんですかね。

Dsc_0578

ところが私のブログ記事にも載せたこの大垣城の写真は、なぜか”1”の熊本城として認識されました。。。

天守閣のてっぺんがちゃんと写ってないので、もうちょっと後ろから撮影していれば、大垣城と認識してくれたかもしれません。

それにしてもどのあたりが”熊本城”だったのやら・・・TensorFlowの考えることはよくわかりません。

うまくいったのやらいかなかったのやら、いずれにせよ画角がちょっと変わると識別できないあたり、あまり実用性はなさそうです。

名古屋城と大坂城、熊本城と松本城を見分けることができただけでも大したものでしょうか。どちらかというと、この微妙な差を見分けられるかの実験だったので、まあ大成功といえるんじゃないでしょうか?

ところで「Re:ゼロから始めるディープラーニング: EeePCの軌跡」などという記事を書いたわりにはあまり成長を感じられない記事書いてるじゃないかと思われた方。まあ、その通りなんですけど、知識習得は継続中。

実は「ゼロから作るDeep Learning」の本以外にも機械学習について学ぶ機会ができそうで、今月からちょっといろいろ動く予定です。

さすがに私ももう40代後半ですので、いきなり成長することはありませんが、今後にご期待ください。。。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

2017年2月 2日 (木)

ディープラーニングが3時間で学べる動画

”ディープラーニング”という言葉自体そうですが、よくわからない難解な用語のオンパレード。

これがディープラーニングにトライしようとしている人たちを阻む最大の要因となってるようです。

そんな状況をたった3時間で解決できる講演動画が公開されてます。

Googleの開発者が作った3時間でディープラーニング(深層学習)をスライドとムービーで学べる集中レッスン - GIGAZINE

リンク先の記事を読む限り、たしかにわかりやすい説明で好評のようです。

が、一つだけ日本人にとっては大きな壁が。

それは”言葉の壁”。

全部英語ですねぇ。頑張って聞けば何とかわかるかもしれませんが、3時間近くも慣れていない言語の説明を聞き続けられるかどうか・・・

日本語版の公開をお願いしたいですねぇ。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

2017年1月30日 (月)

Re:ゼロから始めるディープラーニング

どこかのアニメのタイトルを丸パクリしたことは認めますが、まさにそんな感じなので。”死に戻り”ならぬ、”学び戻り”です。

実は職場で「人工知能に使われてるTensorFlowを職場でも使えるようにしようと思ってる」と何人かに話したところ、「人工知能」だけが独り歩きしていることが先日の飲み会で判明。「あいつ人工知能やるらしいぞ」ってことになってるそうで。

そんなに大げさなものをやるわけじゃないですけど、最近キャッチーな言葉ですからね、人工知能。こうなったら、ちょっと本気出してみようかなと。

ならばこの先決心が緩まないように、このブログでも宣言しちゃおうかと思った次第で。

さて、私自身「人工知能」というものを去年の夏ごろからいじりつつありますが。

人工知能ライブラリ”TensorFlow”をRaspberry Pi 3に入れていろいろなものを画像認識させてみた: EeePCの軌跡

私のようなにわかプログラマーでも簡単に使えてしまう機械学習プログラミング。

ブラックボックスの部分は多いものの、それでも何とか動いてしまうもので、いろいろと作ってみました。

TensorFlowで歴代「クラウン」の画像を判別させてみた: EeePCの軌跡

TensorFlowを使って”ゴキブリ”探知機を作ろうとしてみた: EeePCの軌跡

が、そろそろブラックボックスの部分を理解しないとこれ以上の発展は望めません。

てことで、こういう本を購入。

Img_1240

ゼロから作るDeep Learning」という本です。

ネット上の評判はかなり上々のこの書籍。

買おうかどうしようかと悩んでましたがどうせいつか買うつもりならさっさと買ってしまえと購入。

Img_1241

この本の特徴は、

・ Pythonで最低限のライブラリ(Numpy、Matplotlib)のみ使用したプログラム、画像認識に特化した内容にすることで、基本的な深層学習の仕組み理解を目指す

・ Pythonを使ったことがない人でも使えるよう、Python解説ページも付属

内容理解がメインなので、TensorFlowやCaffeといった機械学習用プラットフォームは一切使われてません。

ということで、これから”ディープラーニング”を始めるという人にはちょうどいい本です。

私も昨年夏から始めたとはいえ、中身はわりとすっからかん。

てことで、再び”ゼロ”からスタートです。

Img_1242

Python初心者でも使えることを謳ってるだけに、1章分をPython解説に使ってます。

Img_1243

人工知能やTensorFlowのコードを読むと結構難解な用語が次から次へと出てきます。この”誤差逆伝播法”という言葉もその一つ。

他にも”畳み込みニューラルネットワーク”だの”交差エントロピー”だの”パーセプトロン”だの・・・もはや何を言ってるのかわからない単語のオンパレード。それが人工知能の世界。

しかしプログラミングというのは動いているところを見ると理解がすすむもので、それを自身でプログラミングしながら促進しようというのがこの本の意図であり、これが多くの人から支持されている理由のようです。

ネット上の情報って結構役に立ちますけど、なんというかLinux系・プログラム言語系にありがちな「行間を読め」的な端折った説明にかなり惑わされます。

まだまだ読み始めたばかりですが、これまでブラックボックスだったところのいくつかがわかり始めてます。

ちょうど私が最初にTensorFlowをいじったときには、まだこの本は出てませんでした。もうちょっと早く出会いたかったですねぇ。

さて、人工知能導入に向けてリスタートを切ったわけですが、そのためにもう一つやらなきゃならないことが。

それは「WindowsにTensorFlow環境を構築」すること。

以前Windows 10のBash on WindowsでTensorFlow動かしてみた: EeePCの軌跡でも書いた通り、Bash on Windows上で構築はしたんですが。

この環境はWindows 10でないと動きません

ちなみに、私の会社のPCは未だにWindows 7

てことでWin 7でもTensorFlowが動かせる環境を導入しました。

参考にしたのはこちらのサイト。

TensorFlowがWindowsサポートしたのでインストールしてみた - デジタル・デザイン・ラボラトリーな日々

Windows用Anacondaを入れてpipでTensorFlowをインストールするというもの。

必要なものを後から入れることもなく一発で導入できるため、楽ですね。

ただTensorFlowで歴代「クラウン」の画像を判別させてみた: EeePCの軌跡で作ったコードを使うにはOpenCVも必要なため、こちらも導入。

Windows Anaconda Python 3.5 への OpenCV 3.1 のインストール - にせねこメモ

ここを参考にインストール。

これで先の”クラウン判別器”は動作させようとしたんですが。

元々Python 2.7で書いていたコードPython 3.5にもってきたため(Anaconda for WindowsはPython 3.5用を導入)、ちょっと改変が必要でした。

例えば”print ~”という文は”print (~)”という感じに変えたり、日本語のコメントを全部消したり(文字コードエラーが起こります)、”for i in range(len(train_image)/FLAGS.batch_size):”というコードでエラーが出るので(整数型のところに浮動小数点型変数が入ってる!みたいなエラー)、”for i in range(len(int(train_image)/FLAGS.batch_size)):”と書き換えたり・・・ちょっと一筋縄ではいきませんでしたが、何とか使えるようにはなりました。

てことで、自宅でも会社でもPython+TensorFlow環境を構築中。

使いこなすために、再度勉強中です。

果たして、この先何かを作ることができるんでしょうかね?

また、報告します。

【おまけ】

再学習に当たり、参考となりそうなサイトをいくつか見つけたので紹介しておきます。

定番のConvolutional Neural Networkをゼロから理解する - DeepAge

「畳む込みニューラルネットワーク」の説明としてはわりとわかりやすいです。

高卒でもわかる機械学習 (0) 前置き | 頭の中に思い浮かべた時には

タイトルのわりには難解なところもありますが、それでも難しい用語でごまかさず説明してるところはなかなかいい。人工知能の前提知識が全くないとお考えの方なら、参考書を手にする前にまずここを一読されるとよろしいかと。この記事書いてる時点では(7)までありました。私もちょっとづつ読んでます。

詳説 人工知能 - ディープラーニングの仕組みと応用:ITpro

ここはディープラーニングの知識習得というより、応用事例の解説が役に立ちます。

日本ならどこでもそうですが、こういう技術って上の人からはマユツバ扱いされるんですよね。説得用にはいい記事かと。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

2017年1月16日 (月)

シアトルにあるレトロPCから最先端のコンピュータ技術までが凝縮された”リビング コンピュータ ミュージアム”

シアトルに”リビング コンピュータ ミュージアム”というのがあるそうですが、1960年代のコンピュータから現在に至るまでのコンピュータ技術が展示された博物館だそうです。

ビンテージから最先端まで!シアトル「リビングコンピュータミュージアム」が楽しい | アメリカ | トラベルjp<たびねす>

ビル ゲイツ氏とともにMS社を作ったポール アレン氏が2012年に開設した博物館で、ただ展示されているだけでなく、動作可能な状態で公開されているんだとか。

Apple IIとかならまだわかるんですが、上のこのバカでかいコンピュータはいったい・・・なんでしょうね?

他にも”ブラックベリー”も展示されてるそうです。この端末作ってる会社も、Androidで再出発を果たしてますが、オリジナルの方はもはや博物館で展示される時代になってしまったんですね。

最先端の技術も紹介されており、例えば自動運転の体験もかのうなんだとか。

一度行ってみたいですねぇ、シアトル。何とか行く機会はないものでしょうか?

B05 地球の歩き方 シアトル&ポートランド 2017~2018

より以前の記事一覧

当ブログ内検索

  • カスタム検索

スポンサード リンク

ブログ村

無料ブログはココログ