前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习与神经网络:正则化小栗子(附代码)

深度学习与神经网络:正则化小栗子(附代码)

原创
作者头像
云时之间
发布2018-05-07 22:53:23
1.4K8
发布2018-05-07 22:53:23
举报
文章被收录于专栏:云时之间

在上一篇文章中我们简单说了说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正则化)

现在让我们执行代码看看结果:

生成数据集:

没有使用正则化的结果:

使用正则化的结果:

因此我们来看,正则化的效果会让曲线更加平稳,非常有效.

代码语言:javascript
复制
代码:
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档