mnist-tensorflow 类lenet5(32-64-128-10)理解(train函数)

近期需要学习下tensorflow下的,minist字符识别,利用lenet5结构:

整个设计如下:

基础知识:with tf.variable_scope():和 tf.get_variable()对应:scope定义了 如下 get的作用域,当超过这个作用域后,w和b不起作用,所以下面第二次可以重新定义新的w和b,

注意  这个scope下如果要重复使用w和b这些自定义的变量,需要增加 如下实例:

 

def my_image_filter(input_images):

    with tf.variable_scope("conv1"):

        # Variables created here will be named "conv1/weights", "conv1/biases".

        relu1 = conv_relu(input_images, [553232], [32])

    with tf.variable_scope("conv2"):

        # Variables created here will be named "conv2/weights", "conv2/biases".

        return conv_relu(relu1, [553232], [32])

with tf.variable_scope('layer——conv1') as scope:

 result1 = my_image_filter(image1)

 scope.reuse_variables()

等价于#with tf.variable_scope('layer——conv1',reuse=True):

 result2 = my_image_filter(image2)

      上述,reuse——variables的功能是可以重复利用第一次利用的权重值,

另外try: catch的用法为 try:except:

如下实现:  5*5*64卷积  最大池化 5*5*32 卷积 最大池化  全连接(L2正则化 dropout)128 全连接 10(L2正则化)输出10个类别:

mnist_inference 实现如下:
import tensorflow as tf
INPUT_NODE = 784
OUTPUT_NODE = 10
IMAGE_SIZE = 28
NUM_CHANNEL = 1
NUM_LABEL = 10

# LAYER1
CONV1_DEEP = 32
CONV1_SIZE = 5

# LAYER2
CONV2_DEEP = 64
CONV2_SIZE = 5

# 全连接层
FC_SIZE = 512
def inference(input_tensor,train,regularizer):
    with tf.variable_scope('layer1-conv'):#注意此处tf.variable_scope表示这个作用域下定义了 w b(使用了get——variable)


        w = tf.get_variable('w', [CONV1_SIZE,CONV1_SIZE,NUM_CHANNEL,CONV1_DEEP],
                            initializer=tf.truncated_normal_initializer(stddev=0.1))#定义权重矩阵为 5*5*单通道*32 初始化为均值0 标准差0.1
        b = tf.get_variable('b',shape=[CONV1_DEEP],initializer=tf.constant_initializer(0.0))#初始化偏置为0
        # filter shape is :[filter_height, filter_width, in_channels, out_channels]
        # input tensor shape is:[batch, in_height, in_width, in_channels]
        # `strides = [1, stride, stride, 1].
        # return [batch, height, width, channels].
        conv1 = tf.nn.conv2d(input_tensor,w,strides=[1,1,1,1],padding='SAME')  #此处 input tensor 输入和filter卷积 运算,padding为same 插值为same后走到最后卷积完成,故outsize=(inputsize)/stride
        #而 padding为  VALID 为表示只取有效位置,故会体积变小 outputsize = (inputwidth-filtersize+1)/stride
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1,b))# 激活函数用relu
with tf.variable_scope('layer2-pool'):
    pool1 = tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')# 利用 2*2 步长 做最大池化
with tf.variable_scope('layer3-conv'):
    w = tf.get_variable('w', [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],
                        initializer=tf.truncated_normal_initializer(stddev=0.1))
    b = tf.get_variable('b',shape=[CONV2_DEEP],initializer=tf.constant_initializer(0.0))

    conv2 = tf.nn.conv2d(pool1, w, strides=[1, 1, 1, 1], padding='SAME')
    relu2 = tf.nn.relu(tf.nn.bias_add(conv2, b))

with tf.variable_scope('layer4-pool'):
    # pool2 size is [batch_size,7,7,64]
    pool2 = tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
# 接下来是全连接层,需要将pool2转换为一维向量,作为后面的输入
pool_shape = pool2.get_shape().as_list()#这里通过获取getshape的tensorshape转化为list,注意此时为3维 list,分别为

nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]# 注意 这个shape 大小转化为list后 是 batch height with channel,故1 2 3 这个三个值表示一个nodes大小

reshaped = tf.reshape(pool2,[-1,nodes])
# reshaped = tf.reshape(pool2,[BATCH_SIZE,-1])
# print(reshaped.get_shape())
with tf.variable_scope('layer5-fc1'):
    fc1_w = tf.get_variable('w',shape=[nodes,FC_SIZE],initializer=tf.truncated_normal_initializer(stddev=0.1))
    try:
        # 只有全连接层的权重需要加入正则化,因为全连接层 计算量和连接超多,需要加入正则,防止过拟合,注意先加入正则化后再使用
        #加入正则化后可以使结构化风险更小,l1正则更容易减到0,L2正则化更平滑
        if regularizer != None:
            tf.add_to_collection('loss',regularizer(fc1_w))#tf.add_to_collection 经过正则化后的数据组成列表 tf.get_collection 获取集合列表,tf.add_n 把列表中的东西都依次加起来
    except:
        pass
    fc1_b = tf.get_variable('b',shape=[FC_SIZE],initializer=tf.constant_initializer(0.1))
    #此处没有conv2d 因为 全连接可以利用 矩阵x
    fc1 = tf.nn.relu(tf.matmul(reshaped,fc1_w) + fc1_b)
    # 使用Dropout随机将部分节点的输出改为0,为了防止过拟合的现象,从而使模型在测试数据中表现更好。
    # dropout一般只会在全连接层使用。
    if train:
        fc1 = tf.nn.dropout(fc1,0.5)

with tf.variable_scope('layer6-fc2'):
    fc2_w = tf.get_variable('w', shape=[FC_SIZE, NUM_LABEL], initializer=tf.truncated_normal_initializer(stddev=0.1))
    try:
        if regularizer != None:
            tf.add_to_collection('loss', regularizer(fc2_w))
    except:
        pass
    fc2_b = tf.get_variable('b', shape=[NUM_LABEL], initializer=tf.constant_initializer(0.1))
    # 最后一层的输出,不需要加入激活函数
    logit = tf.matmul(fc1, fc2_w) + fc2_b

return logit

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值