頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


TFRecordでたくさんの浮動小数点数を扱う

機械学習(TensorFlow)で位置計測っぽいことをやってみた

↑以前このあたりで、TensorFlowでTFRecordのデータセットを自作する時に画像やラベルとしての整数や浮動小数点数を入れたってことはあった。

今回は1つの学習データに浮動小数点数を大量に持たせたい!

これをやったことなく手間取ったのでメモ。
まずは作成から。
{
    import numpy as np

    arr1 = np.asarray([0.123456789 , 1.2 , 1.3], dtype=np.float32)
    a = arr1[0]
    print(a)#0.123457
    print(type(a))#
}
numpyを使う。最初値をPythonのリストに詰め込んでたけどうまくいかなかった。何か方法はあるのかもしれないけど。
numpyのfloatはデフォで64bitある。今回は32bitで十分ってことでfloat32で配列を作る。
これをTFRecord用に出力する。
{
    label_n = 1
    label_x = 2.0
    record = tf.train.Example(features=tf.train.Features(feature={
                                                         'n' : tf.train.Feature(int64_list=tf.train.Int64List(value=[label_n])),
                                                         'arr1': tf.train.Feature(bytes_list=tf.train.BytesList(value=[arr1.tobytes()])),
                                                         'x': tf.train.Feature(float_list=tf.train.FloatList(value=[label_x])),
                                                         }))
    writer.write(record.SerializeToString())
}
numpyの配列だとtobytes()ってのがあるからこれで書き出せる。以前やった画像の場合はPILのImageオブジェクトにtobytes()で書き出してたので、同じようにしてみた。


次にファイルから値を読み込む。
{
    features = tf.parse_single_example(
                                       serialized_example,
                                       features={
                                       'n': tf.FixedLenFeature([], tf.int64),
                                       'arr1': tf.FixedLenFeature([], tf.string),
                                       'x': tf.FixedLenFeature([], tf.float32),
                                       })
    nn = tf.cast(features['n'], tf.int32)
    xx = tf.cast(features['x'], tf.float32)
    arr1 = tf.decode_raw(features['arr1'], tf.float32)
    arr1.set_shape([3])
}
↑これでデータを読み込んで表示させる(これが超絶めんどくさいよね)と、、、

データ読み込みの結果

↑こんな具合で扱えるようになった!


機械学習におけるデータの範囲(2)

機械学習におけるデータの範囲
↑の続き。データの範囲はどうしても0から1じゃないとダメなのか問題。オチもよくわからないってことなんだがやったこと書いとく。

簡単化するためMNISTで同じようなことをやって確認してみた。ちなみに畳み込みのある方のMNIST。
これも自分でtfrecord形式のデータを作成してて、読み込む時は画像データ(輝度)の値を
tf.uint8
で得ている。8ビットの符号なし整数だから0から255。
image = tf.cast(image, tf.float32)
image /= 255.0
という感じでfloatにキャストしといてから255で割って、0から1.0になるようにしてる。当然これはちゃんと学習が進む。

輝度の確認

↑元画像はこんなので明るい部分はをチェックすると0.99近い。
なのでさっきのを
image /= 128.0 # 255.0
って書き換えたら0から2.0くらいになる。
試しにこれでやってみると、、、ちゃんと学習が進んだ!
image /= 85.0
これだと0から3.0くらいなんだが、、、学習が進むことも落ちることもあった。
データファイルの順番、バッチ作成時にランダムになるようにしてるから毎回同じってわけでは決してないので、たまたまいけることもあればたまたまダメなこともあるってことで、そこはええねん。

落ちる時のエラーメッセージにはこんなのが。
Nan in summary histogram for: conv2/weights_0

これってTensorBoardで必要なデータを出力する時の話?と思ってその辺りを消して実行すると、落ちずに処理は進むんだけど、cross entropyがずっとNanのままだった。
損失関数が発散するような場合には学習率を変えればうまくいったことがあったが、今回は全然効果なし。

ちなみに
(1)image /= 255.0(0から1.0)の場合
(2)image /= 85.0(0から3.0)で処理ができた場合
それぞれでTensorBoardのDistibutionを比較するとweight,biasの分布はさほど変わらずだけど、初期の勾配が大きくなっている。

TensorBoardによる係数の分布1

↑こちらは(1)の方。

TensorBoardによる係数の分布2

↑こちらは(2)の方。

けどこの程度で問題になるんかな?
数学的には別に0から1じゃなくてもいけるんだけど、コンピュータの処理上でどこかでオーバーフローでもやってるんだろうか?


機械学習におけるデータの範囲

最近またTensorFlowをいじってる。やったことメモ。

機械学習(TensorFlow)で位置計測っぽいことをやってみた
↑以前こういうのをやったんだけど、これを使って思い出しがてら気になってたデータの範囲について二つ確認。
1つは正解のラベルについて、もう一つは画像のデータについて。

(1)正解のラベル
この時は正解が無次元化された円の座標と半径で学習してる。座標は-1から1で半径は0超から0.5。この正解を得ようというネットワーク(CNN)だったんだが、この正解が無次元化されてなくてもいけんの?というのを確認しようとした。
座標が0から64.0の値を取る場合だと学習がうまく進まなかったので最後の出力層部分のコードをよくよく見ると、

y_conv=tf.nn.tanh(tf.matmul(h_fc2, W_fc3) + b_fc3

となってた。tan(θ)ってことは、-π/2 , π/2で発散するから-π/2 〜π/2の範囲を超えてるからか?ってことでtanhをreluに変えたらいけた。


(2)画像のデータ
画像のデータは0から1.0の値を取るとしてるんだけど、これが0〜255.0のfloatでもいいんじゃないの?といろいろと試してみたんだけど、結果から言うとなぜかできんかった。0〜2.0でもダメ。

tf.image.random_brightness(image, max_delta=0.4)
tf.image.random_contrast(image, lower=0.6, upper=1.4)

といった画像数水増し処理を特に考えず(作った時はどこかでサンプルを見つけたんだろうね)入れてたけど、これよく見ると場合によっては1.0を超えると思うんだ(すでにimageはtf.float32にキャストしてる)。もしかして今まではたまたま学習が進んだけど、実は悪さしてんじゃね?ってことで

tf.clip_by_value(image , 0.0 , 1.0 )

と言うclampと同じ処理を入れてみた。すると、どうよ。学習の進み具合がよくなってるやん!
不思議や。NNの処理をいくら見ても0〜1の範囲を超えるとまずそうな部分は俺には見つけられんのだが。いつか気付いたら追記するわ。







Pythonのsqlite3でデータを削除する

Python3のsqlite3でデータを削除しようとしたんだ。少し調べると
DELETE FROM tableName WHERE condition
といったサンプルを見つけることができて、実際試すと削除もできたんだけど、俺がやりたかったのが tableNameを文字列として直で入れるんじゃなくて変数として入れたかったんだ。

cursor.execute("INSERT INTO %s VALUES (?,?,?)"%targetTableName, (targetDate ,price ,volume))

↑保存の時には%sってのを使うから同じようにやるんだろうな、、、と思ったんだけどどういうわけかうまく動かない。試行錯誤してようやく動いたのがこんなの。

cursor.execute(“DELETE FROM %s WHERE date =?”%targetTableName, ( targetDate, ))

そりゃそうなんじゃないの?って感じだけど、、、ここにたどり着くのに異様に時間がかかったんだ。それは targetTableName を定義していなかったから、という何とも本質からずれてた情けない話なんだけど、Pythonのエラーメッセージはそんなこと教えてくれず単にいつもと同じ例外を投げてくるだけなのでなかなか気付かなかった。とまたPythonに対する愚痴が出る前におしまい。


PythonでGUI欲しくてPyQt5をインストールしてみた

PythonのIDEとしてXcodeを使ってるんだけど、実行するにはSchemeのArguments Passed On Launchでファイルを選択してから実行(⌘+r)してる。

Xcode

Edit Schemeを選んでRun/Argumentsの所に↑こんなのあるでしょ。ここね。

たまにならいいんだけど、頻繁に切り替えるとなるとここで選択するのが面倒。
例えば現在の状況をみてどれを処理するか自分で選んで対応するボタンをクリックで各ファイルを実行する、とかだとやっぱりメニュー画面みたいなのが欲しいやん?

ってことでPythonで何かGUIを扱えるライブラリみたいなのないのかな?と探してみたら、いくつかありますやん。
とりあえず情報が入りやすそうなPyQt5なるものをインストールしてみた。

PyQt5インストール - Qiita

↑こちらを参考にさせていただき、 pip3 install pyqt5 でインストールした。

PyQt5

↑ほー、ウインドウが出てきたぞ〜




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad