読者です 読者をやめる 読者になる 読者になる

Hope is a Dream. Dream is a Hope.

非公開ふぃふぃ工房ブログ

sin波をRNNで推定. r1.0で動作確認済み

sin波をRNNで推定. r1.0で動作確認済み

参考コードはこちら

コード:nayutaya/tensorflow-rnn-sin/ex1/basic/rnn.py

参考コードがtensorflowのr1.0に対応していなかったので,書き直しました.

r1.01で動作確認しました.

import sys
import yaml # sudo pip3 install pyyaml
import numpy as np
import random

import tensorflow as tf
def make_mini_batch(train_data, size_of_mini_batch, length_of_sequences):
    inputs  = np.empty(0)
    outputs = np.empty(0)
    for _ in range(size_of_mini_batch):
        index   = random.randint(0, len(train_data) - length_of_sequences)
        part    = train_data[index:index + length_of_sequences]
        inputs  = np.append(inputs, part[:, 0])
        outputs = np.append(outputs, part[-1, 1])
    inputs  = inputs.reshape(-1, length_of_sequences, 1)
    outputs = outputs.reshape(-1, 1)
    return (inputs, outputs)
def make_prediction_initial(train_data, index, length_of_sequences):
    return train_data[index:index + length_of_sequences, 0]
train_data_path             = "./train_data/normal.npy"
num_of_input_nodes          = 1
num_of_hidden_nodes         = 2
num_of_output_nodes         = 1
length_of_sequences         = 50
num_of_training_epochs      = 2000
length_of_initial_sequences = 50
num_of_prediction_epochs    = 100
size_of_mini_batch          = 100
learning_rate               = 0.1
forget_bias                 = 1.0
print("train_data_path             = %s" % train_data_path)
print("num_of_input_nodes          = %d" % num_of_input_nodes)
print("num_of_hidden_nodes         = %d" % num_of_hidden_nodes)
print("num_of_output_nodes         = %d" % num_of_output_nodes)
print("length_of_sequences         = %d" % length_of_sequences)
print("num_of_training_epochs      = %d" % num_of_training_epochs)
print("length_of_initial_sequences = %d" % length_of_initial_sequences)
print("num_of_prediction_epochs    = %d" % num_of_prediction_epochs)
print("size_of_mini_batch          = %d" % size_of_mini_batch)
print("learning_rate               = %f" % learning_rate)
print("forget_bias                 = %f" % forget_bias)

train_data = np.load(train_data_path)
print("train_data:", train_data)
train_data_path             = ./train_data/normal.npy
num_of_input_nodes          = 1
num_of_hidden_nodes         = 2
num_of_output_nodes         = 1
length_of_sequences         = 50
num_of_training_epochs      = 2000
length_of_initial_sequences = 50
num_of_prediction_epochs    = 100
size_of_mini_batch          = 100
learning_rate               = 0.100000
forget_bias                 = 1.000000
train_data: [[  0.00000000e+00   1.25333234e-01]
 [  1.25333234e-01   2.48689887e-01]
 [  2.48689887e-01   3.68124553e-01]
 ..., 
 [ -3.68124553e-01  -2.48689887e-01]
 [ -2.48689887e-01  -1.25333234e-01]
 [ -1.25333234e-01   3.92877345e-15]]
# 乱数シードを固定する。
random.seed(0)
np.random.seed(0)
tf.set_random_seed(0)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)

with tf.Graph().as_default():
    input_ph      = tf.placeholder(tf.float32, [None, length_of_sequences, num_of_input_nodes], name="input")
    supervisor_ph = tf.placeholder(tf.float32, [None, num_of_output_nodes], name="supervisor")
    istate_ph     = tf.placeholder(tf.float32, [None, num_of_hidden_nodes * 2], name="istate") 
    # 1セルあたり2つの値を必要とする。

    with tf.name_scope("inference") as scope:
        weight1_var = tf.Variable(tf.truncated_normal([num_of_input_nodes, num_of_hidden_nodes], stddev=0.1), name="weight1")
        weight2_var = tf.Variable(tf.truncated_normal([num_of_hidden_nodes, num_of_output_nodes], stddev=0.1), name="weight2")
        bias1_var   = tf.Variable(tf.truncated_normal([num_of_hidden_nodes], stddev=0.1), name="bias1")
        bias2_var   = tf.Variable(tf.truncated_normal([num_of_output_nodes], stddev=0.1), name="bias2")

        in1 = tf.transpose(input_ph, [1, 0, 2])         # (batch, sequence, data) -> (sequence, batch, data)
        in2 = tf.reshape(in1, [-1, num_of_input_nodes]) # (sequence, batch, data) -> (sequence * batch, data)
        in3 = tf.matmul(in2, weight1_var) + bias1_var
        
        # r0.1記法
        #in4 = tf.split(0, length_of_sequences, in3)     # sequence * (batch, data)
        # r1.0記法
        in4 = tf.split(in3, length_of_sequences)

        cell = tf.contrib.rnn.BasicLSTMCell(num_of_hidden_nodes, forget_bias=forget_bias, state_is_tuple=False)
        #rnn_output, states_op = rnn.rnn(cell, in4, initial_state=istate_ph) r(0.1)
        rnn_output, states_op = tf.contrib.rnn.static_rnn(cell, in4, initial_state=istate_ph)
        
        output_op
        = tf.matmul(rnn_output[-1], weight2_var) + bias2_var

    with tf.name_scope("loss") as scope:
        square_error = tf.reduce_mean(tf.square(output_op - supervisor_ph))
        loss_op      = square_error
        # tf.scalar_summary("loss", loss_op) # r0.1
        tf.summary.scalar("loss", loss_op) # r.10

    with tf.name_scope("training") as scope:
        training_op = optimizer.minimize(loss_op)

    # summary_op = tf.merge_all_summaries() #0.1
    summary_op = tf.summary.merge_all() # 1.0
    
    init = tf.initialize_all_variables()

    with tf.Session() as sess:
        saver = tf.train.Saver()
        # summary_writer = tf.train.SummaryWriter("data", graph=sess.graph) # r0.1
        summary_writer = tf.summary.FileWriter("data", graph=sess.graph) # r1.0

        sess.run(init)

        for epoch in range(num_of_training_epochs):
            inputs, supervisors = make_mini_batch(train_data, size_of_mini_batch, length_of_sequences)

            train_dict = {
                input_ph:      inputs,
                supervisor_ph: supervisors,
                istate_ph:     np.zeros((size_of_mini_batch, num_of_hidden_nodes * 2)),
            }
            sess.run(training_op, feed_dict=train_dict)

            if (epoch + 1) % 10 == 0:
                summary_str, train_loss = sess.run([summary_op, loss_op], feed_dict=train_dict)
                summary_writer.add_summary(summary_str, epoch)
                print("train#%d, train loss: %e" % (epoch + 1, train_loss))

        inputs  = make_prediction_initial(train_data, 0, length_of_initial_sequences)
        outputs = np.empty(0)
        states  = np.zeros((num_of_hidden_nodes * 2)),

        print("initial:", inputs)
        np.save("initial.npy", inputs)

        for epoch in range(num_of_prediction_epochs):
            pred_dict = {
                input_ph:  inputs.reshape((1, length_of_sequences, 1)),
                istate_ph: states,
            }
            output, states = sess.run([output_op, states_op], feed_dict=pred_dict)
            print("prediction#%d, output: %f" % (epoch + 1, output))

            inputs  = np.delete(inputs, 0)
            inputs  = np.append(inputs, output)
            outputs = np.append(outputs, output)

        print("outputs:", outputs)
        np.save("output.npy", outputs)

        saver.save(sess, "data/model")
WARNING:tensorflow:<tensorflow.contrib.rnn.python.ops.core_rnn_cell_impl.BasicLSTMCell object at 0x00000000118F9160>: Using a concatenated state is slower and will soon be deprecated.  Use state_is_tuple=True.
WARNING:tensorflow:From <ipython-input-15-d5dd1fd24074>:42: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
train#10, train loss: 5.229673e-01
train#20, train loss: 5.009690e-01
train#30, train loss: 5.198909e-01
train#40, train loss: 5.346115e-01
train#50, train loss: 4.447417e-01
train#60, train loss: 4.501579e-01
train#70, train loss: 4.537308e-01
train#80, train loss: 3.279701e-01
prediction#87, output: -0.983231
prediction#88, output: -0.955930
prediction#89, output: -0.914552
prediction#90, output: -0.859774
prediction#91, output: -0.791508
prediction#92, output: -0.709254
prediction#93, output: -0.612653
prediction#94, output: -0.502259
prediction#95, output: -0.380304
prediction#96, output: -0.250905
prediction#97, output: -0.119140
prediction#98, output: 0.010653
prediction#99, output: 0.136095
prediction#100, output: 0.256669
outputs: [ 0.00926255  0.14518531  0.26629266  0.3826645   0.4946214   0.60127538
  0.70039088  0.78870726  0.86278987  0.92006391  0.95948833  0.98155129
  0.98773634  0.97983921  0.95942783  0.92752028  0.88444293  0.82979822
  0.76252556  0.68110597  0.58405989  0.47093415  0.34376413  0.20819654
  0.07255314 -0.05579655 -0.17396016 -0.28367797 -0.38881654 -0.49280256
 -0.59695822 -0.69951463 -0.79543906 -0.87775397 -0.94028378 -0.98007071
 -0.99764407 -0.99550325 -0.97644424 -0.94260907 -0.89518976 -0.83448744
 -0.76016831 -0.67169166 -0.56896263 -0.45314986 -0.32730505 -0.19613414
 -0.06463058  0.06360264  0.18705504  0.30573574  0.42002755  0.52970022
  0.63335198  0.72833896  0.81128317  0.87901324  0.92949694  0.96226823
  0.97820294  0.97890699  0.96607846  0.94105148  0.90454733  0.85657418
  0.79643178  0.72282809  0.63420713  0.52946943  0.40922943  0.27726871
  0.14084016  0.00827865 -0.11505078 -0.22876213 -0.33597133 -0.44053042
 -0.54490018 -0.64883077 -0.74872804 -0.83822566 -0.91042352 -0.9607482
 -0.98827887 -0.99484038 -0.98323065 -0.95593017 -0.91455233 -0.85977364
 -0.7915076  -0.70925373 -0.6126532  -0.50225872 -0.38030428 -0.25090536
 -0.11914031  0.01065348  0.13609533  0.25666925]

付録

記法の修正

・Cell関連

# r0.1
cell = tf.nn.rnn.LSTMCell()
# r1.0
cell = tf.contrib.rnn.BasicRNNCell()

・rnn.rnn() => tf.contrib.rnn.static_rnn()

# r0.1
from tensorflow.models.rnn import rnn, rnn_cell
rnn_output, states_op = rnn.rnn(cell, in4, initial_state=istate_ph) r(0.1)
# r1.0
rnn_output, states_op = tf.contrib.rnn.static_rnn(cell, in4, initial_state=istate_ph)

・split

# r0.1記法
in4 = tf.split(0, length_of_sequences, in3)     # sequence * (batch, data)
# r1.0記法
in4 = tf.split(in3, length_of_sequences)

・summary

# tf.scalar_summary("loss", loss_op) # r0.1
tf.summary.scalar("loss", loss_op) # r.10

# summary_op = tf.merge_all_summaries() #0.1
summary_op = tf.summary.merge_all() # 1.0

# summary_writer = tf.train.SummaryWriter("data", graph=sess.graph) # r0.1
summary_writer = tf.summary.FileWriter("data", graph=sess.graph) # r1.0

r1.0対応のRNN関連サンプルコード

r1.0未対応のRNN関連サンプルコード

QMainWindowのテンプレート QMainWindowを使うときにいつも使い方を忘れてしまう

詳細はこちら

pyside_cookbook/09_QMainwindow at master · peace098beat/pyside_cookbook · GitHub

QMainWindowのテンプレート

QMainWindowを使うときにいつも使い方を忘れてしまう。Menubarやステータスバー、プログレスバー等々。 また、メインウィンドウではファイルオープンが必須だったりする。 また、デバッグ時の速度計測のためにFPSを表示したり、シグナルをいろいろつくったり。 また、ドラッグアンドドロップをしたり。 また、メッセージダイアログのだしかたをしらべたりとか。 また、セントラルウィジェットを配置する「おまじない」をわすれたりとか。。。 「さてアプリつくるか!」ってなってから、実際のアルゴリズム部分までにいくのにかなりのじかんをつかってしまう。

ってことで

テンプレートをつくった。

継承してつかってね。

demo

#! coding:utf-8
"""
BasedMainWindowの使い方
"""

import sys
import os
import time
from PySide.QtGui import *
from PySide.QtCore import *

from baseqmainwindow import BasedMainWindow


class YourMainWindow(BasedMainWindow):

    """ BaseMainWindwの使いかた その2
  ウィジェットのレイアウトの方法
  """
    
    def __init__(self):
        super().__init__()

        # おまじない
        self.main_widget = QWidget(self)
        self.main_layout = QGridLayout(self.main_widget)
        self.setCentralWidget(self.main_widget)

        # 子供UI
        label1 = QLabel("Top - Left")
        label2 = QLabel("Top - Right")
        label3 = QLabel("Bottom - Left")
        label4 = QLabel("Bottom - right")

        # レイアウトをセット
        self.main_layout.addWidget(label1, 0, 0)
        self.main_layout.addWidget(label2, 0, 1)
        self.main_layout.addWidget(label3, 1, 0)
        self.main_layout.addWidget(label4, 1, 1)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.lastWindowClosed.connect(app.quit)

    win = YourMainWindow()
    win.show()
    sys.exit(app.exec_())
    ```

PySideでグラフ表示はどうしてる?Matplotlib遅くね?高速化方法。

PySideを使ったスピード測定

PySideを使って音声処理をしているとどうしてもリアルタイムでグラフをヌメヌメ動かさないといけない。実装の手軽さからMatplotlibを使ってこれまでやっていたが、遅い。遅い。遅い。10FPSぐらいしかでない。高速化する方法が和歌来。そこで、pyqtgraphとQGraphicsを使って速度を比較してみる。QPainerとPyOpenGLは次回に追加予定

対戦表

  • Matplotlib pyplot.plot
  • Matplotlib pyplot.axex.set_ydata()
  • PyQtGraph pg.plot
  • QGraphics 独自実装

対戦方式

  1. QMainWindow内部で120FPSでメインループを呼び出す。

  2. メインループ内でsin波形を生成しプロット <= このときのFPSを比較する。

結果

結果1 N=2048

  • グラフなし : 120FPS
  • Matplotlib pyplot.plot : 9FPS
  • Matplotlib pyplot.axex.set_ydata() : 15FPS
  • PyQtGraph pg.plot : 120FPS
  • QGraphics 独自実装 : 70~120FPS (なぜか変動する)

結果2 N=10240

  • グラフなし : 120 fps
  • Matplotlib pyplot.plot : 4fps
  • Matplotlib pyplot.axex.set_ydata() : 5fps
  • PyQtGraph pg.plot : 60fps
  • QGraphics 独自実装 : 40~100FPS (なぜか変動する)

QGraphicsを使った実装は安定して早い。また、PyQtGraphも早い。PyQtGraphはウラでQGraphicsを使って、いろいろ高速化の工夫がされているので両方とも同じような速度がでているのはよい。また、PyQtGraphは高速化の工夫からか、fpsが変動し、たまにかなり高い値をだすのも面白い。

詳細はこちら

github.com