強化学習の勉強に良さそうなサイト一覧

OpenAI Gym
Pythonではじめる強化学習
深層強化学習:ピクセルから『ポン』 – 前編
深層強化学習:ピクセルから『ポン』 – 後編
超シンプルにTensorFlowでDQN (Deep Q Network) を実装してみる 〜解説編② 学習の流れを理解する〜
PyBrainを用いて強化学習をしてみた
Q学習(Q-Learning)やバンディットアルゴリズムなどの強化学習のデモ用のコードを公開して保守していくことにした。
path-finding-q-learning-tutorial
DQNをKerasとTensorFlowとOpenAI Gymで実装する
強化学習で参考になったサイトまとめ
Q学習で最良経路をPythonで求めてみる

TensorFlow – 畳み込みニューラルネットワーク(CNN)をやってみる

TensorFlowのチュートリアルにあるので見てみます。
Deep MNIST for Experts
日本語に訳してくれているのがこれです。

CNNとは?(メモ)

畳み込みニューラルネットワーク(CNN)は、Convolutional neural networkの略だそうです。CNNじゃない一般的なものはニューラルネットワークの各ノードが全部結合しているので全結合といいます。全結合の弱点は、形状を持たないことです。確かにMNISTで試した時も、28×28の画像を784列の1次元にしていました。CNNの畳み込み層という層は、入力も出力も形状を持ちます。バッチ処理に対応する入力は、4次元です。バッチ数、高さ、幅、チャンネル数といったように持ちます。CNNのモデルは下記のようになります。

Convolution層(畳み込み層) -> ReLU -> Pooling層(プーリング層)

上記を1セットとして複数回繰り返します。その後で、Poolingしなかったり、ドロップアウトしたり、最後の方に全結合層を通したりして、最終結果を出力するようです。

畳み込み層でやる処理は、畳み込み演算というもので、フィルタを適用して積和演算をします。フィルタのパラメタが重みになります。バイアスもあって、畳み込み演算の結果に適用します。バイアスは1×1の数値です。

プーリング層は、縦横方向の空間を小さくすることです。例えば、2×2のMAXプーリングをストライド2で行うと、2×2の中で一番大きい数字を取ることを2の間隔で繰り返すことで、画像サイズを小さくします。プーリングは小さくするだけ(MAXプーリングなら最大値をとるだけ)なので、パラメタはないですし、チャンネル毎に実行するので、入力と出力でチャンネル数は変わりません。

Deep MNIST for Expertsをやってみる

最初の方は、CNNではなかったです。全結合のシンプルなやつでした。入力層と出力層のみのサンプルです。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
sess.run(tf.global_variables_initializer())
y = tf.matmul(x,W) + b
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

for i in range(1000):
    batch = mnist.train.next_batch(100)
    train_step.run(feed_dict={x: batch[0], y_: batch[1]})

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

CNN

下記のようになってました。自分が理解している内容をコメントに書きました。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

#mnist読み込み
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
#InteractiveSessoin作成
sess = tf.InteractiveSession()

#重み変数の初期化
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')

#2 x 2のMAXプーリング
def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

#x:入力値,y_:出力値のplaceholderセット
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])

#mnistは1次元でデータを返すので、28x28x1にreshape
#[バッチ数、縦、横、チャンネル数]
x_image = tf.reshape(x, [-1,28,28,1])
#畳み込み層1(フィルター数は32個)
#フィルターのパラメタをセット
#[縦、横、チャンネル数、フィルター数]
W_conv1 = weight_variable([5, 5, 1, 32])
#32個のバイアスをセット
b_conv1 = bias_variable([32])
#畳み込み演算後に、ReLU関数適用
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
#2x2のMAXプーリングを実行
#2x2のMAXプーリングをすると縦横共に半分の大きさになる
h_pool1 = max_pool_2x2(h_conv1)

#畳み込み層2(フィルター数は64個)
#フィルターのパラメタをセット
#チャンネル数が32なのは、畳み込み層1のフィルター数が32だから。
#32個フィルターがあると、出力結果が[-1, 28, 28, 32]というshapeになる。
#入力のチャンネル数と重みのチャンネル数を合わせる。
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

#全結合層(ノードの数は1024個)
#2x2MAXプーリングを2回やってるので、この時点で縦横が、28/(2*2)の7になっている。
#h_pool2のshapeは、[-1, 7, 7, 64]となっているので、7*7*64を入力ノード数とみなす。
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
#全結合層の入力仕様に合わせて、2次元にreshape
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

#ドロップアウト処理
#keep_probは、ドロップアウトさせない率
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

#出力層
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2

#softmaxと交差エントロピーを合わせてやってくれるやつっぽい。あとで確認する。
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_conv, y_))
#AdamOptimizerの学習率を0.0001に設定している。デフォルトが0.001だが、
#複雑なモデルになるとより小さくしないと発散してうまくいかないケースがあるらしい。
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.global_variables_initializer())

for i in range(20000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

数値が0.9919になったすごい。

畳み込みフィルターで画像をぼかしてみる

畳み込みニューラルネットワークは、畳み込みフィルターを使ってますが、畳み込みフィルターを使うと画像を加工出来ます。ぼかすには、画像の明るさを周辺の明るさの平均をとってそれで埋めていくことでぼけます。

適当な画像をぼかしてみようと思います。

まずこの画像をNumpy配列として取得します。画像は、幅800px、高さ600pxです。

import numpy as np
from PIL import Image

img = np.array(Image.open('sample_pic.jpg'))
print(img.shape)

結果

(600, 800, 3)

次に5×5のフィルターを作ります。フィルターの全領域の合計が1になるようにします。

filter_size = 5
filter = np.zeros((filter_size, filter_size))
filter += 1 / (filter_size * filter_size)
print(filter)

結果

[[ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]
 [ 0.04  0.04  0.04  0.04  0.04]]

このフィルターをチャンネル毎に画像の左から順に適用していきます。

new_img = np.zeros(img.shape)
for h in range(0, img.shape[0], filter.shape[0]):
    for w in range(0, img.shape[1], filter.shape[1]):
        for c in range(img.shape[2]):
            num = 0
            for hi in range(filter.shape[0]):
                for wi in range(filter.shape[1]): 
                    num += img[h + hi][w + wi][c]
            num /= filter.size
            for hi in range(filter.shape[0]):
                for wi in range(filter.shape[1]):
                    new_img[h + hi][w + wi][c] = num

画像を表示します。

Image.fromarray(np.uint8(new_img)).show()

これだとモザイクって感じなので、全体的にぼやっとさせるには、下記のようにしたらいいと思います。効率性はよろしくないと思いますが、とりあえず出来ました。変えたところは、全ピクセルで別々に平均を計算するようにしたところです。

new_img = np.zeros(img.shape)
for h in range(img.shape[0] - filter_size):
    for w in range(img.shape[1] - filter_size):
        for c in range(img.shape[2]):
            num = 0
            for hi in range(filter.shape[0]):
                for wi in range(filter_size): 
                    num += img[h + hi][w + wi][c]
            num /= filter.size
            for hi in range(filter_size):
                for wi in range(filter.shape[1]):
                    new_img[h + hi][w + wi][c] = num

手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた

MNISTでテストしているだけだと味気ないので、ブラウザで数字を手書きして、それを予測するようにしてみました。JavascriptのCanvasでお絵かきアプリみたいのを作って、そこに手書きで数字を書いてボタン押したら、28×28に縮小して、Base64の状態でサーバに送ります。サーバでPythonが、numpyの配列にして、TensorFlowに渡して推測しております。

多分やり方は大体あってるのではないかと思ってるのですが、いかんせん精度が超悪いです。そもそもまだTensorFlowがCNNになっていないのですが、それでもMNISTで学習・テストすると97%位にはなっているものです。背景黒・文字色白で0-255の明るさを28×28もつ配列にしているので、形式は合っているはずなのですが、やはり文字の太さとか大きさとかそういうのによって、全然違うということなのかなと思っております。ブラウザで割と適当に数字を書いてもいい感じの精度で答えを言ってくるのかなと期待していたので残念です。とりあえず、今度CNNで対応してみて、それでもダメだったら、Javascriptの画像自体で訓練をしていくようにしてみようかなと思ってます。(何か根本的な原因がありそうな気もしますが)

GitHub

一応GitHubに入れておきました。誰か精度よくしてくれたら嬉しいです。

追記(2017/01/25)
上記のリポジトリは、「手書き文字を作れるJavascriptをつくってTensorFlowで予測させてみた(2)」の内容に更新しました。

PythonでWEBサーバ起動して、必要なディレクトリ・ファイルを作成

$ mkdir mnist_test
$ cd mnist_test
$ python -m http.server --cgi
$ touch index.html
$ mkdir cgi-bin
$ touch cgi-bin/mnist.py
$ touch cgi-bin/mytensor.py
$ mkdir cgi-bin/mnist
$ mkdir cgi-bin/ckpt

各ファイルの中身を作成

index.html

<html>
<head>
<title>MNIST TEST</title>
</head>
<body>
<h1>MNIST TEST</h1>
<canvas id="canvas1" width="400" height="400" style="border: 1px solid #999;"></canvas><br><br>
<input id="clear" type="button" value="Clear" onclick="canvasClear();">
<input id="submit" type="button" value="Submit" onclick="saveImg();"><br><br>
<img id="preview"><span id="answer"></span>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var url = 'http://127.0.0.1:8000/cgi-bin/mnist.py';
var lineWidth = 50;
var lineColor = '#ffffff';
var imgW = imgH = 28;

var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
var cleft = canvas.getBoundingClientRect().left;
var ctop = canvas.getBoundingClientRect().top;
var mouseX = mouseY = null;

canvasClear();
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mousedown', mdown, false);
canvas.addEventListener('mouseup', mouseInit, false);
canvas.addEventListener('mouseout', mouseInit, false); 

function mmove(e){
    if (e.buttons == 1 || e.witch == 1) {
        draw(e.clientX - cleft, e.clientY - ctop);
    };
}

function mdown(e){
    draw(e.clientX - cleft, e.clientY - ctop);
}

function draw(x, y){
    ctx.beginPath();
    if(mouseX === null) ctx.moveTo(x, y);
    else ctx.moveTo(mouseX, mouseY);
    ctx.lineTo(x, y);
    ctx.lineCap = "round";
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = lineColor;
    ctx.stroke();
    mouseX = x;
    mouseY = y;
}

function mouseInit(){
    mouseX = mouseY = null;
}

function canvasClear(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#000000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    $('#preview').attr('src', '');
    $('#answer').empty();
}

function toImg(){
    var tmp = document.createElement('canvas');
    tmp.width = imgW;
    tmp.height = imgH;
    var tmpCtx = tmp.getContext('2d');
    tmpCtx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, imgW, imgH);
    var img = tmp.toDataURL('image/jpeg');
    $('#preview').attr('src', img)
    return img;
}

function saveImg(){
    var img = toImg();
    console.log(img);
    $.ajax({
        url: url,
        type: 'POST',
        data: {img: img},
        dataType: 'json',
        success: function(data){
            if(data.status){
                $('#answer').html('は、' + data.num + 'です');
            }else{
                $('#answer').html('は、分かりません');
            }
        },
    });
}
</script>
</body>
</html>

cgi-bin/mnist.py

#!/usr/bin/env python

import sys
import os
import cgi
import json
import cgitb
cgitb.enable()

from PIL import Image
import numpy as np
from io import BytesIO
from binascii import a2b_base64

from mytensor import MyTensor

import logging

print('Content-Type: text/json; charset=utf-8')
print()

if os.environ['REQUEST_METHOD'] == 'POST':
    data = cgi.FieldStorage()
    img_str = data.getvalue('img', None)
    if img_str:
        b64_str = img_str.split(',')[1]
        img = Image.open(BytesIO(a2b_base64(b64_str))).convert('L')
        img_arr = np.array(img).reshape(1, -1)
        tf = MyTensor()
        result = tf.predict(img_arr)
        print(json.dumps({'status': True, 'num': result}))
        sys.exit()
print(json.dumps({'status': False, 'num': False}))

cgi-bin/mytensor.py

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
from PIL import Image

class MyTensor:
    H = 625
    BATCH_SIZE = 100
    DROP_OUT_RATE = 0.5

    def __init__(self):
        self.x = tf.placeholder(tf.float32, [None, 784])
        self.t = tf.placeholder(tf.float32, [None, 10])        
        self.w1 = tf.Variable(tf.random_normal([784, self.H], mean=0.0, stddev=0.05))
        self.b1 = tf.Variable(tf.zeros([self.H]))
        self.w2 = tf.Variable(tf.random_normal([self.H, self.H], mean=0.0, stddev=0.05))
        self.b2 = tf.Variable(tf.zeros([self.H]))
        self.w3 = tf.Variable(tf.random_normal([self.H, 10], mean=0.0, stddev=0.05))
        self.b3 = tf.Variable(tf.zeros([10]))

        self.a1 = tf.sigmoid(tf.matmul(self.x, self.w1) + self.b1)
        self.a2 = tf.sigmoid(tf.matmul(self.a1, self.w2) + self.b2)
        self.keep_prob = tf.placeholder(tf.float32)
        self.drop = tf.nn.dropout(self.a2, self.keep_prob)
        self.y = tf.nn.relu(tf.matmul(self.drop, self.w3) + self.b3)
        self.loss = tf.nn.l2_loss(self.y - self.t) / self.BATCH_SIZE

        self.train_step = tf.train.AdamOptimizer(1e-4).minimize(self.loss)
        self.correct = tf.equal(tf.argmax(self.y, 1), tf.argmax(self.t, 1))
        self.accuracy = tf.reduce_mean(tf.cast(self.correct, tf.float32))
        self.saver = tf.train.Saver()
        if not self.ckpt():
            self.train()

    def ckpt(self):
        return tf.train.get_checkpoint_state('.\cgi-bin\ckpt')        

    def predict(self, img):
        with tf.Session() as sess:
            self.saver.restore(sess, self.ckpt().model_checkpoint_path)
            result = sess.run(self.y, feed_dict={self.x: img, self.keep_prob:1.0})
            return int(np.argmax(result))

    def train(self):
        mnist = input_data.read_data_sets('.\cgi-bin\mnist', one_hot=True, dtype=tf.uint8)        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            for _ in range(20000):
                batch_x, batch_t = mnist.train.next_batch(100)
                sess.run(self.train_step, feed_dict={self.x: batch_x, self.t: batch_t, self.keep_prob:(1-self.DROP_OUT_RATE)})
            self.saver.save(sess, '.\cgi-bin\ckpt\model.ckpt')

ブラウザでアクセス

下記URLにアクセスすると、MNIST TESTというお絵かきページみたいのがでてきます。ちなみに、最初にsubmitボタン押すと、MNISTのダウンロードから学習までをするので、時間かかるし、結果も表示されません。2回目からはちゃんと結果が(一応)表示されます。

http://127.0.0.1:8000

TensorFlow – MNISTで機械学習してみる(入力層・出力層のみ)

MNISTを取得する

TensorFlowのチュートリアル用にMNISTが簡単に取り込めるようになっているらしい。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('.', one_hot=True)

上記を実行するとまだMNISTをダウンロードしてない場合はダウンロードしてくれる。

batch_x, batch_t = mnist.train.next_batch(100)

上記を実行すると、100件分のトレーニング用データとトレーニング用正解ラベルをもらえる。numpyの配列としてもらえる。input_data.read_data_setsの引数で、one_hot=Trueにすると、正解ラベルも正解を1、違うものを0とした配列でもらえる。

やってみること

  • MNISTのトレーニングデータで学習して、テストデータでテストする。
  • トレーニングデータは100件ずつ使って学習する。
  • 最も単純な入力層と出力層しかないものを試してみる。

コード

参考:jupyter_tfbook/Chapter02/MNIST softmax estimation.ipynb

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('.', one_hot=True)

x = tf.placeholder(tf.float32, [None, 784])
w = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
f = tf.matmul(x, w) + b
y = tf.nn.softmax(f)
t = tf.placeholder(tf.float32, [None, 10])
loss = -tf.reduce_sum(t * tf.log(y))
train_step = tf.train.AdamOptimizer().minimize(loss)

correct = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))

sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())

i = 0
for _ in range(1500):
    i += 1
    batch_x, batch_t = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_x, t: batch_t})
    if i % 100 == 0:
        loss_val, acc_val = sess.run([loss, accuracy], feed_dict={x: mnist.test.images, t: mnist.test.labels})
        print ('Step: %d, Loss: %f, Accuracy: %f' % (i, loss_val, acc_val))

Step: 100, Loss: 7747.071777, Accuracy: 0.848400
Step: 200, Loss: 5439.357910, Accuracy: 0.879900
Step: 300, Loss: 4556.465332, Accuracy: 0.890900
Step: 400, Loss: 4132.032715, Accuracy: 0.896100
Step: 500, Loss: 3836.136963, Accuracy: 0.902600
Step: 600, Loss: 3657.867920, Accuracy: 0.904100
Step: 700, Loss: 3498.280762, Accuracy: 0.907500
Step: 800, Loss: 3376.391602, Accuracy: 0.909400
Step: 900, Loss: 3292.480713, Accuracy: 0.910000
Step: 1000, Loss: 3207.918213, Accuracy: 0.912700
Step: 1100, Loss: 3147.843018, Accuracy: 0.914700
Step: 1200, Loss: 3092.903320, Accuracy: 0.916300
Step: 1300, Loss: 3057.232666, Accuracy: 0.915900
Step: 1400, Loss: 3010.664307, Accuracy: 0.916200
Step: 1500, Loss: 2972.114746, Accuracy: 0.917300

TensorFlowのWindows版をインストールする

TensorFlowのWindows版がでてた

「Windows10上のTensorFlowでGPUを利用しようとしてダメだった→できるようになったみたいです!」なんと、Windows版でGPU利用も可能なものが出てるらしい。「Google、オープンソースの機械学習ライブラリ「TensorFlow」のWindows版を公開」

Windows版は「Python」言語のパッケージ管理システム「PyPI」のパッケージとして配布されており、Windows 7/10およびWindows Server 2016で利用が可能。GPUアクセラレーションとして“CUDA 8.0”と“cuDNN 5.1”がサポートされている。

インストール

「TensorFlow が正式に Windows サポートして GPU が使えたので試してみた」ここに色々インストール手順が書いてあります。自分はNVIDAのサイトで登録とかすでにしているのですが、どんな登録をして、何をパソコンにインストールしたのかとかは忘れました。Pythonはanacondaでインストールしたはずでバージョンは3.5です。前は確かTensorFlowはPython2.7に対応していた気がしますが、3.3以上も対応しているようです。

$ python --version
Python 3.5.2 :: Anaconda 4.1.1 (64-bit)

Anacondaの64bit版の4.1.1で、Pythonのバージョンは3.5.2でした。

以下2つを実行して、TensorFlowとTensorFlow-GPUがインストールできるようです。

$ pip install tensorflow

Successfully installed protobuf-3.1.0.post1 tensorflow-0.12.1

$ pip install tensorflow-gpu

Successfully installed tensorflow-gpu-0.12.1

インストールできました。

動くかチェック

とりあえず使えるのかチェックしてみます。
tensor.pyというファイルに、下記を書いて実行してみます。

import tensorflow as tf

結果

I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cublas64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_blas.cc:2294] Unable to load cuBLAS
 DSO.
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cudnn64_5.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_dnn.cc:3459] Unable to load cuDNN D
SO
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cufft64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_fft.cc:344] Unable to load cuFFT DS
O.
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary nvcuda.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 curand64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_rng.cc:338] Unable to load cuRAND D
SO.

GPU関連のインストール・設定等は全くできていなかったようです。

下記を書いて実行してみました。

import tensorflow as tf

hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a + b))

結果

I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cublas64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_blas.cc:2294] Unable to load cuBLAS
 DSO.
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cudnn64_5.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_dnn.cc:3459] Unable to load cuDNN D
SO
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 cufft64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_fft.cc:344] Unable to load cuFFT DS
O.
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary nvcuda.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:119] Couldn't open CUDA library
 curand64_80.dll
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\cuda\cuda_rng.cc:338] Unable to load cuRAND D
SO.
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:885] Found device 0 wit
h properties:
name: GeForce GTX 970
major: 5 minor: 2 memoryClockRate (GHz) 1.1775
pciBusID 0000:01:00.0
Total memory: 4.00GiB
Free memory: 3.31GiB
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:906] DMA: 0
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:916] 0:   Y
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:975] Creating TensorFlo
w device (/gpu:0) -> (device: 0, name: GeForce GTX 970, pci bus id: 0000:01:00.0)
b'Hello, TensorFlow!'
42

GPU関連でWarning的メッセージが沢山でるものの一応動いています。搭載しているGPUも認識されていて名前とかが表示されてます。

NVIDA関連の設定

CUDA Toolkit 8.0

https://developer.nvidia.com/cuda-downloads

上記のように設定してダウンロードして、インストールしました。結構時間かかりました。

cuDNN v5.1

下記でユーザ登録したらダウンロードできます。
https://developer.nvidia.com/rdp/cudnn-download
zip内のcudaフォルダの中身をC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0にコピーします。

動作チェック

パソコンを再起動して、改めてtensor.pyを実行してみました。

I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary cublas64_80.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary cudnn64_5.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary cufft64_80.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary nvcuda.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\stream_executor\dso_loader.cc:128] successfully opened CUDA l
ibrary curand64_80.dll locally
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:885] Found device 0 wit
h properties:
name: GeForce GTX 970
major: 5 minor: 2 memoryClockRate (GHz) 1.1775
pciBusID 0000:01:00.0
Total memory: 4.00GiB
Free memory: 3.31GiB
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:906] DMA: 0
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:916] 0:   Y
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:975] Creating TensorFlo
w device (/gpu:0) -> (device: 0, name: GeForce GTX 970, pci bus id: 0000:01:00.0)
b'Hello, TensorFlow!'
42

全部successfullyと書いてるのでうまくいっているようです。

Python – MNISTを使う

機械学習で使えるサンプル画像の有名なのがMNISTだそうです。0-9までの手書き文字画像と、正解ラベルデータが、トレーニング用とテスト用で分けられています。
http://yann.lecun.com/exdb/mnist/

バイナリデータになっていて、画像等は全部データとしてつながっているらしい。機械学習は画像を数値として扱う必要があります。

参考:https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/dataset/mnist.py

Pythonでダウンロード・読み込み

ダウンロード

import urllib.request
import os.path

url_base = 'http://yann.lecun.com/exdb/mnist/'
key_file = {
    'train_img':'train-images-idx3-ubyte.gz',
    'train_label':'train-labels-idx1-ubyte.gz',
    'test_img':'t10k-images-idx3-ubyte.gz',
    'test_label':'t10k-labels-idx1-ubyte.gz'
}
dataset_dir = os.path.dirname(os.path.abspath(__file__))

def _download(filename):
    file_path = dataset_dir + '/' + filename
    if os.path.exists(file_path):
        return print('already exist')
    print('Downloading ' + filename + ' ...')
    urllib.request.urlretrieve(url_base + filename, file_path)
    print('Done')

def download_mnist():
    for v in key_file.values():
       _download(v)

download_mnist()

読み込み

gzipを使います。

def load_mnist(filename):
    file_path = dataset_dir + '/' + filename
    with gzip.open(file_path, 'rb') as f:
        data = np.frombuffer(f.read(), np.uint8, offset=16)
    return data.reshape(-1, img_size)

試しに画像データを読み込んで1つ表示させてみます。

data = load_mnist(key_file['train_img'])
img1 = data[0].reshape(28, 28)
pil_img = Image.fromarray(np.uint8(img1))
pil_img.show()

手書きの5っぽい画像が表示されました。
load_mnist関数は、gzipで読み込んで、np.frombufferというので、Numpyの配列に格納してます。data.reshapeで、画像サイズの784ずつに配列を分割してます。
784ずつに分割された配列で実際には機械学習すればいいと思います。実際の画像にするために、さらに1つの画像の縦横に合わせて配列を変換してます。

Python – 勾配法

勾配は、すべての変数に対する偏微分をベクトルにしたものです。勾配法は、勾配を使って関数が最小になるパラメタを探す方法のことです。偏微分はある点における、各パラメタに対する微分ですので、傾きです。傾きが分かるとパラメタをどう動かすとマイナスになるかが分かります。勾配はすべてのパラメタに対する傾きが入ってるので、これを使って全部のパラメタを徐々に関数の出力結果がマイナスになるように調整します。ただし、関数のグラフが凸凹している場合、ある部分においての凹の一番下についてしまった場合、出られなくなったりします。残念なことです。でも大体なんとかなるようです。ただしグラフの形状によっては、実際残念な結果に終わったり、最小値を発見するのにものすごく時間がかかったりするそうなのでケースバイケースで勾配法とは別の方法も試す必要があるそうです。

勾配によって、各パラメタの増減すべき方向が分かりますが、どの程度増減させるかは人間がいい感じの数字を設定する必要があります。この一回当たりにパラメタを増減させる数値は、学習率で決めます。偏微分結果に学習率を掛けたものが、増減数値になります。また、どこまでいけば本当の正解なのかは勾配法では分かりませんので、勾配法を何回繰り返すかも人間が決める必要があります。

勾配をPythonで書くと下記になります。

import numpy as np
 
def func(x):
    return x[0]**2 + x[1]**2
 
def gradient(f, x):
    h = 1e-4
    grad = np.zeros_like(x)
    for i in range(x.size):
        tmp = x[i]
        x[i] = tmp + h
        y1 = f(x)
        x[i] = tmp - h
        y2 = f(x)
        grad[i] = (y1 - y2) / (2 * h)
        x[i] = tmp
    return grad
        
g = gradient(func, np.array([3.0, 4.0]))        
print(g)

勾配法をPythonで書くと下記になります。

def gradient_descent(f, x, lr=0.01, num=100):
    for i in range(num):
        x -= lr * gradient(f, x)
    return x

コードサンプル

import numpy as np

def func(x):
    return x[0]**2 + x[1]**2

def gradient(f, x):
    h = 1e-4
    grad = np.zeros_like(x)
    for i in range(x.size):
        tmp = x[i]
        x[i] = tmp + h
        y1 = f(x)
        x[i] = tmp - h
        y2 = f(x)
        grad[i] = (y1 - y2) / (2 * h)
        x[i] = tmp
    return grad
        
def gradient_descent(f, x, lr=0.01, num=100):
    for i in range(num):
        x -= lr * gradient(f, x)
    return x

x2 = gradient_descent(func, np.array([3.0, 4.0]), 0.1, 100)
print(x2)

python – 損失関数

ディープラーニングで使う損失関数の、二乗和誤差と交差エントロピー誤差。

二乗和誤差

二乗和誤差は、差の二乗を全部足して2で割る。

def nijowagosa(y, t):
    return 0.5 * np.sum((y - t)**2)

y = np.array([0.2, 0.03, 0.8])
t = np.array([0, 0, 1])

print(nijowagosa(y, t))

交差エントロピー誤差


$$E = -\displaystyle \sum_{k}t_k \log y_k$$

logは底がeの自然対数を表すそうです。np.logでできます。ディープラーニングで使うときは、yが出力で、tが正解ラベルです。正解ラベルは正解を1とし、間違いを0とすると、正解ラベル以外のものは全部0になるので無視できて、-log yになります。間違いのやつ無視していいのかなと思いましたが、間違いのやつを高確率と判断した場合、ソフトマックス関数では正解の確立が低くなるので問題ないのかなと思いました。

def cross_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))

y = np.array([0.2, 0.03, 0.8])
t = np.array([0, 0, 1])
print(cross_error(y, t))

deltaは、np.log(0)が-infを出すことに対する対策です。超小さい数を加えています。

Python – 偏微分・勾配

偏微分

偏微分は、変数が2つ以上あるときに1つ以外を固定にして、固定じゃない1つに対して微分をすることだそうです。Pythonでやると簡単にできます。

下記の式で、x0が3、x1が4のときの偏微分


$$f(x_0, x_1)=x_0^2+x_1^2$$

コード

import numpy as np

def numerical_diff(f, x):
    h = 1e-4
    return (f(x+h) - f(x-h)) / (2*h)

def func_x0(x0):
    return x0**2 + 4**2

def func_x1(x1):
    return 3**2 + x1**2

d0 = numerical_diff(func_x0, 3) 
d1 = numerical_diff(func_x1, 4)
print(d0)
print(d1)

勾配

勾配は、すべての変数に対する偏微分をベクトルにしたものだそうです。

import numpy as np

def func(x):
    return x[0]**2 + x[1]**2

def gradient(f, x):
    h = 1e-4
    grad = np.zeros_like(x)
    for i in range(x.size):
        tmp = x[i]
        x[i] = tmp + h
        y1 = f(x)
        x[i] = tmp - h
        y2 = f(x)
        grad[i] = (y1 - y2) / (2 * h)
        x[i] = tmp
    return grad
        
g = gradient(func, np.array([3.0, 4.0]))        
print(g)

ディープラーニングのサンプルコード

メモ。ゼロから作るDeep Learningの本用のサンプルコードは、Githubで公開されてます。これは、Githubの公開リポジトリなのでブログに書いても大丈夫なやつなはずなのでメモ。

oreilly-japan/deep-learning-from-scratch

ソフトマックス関数

合計が1になるように、うまく数字を調整してくれる関数らしい。確率を確認するのに便利。


$$y_k = \frac{\exp(a_k)}{\displaystyle \sum_{i=1}^n \exp(a_i)}$$

aがn個あるときの、k番目のyを取得する。分母は全てのaの指数関数の和。分子はk番目のaの指数関数。

pythonで書くと下記になります。

a = np.array([0, 2.3, 3.5])
exp = np.exp(a)
sum_exp = np.sum(exp)
y = exp / sum_exp
print(y)

指数関数を使っているので数字がものすごく大きくなる可能性があり、それによってオーバフローで変な数値が返ってくる場合があるため、aの最大値をそれぞれのaの値から引きます。これで全部0かマイナスになります。

a = np.array([0, 2.3, 3.5])
c = np.max(a)
dexp = np.exp(a - c)
sum_exp = np.sum(exp)
y = exp / sum_exp
print(y)

ソフトマックス関数は、aのそれぞれの値の大きさの順番は変えません。なので、一番大きいaを取得したい場合は、ソフトマックス関数は不要です。

ディープラーニングの出力層で使う活性化関数は、回帰問題だと恒等関数、2クラス分類問題はシグモイド関数、多クラス分類問題はソフトマックス関数を使うのが一般的だそうです。シグモイドは0か1かを表すし、ソフトマックスは、複数の選択肢の確からしさを数値で表すからだと思います。回帰は数値を予測するので確率にする必要がないので恒等関数なんだと思います。

シグモイド関数

ディープラーニングでシグモイド関数というのを使いまっす。シグモイド関数は、何か入力されたら0~1の数値を返します。入力された数値が0未満だったら0を返して、そうでなければ1を返すような関数をステップ関数といいまして、これよりも緩やかに0~1の間を返すのでなんかいいらしいです。

シグモイド関数の式は、下記です。


$$h(x) = \frac{1}{1+\exp(-x))}$$

Pythonで書くと下記になります。

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

グラフにすると下記のようになります。

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

Python x TensorFLow – 最小二乗法

1次関数から試してみます。最小二乗法は、誤差を2乗した合計が小さくなるようにすることで、最もらしい関数を発見する方法です。1次関数でデータを10個つくって、作り出した関数を知らない前提で、機械に関数を発見してもらいます。

1次関数でやってみる

1次関数は下記でやってみます。
y = 3x * 5

トレーニングセット作成

データを10個つくります。xは、0,1,2,3,4,5,6,7,8,9です。Pythonでつくります。

 
data_set = []
[data_set.append(3 * x + 5) for x in range(10)]
print data_set

[5, 8, 11, 14, 17, 20, 23, 26, 29, 32]

これはグラフにすると下記になります。

import matplotlib.pyplot as plt

plt.plot(data_set, 'o')
plt.show()

plot

TensorFlowでやってみる

モデルは、1次関数とします。パラメタは2つあります。誤差関数は、二乗誤差を使います。TensorFlowでやってみます。

import tensorflow as tf

x = tf.placeholder(tf.float32, [None, 2])
w = tf.Variable(tf.zeros([2, 1]))
y = tf.matmul(x, w)
t = tf.placeholder(tf.float32, [None, 1])
loss = tf.reduce_sum(tf.square(y - t))
train_step = tf.train.AdamOptimizer().minimize(loss)

sess = tf.Session()
sess.run(tf.initialize_all_variables())

train_t = np.array(data_set);
train_t = train_t.reshape([10, 1])
train_x = np.zeros([10, 2])
for row in range(10):
    for col in range(2):
        train_x[row][col] = row**col
        
i = 0
for _ in range(100000):
    i += 1
    sess.run(train_step, feed_dict={x:train_x, t:train_t})
    if i % 10000 == 0:
        loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})
        print ('Step: %d, Loss: %f' % (i, loss_val))
        
w_val = sess.run(w)
print w_val

def predict(x):
    result = 0.0
    for n in range(0, 2):
        result += w_val[n][0] * x**n
    return result

fig = plt.figure()
subplot = fig.add_subplot(1, 1, 1)
subplot.set_xlim(1, 10)
subplot.scatter(range(10), train_t)
linex = np.linspace(1, 10, 100)
liney = predict(linex)
subplot.plot(linex, liney)
plt.show()

Step: 10000, Loss: 0.556078
Step: 20000, Loss: 0.000000
Step: 30000, Loss: 0.000000
Step: 40000, Loss: 0.000000
Step: 50000, Loss: 0.000000
Step: 60000, Loss: 0.000000
Step: 70000, Loss: 0.000000
Step: 80000, Loss: 0.000000
Step: 90000, Loss: 0.000000
Step: 100000, Loss: 0.000000
[[ 5.]
[ 3.]]

plot2

1000刻みでLoss値を見てみる

20000回ですでに完璧に誤差がなくなっておりまして、きちんと正しい一次関数を発見しました。せっかくなので、1000刻みで見てみようと思います。

Step: 1000, Loss: 2144.477539
[[ 0.93216914]
[ 0.93001837]]
Step: 2000, Loss: 946.874451
[[ 1.73305488]
[ 1.72308087]]
Step: 3000, Loss: 324.689636
[[ 2.4027319 ]
[ 2.37532687]]
Step: 4000, Loss: 74.941284
[[ 2.92346025]
[ 2.85973501]]
Step: 5000, Loss: 13.527188
[[ 3.27773309]
[ 3.14026999]]
Step: 6000, Loss: 6.525241
[[ 3.50095201]
[ 3.2282424 ]]
Step: 7000, Loss: 4.923757
[[ 3.69913244]
[ 3.2147882 ]]
Step: 8000, Loss: 3.215882
[[ 3.94896293]
[ 3.17392874]]
Step: 9000, Loss: 1.630160
[[ 4.25151825]
[ 3.1236279 ]]
Step: 10000, Loss: 0.556078
[[ 4.56274843]
[ 3.07208133]]
Step: 11000, Loss: 0.099951
[[ 4.81459618]
[ 3.03052568]]
Step: 12000, Loss: 0.006101
[[ 4.95419312]
[ 3.00753903]]
Step: 13000, Loss: 0.000059
[[ 4.9954896 ]
[ 3.00074267]]
Step: 14000, Loss: 0.000000
[[ 4.99989605]
[ 3.00001764]]
Step: 15000, Loss: 0.000000
[[ 4.99996567]
[ 3.00000596]]
Step: 16000, Loss: 0.000000
[[ 4.9999795 ]
[ 3.00000358]]
Step: 17000, Loss: 0.000000
[[ 4.9999876 ]
[ 3.00000215]]
Step: 18000, Loss: 0.000000
[[ 4.99999428]
[ 3.00000095]]
Step: 19000, Loss: 0.000000
[[ 4.99999619]
[ 3.00000072]]
Step: 20000, Loss: 0.000000
[[ 4.99999857]
[ 3.00000024]]

頭よくなっていく過程が分かります。しかし、1次関数かどうかは実際には分からないので、1次~10次までを確認して、一番いい感じのやつを発見するようなプログラムにするといいのではないかと思いました。あと、トレーニングセットとテストセットとかいうらしいですが、最初の学習データとは別のテストデータも必要になります。理由は過学習してしまう可能性があるからです。例えば10個のデータであれば9次関数をつくると確実に10個のデータを再現できる関数になります。しかしこれは過学習しており、11個目のデータがあったときに全然めちゃくちゃになってしまいます。

誤差つきの4次関数でやってみる

では次に4次関数でやってみます。また、実際のデータっぽく誤差をいれてみます。ソースコードきたないですが、実験なのでお許しください。

param_cntは、モデル式のパラメタの最大数です。11と入れると、10次関数まで調べます。3だと2次関数まで調べます。do_cntは、学習回数です。chk_cntは、何回ごとにloss値を出力させるか、です。4次関数にnp.random.normalで正規分布の誤差をいれています。平均0で、標準偏差3の正規分布の誤差ということになるそうです。

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

param_cnt = 11
do_cnt = 20000
chk_cnt = 5000

data_set = []
x_list = np.arange(-5, 5, 0.5)
[data_set.append(0.5 * x**4 + 0.9 * x**3 + 0.5 * x**2 + x + 5 + np.random.normal(0, 3)) for x in x_list]
#[data_set.append(0.5 * x**4 + 0.9 * x**3 + 0.5 * x**2 + x + 5) for x in x_list]
#[data_set.append(3 * x + 5) for x in x_list]
data_cnt = len(data_set)

def multi(param_cnt):
    step = 0
    loss = 0.0
    w = []
    p_cnt = 0
    for i in range(2, param_cnt + 1):
        result = ml(i)
        if i == 2 or loss > result['loss']:
            step = result['step']
            loss = result['loss']
            w = result['w']
            p_cnt = i
    print str(p_cnt - 1) + '次関数'
    print w
    return {'param_cnt': param_cnt, 'w': w, 'step': step , 'loss': loss}
   
def predict(x, w_list):
    result = 0.0
    for i, w in enumerate(w_list):
        result += w[0] * x**i
    return result

def plt_show(w):
    y = predict(x_list, w)
    plt.plot(x_list, y)
    plt.plot(x_list, data_set, 'o')
    plt.show()

def ml(param_cnt):
    print str(param_cnt - 1) + '次関数:'
    x = tf.placeholder(tf.float32, [None, param_cnt])
    w = tf.Variable(tf.zeros([param_cnt, 1]))
    y = tf.matmul(x, w)
    t = tf.placeholder(tf.float32, [None, 1])
    loss = tf.reduce_sum(tf.square(y - t))
    train_step = tf.train.AdamOptimizer().minimize(loss)

    sess = tf.Session()
    sess.run(tf.initialize_all_variables())
    train_t = np.array(data_set);
    train_t = train_t.reshape([data_cnt, 1])
    train_x = np.zeros([data_cnt, param_cnt])
    
    for row, n in enumerate(x_list.tolist()):
        for col in range(param_cnt):
            train_x[row][col] = n**col  
    
    i = 0
    min_loss = 0.0
    step = 0
    w_fix = []
    for _ in range(do_cnt):
        i += 1
        sess.run(train_step, feed_dict={x:train_x, t:train_t})
        if i % chk_cnt == 0:
            loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})
            w_val = sess.run(w)
            print ('Step: %d, Loss: %f' % (i, loss_val))
            print w_val
            if(i == chk_cnt or min_loss > loss_val):
                step = i
                min_loss = loss_val
                w_fix = w_val
    return {'step': step, 'loss': min_loss, 'w': w_fix.tolist()}

result = multi(param_cnt)
#result = ml(param_cnt)
plt_show(result['w'])

1次関数:
Step: 5000, Loss: 215542.093750
[[ 4.95924044]
[ 3.95200872]]
Step: 10000, Loss: 203412.828125
[[ 9.88683128]
[ 5.01568365]]
Step: 15000, Loss: 192418.406250
[[ 14.8010807]
[ 5.1672349]]
Step: 20000, Loss: 182398.625000
[[ 19.70719528]
[ 5.31404638]]
2次関数:
Step: 5000, Loss: 68691.289062
[[ 4.37834597]
[ 4.78828716]
[ 4.51071978]]
Step: 10000, Loss: 19349.113281
[[ 6.14278746]
[ 9.20509338]
[ 8.05002975]]
Step: 15000, Loss: 14812.129883
[[ 0.76773846]
[ 11.64998531]
[ 9.2823782 ]]
Step: 20000, Loss: 13354.574219
[[ -4.00546932]
[ 11.78009605]
[ 9.61374664]]
3次関数:
Step: 5000, Loss: 67975.859375
[[ 4.38982058]
[ 4.47143745]
[ 4.52593517]
[ 0.12835987]]
Step: 10000, Loss: 18511.107422
[[ 6.25019884]
[ 7.83472824]
[ 8.12683201]
[ 0.19194219]]
Step: 15000, Loss: 14246.777344
[[ 0.85353625]
[ 7.43424273]
[ 9.42072201]
[ 0.286881 ]]
Step: 20000, Loss: 12680.401367
[[-3.94125748]
[ 7.13879824]
[ 9.76669121]
[ 0.31357336]]
4次関数:
Step: 5000, Loss: 116.987244
[[ 1.75886464]
[ 0.82387865]
[ 0.73796004]
[ 0.90688848]
[ 0.49740523]]
Step: 10000, Loss: 21.997097
[[ 4.06656361]
[ 1.1654942 ]
[ 0.78540492]
[ 0.88064975]
[ 0.48745832]]
Step: 15000, Loss: 16.351856
[[ 5.03755283]
[ 1.10082293]
[ 0.56437576]
[ 0.88661832]
[ 0.49617034]]
Step: 20000, Loss: 16.351896
[[ 5.03769445]
[ 1.10081434]
[ 0.56434351]
[ 0.8866201 ]
[ 0.4961707 ]]
5次関数:
Step: 5000, Loss: 119.090012
[[ 1.74797881e+00]
[ 1.08122551e+00]
[ 7.19700754e-01]
[ 8.64906728e-01]
[ 4.98723030e-01]
[ 1.43910421e-03]]
Step: 10000, Loss: 22.015015
[[ 4.06811666e+00]
[ 1.07059586e+00]
[ 7.93005526e-01]
[ 8.97920549e-01]
[ 4.86883730e-01]
[ -6.27588655e-04]]
Step: 15000, Loss: 16.261492
[[ 5.05882359e+00]
[ 1.18433976e+00]
[ 5.52112699e-01]
[ 8.70472431e-01]
[ 4.96929288e-01]
[ 5.98916959e-04]]
Step: 20000, Loss: 16.260433
[[ 5.05913115e+00]
[ 1.18449724e+00]
[ 5.52029669e-01]
[ 8.70452166e-01]
[ 4.96929288e-01]
[ 6.06292742e-04]]
6次関数:
Step: 5000, Loss: 53.637337
[[ 2.38433266e+00]
[ 1.57903039e+00]
[ 1.11886275e+00]
[ 8.11793208e-01]
[ 4.61589992e-01]
[ 2.50088377e-03]
[ 6.97513111e-04]]
Step: 10000, Loss: 18.967039
[[ 4.32346010e+00]
[ 1.32767844e+00]
[ 9.70935225e-01]
[ 8.36955488e-01]
[ 4.52258199e-01]
[ 2.08282284e-03]
[ 1.26212556e-03]]
Step: 15000, Loss: 16.296326
[[ 4.93837500e+00]
[ 1.22425616e+00]
[ 6.37905777e-01]
[ 8.61216605e-01]
[ 4.87015426e-01]
[ 1.01356197e-03]
[ 2.91907112e-04]]
Step: 20000, Loss: 16.242428
[[ 5.01489973e+00]
[ 1.20275176e+00]
[ 5.88385046e-01]
[ 8.65994036e-01]
[ 4.92458344e-01]
[ 8.08077923e-04]
[ 1.36406394e-04]]
7次関数:
Step: 5000, Loss: 89.665520
[[ 2.32143140e+00]
[ 1.53826487e+00]
[ 1.07825494e+00]
[ 6.85688794e-01]
[ 4.76195693e-01]
[ 1.93343945e-02]
[ -2.91685792e-05]
[ -4.58549795e-04]]
Step: 10000, Loss: 20.448008
[[ 4.28025007e+00]
[ 1.64763474e+00]
[ 1.00642896e+00]
[ 7.50945508e-01]
[ 4.48578656e-01]
[ 8.27948842e-03]
[ 1.35072204e-03]
[ -1.31144610e-04]]
Step: 15000, Loss: 17.463367
[[ 4.70802307e+00]
[ 1.52105701e+00]
[ 7.85070360e-01]
[ 7.84407139e-01]
[ 4.71286625e-01]
[ 6.25595590e-03]
[ 7.26952916e-04]
[ -1.02008424e-04]]
Step: 20000, Loss: 16.643923
[[ 4.87714958e+00]
[ 1.42680812e+00]
[ 6.72681332e-01]
[ 8.05022180e-01]
[ 4.83814031e-01]
[ 5.21623669e-03]
[ 3.65617452e-04]
[ -9.24795459e-05]]
8次関数:
Step: 5000, Loss: 131.079254
[[ 2.88559628e+00]
[ 1.24204707e+00]
[ 1.10422873e+00]
[ 3.27726752e-01]
[ 2.82681823e-01]
[ 7.58507699e-02]
[ 2.27710828e-02]
[ -2.43731448e-03]
[ -6.57664554e-04]]
Step: 10000, Loss: 28.809479
[[ 4.29814291e+00]
[ 2.01223731e+00]
[ 1.31598830e+00]
[ 3.96377593e-01]
[ 3.03849131e-01]
[ 5.24885505e-02]
[ 1.58709679e-02]
[ -1.51652610e-03]
[ -4.02022008e-04]]
Step: 15000, Loss: 347.819122
[[ 4.51162624e+00]
[ 2.24438071e+00]
[ 1.33831608e+00]
[ 4.33518320e-01]
[ 3.07972670e-01]
[ 4.39823009e-02]
[ 1.46628506e-02]
[ -1.24611927e-03]
[ -3.21475236e-04]]
Step: 20000, Loss: 22.053818
[[ 4.52574492e+00]
[ 2.27882338e+00]
[ 1.34143877e+00]
[ 4.55701292e-01]
[ 3.11556101e-01]
[ 4.05396298e-02]
[ 1.40584493e-02]
[ -1.09993061e-03]
[ -3.34182230e-04]]
9次関数:
Step: 5000, Loss: 5552.634766
[[ 2.33792377e+00]
[ 7.79350579e-01]
[ 6.53970003e-01]
[ 2.03688577e-01]
[ 1.83490813e-01]
[ 4.28588130e-02]
[ 4.29749712e-02]
[ 3.35324835e-03]
[ -1.39146764e-03]
[ -1.60500247e-04]]
Step: 10000, Loss: 194.072403
[[ 4.08490229e+00]
[ 1.23215306e+00]
[ 9.06385481e-01]
[ 2.92194337e-01]
[ 2.03426927e-01]
[ 5.21436632e-02]
[ 3.42375599e-02]
[ 7.02911580e-04]
[ -1.01602043e-03]
[ -9.27555739e-05]]
Step: 15000, Loss: 115.676407
[[ 4.94008017e+00]
[ 1.50322270e+00]
[ 1.05627847e+00]
[ 3.42464149e-01]
[ 2.18068600e-01]
[ 5.66791482e-02]
[ 2.89440639e-02]
[ -7.18827709e-04]
[ -8.12099199e-04]
[ -3.92189686e-05]]
Step: 20000, Loss: 57.366673
[[ 5.27173281e+00]
[ 1.66980028e+00]
[ 1.15057874e+00]
[ 3.71282339e-01]
[ 2.29773715e-01]
[ 5.85983880e-02]
[ 2.56161764e-02]
[ -1.47335778e-03]
[ -6.85952662e-04]
[ -1.29779210e-05]]
10次関数:
Step: 5000, Loss: 2263.479736
[[ 1.01189530e+00]
[ 2.97042310e-01]
[ 2.68756747e-01]
[ 8.43940526e-02]
[ 8.09634402e-02]
[ 2.73650903e-02]
[ 2.04845257e-02]
[ 8.72469600e-03]
[ 2.38272268e-03]
[ -4.05140279e-04]
[ -1.13759939e-04]]
Step: 10000, Loss: 1553.578125
[[ 1.83733785e+00]
[ 4.96752053e-01]
[ 4.51538861e-01]
[ 1.11230105e-01]
[ 1.25275597e-01]
[ 2.73409784e-02]
[ 2.71124728e-02]
[ 7.42600206e-03]
[ 1.07120932e-03]
[ -3.40760889e-04]
[ -7.36084112e-05]]
Step: 15000, Loss: 860.454346
[[ 2.45131707e+00]
[ 7.04376996e-01]
[ 5.79612136e-01]
[ 1.44563615e-01]
[ 1.54916033e-01]
[ 2.92531345e-02]
[ 3.12672704e-02]
[ 6.10585557e-03]
[ 1.98022972e-04]
[ -2.84481910e-04]
[ -4.43308709e-05]]
Step: 20000, Loss: 585.964172
[[ 2.91786623e+00]
[ 9.03335571e-01]
[ 6.71693385e-01]
[ 1.79319546e-01]
[ 1.75147504e-01]
[ 3.20737772e-02]
[ 3.38761806e-02]
[ 4.85530496e-03]
[ -3.96082381e-04]
[ -2.33632789e-04]
[ -2.46588024e-05]]
6次関数
[[5.014899730682373], [1.2027517557144165], [0.5883850455284119], [0.8659940361976624], [0.4924583435058594], [0.0008080779225565493], [0.00013640639372169971]]

g7

6次関数が選ばれました。本当は違うんだけど、グラフは点をしっかり大体通ってます。テストデータで確かめると、4次関数の方がいいってなるのかもしれない。今度はテストデータで確かめたり色々してみようと思います。

TensorFlowの勉強によさそうな記事

TensorFlowのよさそうな解説記事

ここをメンテしていきます。
中学生にも分かるTensorFlow入門 その1 テンソルとはなにか
TensorFlowとは
TensorFlowとは? データフローグラフを構築・実行してみよう
Googleの公開した人工知能ライブラリTensorFlowを触ってみた
TensorFlowで始める深層学習 (1)そもそも何が出来るの?
TensorFlowを遊び倒す! 1-1. MNIST For ML Beginners
TensorFlowで顔識別モデルに最適化した入力画像を生成する
TensorFlow を使った 機械学習ことはじめ (GDG京都 機械学習勉強会)
Windows で動かす TensorFlow
機械学習を始めたい方に見て欲しいTensorflow入門資料まとめ