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