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とかなり精度が上がりました

TensorflowでMNIST(2)

今回は中級?者向けの多層パーセプトロン(multilayer perceptron)を実装します

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

http://qiita.com/TomokIshii/items/92a266b805d7eee02b1d

前回と同様に、input_data.pyを使わずにデータを自前で作成します

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

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

tf_mlp.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
NUMHIDDEN=625
   
### データ処理用
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_h = tf.Variable(tf.random_normal([NUMPARAM, NUMHIDDEN],mean=0.0, stddev=0.05))
  b_h = tf.Variable(tf.zeros([NUMHIDDEN]),name='biases')

  h = tf.sigmoid(tf.matmul(x, w_h) + b_h)
# output layer
with tf.name_scope("output_layer") as scope:
  w_o = tf.Variable(tf.truncated_normal([NUMHIDDEN, NUMCLASS],mean=0.0, stddev=0.05))
  b_o = tf.Variable(tf.zeros([NUMCLASS]),name='biases')

  y = tf.nn.softmax((tf.matmul(h, w_o) + b_o))


# 更なる name scopes はグラフ表現をクリーンアップしま
with tf.name_scope("xent") as scope:
  # Cost Function basic term
  cross_entropy = -tf.reduce_sum(y_*tf.log(y))
  
  # Regularization terms (weight decay)
  L2_sqr = tf.nn.l2_loss(w_h) + tf.nn.l2_loss(w_o)
  lambda_2 = 0.01
  # the loss and accuracy
  loss = cross_entropy + lambda_2 * L2_sqr

  # TensorBoardで表示するよう指定
  tf.scalar_summary("cross_entropy", cross_entropy)

  # 勾配硬化法を用い交差エントロピーが最小となるようyを最適化する
  train_step = tf.train.GradientDescentOptimizer(0.001).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_mlp.py
開始時刻: 1459237690.97
--- 訓練開始 ---
--- 訓練終了 ---
精度
0.9562
終了時刻: 1459238511.06
かかった時間: 820.087219

回帰の場合には0.9227だったのですが、0.9562まで精度が上がりました

TensorflowでMNIST(1)

GoogleのDeeplearningプラットフォームであるtensorflowを触ってみました。

https://www.tensorflow.org/

世の中にはMNISTのサンプルを実行したブログが多いのですが、tutorialを開設しているだけのものが多くちょっとよく理解できていませんでした

自分なりに色々と調べてMNISTを理解していきます

まずはBeginnerということのサンプルです。

Beginnerというか、Deeplearningというよりは回帰分析をTensorflowで行っているというサンプルです

データダウンロード

input_data.pyを使うとよくわからないので自分でデータ取得からハンドリングします。

まず、データをダウンロードします。

https://www.tensorflow.org/versions/master/tutorials/mnist/download/index.html

こちらの真ん中ほどにあるリンクから下記4つをダウンロードし解凍しておきます。

train-images-idx3-ubyte.gz

train-labels-idx1-ubyte.gz

t10k-images-idx3-ubyte.gz

t10k-labels-idx1-ubyte.gz

$ gunzip train-images-idx3-ubyte.gz
$ gunzip train-labels-idx1-ubyte.gz
$ gunzip t10k-images-idx3-ubyte.gz
$ gunzip t10k-labels-idx1-ubyte.gz

データの整形

そのままでは使いづらいので整形します

od -An -v -tu1 -j16 -w784 train-images-idx3-ubyte | sed 's/^ *//' | tr -s ' ' >train-images.txt
od -An -v -tu1 -j8 -w1 train-labels-idx1-ubyte | tr -d ' ' >train-labels.txt
od -An -v -tu1 -j16 -w784 t10k-images-idx3-ubyte | sed 's/^ *//' | tr -s ' ' >t10k-images.txt
od -An -v -tu1 -j8 -w1 t10k-labels-idx1-ubyte | tr -d ' ' >t10k-labels.txt
file_join(){
image=$1
label=$2
ruby < train.txt
file_join t10k-images.txt t10k-labels.txt > t10k.txt

train.txtとt10k.txtというファイルが作成されます。このファイルは1行ごとにMNISTの画像データの数値データ、0-255までの値で構成されています。その行の先頭に正解数字を入れてたデータです。

Deeplearning

Tensorflowのプログラムはこちらの方のサンプルを流用させていただきました

http://tensorflow.classcat.com/2016/02/11/tensorflow-how-tos-visualizing-learning/

#!/bin/env python
# -*- coding: utf-8 -*-
# http://tensorflow.classcat.com/2016/02/11/tensorflow-how-tos-visualizing-learning/
import tensorflow as tf
import numpy as np
import random
import time

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()
### データ取得 ---<


# ファイルを開く
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()

### データ取得 ---
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_regression.py
開始時刻: 1459234322.4
--- 訓練開始 ---
--- 訓練終了 ---
精度
0.9227
終了時刻: 1459234921.58
かかった時間: 599.178552866

精度はあまり良くありませんが計算できました

raspberry piでWifiを固定IPで使う

ハードウエア

raspberry pi B+

wifiアダプタ WNG150U

OS

RASPBIAN JESSIE

設定

ハードウエアの確認

$ lsusb
Bus 001 Device 004: ID 04bb:094c I-O Data Device, Inc. 

ESSIDの確認

$ sudo iwlist wlan0 scan | grep ESSID
										ESSID:"ESSID"

wpa_supplicant.conf

$ sudo su 
#	chmod 660 root% chmod 660 /etc/wpa_suoplicant/wpa_supplicant.comf
# wpa_passphrase "SSID" "KEY" >> /etc/wpa_supplicant/wpa_supplicant.conf
# cat /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="SSID"
	#psk="KEY"
	psk=ハッシュ化されたキー
}

wpa_supplicant.confの編集

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="SSID"
	proto=WPA2
	key_mgmt=WPA-PSK
	pairwise=TKIP CCMP
	group=TKIP CCMP
	#psk="KEY"
	psk=ハッシュ化されたキー
	scan_ssid=1
}
/etc/dhcpcd.conf
>||

interface wlan0
static ip_address=192.168.11.21/24
static routers=192.168.11.254
static domain_name_servers=192.168.10.1

こんな感じでリブート

 $ ifconfig
eth0			Link encap:イーサネット	ハードウェアアドレス b8:27:eb:9c:30:07 
					inetアドレス:192.168.11.20 ブロードキャスト:192.168.11.255	マスク:255.255.255.0
					inet6アドレス: 240f:79:a8f8:1:b289:a029:fc2e:6ac/64 範囲:グローバル
					inet6アドレス: fe80::7474:4b62:ad78:2a00/64 範囲:リンク
					UP BROADCAST RUNNING MULTICAST	MTU:1500	メトリック:1
					RXパケット:2704 エラー:0 損失:594 オーバラン:0 フレーム:0
					TXパケット:607 エラー:0 損失:0 オーバラン:0 キャリア:0
			衝突(Collisions):0 TXキュー長:1000 
					RXバイト:161138 (157.3 KiB)	TXバイト:88612 (86.5 KiB)

lo				Link encap:ローカルループバック	
					inetアドレス:127.0.0.1 マスク:255.0.0.0
					inet6アドレス: ::1/128 範囲:ホスト
					UP LOOPBACK RUNNING	MTU:65536	メトリック:1
					RXパケット:140 エラー:0 損失:0 オーバラン:0 フレーム:0
					TXパケット:140 エラー:0 損失:0 オーバラン:0 キャリア:0
			衝突(Collisions):0 TXキュー長:0 
					RXバイト:11756 (11.4 KiB)	TXバイト:11756 (11.4 KiB)

wlan0		 Link encap:イーサネット	ハードウェアアドレス 34:76:c5:5d:7e:6c 
					inetアドレス:192.168.11.21 ブロードキャスト:192.168.11.255	マスク:255.255.255.0
					inet6アドレス: fe80::d437:7e2c:6380:2ccc/64 範囲:リンク
					inet6アドレス: 240f:79:a8f8:1:98a1:f100:4d2b:b96b/64 範囲:グローバル
					UP BROADCAST RUNNING MULTICAST	MTU:1500	メトリック:1
					RXパケット:3501 エラー:0 損失:632 オーバラン:0 フレーム:0
					TXパケット:119 エラー:0 損失:3 オーバラン:0 キャリア:0
			衝突(Collisions):0 TXキュー長:1000 
					RXバイト:582397 (568.7 KiB)	TXバイト:20034 (19.5 KiB)

認識されました