卷积神经网络(tf.layers / estimator api)使用TensorFlow'layers'和'estimator'API构建卷积神经网络以对MNIST数字数据集进行分类。
2019-03-02 21:15
585 查看
[code]from tensorflow.examples.tutorials.mnist import input_data mnist=input_data.read_data_sets("./data",one_hot=False) import tensorflow as tf learning_rate=0.001 num_steps=2000 batch_size=128 num_input=784 num_classes=10 dropout=0.25 # Dropout,probability to drop a unit # create the neural network def conv_net(x_dict,n_classes,dropout,reuse,is_training): # define a scope for reusing the variables # tf.variable_scope(): 可以让变量有相同的命名,包括tf.get_variable得到的变量, # 还有tf.Variable变量.可变范围允许创建新的variable并分享已创建的variable, # 同时提供检查,不会意外创建或共享。 # tf.variable_scope(name_or_scope, string或VariableScope:要打开的范围 # default_name=None, 如果name_or_scope参数为None, # 则将使用默认名称,此名称将被唯一。 # 如果提供了name_or_scope,它将不会被使用, # 因此它不是必需的,可以是None。 # values=None, 值:传递给op函数的Tensor参数列表。 # initializer=None, 初始化器:此范围内的变量的默认初始化程序。 # regularizer=None, 此范围内的变量的默认正则符。 # caching_device=None, 此范围内的变量的默认缓存设备 # partitioner=None, 此范围内变量的默认分区。 # custom_getter=None, 此范围内变量的默认定制getter。 # reuse=None, True或None 如果是,我们进入该范围以及所有子范围的重用模式; # 如果没有,我们只是继承父范围重用。 # dtype=None) 在此范围中创建的变量类型(默认为传递范围中的类型,或从父范围继承) with tf.variable_scope('ConvNet',reuse=reuse): x=x_dict['images'] x=tf.reshape(x,shape=[-1,28,28,1]) # convolution layer with 32 filters and a kernel size of 5 conv1=tf.layers.conv2d(x,32,5,activation=tf.nn.relu) # max pooling (down-sampling) with strides of 2 and kernel size of 2 # 在卷积神经网络中,卷积层之间往往会加上一个池化层。 # 池化层可以非常有效地缩小参数矩阵的尺寸,从而减少最后全连层中的参数数量。 # 使用池化层即可以加快计算速度也有防止过拟合的作用,一般是放在卷积层之后 # max_pooling2d( # inputs, 进行池化的数据。 # pool_size, 池化的核大小(pool_height, pool_width), # 如[3,3]. 如果长宽相等,也可以直接设置为一个数,如pool_size=3. # strides, 池化的滑动步长。可以设置为[1,1]这样的两个整数. 也可以直接设置为一个数,如strides=2 # padding='valid', 边缘填充,'same' 和'valid‘选其一。默认为valid # data_format='channels_last', 输入数据格式,默认为channels_last ,即 (batch, height, width, channels), # 也可以设置为channels_first 对应 (batch, channels, height, width). # name=None 层的名字。 # ) conv1=tf.layers.max_pooling2d(conv1,2,2) # conv2d(inputs, Tensor 输入 # filters, 整数,表示输出空间的维数(即卷积过滤器的数量) # kernel_size, 一个整数,或者包含了两个整数的元组/队列,表示卷积窗的高和宽。 # 如果是一个整数,则宽高相等 # strides=(1, 1), 一个整数,或者包含了两个整数的元组/队列, # 表示卷积的纵向和横向的步长。如果是一个整数,则横纵步长相等。 # 另外, strides 不等于1 和 dilation_rate 不等于1 # 这两种情况不能同时存在。 # padding='valid', "valid" 或者 "same"(不区分大小写)。 # "valid" 表示不够卷积核大小的块就丢弃, # "same"表示不够卷积核大小的块就补0。 "valid" 的输出形状为输入的 size(高或宽), # 为 filter 的 size, 为 strides 的大小, 为向上取整。 # data_format='channels_last', channels_last 或者 channels_first,表示输入维度的排序。 # `channels_last` corresponds to inputs with shape; # `(batch, height, width, channels)` while `channels_first` corresponds to inputs with shape `(batch, channels, height, width)`. # dilation_rate=(1, 1), 一个整数,或者包含了两个整数的元组/队列, # 表示使用扩张卷积时的扩张率。如果是一个整数, # 则所有方向的扩张率相等。另外, strides 不等于1 和 # dilation_rate 不等于1 这两种情况不能同时存在。 # activation=None, 激活函数。如果是None则为线性函数。 # use_bias=True, Boolean类型,表示是否使用偏差向量。 # kernel_initializer=None, 卷积核的初始化。 # bias_initializer=<tensorflow.python.ops.init_ops.Zeros object at 0x000002596A1FD898>, 卷积核的初始化。 # kernel_regularizer=None, 映射函数,当核被Optimizer更新后应用到核上。 # Optimizer 用来实现对权重矩阵的范数约束或者值约束。 # 映射函数必须将未被影射的变量作为输入, # 且一定输出映射后的变量(有相同的大小)。 # 做异步的分布式训练时,使用约束可能是不安全的。 # bias_regularizer=None, 映射函数,当偏差向量被Optimizer更新后应用到偏差向量上。 # activity_regularizer=None, # kernel_constraint=None, # bias_constraint=None, # trainable=True, Boolean类型。 # name=None, 字符串,层的名字。 # reuse=None) Boolean类型,表示是否可以重复使用具有相同名字的前一层的权重。 conv2=tf.layers.conv2d(conv1,64,3,activation=tf.nn.relu) conv2=tf.layers.max_pooling2d(conv2,2,2) # flatten the data to a 1-D vector for the fully connected layer # flatten(P)这个函数就是把P保留第一个维度,把第一个维度包含的每一子张量展开成一个行向量, # 返回张量是一个二维的, shape=(batch_size,….),一般用于卷积神经网络全链接层前的预处理 fc1=tf.contrib.layers.flatten(conv2) # fully connected layer(in tf contrib folder for now) # tf.layers.dense( # inputs, 输入该网络层的数据 # units, 输出的维度大小,改变inputs的最后一维 # activation=None, 激活函数,即神经网络的非线性变化 # use_bias=True, 使用bias为True(默认使用),不用bias改成False即可,是否使用偏置项 # kernel_initializer=None, 卷积核的初始化器 # bias_initializer=tf.zeros_initializer(), 偏置项的初始化器,默认初始化为0 # kernel_regularizer=None, 卷积核的正则化,可选 # bias_regularizer=None, 偏置项的正则化,可选 # activity_regularizer=None, 输出的正则化函数 # kernel_constraint=None, # bias_constraint=None, # trainable=True, 表明该层的参数是否参与训练。如果为真则变量加入到图集合中 # name=None, 层的名字 # reuse=None 是否重复使用参数 fc1=tf.layers.dense(fc1,1024) # apply dropout (if is_training is false, dropout is not applied) # dropout 是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃, # 可以用来防止过拟合,layers模块中提供了tf.layers.dropout()方法来实现这一操作, # dropout( inputs, 即输入数据。 # rate=0.5, 可选,默认为0.5,即dropout rate,如设置为0.1,则意味着会丢弃10%的神经元。 # noise_shape=None, 可选,默认为 None,int32 类型的一维 Tensor, # 它代表了dropout mask的shape,dropout mask会与inputs相乘对inputs做转换, # 例如inputs的shape为(batch_size,timesteps,features), # 但我们想要droput mask在所有timesteps都是相同的, # 我们可以设置noise_shape=[batch_size,1, features]。 # seed=None, 可选,默认为 None,即产生随机熟的种子值。 # training=False, 可选,默认为 False,布尔类型,即代表了是否标志位 training 模式。 # name=None) 可选,默认为 None,dropout 层的名称。 fc1=tf.layers.dropout(fc1,rate=dropout,training=is_training) out= tf.layers.dense(fc1,n_classes) return out # define the model function(following tf estimator template) def model_fn(features,labels,mode): # because dropout have different behavior at training and prediction time,we # need to create 2 distinct computation graphs that still share the same weight. 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) # predictions # tf.argmax(vector, 1):返回的是vector中的最大值的索引号, # 如果vector是一个向量,那就返回一个值,如果是一个矩阵, # 那就返回一个向量,这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号。 pred_classes=tf.argmax(logits_test,axis=1) # 通过Softmax回归,将logistic的预测二分类的概率的问题推广到了n分类的概率的问题。 # tf.nn.softmax( # logits, 一个非空张量,必须是以下类型之一:half, float32, float64 # axis=None, 将被执行的softmax维度,默认值是-1,表示最后一个维度。 # name=None, 操作的名称(可选)。 # dim=None # ) pred_probas=tf.nn.softmax(logits_test) # if prediction mode,early,return if mode==tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode,predictions=pred_classes) # define loss and optimizer # tf.reduce_mean函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值, # 主要用作降维或者计算tensor(图像)的平均值。 # reduce_mean(input_tensor, 输入的待降维的tensor; # axis=None, 指定的轴,如果不指定,则计算所有元素的均值; # keep_dims=False, 是否降维度,设置为True,输出的结果保持输入tensor的形状, # 设置为False,输出结果会降低维度; # name=None, 操作的名称; # reduction_indices=None) 在以前版本中用来指定轴,已弃用; # tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name=None) # 计算logits和labels之间的稀疏softmax交叉熵度量在离散分类任务中的错误率, # 这些类之间是相互排斥的(每个输入只能对应唯一确定的一个类).举例来说, # 每个CIFAR-10 图片只能被标记为唯一的一个标签:一张图片可能是一只狗或一辆卡车,而不能两者都是。 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) # global_step经常在滑动平均,学习速率变化的时候需要用到,这个参数在tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_steps)里面有,系统会自动更新这个参数的值,从1开始。 # tf.train.get_global_step 获得全局步长张量,全局步长张数必须是整数变量。我们首先尝试在集合GLOBAL_STEP中或通过名称找到它global_step:0。 # 返回:全局步骤变量,或者None如果没有找到 train_op=optimizer.minimize(loss_op,global_step=tf.train.get_global_step()) acc_op=tf.metrics.accuracy(labels=labels,predictions=pred_classes) # 是一个class(类),是定义在model_fn中的, # 并且model_fn返回的也是它的一个实例,这个实例是用来初始化Estimator类的 # TF Estimators requires to return a EstimatorSpec, that specify # the different ops for training, evaluating, ... 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 # class Estimator(builtins.object) # 对象包含了一个模型 model_fn,这个模型给定输入和参数,会返回训练、验证或者预测等所需要的操作节点。 # 所有的输出(检查点、事件文件等)会写入到 model_dir,或者其子文件夹中。如果 model_dir 为空, # 则默认为临时目录。 model=tf.estimator.Estimator(model_fn) # tf.estimator.inputs.numpy_input_fn( # x, numpy数组对象或numpy数组对象的dict。如果是数组,则该数组将被视为单个特征。 # y=None, numpy数组对象或numpy数组对象的dict。None如果没有。 # batch_size=128, 整数,返回的批次大小。 # num_epochs=1, 整数,迭代数据的时期数。如果None将永远运行。 # shuffle=None, 如果为True,则对队列进行洗牌。在预测时避免随机播放。 # queue_capacity=1000, 整数,要累积的队列大小。 # num_threads=1 整数,用于读取和排队的线程数。为了具有预测和可重复的阅读和排队顺序, # 例如在预测和评估模式中,num_threads应该是1。 # ) 返回将numpy数组的dict输入模型的输入函数。 # define the input function for training 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) # train the model model.train(input_fn, steps=num_steps) # evaluate the model # define the input function for evaluation input_fn=tf.estimator.inputs.numpy_input_fn( x={'images':mnist.test.images},y=mnist.test.labels,batch_size=batch_size, shuffle=False) # Use the Estimator 'evaluate' method e=model.evaluate(input_fn) print('Testing Accuracy:',e['accuracy'])
相关文章推荐
- tensorflow 学习专栏(六):使用卷积神经网络(CNN)在mnist数据集上实现分类
- Tensorflow学习教程------利用卷积神经网络对mnist数据集进行分类_利用训练好的模型进行分类
- Tensorflow学习教程------利用卷积神经网络对mnist数据集进行分类_训练模型
- 使用tensorflow利用神经网络分类识别MNIST手写数字数据集,转自随心1993
- TensorFlow学习实践(三):使用TFRecord格式数据和tf.estimator API进行模型训练和预测
- tensorflow 学习专栏(四):使用tensorflow在mnist数据集上使用逻辑回归logistic Regression进行分类
- tensorflow 学习专栏(五):在mnist数据集上使用tensorflow实现临近算法(Nearest-Neighbor)进行手写数字识别
- TF之RNN:基于顺序的RNN分类案例对手写数字图片mnist数据集实现高精度预测—Jason niu
- 深度学习-CNN卷积神经网络使用TensorFlow框架实现MNIST手写数字识别
- 利用tensorflow一步一步实现基于MNIST 数据集进行手写数字识别的神经网络,逻辑回归
- 使用PCA + KNN对MNIST数据集进行手写数字识别 python
- Keras(2):使用Keras构建神经网络进行Mnist手写字体分类,并定性分析各种超参数的影响
- 【TensorFlow-windows】(四) CNN(卷积神经网络)进行手写数字识别(mnist)
- 使用tensorflow卷积神经网络实现mnist手写数字识别
- 神经网络与深度学习 使用Python实现基于梯度下降算法的神经网络和自制仿MNIST数据集的手写数字分类可视化程序 web版本
- 使用TensorFlow双流卷积神经网络对CK+表情数据库进行分类
- 使用Tensorflow实现CNN进行MNIST数字识别
- tensorflow使用RNN分析mnist手写体数字数据集
- Tensorflow——MNIST手写数字数据集识别分类,准确率达到98%以上的方法实验
- TensorFlow学习实践(四):使用TFRecord格式数据和tf.contrib.slim API进行模型训练和预测