详细:tensorflow构建神经网络基础概念和梳理

1#: placeholder
x = tf.compat.v1.placeholder(tf.float32, shape=[None, w, h, c], name='x')
y_ = tf.compat.v1.placeholder(tf.int32, shape=[None, ], name='y_')

placeholder函数定义如下:

tf.placeholder(dtype, shape=None, name=None),placeholder是占位符,在tensorflow中类似于函数参数,运行时必须传入值。

  • dtype:数据类型。常用的是tf.float32,tf.float64等数值类型。

  • shape:数据形状。默认是None,就是一维值,也可以是多维,比如[2,3], [None, 3]表示列是3,行不定, 此参数可以根据提供的数据推导得到,不一定要给出。。

  • name:名称, 比如常在上边的x, y_。

  • 比如计算3*4=12
    
    import tensorflow as tf
    import numpy as np
    input1 = tf.placeholder(tf.float32)
    input2 = tf.placeholder(tf.float32)
    output = tf.multiply(input1, input2)
    with tf.Session() as sess:
        print sess.run(output, feed_dict = {input1:[3.], input2: [4.]})
    计算矩阵相乘x*y
    
    import tensorflow as tf
    import numpy as np
    x = tf.placeholder(tf.float32, shape=(1024, 1024))
    y = tf.matmul(x, x)
    with tf.Session() as sess:
    #  print(sess.run(y))  # ERROR: x is none now
      rand_array = np.random.rand(1024, 1024)
      print(sess.run(y, feed_dict={x: rand_array}))  # Will succeed.
    使用库函数进行矩阵运算
    
    import tensorflow as tf
    # 定义placeholder
    input1 = tf.placeholder(tf.float32,shape=(1, 2),name="input-1")
    input2 = tf.placeholder(tf.float32,shape=(2, 1),name="input-2")
    # 定义矩阵乘法运算(注意区分matmul和multiply的区别:matmul是矩阵乘法,multiply是点乘)
    output = tf.matmul(input1, input2)
    # 通过session执行乘法运行
    with tf.Session() as sess:
        # 执行时要传入placeholder的值
        print sess.run(output, feed_dict = {input1:[1,2], input2:[3,4]})
        # 最终执行结果 [11]

    2#:卷积和池化

  • 卷积层
    
    tf.nn.conv2d(input, filter, strides=, padding=, name=None)
    计算给定4-D input和filter张量的2维卷积
    	* 
    input:给定的输入张量,具有[batch, heigth, width, channel],类型为float32, 64
    	* 
    filter:指定过滤器的大小,[filter_height, filter_width, in_channels, out_channels]. out_channels:窗口数量
    	* 
    strides:strides = [1, stride, stride, 1],步长
    	* 
    padding:“SAME”, “VALID”,使用的填充算法的类型,使用“SAME”。其中”VALID”表示滑动超出部分舍弃,“SAME”表示填充,使得变化后height, width一样大
    
    
    新的激活函数-Reluf(x) = max(0, x)
    tf.nn.relu(features, name=None)
    features: 卷积后加上偏置的结果
    return: 结果
    	1. 
    采用sigmoid等函数,反向传播求误差梯度时,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多
    
    
    	1. 
    对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(求不出权重和偏置)
    
    

    池化层(Pooling)计算

  • Pooling层主要的作用是特征提取,通过去掉Feature Map中不重要的样本,(这里如何确定什么参数不重要是个很难的问题,哪些样本不重要,这个是很不好判断的,)进一步减少参数数量。Pooling的方法很多,最常用的是Max Pooling。
    
    
    tf.nn.max_pool(value, ksize=, strides=, padding=,name=None)
    
    输入上执行最大池数
    	* 
    value: 4-D Tensor形状[batch, height, width, channels]
    	* 
    ksize: 池化窗口大小,[1, ksize, ksize, 1]
    	* 
    strides:步长大小,[1, strides, strides, 1]
    	* 
    padding: “SAME”, “VALID”,使用的填充算法的类型,使用“SAME”
    
    

    Full Connected层(全连接层)

  • 前面的卷积和池化相当于做特征工程,后面的全连接相当于做特征加权。最后的全连接层在整个卷积神经网络中起到“分类器”的作用。

    函数的作用是将tensor变换为参数shape的形式。

    其中shape为一个列表形式,特殊的一点是列表中可以存在-1。-1代表的含义是不用我们自己指定这一维的大小,函数会自动计算,但列表中只能存在一个-1。(当然如果存在多个-1,就是一个存在多解的方程了)

  • import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 输入层# 准备占位符with tf.variable_scope('data'):
        x = tf.placeholder(tf.float32, [None, 784])
        y_true = tf.placeholder(tf.float32, [None, 10])
    
    # 卷积层# 卷积1with tf.variable_scope('conv1'):
        # 初始化权重 窗口3*3  步长1  32个窗口
        weight1 = tf.Variable(tf.random_normal(shape=[3, 3, 1, 32]))
        bias1 = tf.Variable(tf.constant(1.0, shape=[32]))
        x_reshaped = tf.reshape(x, [-1, 28, 28, 1])
        # x [None, 28, 28, 1] ----> [None, 28, 28, 32]
        conved1 = tf.nn.conv2d(input=x_reshaped, filter=weight1, strides=[1, 1, 1, 1], padding='SAME')
        print(conved1)
        relu1 = tf.nn.relu(conved1) + bias1
        print(relu1)# 池化1with tf.variable_scope('pool'):
        # 窗口2*2  步长2     x [None, 28, 28, 32] ----> [None, 14, 14, 32]
        pool1 = tf.nn.max_pool(value=relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        print(pool1)
    
    # 卷积2with tf.variable_scope('conv2'):
        # 窗口3*3  步长1   64个窗口
        weight2 = tf.Variable(tf.random_normal([3, 3, 32, 64]))
        bias2 = tf.Variable(tf.constant(1.0, shape=[64]))
        # x [None, 14, 14, 32] ----> [None, 14, 14, 64]
        conved2 = tf.nn.conv2d(input=pool1, filter=weight2, strides=[1, 1, 1, 1], padding='SAME')
        print(conved2)
        relu2 = tf.nn.relu(conved2) + bias2
    
    # 池化2with tf.variable_scope('pool2'):
        # 窗口2*2  步长2     x [None, 14, 14, 64] ----> [None, 7, 7, 64]
        pool2 = tf.nn.max_pool(value=relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    
    # 全连接层  x[None, 7, 7, 64] -> x[None, 7*7*64] * ([7*7*64, 10]) ----> y[None, 10]with tf.variable_scope('full_coon'):
        x_fc = tf.reshape(pool2, [-1, 7*7*64])
        weight_fc = tf.Variable(tf.random_normal([7*7*64, 10]))
        bias_fc = tf.Variable(tf.constant(1.0, shape=[10]))
        y_predict = tf.matmul(x_fc, weight_fc) + bias_fc
    
    # 交叉熵损失函数with tf.variable_scope('loss'):
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))
        train_op = tf.train.GradientDescentOptimizer(0.001).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))
    
    init_var = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        sess.run(init_var)
        mnist = input_data.read_data_sets('./input_data', one_hot=True)
        for i in range(1000):
            image, label = mnist.train.next_batch(100)
            sess.run(train_op, feed_dict={x: image, y_true: label})
            print('第%s步,准确率为: %s' % (i, sess.run(accuracy, feed_dict={x: image, y_true: label})))
    一个模型例子:::
    
    def model(input_tensor, train,
              regularizer):  
        with tf.variable_scope('layer1-conv1'):  # 定义一个作用域:layer1-conv1,在该作用域下面可以定义相同名称的变量(用于变量)
            conv1_weights = tf.get_variable("weight", [5, 5, 3, 32],
                                            initializer=tf.truncated_normal_initializer(stddev=0.1))
            # 定义变量权重:weight,名称是weight;5,5代表卷积核的大小,3代表输入的信道数目,32代表输出的信道数目;initializer代表神经网络权重和卷积核的推荐初始值,生成截断正态分布随机数,服从标准差为0.1
            conv1_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
            # 定义变量偏置:bias,名称bias,[32]代表当前层的深度;initializer代表偏置的初始化,用函数tf.constant_initializer将其初始化为0,也可以初始化为tf.zeros_initializer或者tf.ones_initializer
            conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
            # 上面为定义卷积层:input_tensor为当前层的节点矩阵;conv1_weights代表卷积层的权重;strides为不同方向上面的步长;padding标识填充,有两种方式,SAME表示用0填充,“VALID”表示不填充。
            relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))  # 定义激活函数:利用bias_add给每个节点都加上偏置项,然后利用relu函数去线性化
        with tf.name_scope("layer2-pool1"):  # 定义一个:layer2-pool1(用于op)
            # 池化层可以优先缩小矩阵的尺寸,从而减小最后全连接层当中的参数;池化层既可以加快计算速度,也可以防止过拟合。
            pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="VALID")
            # ksize代表pool窗口的尺寸,首尾两个数必须是1,ksize最常用[1,2,2,1]和[1,3,3,1];strides代表filter的步长,首尾两个数必须为1;padding代表填充方式;
        with tf.variable_scope("layer3-conv2"):  # 定义作用域(用于变量)
            # 定义权重
            conv2_weights = tf.get_variable("weight", [5, 5, 32, 64],
                                            initializer=tf.truncated_normal_initializer(stddev=0.1))
            conv2_biases = tf.get_variable("bias", [64], initializer=tf.constant_initializer(0.0))  # 定义偏置
            conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')  # 定义卷积层
            relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))  # 定义激活函数
        with tf.name_scope("layer4-pool2"):  # 定义命名空间(用于op)
            pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')  # 定义池化层
        with tf.variable_scope("layer5-conv3"):  # 定义作用域 (用于变量)
            # 定义权重
            conv3_weights = tf.get_variable("weight", [3, 3, 64, 128],
                                            initializer=tf.truncated_normal_initializer(stddev=0.1))
            conv3_biases = tf.get_variable("bias", [128], initializer=tf.constant_initializer(0.0))  # 定义偏置
            conv3 = tf.nn.conv2d(pool2, conv3_weights, strides=[1, 1, 1, 1], padding='SAME')  # 定义卷积层
            relu3 = tf.nn.relu(tf.nn.bias_add(conv3, conv3_biases))  # 定义激活函数
        with tf.name_scope("layer6-pool3"):  # 定义命名空间(用于op)
            pool3 = tf.nn.max_pool(relu3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')  # 定义池化层
        with tf.variable_scope("layer7-conv4"):  # 定义作用域(用于变量)
            # 定义权重
            conv4_weights = tf.get_variable("weight", [3, 3, 128, 128],
                                            initializer=tf.truncated_normal_initializer(stddev=0.1))
            conv4_biases = tf.get_variable("bias", [128], initializer=tf.constant_initializer(0.0))  # 定义偏置
            conv4 = tf.nn.conv2d(pool3, conv4_weights, strides=[1, 1, 1, 1], padding='SAME')  # 定义卷积层
            relu4 = tf.nn.relu(tf.nn.bias_add(conv4, conv4_biases))  # 定义激活函数
        with tf.name_scope("layer8-pool4"):  # 定义命名空间(用于op)
            pool4 = tf.nn.max_pool(relu4, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')  # 定义池化层
          
            nodes = 6 * 6 * 128  
            reshaped = tf.reshape(pool4, [-1, nodes])
            print("shape of reshaped:", reshaped.shape)  # reshape函数将pool4的输出转化成向量
        # 定义作用域:
        with tf.variable_scope('layer9-fc1'):
            # 定义全连接层的权重:
            fc1_weights = tf.get_variable("weight", [nodes, 1024], initializer=tf.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
            # 给全连接层的权重添加正则项,tf.add_to_collection函数可以把变量放入一个集合,把很多变量变成一个列表
            fc1_biases = tf.get_variable("bias", [1024], initializer=tf.constant_initializer(0.1))  # 定义全连接层的偏置:
            fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)  # 定义激活函数:
            if train: fc1 = tf.nn.dropout(fc1, 0.5)  # 针对训练数据,在全连接层添加dropout层,防止过拟合
        with tf.variable_scope('layer10-fc2'):
            fc2_weights = tf.get_variable("weight", [1024, 512], initializer=tf.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
            fc2_biases = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))
            fc2 = tf.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
            if train: fc2 = tf.nn.dropout(fc2, 0.5)
        with tf.variable_scope('layer11-fc3'):
            fc3_weights = tf.get_variable("weight", [512, 5],
                                          initializer=tf.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.add_to_collection('losses', regularizer(fc3_weights))
            fc3_biases = tf.get_variable("bias", [5], initializer=tf.constant_initializer(0.1))
            logit = tf.matmul(fc2, fc3_weights) + fc3_biases
        return logit
    def inference(input_tensor, train, regularizer):
        with tf.compat.v1.variable_scope('layer1-conv1'):
            # 定义变量权重:weight,名称是weight;5,5代表卷积核的大小,3代表输入的信道数目,32代表输出的信道数目;
            # initializer代表神经网络权重和卷积核的推荐初始值,生成截断正态分布随机数,服从标准差为0.1
            conv1_weights = tf.compat.v1.get_variable("weight", [5, 5, 3, 32],
                                                      initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            # 初始化偏置值为0
            conv1_biases = tf.compat.v1.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
            conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
            relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
    
    
        with tf.name_scope("layer2-pool1"):
            pool1 = tf.compat.v1.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="VALID")
            logging.info(f"First convolutional layer:{pool1}")
    
    
        with tf.compat.v1.variable_scope("layer3-conv2"):
            conv2_weights = tf.compat.v1.get_variable("weight", [5, 5, 32, 64],
                                                      initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            conv2_biases = tf.compat.v1.get_variable("bias", [64], initializer=tf.compat.v1.constant_initializer(0.0))
            conv2 = tf.compat.v1.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
            relu2 = tf.compat.v1.nn.relu(tf.nn.bias_add(conv2, conv2_biases))
    
    
        with tf.name_scope("layer4-pool2"):
            pool2 = tf.compat.v1.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
            logging.info(f"Second convolutional layer:{pool2}")
    
    
        with tf.compat.v1.variable_scope("layer5-conv3"):
            conv3_weights = tf.compat.v1.get_variable("weight", [3, 3, 64, 128],
                                                      initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            conv3_biases = tf.compat.v1.get_variable("bias", [128], initializer=tf.compat.v1.constant_initializer(0.0))
            conv3 = tf.compat.v1.nn.conv2d(pool2, conv3_weights, strides=[1, 1, 1, 1], padding='SAME')
            relu3 = tf.compat.v1.nn.relu(tf.nn.bias_add(conv3, conv3_biases))
    
    
        with tf.compat.v1.name_scope("layer6-pool3"):
            pool3 = tf.compat.v1.nn.max_pool(relu3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
            logging.info(f"Third convolutional layer:{pool3}")
    
    
        with tf.compat.v1.variable_scope("layer7-conv4"):
            conv4_weights = tf.compat.v1.get_variable("weight", [3, 3, 128, 128],
                                                      initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            conv4_biases = tf.compat.v1.get_variable("bias", [128], initializer=tf.compat.v1.constant_initializer(0.0))
            conv4 = tf.compat.v1.nn.conv2d(pool3, conv4_weights, strides=[1, 1, 1, 1], padding='SAME')
            relu4 = tf.compat.v1.nn.relu(tf.nn.bias_add(conv4, conv4_biases))
    
    
        with tf.compat.v1.name_scope("layer8-pool4"):
            pool4 = tf.compat.v1.nn.max_pool(relu4, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
            logging.info(f"The fourth convolutional layer:{pool4}")
            nodes = 6 * 6 * 128
            # 展开
            reshaped = tf.compat.v1.reshape(pool4, [-1, nodes])
    
    
        with tf.compat.v1.variable_scope('layer9-fc1'):
            fc1_weights = tf.compat.v1.get_variable("weight", [nodes, 1024],
                                                    initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.compat.v1.add_to_collection('losses', regularizer * tf.nn.l2_loss(fc1_weights))
            fc1_biases = tf.compat.v1.get_variable("bias", [1024], initializer=tf.compat.v1.constant_initializer(0.1))
    
    
            fc1 = tf.compat.v1.nn.relu(tf.compat.v1.matmul(reshaped, fc1_weights) + fc1_biases)
            logging.info(f"The first fully connected layer:{fc1}")
            if train: fc1 = tf.compat.v1.nn.dropout(fc1, 0.5)
    
    
        with tf.compat.v1.variable_scope('layer10-fc2'):
            fc2_weights = tf.compat.v1.get_variable("weight", [1024, 512],
                                                    initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.compat.v1.add_to_collection('losses', regularizer * tf.nn.l2_loss(fc2_weights))
            fc2_biases = tf.compat.v1.get_variable("bias", [512], initializer=tf.compat.v1.constant_initializer(0.1))
    
    
            fc2 = tf.compat.v1.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
            if train: fc2 = tf.compat.v1.nn.dropout(fc2, 0.5)
            logging.info(f"The second fully connected layer:{fc2}")
    
    
        with tf.compat.v1.variable_scope('layer11-fc3'):
            fc3_weights = tf.compat.v1.get_variable("weight", [512, 5],
                                                    initializer=tf.compat.v1.truncated_normal_initializer(stddev=0.1))
            if regularizer != None: tf.compat.v1.add_to_collection('losses', regularizer * tf.nn.l2_loss(fc3_weights))
            fc3_biases = tf.compat.v1.get_variable("bias", [5], initializer=tf.compat.v1.constant_initializer(0.1))
            logit = tf.compat.v1.matmul(fc2, fc3_weights) + fc3_biases
        return logit

    conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding='SAME')

    这是一个常见的卷积操作,其中strides=【1,1,1,1】表示滑动步长为1,padding=‘SAME’表示填0操作

    当我们要设置步长为2时,strides=【1,2,2,1】,很多同学可能不理解了,这四个参数分别代表了什么,

    strides在官方定义中是一个一维具有四个元素的张量,其规定前后必须为1。所以我们可以改的是中间两个数,中间两个数分别代表了水平滑动和垂直滑动步长值,于是就很好理解了。在卷积核移动逐渐扫描整体图时候,因为步长的设置问题,可能导致剩下未扫描的空间不足以提供给卷积核的,大小扫描 比如有图大小为5*5,卷积核为2*2,步长为2,卷积核扫描了两次后,剩下一个元素,不够卷积核扫描了,这个时候就在后面补零,补完后满足卷积核的扫描,这种方式就是same。如果说把刚才不足以扫描的元素位置抛弃掉,就是valid方式。

  • 函数参数的解释:

    tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

    除去name参数用以指定该操作的name,与方法有关的一共五个参数:

    input:

        指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

    filter:

        相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维。【有时候也叫ksize或卷积核】

        * strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4。【注意:一般两边为1.形如[1,height,weight,1]】。

    padding:

        string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同的卷积方式【same:不够还加。valid:不够舍弃。】

    use_cudnn_on_gpu:

        bool类型,是否使用cudnn加速,默认为true

    batch和Eposh

       神经网络中Batch和Epoch之间的区别是什么? 随机梯度下降法是一种具有大量超参数的学习算法。两个超参数: Batch大小和Epoch数量,它们都是整数值。batch字面上是批量的意思,在深度学习中指的是计算一次cost需要的输入数据个数。  这意味着数据集将分为40个Batch,每个Batch有5个样本。每批五个样品后,模型权重将更新。 这也意味着一个epoch将涉及40个Batch或40个模型更新。 有1000个Epoch,模型将暴露或传递整个数据集1,000次。 一个 batch 的样本通常比单个输入更接近于总体输入数据的分布,batch 越大就越近似。然而,每个 batch 将花费更长的时间来处理,并且仍然只更新模型一次。

  • Sample: 样本,数据集中的一个元素,一条数据。

    例1: 在卷积神经网络中,一张图像是一个样本。

    例2: 在语音识别模型中,一段音频是一个样本。

  • Batch: 批,含有 N 个样本的集合。每一个 batch 的样本都是独立并行处理的。在训练时,一个 batch 的结果只会用来更新一次模型。

    一个 batch 的样本通常比单个输入更接近于总体输入数据的分布,batch 越大就越近似。然而,每个 batch 将花费更长的时间来处理,并且仍然只更新模型一次。在推理(评估/预测)时,建议条件允许的情况下选择一个尽可能大的 batch,(因为较大的 batch 通常评估/预测的速度会更快)。

  • Epoch: 轮次,通常被定义为 「在整个数据集上的一轮迭代」,用于训练的不同的阶段,这有利于记录和定期评估。

    当在 Keras 模型的 fit 方法中使用 validation_data 或 validation_split 时,评估将在每个 epoch 结束时运行。

    在 Keras 中,可以添加专门的用于在 epoch 结束时运行的 callbacks 回调。例如学习率变化和模型检查点(保存)。

  • 这也意味着一个epoch将涉及40个Batch或40个模型更新。

    有1000个Epoch,模型将暴露或传递整个数据集1,000次。在整个培训过程中,总共有40,000Batch。

    用一个小例子来说明这一点。

    假设您有一个包含200个样本(数据行)的数据集,并且您选择的Batch大小为5和1,000个Epoch。

    这意味着数据集将分为40个Batch,每个Batch有5个样本。每批五个样品后,模型权重将更新。

  • 池化

    池化过程在一般卷积过程后。池化(pooling) 的本质,其实就是采样。Pooling 对于输入的 Feature Map,选择某种方式对其进行降维压缩,以加快运算速度。

  • 详细:tensorflow构建神经网络基础概念和梳理_第1张图片

     详细:tensorflow构建神经网络基础概念和梳理_第2张图片

    池化的作用:

    (1)保留主要特征的同时减少参数和计算量,防止过拟合。

    (2)invariance(不变性),这种不变性包括translation(平移),rotation(旋转),scale(尺度)。

    Pooling 层说到底还是一个特征选择,信息过滤的过程。也就是说我们损失了一部分信息,这是一个和计算性能的一个妥协,随着运算速度的不断提高,我认为这个妥协会越来越小。

    现在有些网络都开始少用或者不用pooling层了。

你可能感兴趣的:(tensorflow,神经网络,深度学习)