卷积层:定义过滤器(观察窗口)大小,观察窗口里面装的是权重矩阵
观察窗口移动的步长一般为1
当多个窗口去观察时,各窗口的shape要相同
当窗口移动到图片的边界时:1.不越过去,提前一步停止观察 VALID
2.直接越过去,用零填充,超出部分填上0(0*权重=0,所以没影响) SAME
彩色图片:多通道图片(R G B ,各一张表,所以一个观察窗口也有3张表):
这是一个窗口3张表(权重),上面那一个窗口就一张表。卷积层计算公式中观察窗口Filter大小 :F指的是边长,即55的图边长就是5
在卷积网络API中:
input: [batch, heigth, width, channel] 第一个参数表示图片数,最后一个参数为1(黑白)或者3(彩色)
filter: 过滤器大小 [filter_height, filter_width, in_channels, out_channels] in_表示输入图片的通道,out_有多少个过滤器
strides:步长
这里把每一块的最大值用来代替这一块
经过卷积后有个激活函数,这个激活函数用来增加网络非线性分割能力
池化层窗口每次取22大小,步长为2,在这一层中一个窗口内观察到一个2*2的数据块,用这个块内最大的数值代替这个块
我们一般在小图片上用自己设计的cnn,彩色大图片多类别的用api
卷积神经网络设计流程:
原始[None, 784] 最后有10个类别[None, 10]
一层卷积: 卷积:32个filter(窗口),5*5 大小,strides=1, padding=“SAME”, (卷积层的SAME使得输入输出图片大小相同) bias=32
输入:[None, 28, 28, 1], 按要求写成4维
输出:[None, 28, 28, 32] 因为有32个窗口
激活:在这里数据的shape不发生改变
池化:2*2的窗口大小, strides=2, padding="SAME", 这里SAME不保证图像shape不会改变
[None, 28, 28, 32] 变成[None, 14, 14, 32]
二层卷积: 卷积:64个窗口,5*5大小,strides=1, padding=“SAME” bias=64
输入:[None, 14,14,32], 输出:[None, 14,14,64]
激活:shape不变
池化;窗口大小2*2, strides=2, 输入[none ,14, 14, 64], 输出:[ none ,7, 7, 64]
全连接层: 要把[None, 7,7,64], 变成 [None, 10] ,这里bias=10
先把[None, 7,7,64] 变成[none, 7764]
[NOne, 7*7*64] * [7*7*64, 10] = [None, 10]
eg:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
‘’’
首先因为一个CNN会用到很多权重和偏置的定义,
所以我们直接在开头定义初始化权重和偏置的函数
‘’’
def weight_variable(shape):
w=tf.Variable(tf.random_normal(shape=shape, mean=0.0, stddev=1.0))
return w
def bias_variable(shape):
b=tf.Variable(tf.constant(0.0, shape=shape))
return b
#开始定义模型
def model():
#1.因为训练都是实时传入数据,所以我们需要占位符!
#[-1,784], y_true [-1,10]
with tf.variable_scope("data"):
x=tf.placeholder(tf.float32, [-1,784])
y_true=tf.placeholder(tf.int32, [-1,10])
#2.一层卷积,激活,池化
with tf.variable_scope("conv1"):
#随机初始化权重
w_conv1=weight_variable([5,5,1,32])
b_conv1=bias_variable([32])
#对x进行形状的改变,-1指的是不确定
x_reshape=tf.reshape(x, [-1, 28, 28, 1])
#激活,注意strides参数,只得是上下左右步数
x_relu1=tf.nn.relu(tf.nn.conv2d(x_reshape, w_conv1, strides=[1,1,1,1],padding="SAME")+b_conv1)
#池化
x_pool1=tf.nn.max_pool(x_relu1, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
#3.二层卷积
with tf.variable_scope("conv2"):
#随机初始化权重
w_conv2=weight_variable([5,5,32,64])
b_conv2=bias_variable([64])
#激活,注意strides参数,只得是上下左右步数
x_relu2=tf.nn.relu(tf.nn.conv2d(x_pool1, w_conv2, strides=[1,1,1,1],padding="SAME")+b_conv2)
#池化
x_pool2=tf.nn.max_pool(x_relu2, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
#4.全连接层
#随机初始化权重和偏置
w_fc=weight_variable([7*7*64,10])
b_fc=bias_variable([10])
#修改形状 [-1,7,7,64]变成[-1,7*7*64]
x_fc_reshape=tf.reshape(x_pool2,[-1,7*7*64])
#进行矩阵运算得出每个样本的10个结果
y_predict=tf.matmul(x_fc_reshape, w_fc)+b_fc
return x,y,y_predict
#模型定义完了,我们现在使用模型开始训练
def conv_fc():
#获取真实数据
mnist=input_data.read_data_sets("./data/mnist...", one_hot=True)
#调用模型
x,y_true,y_predict=model()
#进行交叉熵损失计算
with tf.variable_scope("soft_cross"):
#求平均交叉熵损失
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#梯度下降,求出损失
with tf.variable_scope("optimizer"):
train_op=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#计算准确率
with tf.variable_scope("acc"):
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#定义一个初始化变量op
init_op=tf.global_variables_initializer()
#开启会话运行
with tf.Session() as sess:
sess.run(init_op)
#开始循环训练
for i in range(1000):
#取出真实存在的特征值和目标值
mnist_x,mnist_y=mnist.train.next_batch(50)
#运行train_op训练
sess.run(train_op,feed_dict={x:mnist_x,y_true:mnist_y})
print("训练第%d步,准确率为:%f" %(i,sess.run(accury,feed_dict={x:mnist_x,y_true:mnist_y})))
if name == “main”:
conv_fc()
#这里会发现准确率来回波动,这是学习率有问题,要把学习率调小