TensorFlow手写数字识别mnist example源码分析

来源:互联网 发布:删除旧的windows文件夹 编辑:程序博客网 时间:2024/06/06 02:16

TensorFlow手写数字识别mnist example源码分析
TensorFlow 默认安装在 /usr/lib/Python/site-packages/tensorflow/

实例文件位于tensorflow/models/image/mnist/convolutional.py,为TensorFlow自带的example文件。

# Copyright 2015 The TensorFlow Authors. All Rights Reserved.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at##     http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.# =============================================================================="""Simple, end-to-end, LeNet-5-like convolutional MNIST model example.This should achieve a test error of 0.7%. Please keep this model as simple andlinear as possible, it is meant as a tutorial for simple convolutional models.Run with --self_test on the command line to execute a short self-test."""from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_functionimport argparseimport gzipimport osimport sysimport timeimport numpyfrom six.moves import urllibfrom six.moves import xrange  # pylint: disable=redefined-builtinimport tensorflow as tfSOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'  # 数据源WORK_DIRECTORY = 'data'  # 工作目录,存放下载的数据# MNIST 数据集特征:#     图像尺寸 28x28IMAGE_SIZE = 28NUM_CHANNELS = 1  # 黑白图像PIXEL_DEPTH = 255  # 像素值0~255NUM_LABELS = 10  # 标签分10个类别VALIDATION_SIZE = 5000  # 验证集大小SEED = 66478  # 随机数种子,可设为 None 表示真的随机BATCH_SIZE = 64  # 批处理大小为64NUM_EPOCHS = 10  # 数据全集一共过10遍网络EVAL_BATCH_SIZE = 64  # 验证集批处理大小也是64# 验证时间间隔,每训练100个批处理,做一次评估EVAL_FREQUENCY = 100  # Number of steps between evaluations.FLAGS = Nonedef data_type():    """Return the type of the activations, weights, and placeholder variables."""    if FLAGS.use_fp16:        return tf.float16    else:        return tf.float32def maybe_download(filename):    """如果下载过了数据,就不再重复下载"""    if not tf.gfile.Exists(WORK_DIRECTORY):        tf.gfile.MakeDirs(WORK_DIRECTORY)    filepath = os.path.join(WORK_DIRECTORY, filename)    if not tf.gfile.Exists(filepath):        filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)        with tf.gfile.GFile(filepath) as f:            size = f.size()        print('Successfully downloaded', filename, size, 'bytes.')    return filepathdef extract_data(filename, num_images):    # 抽取数据,变为 4维张量[图像索引,y, x, c]    # 去均值、做归一化,范围变到[-0.5, 0.5]    print('Extracting', filename)    with gzip.open(filename) as bytestream:        bytestream.read(16)        buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS)        data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32)        data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH        data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)        return datadef extract_labels(filename, num_images):    """Extract the labels into a vector of int64 label IDs."""    print('Extracting', filename)    with gzip.open(filename) as bytestream:        bytestream.read(8)        buf = bytestream.read(1 * num_images)        labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64)    return labelsdef fake_data(num_images):    """Generate a fake dataset that matches the dimensions of MNIST."""    """生成一个匹配MNIST数据集大小的伪造数据集"""    data = numpy.ndarray(        shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS),        dtype=numpy.float32)    labels = numpy.zeros(shape=(num_images,), dtype=numpy.int64)    for image in xrange(num_images):        label = image % 2        data[image, :, :, 0] = label - 0.5        labels[image] = label    return data, labelsdef error_rate(predictions, labels):    """Return the error rate based on dense predictions and sparse labels."""    return 100.0 - (        100.0 *        numpy.sum(numpy.argmax(predictions, 1) == labels) /        predictions.shape[0])# 主函数def main(_):    if FLAGS.self_test:        print('Running self-test.')        train_data, train_labels = fake_data(256)        validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE)        test_data, test_labels = fake_data(EVAL_BATCH_SIZE)        num_epochs = 1    else:        # 下载数据        train_data_filename = maybe_download('train-images-idx3-ubyte.gz')        train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz')        test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz')        test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz')        # 载入数据到numpy        train_data = extract_data(train_data_filename, 60000)        train_labels = extract_labels(train_labels_filename, 60000)        test_data = extract_data(test_data_filename, 10000)        test_labels = extract_labels(test_labels_filename, 10000)        # 产生评测集        validation_data = train_data[:VALIDATION_SIZE, ...]        validation_labels = train_labels[:VALIDATION_SIZE]        train_data = train_data[VALIDATION_SIZE:, ...]        train_labels = train_labels[VALIDATION_SIZE:]        num_epochs = NUM_EPOCHS # 数据全集一共过10遍网络    train_size = train_labels.shape[0]    # 训练样本和标签将从这里送入网络。    # 每训练迭代步,占位符节点将被送入一个批处理数据    # 训练数据节点    train_data_node = tf.placeholder(        data_type(),        shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))    # 训练标签节点    train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,))    # 评测数据节点    eval_data = tf.placeholder(        data_type(),        shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))    # 下面这些变量是网络的可训练权值    # conv1 权值维度为 32 x channels x 5 x 5, 32 为特征图数目    conv1_weights = tf.Variable(        tf.truncated_normal([5, 5, NUM_CHANNELS, 32],  # 5x5 filter, depth 32.                            stddev=0.1,                            seed=SEED, dtype=data_type()))    # conv1 偏置    conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type()))    # conv2 权值维度为 64 x 32 x 5 x 5    conv2_weights = tf.Variable(tf.truncated_normal(        [5, 5, 32, 64], stddev=0.1,        seed=SEED, dtype=data_type()))    # conv2 偏置    conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type()))    # 全连接层 fc1 权值,神经元数目为512    fc1_weights = tf.Variable(  # fully connected, depth 512.        tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512],                            stddev=0.1,                            seed=SEED,                            dtype=data_type()))    fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type()))    # fc2 权值,维度与标签类数目一致    fc2_weights = tf.Variable(tf.truncated_normal([512, NUM_LABELS],                                                  stddev=0.1,                                                  seed=SEED,                                                  dtype=data_type()))    fc2_biases = tf.Variable(tf.constant(        0.1, shape=[NUM_LABELS], dtype=data_type()))    # 两个网络:训练网络和评测网络    # 它们共享权值    # 实现 LeNet-5 模型,该函数输入为数据,输出为fc2的响应    # 第二个参数区分训练网络还是评测网络    def model(data, train=False):        # 二维卷积,使用“不变形”补零(即输出特征图与输入尺寸一致)。        conv = tf.nn.conv2d(data,                            conv1_weights,                            strides=[1, 1, 1, 1],                            padding='SAME')        # 加偏置、过激活函数一块完成        relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases))        # 最大值下采样        pool = tf.nn.max_pool(relu,                              ksize=[1, 2, 2, 1],                              strides=[1, 2, 2, 1],                              padding='SAME')        # 第二个卷积层,步长为1        conv = tf.nn.conv2d(pool,                            conv2_weights,                            strides=[1, 1, 1, 1],                            padding='SAME')        relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases))        pool = tf.nn.max_pool(relu,                              ksize=[1, 2, 2, 1],                              strides=[1, 2, 2, 1],                              padding='SAME')        # 特征图变形为2维矩阵,便于送入全连接层        pool_shape = pool.get_shape().as_list()        reshape = tf.reshape(            pool,            [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]])        # 全连接层,注意“+”运算自动广播偏置        hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases)        # 训练阶段,增加 50% dropout;而评测阶段无需该操作        if train:            hidden = tf.nn.dropout(hidden, 0.5, seed=SEED)        return tf.matmul(hidden, fc2_weights) + fc2_biases        # 训练阶段计算: 对数+交叉熵 损失函数    logits = model(train_data_node, True)    loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(        logits, train_labels_node))    # 全连接层参数进行 L2 正则化    regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) +                    tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases))    # 将正则项加入损失函数    loss += 5e-4 * regularizers    # 优化器: 设置一个变量,每个批处理递增,控制学习速率衰减    batch = tf.Variable(0, dtype=data_type())    # Decay once per epoch, using an exponential schedule starting at 0.01.    #  指数衰减    learning_rate = tf.train.exponential_decay(        0.01,  # 基本学习速率        batch * BATCH_SIZE,  # 当前批处理在数据全集中的位置        train_size,  # Decay step.        0.95,  # 衰减率        staircase=True)    # Use simple momentum for the optimization.    optimizer = tf.train.MomentumOptimizer(learning_rate,                                           0.9).minimize(loss,                                                         global_step=batch)    # 用softmax 计算训练批处理的预测概率    train_prediction = tf.nn.softmax(logits)    # 用 softmax 计算评测批处理的预测概率    eval_prediction = tf.nn.softmax(model(eval_data))    # Small utility function to evaluate a dataset by feeding batches of data to    # {eval_data} and pulling the results from {eval_predictions}.    # Saves memory and enables this to run on smaller GPUs.    def eval_in_batches(data, sess):        """通过运行在小批量数据,得到所有预测结果."""        size = data.shape[0]        if size < EVAL_BATCH_SIZE:            raise ValueError("batch size for evals larger than dataset: %d" % size)        predictions = numpy.ndarray(shape=(size, NUM_LABELS), dtype=numpy.float32)        for begin in xrange(0, size, EVAL_BATCH_SIZE):            end = begin + EVAL_BATCH_SIZE            if end <= size:                predictions[begin:end, :] = sess.run(                    eval_prediction,                    feed_dict={eval_data: data[begin:end, ...]})            else:                batch_predictions = sess.run(                    eval_prediction,                    feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]})                predictions[begin:, :] = batch_predictions[begin - size:, :]        return predictions    # Create a local session to run the training.    start_time = time.time()    with tf.Session() as sess:        # 初始化操作准备参数        tf.global_variables_initializer().run()        print('Initialized!')        # 循环训练        for step in xrange(int(num_epochs * train_size) // BATCH_SIZE):            # 计算当前minibatch的offset            # Note that we could use better randomization across epochs.            offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)            batch_data = train_data[offset:(offset + BATCH_SIZE), ...]            batch_labels = train_labels[offset:(offset + BATCH_SIZE)]            # This dictionary maps the batch data (as a numpy array) to the            # node in the graph it should be fed to.            feed_dict = {train_data_node: batch_data,                         train_labels_node: batch_labels}            # 运行优化器更新权重            sess.run(optimizer, feed_dict=feed_dict)            # print some extra information once reach the evaluation frequency            if step % EVAL_FREQUENCY == 0:                # fetch some extra nodes' data                l, lr, predictions = sess.run([loss, learning_rate, train_prediction],                                              feed_dict=feed_dict)                elapsed_time = time.time() - start_time                start_time = time.time()                print('Step %d (epoch %.2f), %.1f ms' %                      (step, float(step) * BATCH_SIZE / train_size,                       1000 * elapsed_time / EVAL_FREQUENCY))                print('Minibatch loss: %.3f, learning rate: %.6f' % (l, lr))                print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels))                print('Validation error: %.1f%%' % error_rate(                    eval_in_batches(validation_data, sess), validation_labels))                sys.stdout.flush()        # Finally print the result!        test_error = error_rate(eval_in_batches(test_data, sess), test_labels)        print('Test error: %.1f%%' % test_error)        if FLAGS.self_test:            print('test_error', test_error)            assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % (                test_error,)if __name__ == '__main__':    parser = argparse.ArgumentParser()    parser.add_argument(        '--use_fp16',        default=False,        help='Use half floats instead of full floats if True.',        action='store_true')    parser.add_argument(        '--self_test',        default=False,        action='store_true',        help='True if running a self test.')    FLAGS, unparsed = parser.parse_known_args()    tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑装系统黑屏怎么办 电脑c盘无法访问怎么办 d盘变成ntfs怎么办 系统重装卡住了怎么办 系统关机没反应怎么办 232串口打开失败怎么办 逆水寒cpu不支持怎么办 显卡被禁用了怎么办 vmvare注册错了怎么办 电脑主机未成功启动怎么办 主机未成功启动怎么办 电脑主机未能成功启动怎么办 虚拟机没有自带怎么办 错误连接为720怎么办 dns错误不能上网怎么办 家里无线用不了怎么办 磁盘c5坏了怎么办 一体机装xp蓝屏怎么办 虚拟机密码忘记了怎么办 vivoy66手机太卡怎么办 虚拟机装xp蓝屏怎么办 exagear玩起来卡怎么办 第五人格模拟器玩太卡怎么办 速腾油箱盖打不开怎么办 奥迪a6油箱盖打不开怎么办 苹果手提虚拟机黑屏怎么办 mac系统桌面变大怎么办 删除文件要权限怎么办 页面载入错误了怎么办 手机打不开excel表格怎么办 皇室战争闪退怎么办 苹果老是闪退怎么办 黑苹果开机黑屏怎么办 MAC磁盘删了怎么办 mac磁盘被锁定怎么办 bt5读不到网卡怎么办 笔记本电脑cpu温度过高怎么办 笔记本cpu温度过高怎么办 联想系统崩溃了怎么办 办公软件用不了怎么办 win10设置闪退怎么办