【TensorFlow/简单网络】MNIST数据集-softmax、全连接神经网络,卷积神经网络模型

时间:2022-08-31 10:16:50

初学tensorflow,参考了以下几篇博客:

soft模型

tensorflow构建全连接神经网络

tensorflow构建卷积神经网络

tensorflow构建卷积神经网络

tensorflow构建CNN[待学习]

全连接+各种优化[待学习]

BN层[待学习]

先解释以下MNIST数据集,训练数据集有55,000 条,即X为55,000 * 784的矩阵,那么Y为55,000 * 10的矩阵,每个图片是28像素*28像素,带有标签,Y为该图片的真实数字,即标签,每个图片10个数字,1所在位置代表图片类别。

Softmax模型

准确率92.3,读入时候将图片拉成一个向量。使用Adam梯度下降求答案。


  1. import tensorflow as tf
  2. import numpy as np
  3. from tensorflow.examples.tutorials.mnist import input_data
  4. #训练数据集有55,000 条,即X为55,000 * 784的矩阵,那么Y为55,000 * 10的矩阵
  5. #读数据,one_hot表示将矩阵处理为行向量,即28*28 => 1*784
  6. mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
  7. learning_rate = 0.01
  8. batch_size = 128
  9. n_epochs = 1000
  10. x = tf.placeholder(tf.float32, [None, 784]) #因为训练时跟测试时样本数量不一样,所以直接None
  11. #只是一个softmax分类器,初始化0就好了,默认训练variable.trainable=True的参数
  12. W = tf.Variable(tf.zeros([784, 10]))
  13. b = tf.Variable(tf.zeros([10]))
  14. #softmax 输出一个10*1的矩阵,代表每个值的概率分布
  15. y_hat = tf.nn.softmax(tf.matmul(x, W) + b)
  16. y = tf.placeholder(tf.float32, [None, 10])
  17. #交叉熵损失函数
  18. loss = tf.reduce_mean(-tf.reduce_sum(y * tf.log(y_hat)))
  19. #也可以调用内置函数
  20. #entropy = tf.nn.softmax_cross_entropy_with_logits(logits, Y) #第一个是测试输出的函数,第二个是样本类别真实值
  21. #loss = tf.reduce_mean(entropy) # computes the mean over examples in the batch
  22. #学习率为0.01 使用Adam梯度下降
  23. train = tf.train.AdamOptimizer(learning_rate).minimize(loss)
  24. correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_hat, 1)) # 测试样本只有一个1,看这个1的位置和预测的概率最大值是否一样
  25. accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 通过cast将布尔类型转化成float类型,每个值要么0要么1,求他的均值就是准确率
  26. with tf.Session() as sess:
  27. sess.run(tf.global_variables_initializer())
  28. for i in range(n_epochs):
  29. batch_x, batch_y = mnist.train.next_batch(batch_size) #获取批量样本
  30. sess.run(train, feed_dict={x: batch_x, y: batch_y}) #运行计算图
  31. print(sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))

全连接神经网络模型

2层隐藏层,激活函数为relu函数,分类函数为softmax函数,学习率采用指数下降法,基本初始学习率0.01,如果太大会只有9.8%的准确率,学习率衰减速度如果太快也会准确率下降(过拟合),dropout正则化不是很管用,会让准确率下降,只有keep_prob = 0.99才勉强准确率高点。如果一个隐藏层,准确率为93.45%,无论是学习率大了,过度正则化都会导致9.8%。学习率太低则90左右的准确率


  1. import tensorflow as tf
  2. import numpy as np
  3. from tensorflow.examples.tutorials.mnist import input_data
  4. # 训练数据集有55,000 条,即X为55,000 * 784的矩阵,那么Y为55,000 * 10的矩阵
  5. # 读数据,one_hot表示将矩阵处理为行向量,即28*28 => 1*784
  6. mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
  7. base_learning_rate = 0.01
  8. batch_size = 128
  9. n_epochs = 1000
  10. keep_prob = 1
  11. decay_steps = 2
  12. decay_rate = 0.99
  13. def add_layer(inputs, input_size, output_size, activation_function=None):
  14. W = tf.Variable(tf.random_normal([input_size, output_size]) * np.sqrt(1/input_size))
  15. b = tf.Variable(tf.zeros([1, output_size]) + 0.1)
  16. y_hat = tf.matmul(inputs, W) + b
  17. y_hat = tf.nn.dropout(y_hat, keep_prob=keep_prob) #dropout 自动除以了keep_prob
  18. if activation_function is None:
  19. outputs = y_hats
  20. else:
  21. outputs = activation_function(y_hat)
  22. return outputs
  23. x = tf.placeholder(tf.float32, [None, 784])
  24. y = tf.placeholder(tf.float32, [None, 10])
  25. layer1 = add_layer(x, 784, 100, activation_function=tf.nn.relu)
  26. layer2 = add_layer(layer1, 100, 10, activation_function=tf.nn.relu)
  27. y_hat = add_layer(layer2, 10, 10, tf.nn.softmax)
  28. #定义存储训练轮数的变量,这个变量不需要被训练
  29. global_step = tf.Variable(0, trainable=False)
  30. learning_rate = tf.train.exponential_decay(base_learning_rate, global_step, decay_steps, decay_rate)
  31. #base_learning_rate为基础学习率,global_step为当前迭代的次数
  32. #decay_steps为几步一下降
  33. #decay_rate为学习率衰减速度
  34. loss = tf.reduce_mean(-tf.reduce_sum(y*tf.log(y_hat)))
  35. train = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step=global_step) #会自增
  36. correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_hat, 1)) # 测试样本只有一个1,看这个1的位置和预测的概率最大值是否一样
  37. accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 通过cast将布尔类型转化成float类型,每个值要么0要么1,求他的均值就是准确率
  38. with tf.Session() as sess:
  39. sess.run(tf.global_variables_initializer())
  40. for i in range(n_epochs):
  41. batch_x, batch_y = mnist.train.next_batch(batch_size)
  42. sess.run(train, feed_dict={x: batch_x, y: batch_y})
  43. print(sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))

卷积网络模型(LENET)

思路

使用一个简单的CNN网络结构如下,括号里边表示tensor经过本层后的输出shape:

  • 输入层(28 * 28 * 1)
  • 卷积层1(28 * 28 * 32)
  • pooling层1(14 * 14 * 32)
  • 卷积层2(14 * 14 * 64)
  • pooling层2(7 * 7 * 64)
  • 全连接层(1 * 1024)
  • softmax层(10)

主要的函数说明:

卷积层: 
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

参数说明:
  • data_format:表示输入的格式,有两种分别为:“NHWC”和“NCHW”,默认为“NHWC”

  • input:输入是一个4维格式的(图像)数据,数据的 shape 由 data_format 决定:当 data_format 为“NHWC”输入数据的shape表示为[batch, in_height, in_width, in_channels],分别表示训练时一个batch的图片数量、图片高度、 图片宽度、 图像通道数。当 data_format 为“NHWC”输入数据的shape表示为[batch, in_channels, in_height, in_width]

  • filter:卷积核是一个4维格式的数据:shape表示为:[height,width,in_channels, out_channels],分别表示卷积核的高、宽、深度(与输入的in_channels应相同)、输出 feature map的个数(即卷积核的个数)。

  • strides:表示步长:一个长度为4的一维列表,每个元素跟data_format互相对应,表示在data_format每一维上的移动步长。当输入的默认格式为:“NHWC”,则 strides = [batch , in_height , in_width, in_channels]。其中 batch 和 in_channels 要求一定为1,即只能在一个样本的一个通道上的特征图上进行移动,in_height , in_width表示卷积核在特征图的高度和宽度上移动的布长,即  和  。

  • padding:表示填充方式:“SAME”表示采用填充的方式,简单地理解为以0填充边缘,当stride为1时,输入和输出的维度相同;“VALID”表示采用不填充的方式,多余地进行丢弃。具体公式:

    “SAME”:

    “VALID”:

池化层: 
tf.nn.max_pool( value, ksize,strides,padding,data_format=’NHWC’,name=None) 
或者 
tf.nn.avg_pool(…)

参数说明:
  • value:表示池化的输入:一个4维格式的数据,数据的 shape 由 data_format 决定,默认情况下shape 为[batch, height, width, channels]

  • 其他参数与 tf.nn.cov2d 类型

  • ksize:表示池化窗口的大小:一个长度为4的一维列表,一般为[1, height, width, 1],因不想在batch和channels上做池化,则将其值设为1。

Batch Nomalization层: 
batch_normalization( x,mean,variance,offset,scale, variance_epsilon,name=None)

  • mean 和 variance 通过 tf.nn.moments 来进行计算: 
    batch_mean, batch_var = tf.nn.moments(x, axes = [0, 1, 2], keep_dims=True),注意axes的输入。对于以feature map 为维度的全局归一化,若feature map 的shape 为[batch, height, width, depth],则将axes赋值为[0, 1, 2]

  • x 为输入的feature map 四维数据,offset、scale为一维Tensor数据,shape 等于 feature map 的深度depth。

注意,计算准确率的时候,一定让keep_prob等于1


  1. import tensorflow as tf
  2. import numpy as np
  3. #导入input_data用于自动下载和安装MNIST数据集
  4. from tensorflow.examples.tutorials.mnist import input_data
  5. mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
  6. #创建两个占位符,x为输入网络的图像,y_为输入网络的图像类别
  7. x = tf.placeholder("float", shape=[None, 784])
  8. y = tf.placeholder("float", shape=[None, 10])
  9. #权重初始化函数
  10. def weight_variable(shape):
  11. #输出服从截尾正态分布的随机值
  12. initial = tf.truncated_normal(shape, stddev=0.1)
  13. return tf.Variable(initial)
  14. #偏置初始化函数
  15. def bias_variable(shape):
  16. initial = tf.constant(0.1, shape=shape)
  17. return tf.Variable(initial)
  18. #创建卷积op
  19. #x 是一个4维张量,shape为[batch,height,width,channels]
  20. #卷积核移动步长为1。填充类型为SAME,可以不丢弃任何像素点
  21. def conv2d(x, W):
  22. return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding="SAME")
  23. #创建池化op
  24. #采用最大池化,也就是取窗口中的最大值作为结果
  25. #x 是一个4维张量,shape为[batch,height,width,channels]
  26. #ksize表示pool窗口大小为2x2,也就是高2,宽2
  27. #strides,表示在height和width维度上的步长都为2
  28. def max_pool_2x2(x):
  29. return tf.nn.max_pool(x, ksize=[1,2,2,1],
  30. strides=[1,2,2,1], padding="SAME")
  31. #第1层,卷积层
  32. #初始化W为[5,5,1,32]的张量,表示卷积核大小为5*5,第一层网络的输入和输出神经元个数分别为1和32
  33. W_conv1 = weight_variable([5,5,1,32])
  34. #初始化b为[32],即输出大小
  35. b_conv1 = bias_variable([32])
  36. #把输入x(二维张量,shape为[batch, 784])变成4d的x_image,x_image的shape应该是[batch,28,28,1]
  37. #-1表示自动推测这个维度的size
  38. x_image = tf.reshape(x, [-1,28,28,1])
  39. #把x_image和权重进行卷积,加上偏置项,然后应用ReLU激活函数,最后进行max_pooling
  40. #h_pool1的输出即为第一层网络输出,shape为[batch,14,14,1]
  41. h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
  42. h_pool1 = max_pool_2x2(h_conv1)
  43. #第2层,卷积层
  44. #卷积核大小依然是5*5,这层的输入和输出神经元个数为32和64
  45. W_conv2 = weight_variable([5,5,32,64])
  46. b_conv2 = weight_variable([64])
  47. #h_pool2即为第二层网络输出,shape为[batch,7,7,1]
  48. h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
  49. h_pool2 = max_pool_2x2(h_conv2)
  50. #第3层, 全连接层
  51. #这层是拥有1024个神经元的全连接层
  52. #W的第1维size为7*7*64,7*7是h_pool2输出的size,64是第2层输出神经元个数
  53. W_fc1 = weight_variable([7*7*64, 1024])
  54. b_fc1 = bias_variable([1024])
  55. #计算前需要把第2层的输出reshape成[batch, 7*7*64]的张量
  56. h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
  57. h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
  58. #Dropout层
  59. #为了减少过拟合,在输出层前加入dropout
  60. keep_prob = tf.placeholder("float")
  61. h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
  62. #输出层
  63. #最后,添加一个softmax层
  64. #可以理解为另一个全连接层,只不过输出时使用softmax将网络输出值转换成了概率
  65. W_fc2 = weight_variable([1024, 10])
  66. b_fc2 = bias_variable([10])
  67. y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
  68. #预测值和真实值之间的交叉墒
  69. cross_entropy = -tf.reduce_sum(y * tf.log(y_conv))
  70. #train op, 使用ADAM优化器来做梯度下降。学习率为0.0001
  71. train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  72. #评估模型,tf.argmax能给出某个tensor对象在某一维上数据最大值的索引。
  73. #因为标签是由0,1组成了one-hot vector,返回的索引就是数值为1的位置
  74. correct_predict = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y, 1))
  75. #计算正确预测项的比例,因为tf.equal返回的是布尔值,
  76. #使用tf.cast把布尔值转换成浮点数,然后用tf.reduce_mean求平均值
  77. accuracy = tf.reduce_mean(tf.cast(correct_predict, "float"))
  78. with tf.Session() as sess:
  79. # 初始化变量
  80. sess.run(tf.global_variables_initializer())
  81. # 开始训练模型,循环20000次,每次随机从训练集中抓取50幅图像
  82. for i in range(1000):
  83. batch = mnist.train.next_batch(50)
  84. if i % 100 == 0:
  85. # 每100次输出一次日志
  86. train_accuracy = accuracy.eval(feed_dict={
  87. x: batch[0], y: batch[1], keep_prob: 1.0}) #计算准确率时候一定让keep_prob等于1
  88. print("step %d, training accuracy %g" % (i, train_accuracy))
  89. train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})
  90. print(sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}))


【TensorFlow/简单网络】MNIST数据集-softmax、全连接神经网络,卷积神经网络模型的更多相关文章

  1. tensorflow中使用mnist数据集训练全连接神经网络-学习笔记

    tensorflow中使用mnist数据集训练全连接神经网络 ——学习曹健老师“人工智能实践:tensorflow笔记”的学习笔记, 感谢曹老师 前期准备:mnist数据集下载,并存入data目录: ...

  2. 深度学习tensorflow实战笔记(1)全连接神经网络(FCN)训练自己的数据(从txt文件中读取)

    1.准备数据 把数据放进txt文件中(数据量大的话,就写一段程序自己把数据自动的写入txt文件中,任何语言都能实现),数据之间用逗号隔开,最后一列标注数据的标签(用于分类),比如0,1.每一行表示一个 ...

  3. Tensorflow 多层全连接神经网络

    本节涉及: 身份证问题 单层网络的模型 多层全连接神经网络 激活函数 tanh 身份证问题新模型的代码实现 模型的优化 一.身份证问题 身份证号码是18位的数字[此处暂不考虑字母的情况],身份证倒数第 ...

  4. TensorFlow之DNN(二):全连接神经网络的加速技巧(Xavier初始化、Adam、Batch Norm、学习率衰减与梯度截断)

    在上一篇博客<TensorFlow之DNN(一):构建“裸机版”全连接神经网络>中,我整理了一个用TensorFlow实现的简单全连接神经网络模型,没有运用加速技巧(小批量梯度下降不算哦) ...

  5. TensorFlow之DNN(一):构建&OpenCurlyDoubleQuote;裸机版”全连接神经网络

    博客断更了一周,干啥去了?想做个聊天机器人出来,去看教程了,然后大受打击,哭着回来补TensorFlow和自然语言处理的基础了.本来如意算盘打得挺响,作为一个初学者,直接看项目(不是指MINIST手写 ...

  6. MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网络训练实现及比较(三)

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在前两篇文章MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网 ...

  7. tensorflow读取本地MNIST数据集

    tensorflow读取本地MNIST数据集 数据放入文件夹(不要解压gz): >>> import tensorflow as tf >>> from tenso ...

  8. 如何使用numpy实现一个全连接神经网络?(上)

    全连接神经网络的概念我就不介绍了,对这个不是很了解的朋友,可以移步其他博主的关于神经网络的文章,这里只介绍我使用基本工具实现全连接神经网络的方法. 所用工具: numpy == 1.16.4 matp ...

  9. 使用PyTorch简单实现卷积神经网络模型

    这里我们会用 Python 实现三个简单的卷积神经网络模型:LeNet .AlexNet .VGGNet,首先我们需要了解三大基础数据集:MNIST 数据集.Cifar 数据集和 ImageNet 数 ...

随机推荐

  1. Welcome to China

    subway, railway, highway ,way way to dieofficer,announcer, professor, sir sir to lieWelcome to China

  2. tomcat中配置jmx监控

    1.在tomcat的start.bat中添加下面代码, -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote. ...

  3. Android android&colon;gravity属性介绍及效果图

    转自: http://blog.csdn.net/aminfo/article/details/7784229 Android:gravity的属性官方说明如下: public static fina ...

  4. A Knight&&num;39&semi;s Journey&lowbar;DFS

    Description Background The knight is getting bored of seeing the same black and white squares again ...

  5. CodeForces-2015 HIAST Collegiate Programming Contest-Gym-100952A-Who is the winner&quest;

    A. Who is the winner? time limit per test 1 second memory limit per test 64 megabytes input standard ...

  6. Lambda表达式Contains方法&lpar;等价于SQL语句中的like&rpar;使用注意事项

    貌似已经半年多没写一篇帖子了,充分的说明要么老总一天折腾的让人心齐疲惫,没心情去写:要么另外一种可能就是自己不思进取,说白了就是懒.好在这种状态在今天被打破了.MoNey加油. 众所周知,想在Enti ...

  7. Java 代码需要使用转义符的地方

    1.正则表达式特殊字符 Java 代码中使用到正则表达式里的特殊字符需要使用转义符 \ 进行转义 . ? * + ! ^ $ [ ] ( ) \ 因为反斜线 \ 也是特殊字符,所以转义需双反斜线 \\ ...

  8. SQl server更新某阶段的匹配关系。

    DECLARE @count INTEGERDECLARE @id INTEGERDECLARE @subjectID INTEGERSET @count=1SET @id =11894SET @su ...

  9. Java并发编程:什么是线程安全,以及并发必须知道的几个概念

    废话 众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试的必问题,一个好的Java程序员是必须对并发编程这块有所了解的.为了追求成为一个好的Java程序员,我决定从今天开始死磕Jav ...

  10. influxdb简单使用

    之前对influxdb有一个简单的了解和入门的使用,近期由于想使用influxdb做一点东西玩玩,又要捡起influxdb.本篇就针对influxdb的数据库.表的概念,增删改查操作.RESTful操 ...