Tensorflow1.8用keras實現MNIST資料集手寫字型識別例程
阿新 • • 發佈:2018-12-12
import tensorflow as tf
tf.enable_eager_execution()
eager是新版本加入的動態圖,可以直接計算出結果而不用使用Session。同時也支援微分操作。
class DataLoader(): def __init__(self): mnist = tf.contrib.learn.datasets.load_dataset("mnist") self.train_data = mnist.train.images # np.array [55000,784] self.train_labels = np.asarray(mnist.train.labels, dtype=np.int32) self.eval_data = mnist.test.images self.eval_labels = np.asarray(mnist.test.labels, dtype=np.int32) def get_batch(self, batch_size): index = np.random.randint(0, np.shape(self.train_data)[0], batch_size) return self.train_data[index, :], self.train_labels[index]
下載資料集,load_dataset已經被棄用,但是作為練習入門,可是可以用以下。不fq可能會下載失敗,這裡可以把從其他地方下載好的資料放在當前執行目錄下的MNIST-data資料夾下。該函式會檢測到已經存在資料集,不執行下載,但是會把資料載入到mnist物件中。提供一個下載連結:MNIST資料集
接下來使用keras建立模型
class MLP(tf.keras.Model): def __init__(self): super().__init__() self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu) self.dense2 = tf.keras.layers.Dense(units=10) def call(self, inputs): x = self.dense1(inputs) x = self.dense2(x) return x def predict(self, inputs): logits = self(inputs) return tf.argmax(logits, axis=-1)
這裡predict函式中的self(inputs)的用法,我認為是呼叫了自身的call函式。不知道詳細的該怎麼解釋。
然後是一些引數的設定和建立模型。
num_batches = 1000
batch_size = 50
learning_rate = 0.001
model = MLP()
data_loader = DataLoader()
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
接下來訓練模型
for batch_index in range(num_batches): X, y = data_loader.get_batch(batch_size) with tf.GradientTape() as tape: y_logit_pred = model(tf.convert_to_tensor(X)) loss = tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_logit_pred) print("batch %d: loss %f" % (batch_index, loss.numpy())) grads = tape.gradient(loss, model.variables) optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
此處loss.numpy()將tesor轉為numpy陣列是為了方便輸出。下一步測試的時候這樣做也是為了能夠直接參與‘==’計算。
訓練10000次,損失在百分之一左右。多加層數結果差不多,這應該全連線這種結構的極限了。
batch 9987: loss 0.035664
batch 9988: loss 0.020450
batch 9989: loss 0.007081
batch 9990: loss 0.016520
batch 9991: loss 0.017806
batch 9992: loss 0.003520
batch 9993: loss 0.006888
batch 9994: loss 0.051535
batch 9995: loss 0.071949
batch 9996: loss 0.033571
batch 9997: loss 0.001418
batch 9998: loss 0.010215
batch 9999: loss 0.008465
測試。
num_eval_samples = np.shape(data_loader.eval_labels)[0]
y_pred = model.predict(data_loader.eval_data).numpy()#轉化成numpy才可以做下一步的 == 運算
print("test accuracy: %f" % (sum(y_pred == data_loader.eval_labels) / num_eval_samples))
準確度為97%
test accuracy: 0.975500