利用 s和estimator api构建cnn进行mnist手写字体识别,带有注释。

import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(\'../data/mnist/\', one_hot=False)

import matplotlib.pyplot as plt
import numpy as np


learning_rate = 0.001
num_steps = 2000
batch_size = 128

num_input = 784
num_classes = 10
dropout = 0.25


def conv_net(x_dict, n_classes, dropout, reuse, is_training):
    # 对variable_scope, reuse, 这个介绍的比较清楚:https://www.cnblogs.com/q735613050/p/7777833.html
    with tf.variable_scope(\'ConvNet\', reuse=reuse):
        x = x_dict[\'images\']
        # mnist数据集为28*28像素,真实图片格式为[w,h,c]二值化的图片channle为1,Tensor 输入为[batchise, w, h, c]
        x = tf.reshape(x, shape=[-1, 28, 28, 1])
        # 卷积核数目为32, 尺寸为5
        # 卷积核的大小由用户来定义,即定义的感受视野的大小;卷积核的权重矩阵的值,便是卷积神经网络的参数,为了有一个偏移项,
        # 卷积核可附带一个偏移项b ,它们的初值可以随机来生成,可通过训练进行变化。
        # http://blog.sina.com.cn/s/blog_6fd8e1cd0102wu4u.html 对cnn的介绍很好。
        conv1 = tf. s.conv2d(x, 32, 5, activation=\'relu\')
        # 池化层,步长为2,尺寸为2
        conv1 = tf. s.max_pooling2d(conv1, 2, 2)

        conv2 = tf. s.conv2d(conv1, 64, 3, activation=tf.nn.relu)
        conv2 = tf. s.max_pooling2d(conv2, 2, 2)
        # 后全连接层,将数据转为一维向量
        fc1 = tf.contrib. s.flatten(conv2)
        # 全连接层
        fc1 = tf. s.dense(fc1, 1024)
        # train, 不dropout
        fc1 = tf. s.dropout(fc1, rate=dropout, training=is_training)
        # 输出预测
        out = tf. s.dense(fc1, n_classes)


    return out

# 使用Estimator构建模型函数
def model_fn(features, labels, mode):
    # 因为训练的时候没有dropout,因此需要两个不同的计算图,仍然共享权值
    logits_train = conv_net(features, num_classes, dropout, reuse=False, is_training=True)
    logits_test = conv_net(features, num_classes, dropout, reuse=True, is_training=False)

    pred_classes = tf.argmax(logits_test, axis=1)
    pred_probas = tf.nn.softmax(logits_test)

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode, predictions=pred_classes)

    # 定义损失函数和优化器
    loss_op = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
        logits=logits_train, labels=tf.cast(labels, dtype=tf.int32)
    ))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
    train_op = optimizer.minimize(loss_op, global_step=tf.train.get_global_step())

    # 评估模型的准确率
    acc_op = tf.metrics.accuracy(labels=labels, predictions=pred_classes)

    # Estimators 需要返回一个EstimatorSpec,它指定training, evaluating, predict的不同操作
    estim_specs = tf.estimator.EstimatorSpec(
        mode=mode,
        predictions=pred_classes,
        loss=loss_op,
        train_op=train_op,
        eval_metric_ops={\'accuracy\':acc_op}
    )
    return estim_specs



model = tf.estimator.Estimator(model_fn)

# 定义用于训练的输入函数
input_fn = tf.estimator.inputs.numpy_input_fn(
    x={\'images\':mnist.train.images}, y=mnist.train.labels,
    batch_size=batch_size, num_epochs=None, shuffle=True
)


# 训练
model.train(input_fn, steps=num_steps)

# 对模型评估, 定义评估模型的输入
input_fn = tf.estimator.inputs.numpy_input_fn(
    x={\'images\':mnist.test.images}, y = mnist.test.labels,
    batch_size=batch_size, shuffle=False
)
print(model.evaluate(input_fn))

\"\"

准确率大概0.99的样子。

收藏 打印