Tensorflow中的正則化
參數加正則項
在損失函數上加上正則項是防止過擬合的一個重要方法,下面介紹如何在TensorFlow中使用正則項.
tensorflow中對參數使用正則項分爲兩步:
- 創建一個正則方法(函數/對象)
- 將這個正則方法(函數/對象),應用到參數上
如何創建一個正則方法函數
tf.contrib.layers.l1_regularizer(scale, scope=None)
返回一個用來執行L1正則化的函數,函數的簽名是func(weights).
參數:
- scale: 正則項的係數.
- scope: 可選的scope name
tf.contrib.layers.l2_regularizer(scale, scope=None)
返回一個執行L2正則化的函數.
tf.contrib.layers.sum_regularizer(regularizer_list, scope=None)
返回一個可以執行多種(個)正則化的函數.意思是,創建一個正則化方法,這個方法是多個正則化方法的混合體.
參數:
- regularizer_list: regulizer的列表
已經知道如何創建正則化方法了,下面要說明的就是如何將正則化方法應用到參數上
應用正則化方法到參數上
tf.contrib.layers.apply_regularization(regularizer, weights_list=None)
參數:
- regularizer:就是我們上一步創建的正則化方法
- weights_list: 想要執行正則化方法的參數列表,如果爲None的話,就取GraphKeys.WEIGHTS中的weights.
函數返回一個標量Tensor,同時,這個標量Tensor也會保存到GraphKeys.REGULARIZATION_LOSSES中.這個Tensor保存了計算正則項損失的方法.
- tensorflow中的Tensor是保存了計算這個值的路徑(方法),當我們run的時候,tensorflow後端就通過路徑計算出Tensor對應的值。
現在,我們只需將這個正則項損失加到我們的損失函數上就可以了.
- 如果是自己手動定義weight的話,需要手動將weight保存到GraphKeys.WEIGHTS中,但是如果使用layer的話,就不用這麼麻煩了,別人已經幫你考慮好了.(最好自己驗證一下tf.GraphKeys.WEIGHTS中是否包含了所有的weights,防止被坑)
其他方法
- 在使用tf.get_variable()和tf.variable_scope()的時候,你會發現,它倆中有regularizer形參.如果傳入這個參數的話,那麼variable_scope內的weights的正則化損失,或者weights的正則化損失就會被添加到GraphKeys.REGULARIZATION_LOSSES中
import tensorflow as tf
from tensorflow.contrib import layers
# 在tf.variable_scope()中加入regulizer
regularizer = layers.l1_regularizer(0.1)
with tf.variable_scope('var', initializer=tf.random_normal_initializer(),
regularizer=regularizer):
weight = tf.get_variable('weight', shape=[8], initializer=tf.ones_initializer())
with tf.variable_scope('var2', initializer=tf.random_normal_initializer(),
regularizer=regularizer):
weight2 = tf.get_variable('weight', shape=[8], initializer=tf.ones_initializer())
regularization_loss = tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
網絡層加Dropout
- tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
- tf.nn.rnn_cell.DropoutWrapper(rnn_cell, input_keep_prob=1.0, output_keep_prob=1.0)
tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
-
第一個參數x:指輸入
-
第二個參數keep_prob: 設置神經元被選中的概率,在初始化時keep_prob是一個佔位符, keep_prob = tf.placeholder(tf.float32) 。tensorflow在run時設置keep_prob具體的值,例如keep_prob: 0.5
# 普通的dropout
def dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
w = tf.get_variable("w1",shape=[size, out_size])
x = tf.placeholder(tf.float32, shape=[batch_size, size])
x = tf.nn.dropout(x, keep_prob=0.5)
y = tf.matmul(x,w)
# rnn中的dropout
def rnn_cell.DropoutWrapper(rnn_cell, input_keep_prob=1.0, output_keep_prob=1.0):
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(size, forget_bias=0.0, state_is_tuple=True)
lstm_cell = tf.nn.rnn_cell.DropoutWrapper(lstm_cell, output_keep_prob=0.5)