在github上,tensorflow的star是22798,caffe是10006,torch是4500,theano是3661。作为小码农的我,最近一直在学习tensorflow,主要使用python的接口进行学习。本博文主要以/tensorflow/tensorflow/models/image/mnist(github上下载)作为例程,讲解python代码的实现。

读代码的时候,建议大家理清主线,从主函数开始,调用到那个子函数时,再去阅读子函数的功能。我在minist的python代码中作了注解,以蓝色标出,希望对你有用。

安装tensorflow请参考:

http://blog.csdn.net/helei001/article/details/49799791

http://blog.csdn.net/helei001/article/details/51285951

# Copyright 2015 Google Inc. 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 and

linear 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.

"""

#引入python模块,用于相关操作



from __future__ import absolute_import

from __future__ import division

from __future__ import print_function





import gzip

import os

import sys

import time





import numpy

from six.moves import urllib

from six.moves import xrange  # pylint: disable=redefined-builtin

import tensorflow as tf



#定义参数:数据库下载地址,深度学习的参数设置



SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'

WORK_DIRECTORY = 'data'

IMAGE_SIZE = 28

NUM_CHANNELS = 1

PIXEL_DEPTH = 255

NUM_LABELS = 10

VALIDATION_SIZE = 5000  # Size of the validation set.

SEED = 66478  # Set to None for random seed.

BATCH_SIZE = 64

NUM_EPOCHS = 10

EVAL_BATCH_SIZE = 64

EVAL_FREQUENCY = 100  # Number of steps between evaluations.









tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.")

FLAGS = tf.app.flags.FLAGS





#根据参数设置,下载相应数据



def maybe_download(filename):

  """Download the data from Yann's website, unless it's already here."""

  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 filepath





#读取下载文件的数据,转换成tensorflow识别的4维向量,并把数据归一化到[-0.5,0.5]



def extract_data(filename, num_images):

  """Extract the images into a 4D tensor [image index, y, x, channels].





  Values are rescaled from [0, 255] down to [-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)

    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, 1)

    return data





#提取图像数据对应的标签

def 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 labels









def fake_data(num_images):

  """Generate a fake dataset that matches the dimensions of 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, labels





#计算错误率



def 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(argv=None):  # pylint: disable=unused-argument

  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:

    # Get the data. #定义下载的文件名,调用maybe_download函数进行下载

    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')





    # Extract it into numpy arrays.#调用extract_data和extract_labels提取训练和测试的图像数据和对应标签

    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)





    # Generate a validation set.#在训练数据里划分训练集和验证集,以及整个训练集的训练次数

    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

  train_size = train_labels.shape[0]





  # This is where training samples and labels are fed to the graph.

  # These placeholder nodes will be fed a batch of training data at each

  # training step using the {feed_dict} argument to the Run() call below.

#定义训练数据及标签,验证数据的输入节点以及数据结构格式

  train_data_node = tf.placeholder(

      tf.float32,

      shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))

  train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,))

  eval_data = tf.placeholder(

      tf.float32,

      shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS))





  # The variables below hold all the trainable weights. They are passed an

  # initial value which will be assigned when we call:

  # {tf.initialize_all_variables().run()}

#定义存储网络参数的变量,每次训练只是更新迭代各个变量的值,实际上,我们也可以从这里推测出网络的结构

  conv1_weights = tf.Variable(

      tf.truncated_normal([5, 5, NUM_CHANNELS, 32],  # 5x5 filter, depth 32.

                          stddev=0.1,

                          seed=SEED))

  conv1_biases = tf.Variable(tf.zeros([32]))

  conv2_weights = tf.Variable(

      tf.truncated_normal([5, 5, 32, 64],

                          stddev=0.1,

                          seed=SEED))

  conv2_biases = tf.Variable(tf.constant(0.1, shape=[64]))

  fc1_weights = tf.Variable(  # fully connected, depth 512.

      tf.truncated_normal(

          [IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512],

          stddev=0.1,

          seed=SEED))

  fc1_biases = tf.Variable(tf.constant(0.1, shape=[512]))

  fc2_weights = tf.Variable(

      tf.truncated_normal([512, NUM_LABELS],

                          stddev=0.1,

                          seed=SEED))

  fc2_biases = tf.Variable(tf.constant(0.1, shape=[NUM_LABELS]))





  # We will replicate the model structure for the training subgraph, as well

  # as the evaluation subgraphs, while sharing the trainable parameters.

#定义网络graph的结构,每个层之间实际上是一种依赖的输入输出关系,建议把graph画出来,理解起来就很清楚了

  def model(data, train=False):

    """The Model definition."""

    # 2D convolution, with 'SAME' padding (i.e. the output feature map has

    # the same size as the input). Note that {strides} is a 4D array whose

    # shape matches the data layout: [image index, y, x, depth].

    conv = tf.nn.conv2d(data,

                        conv1_weights,

                        strides=[1, 1, 1, 1],

                        padding='SAME')

    # Bias and rectified linear non-linearity.

    relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases))

    # Max pooling. The kernel size spec {ksize} also follows the layout of

    # the data. Here we have a pooling window of 2, and a stride of 2.

    pool = tf.nn.max_pool(relu,

                          ksize=[1, 2, 2, 1],

                          strides=[1, 2, 2, 1],

                          padding='SAME')

    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')

    # Reshape the feature map cuboid into a 2D matrix to feed it to the

    # fully connected layers.

    pool_shape = pool.get_shape().as_list()

    reshape = tf.reshape(

        pool,

        [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]])

    # Fully connected layer. Note that the '+' operation automatically

    # broadcasts the biases.

    hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases)

    # Add a 50% dropout during training only. Dropout also scales

    # activations such that no rescaling is needed at evaluation time.

    if train:

      hidden = tf.nn.dropout(hidden, 0.5, seed=SEED)

    return tf.matmul(hidden, fc2_weights) + fc2_biases



  #定义网络的loss和正则项,即优化的目标函数,用于误差反传

  # Training computation: logits + cross-entropy loss.

  logits = model(train_data_node, True)

  loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(

      logits, train_labels_node))





  # L2 regularization for the fully connected parameters.

  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))

  # Add the regularization term to the loss.

  loss += 5e-4 * regularizers



  # 定义优化目标函数时,学习率,梯度动量的迭代策略

  # Optimizer: set up a variable that's incremented once per batch and

  # controls the learning rate decay.

  batch = tf.Variable(0)

  # Decay once per epoch, using an exponential schedule starting at 0.01.

  learning_rate = tf.train.exponential_decay(

      0.01,                # Base learning rate.

      batch * BATCH_SIZE,  # Current index into the dataset.

      train_size,          # Decay step.

      0.95,                # Decay rate.

      staircase=True)

  # Use simple momentum for the optimization.

  optimizer = tf.train.MomentumOptimizer(learning_rate,

                                         0.9).minimize(loss,

                                                       global_step=batch)



  # 预测当前输出,以及利用训练好的模型预测验证集的输出

  # Predictions for the current training minibatch.

  train_prediction = tf.nn.softmax(logits)





  # Predictions for the test and validation, which we'll compute less often.

  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.

# 为了节约内存,每次使用较小size的数据进行验证,比如batch size等

  def eval_in_batches(data, sess):

    """Get all predictions for a dataset by running it in small batches."""

    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



  # 在定义好graph,目标函数以及优化策略的基础上,使用seesion在硬件上执行计算。每次迭代都是batch size的数据集,每隔一定迭代次数后,输出损失函数,学习率,训练误差,以及验证误差。

  # Create a local session to run the training.

  start_time = time.time()

  with tf.Session() as sess:

    # Run all the initializers to prepare the trainable parameters.

    tf.initialize_all_variables().run()

    print('Initialized!')

    # Loop through training steps.

    for step in xrange(int(num_epochs * train_size) // BATCH_SIZE):

      # Compute the offset of the current minibatch in the data.

      # 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}

      # Run the graph and fetch some of the nodes.

      _, l, lr, predictions = sess.run(

          [optimizer, loss, learning_rate, train_prediction],

          feed_dict=feed_dict)

      if step % EVAL_FREQUENCY == 0:

        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__':

  tf.app.run()

学习TensorFlow,浅析MNIST的python代码的更多相关文章

  1. 风炫安全web安全学习第三十二节课 Python代码执行以及代码防御措施

    风炫安全web安全学习第三十二节课 Python代码执行以及代码防御措施 Python 语言可能发生的命令执行漏洞 内置危险函数 eval和exec函数 eval eval是一个python内置函数, ...

  2. 深度学习模型stacking模型融合python代码,看了你就会使

    话不多说,直接上代码 def stacking_first(train, train_y, test): savepath = './stack_op{}_dt{}_tfidf{}/'.format( ...

  3. 常用正则表达式最强汇总(含Python代码举例讲解+爬虫实战)

    大家好,我是辰哥~ 本文带大家学习正则表达式,并通过python代码举例讲解常用的正则表达式 最后实战爬取小说网页:重点在于爬取的网页通过正则表达式进行解析. 正则表达式语法 Python的re模块( ...

  4. tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)

    tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...

  5. tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)

    续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...

  6. 深度学习-tensorflow学习笔记(2)-MNIST手写字体识别

    深度学习-tensorflow学习笔记(2)-MNIST手写字体识别超级详细版 这是tf入门的第一个例子.minst应该是内置的数据集. 前置知识在学习笔记(1)里面讲过了 这里直接上代码 # -*- ...

  7. tensorflow学习笔记————分类MNIST数据集

    在使用tensorflow分类MNIST数据集中,最容易遇到的问题是下载MNIST样本的问题. 一般是通过使用tensorflow内置的函数进行下载和加载, from tensorflow.examp ...

  8. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  9. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

随机推荐

  1. 勤拂拭软件系列教程 之 Android开发之旅

    勤拂拭软件工作室持续推出Android开发系列教程与案例,供广大朋友分享交流技术经验,帮助喜欢Android的朋友们学习进步: 1. 勤拂拭软件Android开发之旅(1) 之 Android 开发环 ...

  2. 网络硬盘NFS

    NFS是网络文件系统,用于计算机间共享文件系统,由sun公司1985年推出的协议,现在已经被广泛使用.一般来说,所有的linux发型版都支持NFS.nfs是一个服务器,客户端的架构,建立一个nfs的服 ...

  3. 某些情况下调用函数为什么要在函数名前加“(void)”

    我们知道,在定义函数时,加在函数名前的"void"表示该函数没有返回值.但在调用时,在函数名前加"(void)"的作用又是什么呢? 最明显的一点就是表示程序并不 ...

  4. box-sizing position

    box-sizing 属性 用于更改用于计算元素宽度和高度的默认的 CSS 盒子模型.可以使用此属性来模拟不正确支持CSS盒子模型规范的浏览器的行为. /* 关键字 值 */ box-sizing: ...

  5. 如何在 vmware esxi 中开放 VNC功能及端口实现远程管理 完整篇

    VMWare esxi中开放 VNC功能及端口实现远程管理 完整篇 在多个论坛上看了相关文章,总的写得不完整.现将各方资源整编写完整版.详文如下! (图片来自51CTO) 步骤1. 修改ESXi主机的 ...

  6. servlet的web-xml配置详解

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  7. Nginx+Tomca+Redis实现负载均衡、资源分离、session共享

    目标实现:Nginx作为负载均衡后端多Tomcat实例,通过Redis实现Session共享. 操作系统环境:CentOS 6.8 SSH:SecureCRT 其中 Nginx服务:80端口 Tomc ...

  8. Lintcode392 Is Subsequence solution 题解

    [题目描述] Given a string s and a string t, check if s is subsequence of t. You may assume that there is ...

  9. 110个oracle常用函数总结

    . ASCII 返回与指定的字符对应的十进制数; SQL) zero,ascii( ) space from dual; A A ZERO SPACE --------- --------- ---- ...

  10. 剑指架构师系列-Redis集群部署

    初步搭建Redis集群 克隆已经安装Redis的虚拟机,我们使用这两个虚拟机中的Redis来搭建集群. master:192.168.2.129 端口:7001 slave:192.168.2.132 ...