在MNIST数据集上构建LeNet
机器学习相关术语
epoch、batch size、iteration:
假设数据集样本为4096,分成batch size=256,那进行1个epoch需要16次iteration。
TensorFlow常见函数
参考链接:
http://www.tensorfly.cn/tfdoc/api_docs/python/array_ops.html
https://blog.csdn.net/weixin_42247762/article/details/80459102
tf.shape(Tensor) # 返回tensor的形状 类型也是一个tensor
tf.Variable(initializer, name=None) # 初始化一个tensor
tf.reshape(tensor, shape, name=None)
tf.random_normal(shape, mean, stddev, dtype, seed=None, name=None) # 生成正太分布随机数的tensor
tf.matmul(a, b) # 矩阵乘法
有的函数返回一个tensor。用sess.run(Tensor)来得到具体的值。
sess = tf.InteractiveSession()
print(sess.run(tensor))
关于tf.placefolder()和feed_dict
参考:https://www.jianshu.com/p/ec261a65e3c9
TensorFlow首先构筑整个系统的graph,代码并不会直接生效。在实际的运行时,启动一个session,程序才会真正的运行。
TensorFlow构建卷积层
tf.nn.conv2d(
input, # 数据张量的形状[batch_size, input_height, input_width, input_depth]
filter, # 核张量的形状[filter_height, filter_width, input_depth, output_depth]
strides, # 步长
padding, # 填充 可取VALID和SAME
use_cudnn_on_gpu = None,
data_format = None,
name = None
)
关于padding参数
假设矩阵height = width。
padding = ‘VALID’
new_height = new_width = (W – F + 1) / S (结果向上取整)
最后得到特征图和输入尺寸,步长也和卷积核的大小都是有关系的。
padding = ‘SAME’
new_height = new_width = W / S (结果向上取整)
最后得到的特征图和卷积核大小无关,用0填充。
构建LeNet
fork了GitHub上的代码:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/tutorials/mnist
首先建立数据集
#将MNIST数据集分为训练集和测试集(tf自带下载数据集模块,需fq)
import os
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(os.path.join('.', 'mnist'), one_hot=True)
X_train = mnist.train.images
X_test = mnist.test.images
Y_train = mnist.train.labels
Y_test = mnist.test.labels
然后定义超参数
# 超参数
n_classes = 10 # 10种数字分类
n_width = 28
n_height = 28
n_depth = 1
n_inputs = n_height * n_width * n_depth # 总像素
learning_rate = 0.001
n_epochs = 10
batch_size = 100
n_batches = int(mnist.train.num_examples/batch_size)
# 输入图像形状(n_samples, n_pixels)
x = tf.placeholder(dtype = tf.float32, name = "x", shape = [None, n_inputs])
#转换输入x的形状(n_samples, n_width, n_height, n_depth)
x_ = tf.reshape(x, shape = [-1, n_width, n_height, n_depth])
# 输出标签
y = tf.placeholder(dtype = tf.float32, name = "y", shape = [None, n_inputs])
两个卷积层和池化层
##第一层
###权重和偏差
layer1_w = tf.Variable(tf.random_normal(shape = [4, 4, n_depth, 32],
stddev = 0.1), name = 'l1_w')
layer1_b = tf.Variable(tf.random_normal([32]), name = 'l1_b')
###卷积层 32个4*4的卷积核 产生32个28*28*1的特征图
layer1_conv = tf.nn.relu(tf.nn.conv2d(x_, layer1_w,
strides = [1, 1, 1, 1],
padding = 'SAME'
) + layer1_b)
###池化层 池化成32个14*14*1的特征图
layer1_pool = tf.nn.max_pool(layer1_conv, ksize = [1, 2, 2, 1],
strides = [1, 2, 2, 1], padding = 'SAME')
##第二层
###权重和偏差
layer2_w = tf.Variable(tf.random_normal(shape = [4, 4, 32, 64],
stddev = 0.1), name = 'l2_w')
layer2_b = tf.Variable(tf.random_normal([64]), name = 'l2_b')
###卷积层 生成64个14*14*1的特征图
layer2_conv = tf.nn.relu(tf.nn.conv2d(layer1_pool, layer2_w,
strides = [1, 1, 1, 1],
padding = 'SAME'
) + layer2_b)
###池化层 池化成64个7*7*1的特征图
layer2_pool = tf.nn.max_pool(layer2_conv, ksize = [1, 2, 2, 1],
strides = [1, 2, 2, 1], padding = 'SAME')
全连接层和输出层
##全连接层。1024个神经元 拉伸(flat)成大小为1024的tensor
layer3_w = tf.Variable(tf.random_normal(shape = [64*7*7*1, 1024],
stddev = 0.1), name = 'l3_w')
layer3_b = tf.Variable(tf.random_normal([1024]), name = 'l3_b')
layer3_fc = tf.nn.relu(tf.matmul(tf.reshape(layer2_pool,
[-1, 64*7*7*1]), layer3_w) + layer3_b)
##输出层。10个分类。没有使用softmax
layer4_w = tf.Variable(tf.random_normal(shape = [1024, n_classes],
stddev = 0.1), name = 'l4_w')
layer4_b = tf.Variable(tf.random_normal([n_classes]), name = 'l4_b')
layer4_out = tf.matmul(layer3_fc, layer4_w) + layer4_b
#将模型保存在model中
model = layer4_out
损失函数和优化器
#损失函数和优化器
entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits = model, labels = y)
loss = tf.reduce_mean(entropy)
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)
网友评论