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
- TensorFlow手写数字识别mnist example源码分析
- TensorFlow学习笔记之源码分析(2)----手写数字识别mnist example
- tensorflow-mnist手写数字识别
- 基于tensorflow的MNIST手写数字识别
- 基于tensorflow的MNIST手写数字识别
- Tensorflow 实现 MNIST 手写数字识别
- 神经网络-tensorflow实现mnist手写数字识别
- tensorflow中mnist手写数字识别
- tensorflow中logistic识别mnist手写数字
- tensorflow中MLP识别mnist手写数字
- tensorflow构建RNN识别mnist手写数字
- TensorFlow学习---实现mnist手写数字识别
- TensorFlow实战—mnist手写数字识别
- tensorflow进行MNIST手写数字识别-CNN
- tensorflow进行MNIST手写数字识别-LSTM
- 训练Tensorflow识别手写数字 mnist
- TensorFlow笔记之一:MNIST手写数字识别
- Tensorflow入门 mnist手写数字识别
- 基于Netty3的RPC架构笔记2之服务端与客户端
- HDU 1597 二分+数学
- javaSE的几个基本问题
- CentOS里上传下载rzsz
- ThinkPhP 学习笔记 1.介绍及安装
- TensorFlow手写数字识别mnist example源码分析
- maya布尔运算遇到的问题
- Android界面UI控件的夜间模式及隐藏
- 多态
- 正则表达式(简单易懂篇)
- pdf2swf转换ppt时出现错误的解决办法
- MySQL Join查询
- Qt|C/C++植物大战僵尸修改器(用户版)
- 强制找回GitLab管理员账户密码的方法