edo1z blog

プログラミングなどに関するブログです

TensorFlow - 隠れ層があるニューラルネットをつくる

入力層、出力層の間に隠れそうをつくります。隠れそうが何層あっても対応できるプログラムにしたいと思ったのですが、TensorFlowは事前にモデルをつくるので、forとか使えないかもと思って良くわからなかったし、そもそも単純に層の数が多ければいいってもんじゃないらしいので、隠れ層は2層にしてみます。

コードはこれです。

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

H = 625
BATCH_SIZE = 100
DROP_OUT_RATE = 0.5

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

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

train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
correct = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))

with tf.Session() as sess:
    mnist = input_data.read_data_sets('.\mnist', one_hot=True, dtype=tf.uint8)
    sess.run(tf.global_variables_initializer())
    i = 0
    for _ in range(20000):
        i += 1
        bx, bt = mnist.train.next_batch(BATCH_SIZE)
        sess.run([train_step], feed_dict={x:bx, t:bt, keep_prob:(1-DROP_OUT_RATE)})
        if not i % 1000:
            loss_val, acc_val = sess.run([loss, accuracy], feed_dict={x:mnist.test.images, t:mnist.test.labels, keep_prob:1.0})
            print ('Step: %d, Loss: %f, Accuracy: %f' % (i, loss_val, acc_val))

dropoutをうまく使うと過学習が防げるそうです。うまい使い方はこれから確認しますが、とりあえず参考サイトのように入れてみたら精度は上がりました。あと、lossの計算方法が私の知っているものではないですが、参考サイトと同じように設定してみました。あと、Variableの初期値を全部0にするのはご法度だそうです。最初全部0でやってたけどやめます。非常に小さい数字をランダムに設定するのがよろしいそうです。モデルによって、非常に小さい数値といってもよりよい数値があるそうなので今度やってみます。

2万回やると、精度が0.9713になりました。なんかいい感じの数字になりましたが、CNNをやると99.8%とかになるそうなので、次にやってみます。

Step: 1000, Loss: 33.165092, Accuracy: 0.386300
Step: 2000, Loss: 10.525957, Accuracy: 0.898100
Step: 3000, Loss: 7.087694, Accuracy: 0.930000
Step: 4000, Loss: 5.988323, Accuracy: 0.942400
Step: 5000, Loss: 5.395752, Accuracy: 0.948400
Step: 6000, Loss: 4.864991, Accuracy: 0.952200
Step: 7000, Loss: 4.590996, Accuracy: 0.954400
Step: 8000, Loss: 4.247609, Accuracy: 0.958300
Step: 9000, Loss: 4.008740, Accuracy: 0.959500
Step: 10000, Loss: 3.788574, Accuracy: 0.962100
Step: 11000, Loss: 3.686205, Accuracy: 0.963000
Step: 12000, Loss: 3.471644, Accuracy: 0.965400
Step: 13000, Loss: 3.329534, Accuracy: 0.966200
Step: 14000, Loss: 3.216643, Accuracy: 0.966800
Step: 15000, Loss: 3.191551, Accuracy: 0.967400
Step: 16000, Loss: 3.022474, Accuracy: 0.970000
Step: 17000, Loss: 2.946394, Accuracy: 0.968600
Step: 18000, Loss: 2.848071, Accuracy: 0.970000
Step: 19000, Loss: 2.786939, Accuracy: 0.970300
Step: 20000, Loss: 2.756026, Accuracy: 0.971300

参考: 落ちこぼれないためのTensorFlow Tutorialコード TensorFlowで機械学習と戯れる: AutoEncoderを作ってみる