tensorlfow正则化
为了避免过拟合问题,一个常用方法是正则化,在训练数据上不直接优化损失函数J(θ),而是优化J(θ)+λR(w)。
θ表示的是一个神经网络中所有参数
R(w)是模型的复杂程度,一般由权重w决定,常用的R(w)有两种,一种是L1正则化,另一种是L2正则化。
R(w) = ∑|w|
R(w) = ∑|w^2|
下面是L2正则化的损失函数定义
import tensorflow as tf
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
w = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))
y = tf.matmul(x, w)
loss = tf.reduce_mean(tf.square(y_ - y)) + tf.contrib.layers.l2_regularizer(.5)(w)
loss定义了损失函数,tf.reduce_mean(tf.square(y_ - y))是均方误差损失函数,第二部分就是正则化,它是防止模型过度拟合的随机噪声,.5是正则化项的权重就是公式中的λ,w即为权重参数,tf.contrib.layers.l2_regularizer(.5)(w)可以计算给定参数的L2正则化项的值。类似的tf.contrib.layers.l1_regularizer可以计算L1正则化项的值。
当网络结构复杂后,定义网络结构的部分和计算损失函数的部分不可能在同一个函数中,这样通过变量这种方式计算损失函数就不方便了,为了解决这个问题可以使用tf提供的集合(collection)。以下代码给出了通过集合计算一个5层神经网络带L2正则化的损失函数的计算方法。
迭代的过程可以仿照学下,不是很好理解,但多写几次就差不多理解了,这里只说下最后一行的loss = tf.add_n(tf.get_collection(‘losses’)),get_collection返回一个列表(列表有集合中的所有元素),此时该集合中已经有了均方误差损失函数值和正则化项的值,最后通过add_n将它们加起来就可以得到最终的损失函数。
import tensorflow as tf
# 获取一层神经网络边上的权重,并将这个权重的L2正则化损失加入'losses'的集合中
def get_weight(shape, lambda_):
# 生成一个变量
var = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
# 将这个新生成的变量加的L2值加入集合
tf.add_to_collection(
'losses', tf.contrib.layers.l2_regularizer(lambda_)(var)
)
return var
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
y_ = tf.placeholder(tf.float32, shape=(None, 1), name="y-input")
batch_size = 8
# 定义每层网络中结点个数
layer_dimension = [2, 10, 10, 10, 1]
# 神经网络层数
n_layers = len(layer_dimension)
# 这个变量维护前向传播时最深层的结点,开始的时候就是输入层
cur_layer = x
# 当前层的结点个数
in_dimension = layer_dimension[0]
# 通过一个循环来生成5层全连接的神经网络结构
for i in range(1, n_layers):
# layer_dimension[i]为下一层结点个数
out_dimension = layer_dimension[i]
# 生成当前层的权重变量,并将这个变量的L2值加入集合
weight = get_weight([in_dimension, out_dimension], 0.001)
bias = tf.Variable(tf.constant(0.1, shape=[out_dimension]))
# 使用ReLu**函数
cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)
# 更新当前层结点个数
in_dimension = layer_dimension[i]
# 计算在训练数据上的损失函数
mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
# 将均方误差损失函数加入losses集合
tf.add_to_collection('losses', mse_loss)
# 定义好最终的损失函数
loss = tf.add_n(tf.get_collection('losses'))
上面代码定义了5层全连接网络的结构和损失函数,通过集合的方法使得代码的可读性更高,在更加复杂的网络结构中,使用这种方式计算损失函数将大大增强代码的可读性。
上一篇: EXCEL POI 合并单元格解析