パソコン系

2017年3月29日 (水)

上海問屋から最大10枚のmicroSDカードをSATAドライブにできるアダプタ

最近はmicroSDカードも安くなっており、気が付いたら思わず何枚も買っているなんて人も多いんじゃないでしょうか。

そんなmicroSDカードを複数挿してSATAドライブとして使えてしまうアダプターが上海問屋から発売されたそうです。

10枚のmicroSDカードをSATAドライブ化するアダプタが発売、上海問屋 - AKIBA PC Hotline!

このアダプター、その名も”10枚のmicroSDカードをSATAドライブにできる変換アダプター”。そのまんまです。

ただ、組み合わせや挿す位置には若干制約があって、挿せる枚数は1、2、4、5、8、10枚という組み合わせで、それぞれ挿す位置もだいたい決まっているようです。

すべて同容量のカードを挿すことが必須。違う容量にすると誤認識されるそうです。

256GBのカードを1枚挿して使えたそうなので、一応256GBまでは大丈夫な模様。まあ、そんなカードをこういうものに挿す人も少ないかもしれませんが。

お値段は3,999円。大容量のカードに変えたら32GBのカードが何枚か余ってしまった・・・という人ならこれで再利用することができますね。

Goliton・ マイクロSD TFのスイッチ SATAアダプタへ ノートブックハードドライブアダプタ SATA SSDのRAIDグループ10* TFカード

2017年3月28日 (火)

AKIBA Hotlineで”ザナドゥ”が!

ザナドゥといえば、私が最初に買ったパソコンゲームソフトですね。

X1用FD版を購入、友人とやりこみましたね。

デカキャラが衝撃的だった「ザナドゥ」 - AKIBA PC Hotline!

で、そんな”ザナドゥ”がAKIBA Hotlineに紹介されてました。

この記事のタイトルにもありますが、ザナドゥってところどころどでかいボスキャラが出てくるんですよね。

当時ファミコンに慣れていた私でも、この大きさは衝撃的でした。

最後のドラゴンと闘うときなんて結構緊張しましたねぇ。なかなか勝てなかった記憶ですが。

そんなザナドゥ。たしかX1版以外には88版、FM-77版などもありました。

記事にもある通りX1版にはテープ版も存在してて、私の友人は最初テープ版でやってたんですよね。

攻略途中でデータが壊れたため、X1Fを買ったばかりの私に強引に勧めてきてFD版を買った(買わされた)次第。

テープとFDのアクセス速度の差に、度肝を抜かれてました。

レトロパソコンの思い出、当時最先端だったフロッピーディスクのアクセス性能の高さ、そしてファミコンにはない深い世界観のゲームとの出会い。

いろいろと想いが染みついてますね、このザナドゥ。

Img_0086

ちなみに、まだちゃんと動きます、うちのザナドゥ。

また近いうちに攻略してみようかな。空のFDも一枚くらいはあったはずですし。

レジェンドパソコンゲーム80年代記

2017年3月26日 (日)

”AptPackageIndexUpdate”というプロンプトが出てきて・・・

なんじゃ!?新手のウィルスか!??

Aptpkgindxup01

・・・と思うようなコマンドプロンプト画面がPC起動時に登場。

で、調べてみたら・・・apt-getの自動アップデートでした。

そういえば、Windows 10に”Bash on Ubuntu on Windows”を入れてましたねぇ。最近Anacondaに浮気して起動しなかったので、自動でアップデートしたらしいです。

たまには相手しろってことですかねぇ・・・ひねくれないうちに、時々は起動してあげるのが吉のようです。

ちょっとだけLinuxにさわってみたい人のための Bash on Ubuntu on Windows入門

2017年3月25日 (土)

Windows 10のディスクアクセス負荷が高い!時の対処法

いろいろな対処法があるようですが、こんなことでアクセス負荷が下がるの!?と思われる方法もあります。

Windows10のディスクアクセス負荷が高い場合の対処 | code-lab

こちらに出ているやり方は、

・「個人用設定」を開く

(デスクトップの右ボタンか、アクセスセンターの「すべての設定」の中から)

・「色」タブを選択

・「スタート、タスクバー、アクションセンターを透明にする」をオフにする

私もこれを試してみましたけど、確かにちょっと下がった感じ。

うちのメインPCは休止状態にして使ってますけど、復帰した直後にいつまでもガラガラとHDDが回りっぱなしになってしまいます。

ほぼ100%負荷が数分続くんですが、これが90%程度になりました。

改善レベルはほんのわずかですが、ブラウザ一つ立ち上げるにもすごい待たされていたのが体感的にかなり解消。これは大きい。

古いPCほど効果があるようなので、起動後にディスクアクセスが遅い場合はぜひお試しあれ。

Microsoft Windows 10 Home Anniversary Update適用版 32bit/64bit 日本語版 (最新)|USBフラッシュドライブ

2017年3月24日 (金)

週刊アスキー特別編集『2017春の超お買物特大号』買いました

だって、”週刊アスキー”サイトで散々煽ってましたし。

ふ〜ん、4Kテレビって10万円で買えちゃうんだ〜。へ〜 - 週刊アスキー

え、お前WiGigも知らないの? ダサくね? って言われないために週アスを買おう - 週刊アスキー

こりゃもう、買うしかないでしょ。

Img_0776

てことで、買ってまいりました、週刊アスキー特別編集『2017春の超お買物特大号』。

電子版の週アスはたまに買いますけど、紙版は本当に久しぶりですね。

Img_0777

まず目を引くのは中綴じのこれ。

「格安SIM/格安スマホ乗換マニュアル」です。

この部分は本体から切り離し可能。最近相談が多いので、私もこれを会社にもっていこうかと思ってます。

Img_0778

中身はこんな感じ。MVNOサービスに興味はあるけどちょっと・・・という方の背中をきっと押してくれる内容です。

ちなみに、私の会社の同僚の方が娘にSIMフリーiPhone 7 + イオンモバイル(音声通話付き4GB)を与えたようですが、あまりに快適に使ってるので自身も乗り換えようかと画策しているとのこと。

Img_0779

ちなみにこの中綴じ冊子の前ページにはこんな広告が。

これはこれで気になります。

Img_0780

煽ってきた記事に出ていたWiGigの解説も載ってます。

いずれ家庭向け無線LANの標準規格として今のWi-Fiと置き換わるんですかね。

Img_0782

他にもLINE/SNSデビューに関する記事や

Img_0781

次にヒットするであろう製品も紹介されてます。

なかなかお買い得な週アス特別編集。

お値段は690円ほど。内容のわりにお買い得です。

週刊アスキー特別編集 2017春の超お買物特大号 (アスキームック)

2017年3月18日 (土)

BuffaloのNAS”LS210D”のアクセスランプがオレンジ色に!?原因は・・・

突然うちのBuffalo製NAS”LS-210D”のアクセスランプが妙な色に変わりまして。

Img_0724

普段は白っぽい色ですが、ちょっと赤みのかかったオレンジ色というんでしょうか、急にこんな色に変わりました。

再起動したんですが、結局この色に戻ってしまいます。

ただ、NAS自体は何ら問題なく使えるんですよね。いったいどんなトラブルが起きたのか!?

心配になって、Buffaloのサイトへ行くと、こんなのを発見。

LinkStaiton前面のランプが橙色で点灯しています/NasNavigator2で「I52」と表示されます - アンサー詳細 | BUFFALO バッファロー

なんと・・・ファームウェア アップデートのリリースを知らせる色だったんですね。

いかにも警告っぽい色なのでやばい事態でも発生したかと思ったんですけど、案外大した理由じゃなかったですね。もうちょっと穏便な色で知らせてほしいものです。

てことで、NASの管理画面にアクセスし、アップデートすることにしました。

Bnas01

詳細設定から「admin」にアクセスし「アップデート」を選択すると、こんな画面が。

「アップデート実行」をクリックします。

Bnas02

あとはひたすら待ちます。

Bnas03

しばらくすると、完了です。

Img_0730

メニューなど、特に変わった感じはしませんが、ランプの色は元に戻りました。

Buffalo製NASのアクセスランプが変な色に変わっていたら、まずは詳細設定を確認しろってことですね。

BUFFALO リンクステーション 210シリーズ ネットワーク対応HDD(NAS) 2TB  LS210D0201N [フラストレーションフリーパッケージ(FFP)]

2017年3月14日 (火)

Windows Vistaのサポートはあと1か月!

あらら、もうそんな時期なんですね。

「Windows Vista」のサポート終了まで残り1ヶ月 | 気になる、記になる…

すっかり忘れてましたが、Windows Vistaのサポートは2017年4月11日まで。つまりもう一か月を切ってます。

ちょうどEeePC 4G-Xが出る前に登場し、グラフィカルなUIで話題をさらったものの、当時のPCには荷が重い仕様だったため”失敗作”のレッテルを張られてしまった不運のWindows。

Vistaが出た当時はまだメモリが512MBというのが珍しくなかったころ。Raspberry Pi B並みのメモリで動かすにはいささか重すぎでした。

その後、CPUやメモリ等のハードの環境が追い付き、また軽量化にも力を入れたWindows 7では挽回できましたけど、Vista自体はほとんど普及することなく短命で終わってしまいました。

なにせその直後に出たEeePC 4G-Xでは当初Linuxが採用されたんですが、これに対抗する形でネットブック向けにXPが復活。

Windows 7が出るまでXPが再び全盛という事態を招いてしまいました。

そんな私も、一時Windows Vistaを使ってたんですよね。

連休中のパソコン増強: EeePCの軌跡

2009年4月30日の記事に、TS抜きチューナー”QRS-UT100B”とともに購入。

エディションはもっともしょぼいBasicでしたが、当時そんなに困らなかったですね。

Aeroが使えないとか言われてましたが、あっても使いませんでしたよね、そんな機能。

その後Windows 7を買う(2012年5月1日の記事:Windows 7への移行完了: EeePCの軌跡)までの3年間、何ら問題なく使えてました。悪いOSではなかったですよね。

しかしOSの歴史では存在の薄いまま終焉を迎えることになりそうです。

その後7で盛り返し、8や8.1でまた微妙な空気に逆戻りし、10で再び盛り返そうという歴史を歩んでますが、徐々にARM系チップ+スマホにおされ気味な今日この頃。

フル版Windows 10にもARM対応版が出るとアナウンスされてますが、Vistaが出たころを思えばそんな時代が来ること自体想像すらできなかったことです。

そんなVistaですが、ついにサポート終了。

ほとんど使っている人はいないでしょうけど、セキュリティのことを考えると、Vistaを使っているユーザーは速めにWindows 10への乗り換えを考えた方がいいでしょうね。

Microsoft Windows 10 Home Anniversary Update適用版 32bit/64bit 日本語版 (最新)|USBフラッシュドライブ

2017年3月12日 (日)

OpenCVによる”アニメ顔”検出

急にアニメ動画から顔を取り出したくなったので、OpenCV用のアニメ顔検出器を探してたんですが、ここのを使うと便利なようです。

OpenCVによるアニメ顔検出ならlbpcascade_animeface.xml - デー

よくある”顔検出器”ではアニメ顔をほとんど検出してくれませんが、ここにある”lbpcascade_animeface.xml”を使うとほんとによく検出してくれます。

入手元:http://anime.udp.jp/data/lbpcascade_animeface.xml

てことで、動画から直接顔を検出するコードを作りました。

◆「movie2face.py

import cv2
import glob

video_path = './(動画ファイル名)'
video_name = video_path[2:8] + '_'
output_path = './movie/'
out_face_path = './face/'
xml_path = "./lbpcascade_animeface.xml"

def movie_to_image(num_cut):

    capture = cv2.VideoCapture(video_path)

    img_count = 0
    frame_count = 0

    while(capture.isOpened()):

        ret, frame = capture.read()
        if ret == False:
            break

        if frame_count % num_cut == 0:
            img_file_name = output_path + str(img_count) + ".jpg"
            cv2.imwrite(img_file_name, frame)
            img_count += 1

        frame_count += 1

    capture.release()

def face_detect(img_list):

    classifier = cv2.CascadeClassifier(xml_path)

    img_count = 1
    for img_path in img_list:

        org_img = cv2.imread(img_path, cv2.IMREAD_COLOR)

        gray_img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)

        face_points = classifier.detectMultiScale(gray_img, \
                scaleFactor=1.2, minNeighbors=2, minSize=(1,1))

        for points in face_points:

            x, y, width, height =  points

            dst_img = org_img[y:y+height, x:x+width]

            face_img = cv2.resize(dst_img, (64,64))
            new_img_name = out_face_path + video_name + str(img_count) + 'face.jpg'
            cv2.imwrite(new_img_name, face_img)
            img_count += 1

if __name__ == '__main__':

    movie_to_image(int(10))

    images = glob.glob(output_path + '*.jpg')
    face_detect(images)

この「movie2face.py」と先の「lbpcascade_animeface.xml」と動画ファイルを同一フォルダに置きます。

そのフォルダ内に「face」と「movie」というフォルダを作成。

あとは

> python movie2face.py

と実行すれば、まず「movie」フォルダに動画から取り出された静止画が保存され

Tf_kemo01

その静止画から取り出された顔の部分が「face」に保存されます(64×64)。

Tf_kemo02

若干誤認識がありますけど、結構な精度で落としてくれます。

ただ”ハシビロちゃん”がうまく認識されないですよね・・・ってなにをキャプチャしてるんだか。

上のコードの「xml_path = "./lbpcascade_animeface.xml"」の部分を「xml_path = "./haarcascade_frontalface_default.xml"」と置き換えて、動画をアニメからドラマやホームビデオに変えれば、人の顔をキャプチャする検出器に早変わりします。

haarcascade_frontalface_default.xml”は、たいていOpenCVをインストールすればデフォルトで入ってくるようですが、別途入手する方法は以下。

(1) https://github.com/opencv/opencvにアクセス

(2) 「Clone or Download」をクリックし「Download ZIP」をクリック

(3) ダウンロードしたファイル(opencv-master.zip)を解凍

(4) 解凍したフォルダ内にある「data\haarcascades」の中に「haarcascade_frontalface_default.xml」というのがあるのでこれを取り出す

これを使えばリアルな人の顔を検出できます。

動画から何かを取り出したい場合は同様に、別の検出器を入手し、このコードの”xml_path=・・・”に入れればOK。

例えば猫を検出したかったら、以下のサイトから”xml”ファイルが入手可能。

ねこと画像処理 part 2 – 猫検出 (モデル配布) « Rest Term

試しにここから検出器を入手して

https://github.com/wellflat/cat-fancier

猫動画を処理してみると

Tf_neko01

確かに猫だらけになります。ただし、誤認識もちょっと多め。

自分で”物体検出器”を作りたくなったら、以下を参照。

OpenCVで物体検出器を作成する① ~基礎知識~ - 技術者ブログ

これをやるためには3000枚以上のサンプル画像を作る覚悟が必要ですが。

結構いろいろな”検出器”が転がってるようなので、応用はききそうですね。

Raspberry Pi3 Model B ボード&ケースセット 3ple Decker対応 (Element14版, Clear)-Physical Computing Lab

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年3月 8日 (水)

メインPCのキーボードを交換

今までiBUFFALOのキーボードを使ってきましたが

Img_2733

とりあえず自宅にある予備のキーボードと交換することにしました。

Img_2734

交換理由その1:いくつかのキーの刻印が消滅。

ほぼ毎日ブログ記事を書いてますからね、A、S、Dなどは爪先などで削れてしまいました。

Img_2735

反対側の”K”のキーもHと区別できません。M、Nも同様。

交換理由その2:キータッチが硬い。

Img_2736

毎日たたいてるからでしょうか、押し込むのがつらくなるくらい硬くなってきました。

これを買ったのは2012年6月。当時の記事はこちら。

Buffalo製キーボード購入: EeePCの軌跡

120610_20_06_49

このときもキータッチが硬くなったので交換してると書いてますね。

この記事ではキータッチが軽いと書いてるので、やはり経年劣化で硬くなってきてたようです。

Img_2737

ところでこのキーボード、いつ買ったのかは覚えがありませんが、2013年5月のこの記事ですでに登場しています。

30ピン→Lightning変換ケーブルでiPad miniとキーボードなどをつないでみた: EeePCの軌跡

Img_3157

てことは、先のiBUFFALOのキーボードとあまり変わらない時期に買ってるんですよね。

Img_2739

ですが、全然キータッチは軽い。やはり毎日使うと硬くなるんでしょうかね。

Img_2738

1000円ほどで買った安物キーボードなので大して期待してませんでしたが、ちゃんとPowerキーがついてます。今までと同じ使い勝手を確保できそうです。

とはいえ、やはり古くて安物の予備キーボード。ちゃんとしたキーボードを買わないといけません。そのうち買ってくるつもりです。

Logicool ロジクール フルサイズ 薄型 ワイヤレスキーボード テンキー付 耐水 静音設計 USB接続 3年間無償保証ボード Unifying対応レシーバー採用 K270

より以前の記事一覧

当ブログ内検索

  • カスタム検索

スポンサード リンク

ブログ村

無料ブログはココログ