全连接笔记tf.contrib.layers.fully_connected

*来源于一些大佬笔记的整合,仅用于便于学习和记忆*

1、代码释意:

fully_connected创建一个名为的变量weights,表示一个完全连接的权重矩阵,乘以它inputs产生一个 Tensor隐藏单位。

如果normalizer_fn提供了数据(例如 batch_norm),则应用它。否则,如果normalizer_fn为None且使用了biases_initializerbiases则将创建变量并添加隐藏单位。

如果activation_fn不是None,它也会应用于隐藏单位。

tf.contrib.layers.fully_connected(
    inputs,
    num_outputs,
    activation_fn=tf.nn.relu,
    normalizer_fn=None,
    normalizer_params=None,
    weights_initializer=initializers.xavier_initializer(),
    weights_regularizer=None,
    biases_initializer=tf.zeros_initializer(),
    biases_regularizer=None,
    reuse=None,
    variables_collections=None,
    outputs_collections=None,
    trainable=True,
    scope=None
)
  • inputs:至少为二阶张量和最后一个维度的静态值; 即[batch_size, depth][None, None, None, channels]
  • num_outputs:整数或长整数,图层中的输出单位数。
  • activation_fn:激活功能。默认值是ReLU功能。将其明确设置为“无”以跳过它并保持线性激活。
  • normalizer_fn:使用标准化功能代替biases。如果 normalizer_fn提供biases_initializerbiases_regularizer则忽略并且biases不创建也不添加。没有规范化器功能,默认设置为“无”
  • normalizer_params:规范化函数参数。
  • weights_initializer:权重的初始化程序。
  • weights_regularizer:可选的权重正则化器。
  • biases_initializer:偏见的初始化程序。如果没有跳过偏见。
  • biases_regularizer:偏见的可选正则化器。
  • reuse:是否应重用图层及其变量。必须给出能够重用层范围的能力。
  • variables_collections:所有变量的集合的可选列表或包含每个变量的不同集合列表的字典。
  • outputs_collections:用于添加输出的集合。
  • trainable:如果True还将变量添加到图表集合中 GraphKeys.TRAINABLE_VARIABLES(请参阅tf.Variable)。
  • scope:variable_scope的可选范围。

(借鉴于:tf.contrib.layers.fully_connected参数笔记 - 仝渊涛 - 博客园)

示例:

        out = layers.flatten(x) # 将矩阵展平
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)

2、将正则化项加入loss优化:

import tensorflow.contrib.layers as layers

def easier_network(x, reg):
    """ A network based on tf.contrib.learn, with input `x`. """
    with tf.variable_scope('EasyNet'):
        out = layers.flatten(x)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=10, # Because there are ten digits!
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = None)
        return out 

def main(_):
    mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])
 
    # Make a network with regularization
    y_conv = easier_network(x, FLAGS.regu)
    weights = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'EasyNet') 
    print("")
    for w in weights:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")
    reg_ws = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES, 'EasyNet')
    for w in reg_ws:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")
 
    # Make the loss function `loss_fn` with regularization.
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    loss_fn = cross_entropy + tf.reduce_sum(reg_ws)
    train_step = tf.train.AdamOptimizer(1e-4).minimize(loss_fn)

(代码来源:tensorflow 使用正则化_liyaohhh的博客-CSDN博客_tensorflow正则)

在代码中,下式得到正则化的损失:

tf.GraphKeys.REGULARIZATION_LOSSES
#或
regularizer=tf.contrib.layers.apply_regularization(tf.contrib.layers.l2_regularizer(weight_decay)
                                                    ,gen_vars+d_vars)

 3、训练技巧:

(借鉴于:全连接网络训练中的优化技巧(个人笔记)_枫城雪的博客-CSDN博客)

欠拟合:
       根本原因是特征维度过少,模型过于简单,导致拟合的函数无法满足训练集,误差较大。
       解决方法:增加特征维度,增加训练数据;
过拟合:
       根本原因是特征维度过多,模型假设过于复杂,参数过多,训练数据过少,噪声过多,导致拟合的函数完美的预测训练集,但对新数据的测试集预测结果差。 过度的拟合了训练数据,而没有考虑到泛化能力。
避免过拟合常用的方法:

1.early stopping: 在发生过拟合之前提前结束训练;理论上是可以,但这一点不好把握。
2.数据集扩增:就是让模型见到更多的情况,可以最大化的满足全样本,但是实际应用中对未来事件的预测却显得鞭长莫及。数据增强包含两个方向:一是采集新的数据进行数据扩充,二是根据已有数据集生成新的数据集从而达到数据数量上的增加 例如图片数据集,通过对图像进行翻转,平移,旋转,缩放,更改亮度,添加噪声等操作从而生成新的数据集。
3.正则化:是通过引入范数概念,增强模型的泛化能力,包括L1、L2
4.dropout:使网络模型的一种方法,每次训练是舍去一些节点来增强泛化能力。
       在训练过程中每次随机选择一部分节点不要去“学习”。
       这是因为,数据本身是不可能很纯净,即任何一个模型不能100%把数据完全分开,再某一类中一定会有异常数据,过拟合的问题恰恰是把这些异常数据当成规律来学习了。

        注意:
       ①由于dropout让一部分节点不去学习,所以在增加模型的泛化能力的同时,会使学习速度降低,使模型不太容易学成,所以在使用过程需要合理的调节到底丢掉多少节点,不是越多越好。

       ②dropout改变了神经网络的网络结构,它仅仅是属于训练时的方法,所以一般在进行测试时要将dropout 的 keep_prob变为1,代表不需要进行丢弃,否则会影响模型的正常输出。

5、简化模型:处理过度拟合的第一个想到的是降低模型的复杂性。为了降低复杂度,我们可以简单地删除神经网络层数或减少神经元数量以使网络更小。在执行此操作时,重要的是计算神经网络中涉及的各个层的输入和输出尺寸。对于删除的数量或网络的大小,没有一般性规定应该根据实际情况来看。

你可能感兴趣的:(python)