目录
1. 定义网络输入:N 个 32x32 的 1 通道图像数据
CNN 实现基本设计模式: 划分三个阶段
1. 定义网络输入:占位符定义输入变量
2. 逐层定义网络各个功能层:
- 确定每层的网络参数变量
- 定义功能层相关操作
3. 定义网络输出:设计和预测类型匹配的输出函数
1. 定义网络输入:N 个 32x32 的 1 通道图像数据
-
对于需要传递给网络的变量,采用占位符 placeholder 来定义
-
x = tf.placeholder(tf.float32, (None, 32, 32, 1))
2. 逐层定义网络各个功能层
2.1 LeNet-5 第一个卷积层:6 个 5x5 的 1 通道卷积核
- conv1_W = tf.Variable(tf.truncated_normal(shape=(5, 5, 1, 6), mean = mu, stddev = sigma)) (卷积核参数变量)
- conv1_b = tf.Variable(tf.zeros(6)) (卷积偏置参数变量)
- conv1 = tf.nn.conv2d(x, conv1_W, strides=[1, 1, 1, 1], padding= ‘VALID’) + conv1_b (采用卷积核 conv1_W 与偏置 conv1_b 连接输 入 x 的卷积操作)
2.2 LeNet-5 第一个卷层之后的激活层和池化层:
- conv1 = tf.nn.relu(conv1) (Relu 非线性激活)
- conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=’VALID’) 积层之后的激活层及池化层:
- 池化核的大小为 1x2x2x1(图像序列 x 高 x 宽 x 通道序列),步长只 设定在“高”和“宽”的维度为 2
2.3 LeNet-5 第二个卷积层:16 个 5x5 的 6 通道卷积核(因为之前 的输出为 6 个通道)
- conv2_W = tf.Variable(tf.truncated_normal(shape=(5, 5, 6, 16), mean = mu, stddev = sigma)) (卷积核参数变量)
- conv2_b = tf.Variable(tf.zeros(16)) (卷积偏置参数变量)
- conv2 = tf.nn.conv2d(conv1, conv1_W, strides=[1, 1, 1, 1], padding= ‘VALID’) + conv2_b (采用卷积核 conv1_W 与偏置 conv1_b 连接上 一层 conv1 结果的卷积操作)
2.4 LeNet-5 第二个卷层之后的激活层和池化层:
- conv2 = tf.nn.relu(conv2) (Relu 非线性激活)
- conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding=’VALID’) 积层之后的激活层及池化层:
- 池化核的大小为 1x2x2x1(图像序列 x 高 x 宽 x 通道序列),步长只 设定在“高”和“宽”的维度为 2。
2.5 LeNet-5 第二个池化层到第一个全连接层的向量化:
- 把 2 维的 conv2 输出“压平”为 1 维的全连接输入:
- 输入维度由 Nx5x5x16 压平后变为 Nx400
- fc0 = flatten(conv2)
2.6 LeNet-5 第一个全连接层:
- fc1_W = tf.Variable(tf.truncated_normal(shape=(400, 120), mean = mu, stddev = sigma))
- (从维度 400 映射为 200 的全连接参数变量)
- fc1_b = tf.Variable(tf.zeros(120)) (偏置变量)
- fc1 = tf.matmul(fc0, fc1_W) + fc1_b (全连接操作既输入和全连接参数 的矩阵乘加偏置操作)
- fc1 = tf.nn.relu(fc1) (Relu 非线性激活)
2.7 LeNet-5 第二个全连接层:
- fc2_W = tf.Variable(tf.truncated_normal(shape=(120, 84), mean = mu, stddev = sigma))
- (从维度 120 映射为 84 的全连接参数变量)
- fc2_b = tf.Variable(tf.zeros(84)) (偏置变量)
- fc2 = tf.matmul(fc1, fc2_W) + fc2_b (全连接操作既输入和全连接参数 的矩阵乘加偏置操作)
- fc2 = tf.nn.relu(fc2) (Relu 非线性激活)
2.8 LeNet-5 第三个全连接层:
- fc3_W = tf.Variable(tf.truncated_normal(shape=(84, 10), mean = mu, stddev = sigma))
- (从维度 84 映射为 10 的全连接参数变量)
- fc3_b = tf.Variable(tf.zeros(10)) (偏置变量)
- logits = tf.matmul(fc2, fc3_W) + fc3_b (全连接操作既输入和全连接参 数的矩阵乘加偏置操作, logits 作为最后的网络概率输出,不进行激 活操作)
定义网络输出
- 之前定义的网络最后被封装为 LeNet(x) 函数,x 为图像数据输入
- 对于分类 0-9 数字图像的网络,最后输出 logits 设计为 10 位,每一 位对应一个数字的预测概率。
- logits = LeNet(x)
- 采用最大输出位的序列号作为预测数字编号,则预测类型标签:
- y_prediction=tf.argmax(logits, 1)
Lenet 结构定义完整代码
import tensorflow as tf
def LeNet(x):
# Arguments used for tf.truncated_normal , randomly defines variables for the weights and biases for each layer
mu = 0
sigma = 0.1
'''
Layer 1
'''
# SOLUTION: Layer 1: Convolutional. Input = 32x32x1. Output = 28x28x6.
conv1_W = tf.Variable(tf.truncated_normal(shape=(5, 5, 1, 6), mean=mu, stddev=sigma), name="conv1_W")
conv1_b = tf.Variable(tf.zeros(6))
conv1 = tf.nn.conv2d(x, conv1_W, strides=[1, 1, 1, 1], padding='VALID') + conv1_b
# SOLUTION: Activation.
conv1 = tf.nn.relu(conv1)
# SOLUTION: Pooling. Input = 28x28x6. Output = 14x14x6.
conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
'''
Layer 2
'''
# SOLUTION: Layer 2: Convolutional. Output = 10x10x16.
conv2_W = tf.Variable(tf.truncated_normal(shape=(5, 5, 6, 16), mean=mu, stddev=sigma))
conv2_b = tf.Variable(tf.zeros(16))
conv2 = tf.nn.conv2d(conv1, conv2_W, strides=[1, 1, 1, 1], padding='VALID') + conv2_b
# SOLUTION: Activation.
conv2 = tf.nn.relu(conv2)
# SOLUTION: Pooling. Input = 10x10x16. Output = 5x5x16.
conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
'''
full connection
'''
# SOLUTION: Flatten. Input = 5x5x16. Output = 400. 压平
fc0 = flatten(conv2)
'''
fc1
'''
# SOLUTION: Layer 3: Fully Connected. Input = 400. Output = 120.
fc1_W = tf.Variable(tf.truncated_normal(shape=(400, 120), mean=mu, stddev=sigma))
fc1_b = tf.Variable(tf.zeros(120))
fc1 = tf.matmul(fc0, fc1_W) + fc1_b
# SOLUTION: Activation.
fc1 = tf.nn.relu(fc1)
'''
fc2
'''
# SOLUTION: Layer 4: Fully Connected. Input = 120. Output = 84.
fc2_W = tf.Variable(tf.truncated_normal(shape=(120, 84), mean=mu, stddev=sigma))
fc2_b = tf.Variable(tf.zeros(84))
fc2 = tf.matmul(fc1, fc2_W) + fc2_b
# SOLUTION: Activation.
fc2 = tf.nn.relu(fc2)
'''
fc3
'''
# SOLUTION: Layer 5: Fully Connected. Input = 84. Output = 10.
fc3_W = tf.Variable(tf.truncated_normal(shape=(84, 10), mean=mu, stddev=sigma))
fc3_b = tf.Variable(tf.zeros(10))
logits = tf.matmul(fc2, fc3_W) + fc3_b
return logits