macにwgetを入れてみた

MacOSX10.8にはデフォルトでwgetが入っていません。必要ならばソースコードからコンパイルする必要があります。

まず手始めにはgccをインストールする必要があります。こちらを参考にコマンドライン版gccもいれます

wgetはソースコードからコンパイルするため、ブラウザでGNUのページからダウンロードします

$ cd /Users/UserName/Downloads
$ tar zxvfp wget-1.14.tar.gz
$ cd wget-1.14
$ ./configure --with-ssl=openssl
$ make
# su
# make install

こんな感じでインストールできます。

ちなみに–with-ssl=opensslをつけないとconfigureに失敗しました

KH CoderをMacにインストール

KH Coderという、自然言語の解析用の統合ソフトウエアをMacにインストールする際のメモ

環境

    • MacOS10.11
  • 関連モジュールのインストール

    まず、関連するモジュールをインストールします。KH Coderは内部でR,MySQL,mecab,Perlを使用しますのでMacにあらかじめこれらを入れておく必要があります。

    mysql

    brewで入れるのが簡単です
    brewって何って言う人はこのあたりを参考に入れてみてください
    このあたりを参考にインストールします。DBのユーザ名、パスワードは任意に決めておきます

    $ brew install mysql
    $ echo "[mysqld]" > /usr/local/etc/my.cnf
    $ echo "sql_mode = \"\"" >> /usr/local/etc/my.cnf
    $ mysql.server start
    

    KH CoderはMySQL5.7だと不具合が出るのでsql_modeをブランクにしておきます
    確認します

    $ mysql -uroot
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 243
    Server version: 5.7.12 Homebrew
    
    Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> 
    
    

    R

    同じくBrewが簡単です

    $ brew install r
    

    mecab

    $ brew install mecab
    $ brew install mecab-ipadic
    

    Perl

    Macには初めからPerlがインストールされているので、今回は関連するモジュールを追加します。

    $ sudo su -
    # perl -MCPAN -e shell
    

    初めて起動する際には色々聞かれますがデフォルトで全てOKです。黙ってリターンキーを押しましょう
    CPANのシェルが起動すれば黙々と以下インストールします

    cpan> install Jcode
    cpan> install Tk
    cpan> install DBD::CSV
    cpan> install Net::Telnet
    cpan> install YAML
    cpan> install Spreadsheet::ParseExcel
    cpan> install Spreadsheet::ParseXLSX
    cpan> install Clipboard
    cpan> install Statistics::Lite
    cpan> install Algorithm::NaiveBayes
    cpan> install Text::Iconv
    

    こんな感じでインストールしていきます。
    たまにエラーが出る場合にはあわてず以下の通りにします

    例えば Spreadsheet-ParseExcelがエラーになった場合には

    # cd ~/.cpan/build
    # cd Spreadsheet-ParseExcel-0.65-OEiGuu
    # perl Makefile.PL
    # ./configure
    # make
    # make install
    

    こんな感じです。

    KH Coder

    こちらからソースコードをダウンロードして解凍しておきます
    KH Coderをダウンロードしたディレクトリに移動し一度起動します。こすればconfigいかにファイルが作成されます

    $ perl kh_coder.pl
    

    そのあと設定ファイルを設定します。インストールした際のMySQLのユーザ名とパスワード、Mecabを設定します。

    $ vi kh_coder/config/config.ini
    c_or_j          mecab
    sql_username    ユーザ
    sql_password    パスワード
    

    設定ファイルの文字コードを修正します。nkfが入っていない場合にはbrew でインストールしてください

    $ cd config
    $ nkf -s hinshi_mecab > /tmp/$$ && mv -f /tmp/$$ hinshi_mecab
    

    起動

    KH Coderをダウンロードしたディレクトリに移動します

    $ perl kh_coder.pl
    

    これで起動できるはずです。

    こんな感じでPerlのエラーが出た際には、Perlのモジュールを入れてください。以下の例だとDBD/CSV.pmが足りないので install DBD::CSVをインストールします

    $ perl kh_coder.pl 
    Can't locate DBD/CSV.pm in @INC (you may need to install the DBD::CSV module) (@INC contains: /Users/utsubo/Downloads/kh_coder/kh_lib /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.2/darwin-thread-multi-2level /Library/Perl/Updates/5.18.2 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/L
    
    cpan> install DBD::CSV
    

    おまけ

    mysql5.7でのエラーについて

    前処理を実行するとこういうエラーが出ます

    DBD::mysql::db do failed: Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'khc0.hinshi.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by at /Users/utsubo/Downloads/kh_coder/kh_lib/mysql_exec.pm line 256.
    Exit (gui_errormsg.pm)
    

    こちらによると5.7からGroupBYの仕様が変わったらしいです。

    Day Of Yearカレンダープラグイン

    WordPressのプラグインでDayOfYearを表示するものを作成してみました

    プラグイン作成準備

    最初にディレクトリを作成します。今回は自分用に作成するので特に名前も気にしていないのですが、公開する場合には名前のかぶらないものにすることをお勧めします。

    $ mkdir utbt_doycalendar
    

    このディレクトリにplugin.phpファイルを作成しヘッダを作成します。
    この辺りはお決まりですので、このあたりのサイトに書かれている通りにします

    
    
    
    

    こんな感じで十分でしょうか?

    ショートコード対応

    今回はWordpressのプラグインとしてショートコードをページに記入レバ表示できるような仕様にします。
    また、ページには1年間分のカレンダーを表示し、年をテキストボックスでフォーム入力し、Submitすることにより切り替えます。
    この際に、FormからはGetパラメタで送信し、プラグイン内でGetパラメタを取得して年を切り替えます。

    カレンダー作成

    最初から作ってもいいのですが、こちらを参考にさせていただきました。

    ソースコード

    で、完成したコードがこちら

    
    
    calendar($year);
    }
    
    add_shortcode('utbt_calendar','utbt_calendar_func');
      class UtbtCalendar{
    
        function calendar($year=''){
    
    
            if (empty($year) && empty($month)) {
                $year = date('Y');
            }
            $html="
    Input Yea r:"; for($i=1;$i<=12;$i++){ $html.=$this->calendar_exec($year,$i); } $html.="
    "; return $html; } //http://shanabrian.com/web/php_calendar.php private function calendar_exec($year = '', $month = '') { $tab=""; $str=""; if (empty($year) && empty($month)) { $year = date('Y'); $month = date('n'); } //月末の取得 $l_day = date('j', mktime(0, 0, 0, $month + 1, 0, $year)); //初期出力 $html = << {$year}/{$month} Sun Mon Tue Wed Thr Fri Sat \n EOM; $lc = 0; // 月末分繰り返す for ($i = 1; $i < $l_day + 1;$i++) { $classes = array(); $class = ''; // 曜日の取得 $week = date('w', mktime(0, 0, 0, $month, $i, $year)); // 曜日が日曜日の場合 if ($week == 0) { $str .= $tab."\t\t\n"; $lc++; } // 1日の場合 if ($i == 1) { if($week != 0) { $str .= $tab."\t\t\n"; $lc++; } $str .= $this->repeatEmptyTd($week); } if ($week == 6) { array_push($classes, '#0000FF'); } else if ($week == 0) { array_push($classes , '#FF0000'); } if (count($classes) > 0) { $class = '"'.implode(' ', $classes).'"'; } $doy = date('z', mktime(0, 0, 0, $month, $i, $year))+1; $str .= $tab."\t\t\t".''.$i.'('.$doy.')'."\n"; // 月末の場合 if ($i == $l_day) { $str .= $this->repeatEmptyTd(6 - $week); } // 土曜日の場合 if ($week == 6) { $str .= $tab."\t\t\n"; } } $html .=$str; $html .= "\n"; return $html; } private function repeatEmptyTd($n = 0) { return str_repeat("\t\t \n", $n); } } ?>

    リリース

    できたコードをディレクトリごとZIPファイルにし、Wordpressのプラグインに追加します。
    また、ページにはこんな感じで書けば無事カレンダーが表示されます

    [utbt_calendar]
    

    デモ

    作成したデモサイトはこちらになります

    pdftotextでPDFを文字列化

    最近の人工知能ブームでテキストマイニングから法則を発見するといったこともしばしば行うようになってきました。
    PDFから文字列を抽出する方法をメモっておきます

    環境

    • mac os 10.11

    インストール

    まずはpdftotextをインストールします

    $ brew install homebrew/x11/xpdf-japanese
    

    このまま実行するとエラーになります

    $ pdftotext test.pdf
    Syntax Error: No font in show
    Syntax Error: Unknown character collection 'Adobe-Japan1'
    

    こちらを参考に修正します

    $ wget ftp://ftp.foolabs.com/pub/xpdf/xpdf-japanese.tar.gz
    $ tar zxvpf xpdf-japanese.tar.gz
    $ mkdir -p /usr/local/share/xpdf/japanese 
    $ mv xpdf-japanese/* /usr/local/share/xpdf/japanese/
    $ echo "textEncoding UTF-8" >> /usr/local/etc/xpdfrc
    $ echo "cidToUnicode    Adobe-Japan1    /usr/local/share/xpdf/japanese/Adobe-Japan1.cidToUnicode" >> /usr/local/etc/xpdfrc
    $ echo "unicodeMap  ISO-2022-JP /usr/local/share/xpdf/japanese/ISO-2022-JP.unicodeMap" >> /usr/local/etc/xpdfrc
    $ echo "unicodeMap  EUC-JP      /usr/local/share/xpdf/japanese/EUC-JP.unicodeMap" >> /usr/local/etc/xpdfrc
    $ echo "unicodeMap  Shift-JIS   /usr/local/share/xpdf/japanese/Shift-JIS.unicodeMap" >> /usr/local/etc/xpdfrc
    $ echo "cMapDir     Adobe-Japan1    /usr/local/share/xpdf/japanese/CMap" >> /usr/local/etc/xpdfrc
    $ echo "toUnicodeDir            /usr/local/share/xpdf/japanese/CMap" >> /usr/local/etc/xpdfrc
    

    実行

    2ページ目から出力してみます。

    $ pdftotext -f 2 -raw -layout -enc UTF-8 test.pdf 
    

    test.txtというファイル名で作成されます

    UCD-DISKIO-MIB::diskIODevice = No more variables left in this MIB View (It is past the end of the MIB tree)エラー

    Hinemos5.0でサーバ監視をしているのですが、EC2のAmazonLinuxで作成したサーバのリソース監視がデフォルトではうまくいかなかったのでメモ。

    * Amazon Linux AMI release 2015.09

    AmazonLinuxは作成すると自動で、SNMPが起動されています。そこに対してHinemosから監視をかけるわけですが、タイムアウトというエラーが出たりします。

    まず確認用に監視サーバからコマンドを打ちます

    $ snmpwalk -c public -v 2c IPADDRESS 1.3.6.1.4.1.2021.13.15.1.1.2
    UCD-DISKIO-MIB::diskIODevice = No more variables left in this MIB View (It is past the end of the MIB tree)
    

    こんな感じのエラー。
    こちらに対処法が書いてありましたので実行してみます。

    被監視サーバの設定を修正します

    $ sudo echo "view systemview included .1.3.6.1." >> emacs /etc/snmp/snmpd.conf
    $ sudo service snmpd restart
    

    先のブログには再起動と書いていますがリスタートのみでOKです

    再度、監視サーバからコマンドを打ちます

    $ snmpwalk -c public -v 2c IPADDRESS 1.3.6.1.4.1.2021.13.15.1.1.2
    UCD-DISKIO-MIB::diskIODevice.1 = STRING: xvda
    UCD-DISKIO-MIB::diskIODevice.2 = STRING: xvda1
    UCD-DISKIO-MIB::diskIODevice.3 = STRING: loop0
    UCD-DISKIO-MIB::diskIODevice.4 = STRING: loop1
    UCD-DISKIO-MIB::diskIODevice.5 = STRING: loop2
    UCD-DISKIO-MIB::diskIODevice.6 = STRING: loop3
    UCD-DISKIO-MIB::diskIODevice.7 = STRING: loop4
    UCD-DISKIO-MIB::diskIODevice.8 = STRING: loop5
    UCD-DISKIO-MIB::diskIODevice.9 = STRING: loop6
    UCD-DISKIO-MIB::diskIODevice.10 = STRING: loop7
    UCD-DISKIO-MIB::diskIODevice.11 = STRING: dm-0
    UCD-DISKIO-MIB::diskIODevice.12 = STRING: dm-1
    

    無事コマンドが通りました。
    しばらくするとエラーになっていたHinemosの監視項目にも値が入るようになります

    ElasticSearchでClusterBlockException[blocked by: [FORBIDDEN/8/index write (api)]エラーの対応

    ElasticSearchをAWSで運用しているとたまにエラーが出ます。

    ClusterBlockException[blocked by: [FORBIDDEN/8/index write (api)]
    

    このメッセージが出る場合の対処方法ですが、こちらの記事にある通りにディスクフルの場合には容量アップで対応できるみたいですが、そうでない場合もあります。

    http://qiita.com/dorachan1029/items/f3b47f4d9859450d9b90

    その場合には再度テーブルを作成しなおすとなおったりします。こんな感じで。

    $ curl -XDELETE "http://hostname/table"
    $ -XPUT http://hostname/table -d '{
      "mappings": {
        "data":{
          "properties": {
            "id": { "type": "string" },
    ...
          }
        }
      }
    }'
    

    http://qiita.com/shouta-dev/items/c2d2eb6cf61bb1fa8e1b

    自分の場合には、データを毎日入れ替えていたのですが、全入れ替えするとその間検索ができなくなってしまうので、要、不要を判断し、1レコードづつ入れ替えていたのが悪かったのかもしれません。半年ほど運用していたらこのエラーになりました。

    tcpdumpでパケット通信サイズを求める

    WebサーバとDB間の通信など、DBが他のサービスなどと共用だとそのDBへの通信量などが気になったりします。

    WebサーバからDBへの通信パケットサイズをtcpdumpを使って測定してみます。

    条件

    • DB Server: 192.168.10.100
    • DB Application: MySQL port 3306

    測定

    #	tcpdump -e -s0 host 192.168.10.100 > db.txt
    # ^C	 # ctrl+Cで中断
    # a=0
    # for i in `cat db.txt |awk '{print $13}'|sed -e 's/://'`;do let a=$a+$i;done ; echo $a
    102799
    

    こんな感じでバイト数が求まります

    TensorflowでMNIST(5)

    毎回学習させるのは効率が悪いので、一度学習させそれを保存しておき、判定時には判定のみをさせるように修正します

    畳み込みニューラルネットワーク(CNN)のプログラムを修正していきます

    学習用

    tf_cnn3.py

    #!/bin/env python
    # -*- coding: utf-8 -*-
    # http://qiita.com/ikki8412/items/95bc81a744dc377d9119
    import tensorflow as tf
    import numpy as np
    import random
    import time
    import math
    
    NUMCLASS=10
    NUMPARAM=784
       
    ### データ処理用
    def label_data(lines):
      labels=[]
      for line in lines:
        # ラベルを1-of-k方式で用意する
        tmp = np.zeros(NUMCLASS)
        tmp[int(line)] = 1
        labels.append(tmp)
      return np.asarray(labels)
    
    def image_data(test):
      test_image=map(lambda n: map(lambda k: float(k)/255.0,n),test[:,1:NUMPARAM+1])
      return np.asarray(test_image)
    
    
    # 開始時刻
    start_time = time.time()
    print "開始時刻: " + str(start_time)
    
    
    ### データ取得 --->
    # ファイルを開く
    f = open("train.txt", 'r')
    # データを入れる配列
    train = []
    for line in f:
        # 改行を除いてスペース区切りにする
        line = line.rstrip()
        l = line.split(" ")
        l = map(lambda n: int(n),l)
        #l=map(lambda n: 0 if n=="0" else 1,l)
        train.append(l)
    
    
    # numpy形式に変換
    train = np.asarray(train)
    f.close()
    
    f = open("t10k.txt", 'r')
    test = []
    for line in f:
        line = line.rstrip()
        l = line.split(" ")
        l = map(lambda n: int(n),l)
        #l=map(lambda n: 0 if n=="0" else 1,l)
        test.append(l)
    
    test = np.asarray(test)
    f.close()
    ### データ取得 ---<
    
    
    # 訓練画像を入れる変数
    # 訓練画像は28x28pxであり、これらを1行784列のベクトルに並び替え格納する
    # Noneとなっているのは訓練画像がいくつでも入れられるようにするため
    x = tf.placeholder(tf.float32, [None, NUMPARAM], name="x-input")
    
    # 交差エントロピー
    # y_は正解データのラベル
    # 損失とオプティマイザを定義します
    y_ = tf.placeholder(tf.float32, [None, NUMCLASS], name="y-input")
    
    
    # hidden1
    with tf.name_scope("hidden_layer1") as scope:
      w_h1 = tf.Variable(tf.truncated_normal([NUMPARAM, 500],
                              stddev=1.0 / math.sqrt(float(NUMPARAM))),name='weights')
      b_h1 = tf.Variable(tf.zeros([500]),name='biases')
    
      h1 = tf.nn.sigmoid(tf.matmul(x, w_h1) + b_h1)
    # hidden2
    with tf.name_scope("hidden_layer2") as scope:
      w_h2 = tf.Variable(tf.truncated_normal([500, 300],
                              stddev=1.0 / math.sqrt(float(500))),name='weights')
      b_h2 = tf.Variable(tf.zeros([300]),name='biases')
    
      h2 = tf.nn.sigmoid(tf.matmul(h1, w_h2) + b_h2)
    # softmax layer
    with tf.name_scope("softmax_layer") as scope:
      w_o = tf.Variable(tf.truncated_normal([300, NUMCLASS],
                              stddev=1.0 / math.sqrt(float(300))),name='weights')
      b_o = tf.Variable(tf.zeros([NUMCLASS]),name='biases')
    
      y = tf.nn.softmax((tf.matmul(h2, w_o) + b_o))
    
    
    # 更なる name scopes はグラフ表現をクリーンアップしま
    with tf.name_scope("xent") as scope:
      cross_entropy = -tf.reduce_sum(y_*tf.log(y))
      # TensorBoardで表示するよう指定
      tf.scalar_summary("cross_entropy", cross_entropy)
    
      # 勾配硬化法を用い交差エントロピーが最小となるようyを最適化する
      train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
    
    # 用意した変数Veriableの初期化を実行する
    init = tf.initialize_all_variables()
    
    # Sessionを開始する
    # runすることで初めて実行開始される(run(init)しないとinitが実行されない)
    sess = tf.Session()
    sess.run(init)
    # TensorBoardで表示する値の設定
    summary_op = tf.merge_all_summaries()
    summary_writer = tf.train.SummaryWriter("/tmp/data", sess.graph_def)
    
    
    # 1000回の訓練(train_step)を実行する
    # next_batch(100)で100つのランダムな訓練セット(画像と対応するラベル)を選択する
    # 訓練データは60000点あるので全て使いたいところだが費用つまり時間がかかるのでランダムな100つを使う
    # 100つでも同じような結果を得ることができる
    # feed_dictでplaceholderに値を入力することができる
    print "--- 訓練開始 ---"
    for i in range(20000):
      train_sample=np.asarray(random.sample(train,100))
      batch_ys=label_data(train_sample[:,0])
      batch_xs=image_data(train_sample)
      train_accuracy=sess.run(train_step, feed_dict={x: batch_xs, y_:batch_ys})
    
      # 1 step終わるたびにTensorBoardに表示する値を追加する
      summary_str=sess.run(summary_op, feed_dict={x: batch_xs, y_:batch_ys})
      summary_writer.add_summary(summary_str, i)
    print "--- 訓練終了 ---"
    
    # 正しいかの予測
    # 計算された画像がどの数字であるかの予測yと正解ラベルy_を比較する
    # 同じ値であればTrueが返される
    # argmaxは配列の中で一番値の大きい箇所のindexが返される
    # 一番値が大きいindexということは、それがその数字である確率が一番大きいということ
    # Trueが返ってくるということは訓練した結果と回答が同じということ
    with tf.name_scope("test") as scope:
      correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    
    # 精度の計算
    # correct_predictionはbooleanなのでfloatにキャストし、平均値を計算する
    # Trueならば1、Falseならば0に変換される
      accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    
      tf.scalar_summary("accuracy", accuracy)
    
    # 精度の実行と表示
    # テストデータの画像とラベルで精度を確認する
    # ソフトマックス回帰によってWとbの値が計算されているので、xを入力することでyが計算できる
    test_label=label_data(test[:,0])
    test_image=image_data(test)
    # http://d.hatena.ne.jp/sugyan/20151124/1448292129
    print "精度"
    print(sess.run(accuracy, feed_dict={x: test_image, y_: test_label}))
    
    ## save 
    saver = tf.train.Saver([w_h1,b_h1,w_h2,b_h2,w_o,b_o])
    saver.save(sess, "/tmp/tf_cnn.ckpt")
    
    # 終了時刻
    end_time = time.time()
    print "終了時刻: " + str(end_time)
    print "かかった時間: " + str(end_time - start_time)
    
    

    判定用

    tf_cnn3_exec.py

    #!/bin/env python
    # -*- coding: utf-8 -*-
    # http://qiita.com/ikki8412/items/95bc81a744dc377d9119
    import tensorflow as tf
    import numpy as np
    import random
    import time
    import math
    
    NUMCLASS=10
    NUMPARAM=784
       
    ### データ処理用
    def label_data(lines):
      labels=[]
      for line in lines:
        # ラベルを1-of-k方式で用意する
        tmp = np.zeros(NUMCLASS)
        tmp[int(line)] = 1
        labels.append(tmp)
      return np.asarray(labels)
    
    def image_data(test):
      test_image=map(lambda n: map(lambda k: float(k)/255.0,n),test[:,1:NUMPARAM+1])
      return np.asarray(test_image)
    
    
    # 開始時刻
    start_time = time.time()
    print "開始時刻: " + str(start_time)
    
    
    ### データ取得 --->
    # ファイルを開く
    
    f = open("t10k.txt", 'r')
    test = []
    for line in f:
        line = line.rstrip()
        l = line.split(" ")
        l = map(lambda n: int(n),l)
        #l=map(lambda n: 0 if n=="0" else 1,l)
        test.append(l)
    
    test = np.asarray(test)
    f.close()
    ### データ取得 ---<
    
    
    # 訓練画像を入れる変数
    # 訓練画像は28x28pxであり、これらを1行784列のベクトルに並び替え格納する
    # Noneとなっているのは訓練画像がいくつでも入れられるようにするため
    x = tf.placeholder(tf.float32, [None, NUMPARAM], name="x-input")
    
    # 交差エントロピー
    # y_は正解データのラベル
    # 損失とオプティマイザを定義します
    y_ = tf.placeholder(tf.float32, [None, NUMCLASS], name="y-input")
    
    
    # hidden1
    with tf.name_scope("hidden_layer1") as scope:
      w_h1 = tf.Variable(tf.truncated_normal([NUMPARAM, 500],
                              stddev=1.0 / math.sqrt(float(NUMPARAM))),name='weights')
      b_h1 = tf.Variable(tf.zeros([500]),name='biases')
    
      h1 = tf.nn.sigmoid(tf.matmul(x, w_h1) + b_h1)
    # hidden2
    with tf.name_scope("hidden_layer2") as scope:
      w_h2 = tf.Variable(tf.truncated_normal([500, 300],
                              stddev=1.0 / math.sqrt(float(500))),name='weights')
      b_h2 = tf.Variable(tf.zeros([300]),name='biases')
    
      h2 = tf.nn.sigmoid(tf.matmul(h1, w_h2) + b_h2)
    # softmax layer
    with tf.name_scope("softmax_layer") as scope:
      w_o = tf.Variable(tf.truncated_normal([300, NUMCLASS],
                              stddev=1.0 / math.sqrt(float(300))),name='weights')
      b_o = tf.Variable(tf.zeros([NUMCLASS]),name='biases')
    
      y = tf.nn.softmax((tf.matmul(h2, w_o) + b_o))
    
    
    
    # 用意した変数Veriableの初期化を実行する
    init = tf.initialize_all_variables()
    
    # Sessionを開始する
    # runすることで初めて実行開始される(run(init)しないとinitが実行されない)
    sess = tf.Session()
    sess.run(init)
    
    
    
    saver = tf.train.Saver([w_h1,b_h1,w_h2,b_h2,w_o,b_o])
    saver.restore(sess, "/tmp/tf_cnn.ckpt")
    
    
    # 精度の実行と表示
    # テストデータの画像とラベルで精度を確認する
    # ソフトマックス回帰によってWとbの値が計算されているので、xを入力することでyが計算できる
    test_label=label_data(test[:,0])
    test_image=image_data(test)
    
    
    # http://d.hatena.ne.jp/sugyan/20151124/1448292129
    print "精度"
    print(test_image[0])
    res=(sess.run(y, feed_dict={x: [test_image[0]]}))
    print res[0]
    
    
    # 終了時刻
    end_time = time.time()
    print "終了時刻: " + str(end_time)
    print "かかった時間: " + str(end_time - start_time)
    
    

    実行

    学習させて、テストデータの先頭の1つを判定します。その際、どの数値をどの確率で判定しているかのリストを表示させています。その数値が最も高いものがこのエンジンでの判定結果となります。

    $ python tf_cnn3.py
    開始時刻: 1459469907.05
    --- 訓練開始 ---
    --- 訓練終了 ---
    精度
    0.9804
    終了時刻: 1459470791.98
    かかった時間: 884.936733961
    ubuntu@ubuntu:~/mnist$ python tf_cnn3_exec.py
    開始時刻: 1459471244.43
    結果
    [	1.49596369e-09	 4.64228158e-08	 5.76857360e-07	 1.40932752e-05
    2.07982364e-11	 3.24105409e-10	 2.27739631e-15	 9.99985099e-01
    5.93633684e-11	 2.51105405e-07]
    終了時刻: 1459471249.84
    かかった時間: 5.40709519386
    

    この結果では7が9.99985099e-01で最も数値が高くなっています

    TensorflowでMNIST(4)

    前回までで、MNISTをDeeplearningするにあたって、回帰分析、多層パーセプトロン、畳み込みニューラルネットワークとTensorflowで実装してみました。

    入力データに関しての補足です

    入力用のデータはMNISTのデータを使っているのですが、28×28のビットマップデータを0-254までの数値(白黒)で表したデータを入力とします。

    これを用いてTensorflowの入力データ用に1次元配列に変換します。その際、ビットマップデータを左上から順に1次元の配列に格納しているので、結局784要素の配列となります。これを、ビットマップデータ数分用意(60000)するので結局、784×60000という巨大な行列が入力となります。

    実際の入力利用したデータは、その列の先頭に正解を付与しているので、785×60000でできたファイルとなります

    入力ファイル

    これが1つのデータです。先頭の5が正解データ、それ以降0から続くデータがビットマップの数値表現です

    train.txt

    5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126
    136 175 26 166 255 247 127 0 0 0 0 0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253
    253 253 225 172 253 242 195 64 0 0 0 0 0 0 0 0 0 0 0 49 238 253 253 253 253 253
    253 253 253 251 93 82 82 56 39 0 0 0 0 0 0 0 0 0 0 0 0 18 219 253 253 253 253 2
    53 198 182 247 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 156 107 253 253 205 11
    0 43 154 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 139 253 190 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 11 190 253 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    35 241 225 160 108 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 81 240 253 25
    3 119 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 186 253 253 150 27 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 93 252 253 187 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 249 253 249 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 46 130 183 253 253 207 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39 148 22
    9 253 253 253 250 182 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 114 221 253 253 253
    253 201 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23 66 213 253 253 253 253 198 81 2
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 171 219 253 253 253 253 195 80 9 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 55 172 226 253 253 253 253 244 133 11 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 136 253 253 253 212 135 132 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0
    

    Tensorflow入力

    実際にTensorflowに計算させる際には0-254のビットマップデータを0-1の表現に変更します

    [ 0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.
    0.32941176	0.7254902	 0.62352941	0.59215686	0.23529412	0.14117647
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.87058824	0.99607843	0.99607843	0.99607843	0.99607843
    0.94509804	0.77647059	0.77647059	0.77647059	0.77647059	0.77647059
    0.77647059	0.77647059	0.77647059	0.66666667	0.20392157	0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.2627451	 0.44705882	0.28235294
    0.44705882	0.63921569	0.89019608	0.99607843	0.88235294	0.99607843 
    ...
    0.4745098	 0.99607843	0.81176471	0.07058824	0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.					0.					0.					0.
    0.					0.					0.					0.				]
    

    教師データ

    正解データは1-of-k方式のデータに直します。下記ですと7になります

    [ 0.	0.	0.	0.	0.	0.	0.	1.	0.	0.]
    

    回帰分析のダミー変数みたいな感じだと思えばいいかと思います

    TensorflowでMNIST(3)

    最後は畳み込みニューラルネットワーク(CNN)を実装します。

    TensorflowではExpertとしてTutorialに入っているものです。

    前回と同様に、MNISTのデータを作成し、Deeplearningしてみます。

    コードは前回、前々回のものの一部エンジン部分のみを変更していますので合わせて比較してみるとよくわかるかもしません。

    データ作成

    まずデータを作成します。こちらの手順を実行します

    http://d.hatena.ne.jp/anagotan/20160328/1459156607

    train.txtとt10k.txtを作成しておきます

    tf_cnn.py

    こちらのコードは以下のものを流用させていただきました

    http://qiita.com/ikki8412/items/95bc81a744dc377d9119

    #!/bin/env python
    # -*- coding: utf-8 -*-
    # http://qiita.com/ikki8412/items/95bc81a744dc377d9119
    import tensorflow as tf
    import numpy as np
    import random
    import time
    import math
    
    NUMCLASS=10
    NUMPARAM=784
       
    ### データ処理用
    def label_data(lines):
      labels=[]
      for line in lines:
        # ラベルを1-of-k方式で用意する
        tmp = np.zeros(NUMCLASS)
        tmp[int(line)] = 1
        labels.append(tmp)
      return np.asarray(labels)
    
    def image_data(test):
      test_image=map(lambda n: map(lambda k: float(k)/255.0,n),test[:,1:NUMPARAM+1])
      return np.asarray(test_image)
    
    
    # 開始時刻
    start_time = time.time()
    print "開始時刻: " + str(start_time)
    
    
    ### データ取得 --->
    # ファイルを開く
    f = open("train.txt", 'r')
    # データを入れる配列
    train = []
    for line in f:
        # 改行を除いてスペース区切りにする
        line = line.rstrip()
        l = line.split(" ")
        l = map(lambda n: int(n),l)
        #l=map(lambda n: 0 if n=="0" else 1,l)
        train.append(l)
    
    
    # numpy形式に変換
    train = np.asarray(train)
    f.close()
    
    f = open("t10k.txt", 'r')
    test = []
    for line in f:
        line = line.rstrip()
        l = line.split(" ")
        l = map(lambda n: int(n),l)
        #l=map(lambda n: 0 if n=="0" else 1,l)
        test.append(l)
    
    test = np.asarray(test)
    f.close()
    ### データ取得 ---<
    
    
    # 訓練画像を入れる変数
    # 訓練画像は28x28pxであり、これらを1行784列のベクトルに並び替え格納する
    # Noneとなっているのは訓練画像がいくつでも入れられるようにするため
    x = tf.placeholder(tf.float32, [None, NUMPARAM], name="x-input")
    
    # 交差エントロピー
    # y_は正解データのラベル
    # 損失とオプティマイザを定義します
    y_ = tf.placeholder(tf.float32, [None, NUMCLASS], name="y-input")
    
    
    # hidden1
    with tf.name_scope("hidden_layer1") as scope:
      weights = tf.Variable(tf.truncated_normal([NUMPARAM, 500],
                              stddev=1.0 / math.sqrt(float(NUMPARAM))),name='weights')
      biases = tf.Variable(tf.zeros([500]),name='biases')
    
      hidden1 = tf.nn.sigmoid(tf.matmul(x, weights) + biases)
    # hidden2
    with tf.name_scope("hidden_layer2") as scope:
      weights = tf.Variable(tf.truncated_normal([500, 300],
                              stddev=1.0 / math.sqrt(float(500))),name='weights')
      biases = tf.Variable(tf.zeros([300]),name='biases')
    
      hidden2 = tf.nn.sigmoid(tf.matmul(hidden1, weights) + biases)
    # softmax layer
    with tf.name_scope("softmax_layer") as scope:
      weights = tf.Variable(tf.truncated_normal([300, NUMCLASS],
                              stddev=1.0 / math.sqrt(float(300))),name='weights')
      biases = tf.Variable(tf.zeros([NUMCLASS]),name='biases')
    
      y = tf.nn.softmax((tf.matmul(hidden2, weights) + biases))
    
    
    # 更なる name scopes はグラフ表現をクリーンアップしま
    with tf.name_scope("xent") as scope:
      cross_entropy = -tf.reduce_sum(y_*tf.log(y))
      # TensorBoardで表示するよう指定
      tf.scalar_summary("cross_entropy", cross_entropy)
    
      # 勾配硬化法を用い交差エントロピーが最小となるようyを最適化する
      train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
    
    # 用意した変数Veriableの初期化を実行する
    init = tf.initialize_all_variables()
    
    # Sessionを開始する
    # runすることで初めて実行開始される(run(init)しないとinitが実行されない)
    sess = tf.Session()
    sess.run(init)
    # TensorBoardで表示する値の設定
    summary_op = tf.merge_all_summaries()
    summary_writer = tf.train.SummaryWriter("/tmp/data", sess.graph_def)
    
    
    # 1000回の訓練(train_step)を実行する
    # next_batch(100)で100つのランダムな訓練セット(画像と対応するラベル)を選択する
    # 訓練データは60000点あるので全て使いたいところだが費用つまり時間がかかるのでランダムな100つを使う
    # 100つでも同じような結果を得ることができる
    # feed_dictでplaceholderに値を入力することができる
    print "--- 訓練開始 ---"
    for i in range(20000):
      train_sample=np.asarray(random.sample(train,100))
      batch_ys=label_data(train_sample[:,0])
      batch_xs=image_data(train_sample)
      train_accuracy=sess.run(train_step, feed_dict={x: batch_xs, y_:batch_ys})
    
      # 1 step終わるたびにTensorBoardに表示する値を追加する
      summary_str=sess.run(summary_op, feed_dict={x: batch_xs, y_:batch_ys})
      summary_writer.add_summary(summary_str, i)
    print "--- 訓練終了 ---"
    
    # 正しいかの予測
    # 計算された画像がどの数字であるかの予測yと正解ラベルy_を比較する
    # 同じ値であればTrueが返される
    # argmaxは配列の中で一番値の大きい箇所のindexが返される
    # 一番値が大きいindexということは、それがその数字である確率が一番大きいということ
    # Trueが返ってくるということは訓練した結果と回答が同じということ
    with tf.name_scope("test") as scope:
      correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    
    # 精度の計算
    # correct_predictionはbooleanなのでfloatにキャストし、平均値を計算する
    # Trueならば1、Falseならば0に変換される
      accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    
      tf.scalar_summary("accuracy", accuracy)
    
    # 精度の実行と表示
    # テストデータの画像とラベルで精度を確認する
    # ソフトマックス回帰によってWとbの値が計算されているので、xを入力することでyが計算できる
    test_label=label_data(test[:,0])
    test_image=image_data(test)
    print "精度"
    print(sess.run(accuracy, feed_dict={x: test_image, y_: test_label}))
    
    # 終了時刻
    end_time = time.time()
    print "終了時刻: " + str(end_time)
    print "かかった時間: " + str(end_time - start_time)
    
    

    実行

    $ python tf_cnn.py
    開始時刻: 1459233406.76
    --- 訓練開始 ---
    --- 訓練終了 ---
    精度
    0.9806
    終了時刻: 1459234272.93
    かかった時間: 866.176848888
    

    回帰(0.9227)、多層パーセプトロン(0.9562)に比較し0.9806とかなり精度が上がりました