Google Cloud Platformではじめる機械学習と深層学習を読む

7-7ニューラルネットワークの実装

# パッケージの読み込み
import tensorflow as tf
import numpy as np
import pandas as pd

# BigQueryクエリ結果をDataFrameに読み込む
query = 'SELECT * FROM testdataset.wdbc ORDER BY index'
dataset = pd.read_gbq(project_id='my-project-test-189202', query=query)
print(dataset.info())
# データの先頭5行を表示
dataset.head()

フィールドが32,行が569
f:id:bitop:20171228150911p:plain

from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

# 'M'を0, 'B'を1に変換
dataset['diagnostic'] = dataset['diagnostic'].apply(
    lambda x: 0 if x == 'M' else 1)

# 'index'カラムを削除
dataset.drop('index', axis=1, inplace=True)

# DataFrameからarrayに変換
# diagnosticは正解なので訓練データには不要
# as_matrix()はnumpy arrayに変換する
X_dataset = dataset.drop('diagnostic', axis=1).as_matrix()
y_dataset = dataset.diagnostic.as_matrix()

# 学習用とテスト用にデータセットを分ける(testは20%)
X_train, X_test, y_train, y_test = train_test_split(
    X_dataset, y_dataset, test_size=0.2, random_state=42)

#X_train,X_testを正規化している
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

NUM_FEATURES = 30
NUM_UNITS_H1 = 4
NUM_UNITS_H2 = 4
NUM_CLASSES = 2

# 初期化
tf.reset_default_graph()

with tf.Graph().as_default():
    # 入力層
    #フィールド数が30のデータをXとする
    X = tf.placeholder(tf.float32, shape=[None, NUM_FEATURES], name="X")
    #教師データ
    y = tf.placeholder(tf.float32, shape=[None, ], name="y")

    # 隠れ層1
    #30の重み係数と4つの出力をもつ隠れ層。活性化関数はrelu
    w1 = tf.Variable(tf.truncated_normal(
        [NUM_FEATURES, NUM_UNITS_H1], stddev=0.1), name='w1')
    b1 = tf.Variable(tf.zeros([NUM_UNITS_H1]), name='b1')
    h1 = tf.nn.relu(tf.matmul(X, w1) + b1)

    # 隠れ層2
    #4の重み係数と4つの出力を持つ。活性化関数はrelu
    w2 = tf.Variable(tf.truncated_normal(
        [NUM_UNITS_H1, NUM_UNITS_H2], stddev=0.1), name='w2')
    b2 = tf.Variable(tf.zeros([NUM_UNITS_H2]), name='b2')
    h2 = tf.nn.relu(tf.matmul(h1, w2) + b2)

    # 出力層
    #重み係数は4つで出力は2(M,B)
    w3 = tf.Variable(tf.truncated_normal(
        [NUM_UNITS_H2, NUM_CLASSES], stddev=0.1), name='w3')
    b3 = tf.Variable(tf.zeros([NUM_CLASSES]), name='b3')
    logits = tf.matmul(h2, w3) + b3

    # 損失
    # 損失関数は交差エントロピー
    onehot_labels = tf.one_hot(indices=tf.cast(y, tf.int32), depth=NUM_CLASSES)
    cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
        labels=onehot_labels, logits=logits, name='xentropy')
    loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')

    # 損失を最小化
    # 最適化手法はAdamOptimizer
    train_op = tf.train.AdamOptimizer(0.01).minimize(loss)

    # テスト用の正解率演算オペレーション
    correct_prediction = tf.equal(
        tf.argmax(logits, 1), tf.argmax(onehot_labels, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    #セッション開始
    with tf.Session() as sess:
        #変数の初期化
        sess.run(tf.global_variables_initializer())

        for step in range(1000):
            _, loss_value = sess.run([train_op, loss],
                                    feed_dict={X: X_train, y: y_train})
            if step % 100 == 0:
                print('Step: %d, Loss: %f' % (step, loss_value))
        # テストデータで精度を確認
        _a = sess.run(accuracy, feed_dict={X: X_test, y: y_test})
        print('Accuracy: %f' % _a)

f:id:bitop:20171228151149p:plain

正解率は95.6%
隠れ層の出力は2層とも4であったがこの大きさで正解率が異なるのか
試してみた。
4 = 0.956
5 = 0.938
6 = 0.938
7 = 0.947
8 = 0.947
9 = 0.947
10 = 0.948
4が最適のようだが