在上一篇文章中我们简单说了说AIC,BIC和L1,L2正则化的东西,而今天这篇文章,我们将着重说说正则化.
1:什么是正则化?
首先,拿过来上一篇文章的定义:
√正则化:在损失函数中给每个参数 w 加上权重,引入模型复杂度指标,从而抑制模型噪声,减小 过拟合。
使用正则化后,损失函数 loss 变为两项之和:
loss = loss(y 与 y_) + REGULARIZER*loss(w)
其中,第一项是预测结果与标准答案之间的差距,如之前讲过的交叉熵、均方误差等;第二项是正则化计算结果。
2:正则化如何计算?
① L1 正则化: 𝒍𝒐𝒔𝒔𝑳𝟏 = ∑𝒊 |𝒘𝒊 |
用 Tesnsorflow 函数表示:
loss(w) = tf.contrib.layers.l1_regularizer(REGULARIZER)(w)
② L2 正则化: 𝒍𝒐𝒔𝒔𝑳𝟐 = ∑𝒊 |𝒘𝒊 | 𝟐
用 Tesnsorflow 函数表示:
loss(w) = tf.contrib.layers.l2_regularizer(REGULARIZER)(w)
③:用 Tesnsorflow 函数实现正则化:
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w)
loss = cem + tf.add_n(tf.get_collection('losses'))
现在我们用一个实例来看看使用正则化和不适用正则化的差距.(这个例子是之前我自己做过的一个实验改过来的).
首先,我们做一批数据集:
用 300 个符合正态分布的点 X[x0, x1]作为数据集,根据点 X[x0, x1]计算生成标注 Y_,将数据集标注为红色点和蓝色点。
标注规则为:当 x0 ²+ x1 ² < 2 时,y_=1,标注为红色;当 x0 ²+ x1 ² ≥2 时,y_=0,标注为蓝色。 我们分别用无正则化和有正则化两种方法,拟合曲线,把红色点和蓝色点分开。在实际分类时, 如果前向传播输出的预测值 y 接近 1 则为红色点概率越大,接近 0 则为蓝色点概率越大,输出的预测值 y 为 0.5 是红蓝点概率分界线。
然后我们来创建一个简单的神经网络,就只有一个隐藏层(以后多用TensorFlow),
现在让我们不用正则化试验下:
然后我们就在正则化的效果下看看效果:(这里用的是L2正则化)
现在让我们执行代码看看结果:
生成数据集:
没有使用正则化的结果:
使用正则化的结果:
因此我们来看,正则化的效果会让曲线更加平稳,非常有效.
代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
'''制作数据集'''
BATCH_SIZE = 30
SEED = 100
#产生随机数
rdm = np.random.RandomState(SEED)
X = rdm.randn(300,2) #随机三百行两列的数
Y_ = [int(x0 * x0 + x1 * x1 < 2) for (x0, x1) in X]
#从X中获取,得到正确Y
Y_c = [['red' if y else 'blue']for y in Y_] #y_中标注颜色
X = np.vstack(X).reshape(-1,2)
Y_ = np.vstack(Y_).reshape(-1,1)
plt.scatter(X[:,0],X[:,1],c = np.squeeze(Y_c))#横坐标的第一二列元素
plt.show()
'''定义神经网络'''
def get_weight(shape,regularizer):
w = tf.Variable(tf.random_normal(shape),dtype=tf.float32)
tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))
return w
def get_bias(shape):
b = tf.Variable(tf.constant(0.01,shape=shape))
return b
x = tf.placeholder(tf.float32,shape=(None,2))
y_ = tf.placeholder(tf.float32,shape=(None,1))
#隐藏层
w1 = get_weight([2,11],0.01)
b1 = get_bias([11])
y1 = tf.nn.relu(tf.matmul(x,w1)+b1)
#输出层
w2 = get_weight([11,1],0.01)
b2 = get_bias([1])
y = tf.matmul(y1,w2)+b2
#损失函数
lose_mse = tf.reduce_mean(tf.squeeze(y-y_))
lose_total = lose_mse+tf.add_n(tf.get_collection('losses'))
#定义反向传播,无正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(lose_mse)
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
STEPS = 40000
for i in range(STEPS):
start = (i*BATCH_SIZE)%300
end = start+BATCH_SIZE
sess.run(train_step,feed_dict={x:X[start:end],y_:Y_[start:end]})
if i%2000 ==0:
lose_mse_v = sess.run(lose_mse,feed_dict={x:X,y_:Y_})
print("after %d step,loss is:%f"%(i,lose_mse_v))
xx,yy = np.mgrid[-3:3:.01,-3:3:.01]
grid = np.c_[xx.ravel(),yy.ravel()]
probs = sess.run(y,feed_dict={x:grid})
probs = probs.reshape(xx.shape)
print("w1:\n",sess.run(w1))
print("b1:\n",sess.run(b1))
print("w2:\n",sess.run(w2))
print("b2:\n",sess.run(b1))
plt.scatter(X[:,0], X[:,1],c = np.squeeze(Y_c))
plt.contour(xx,yy,probs,levels = [.5])
plt.show()
# 定义反向传播方法:包含正则化
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
STEPS = 40000
for i in range(STEPS):
start = (i * BATCH_SIZE) % 300
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
if i % 2000 == 0:
loss_v = sess.run(lose_total, feed_dict={x: X, y_: Y_})
print("After %d steps, loss is: %f" % (i, loss_v))
xx, yy = np.mgrid[-3:3:.01, -3:3:.01]
grid = np.c_[xx.ravel(), yy.ravel()]
probs = sess.run(y, feed_dict={x: grid})
probs = probs.reshape(xx.shape)
print
"w1:\n", sess.run(w1)
print
"b1:\n", sess.run(b1)
print
"w2:\n", sess.run(w2)
print
"b2:\n", sess.run(b2)
plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))
plt.contour(xx, yy, probs, levels=[.5])
plt.show()
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。