《人工智能实践:Tensorflow笔记》听课笔记17_4.4正则化

附:课程链接

第四讲.神经网络优化
4.4正则化

由于个人使用Win7系统,并未完全按照课程所讲,以下记录的也基本是我的结合课程做的Windows系统+PyCharm操作。且本人有python基础,故一些操作可能简略。并未完全按照网课。

记住编写代码时,除注释内容外,字符均使用英文格式。

二、神经网络的优化(从四个方面理解:损失函数loss、学习率learning_rate、滑动平均ema、正则化regularization)

4.正则化regularization
过拟合:神经网络模型在训练数据集上的准确率较高,在新的数据进行预测或分类时准确率较低,说明模型的泛化能力差。
正则化:在损失函数中给每个参数w加上权重,引入模型复杂度指标,从而抑制模型噪声,减小过拟合。(一般不对偏置b使用正则化)

使用正则化后,损失函数loss变成两部分:
在这里插入图片描述
loss(w)有两种正则化方法,L1正则化、L2正则化,使用时选择其中一个即可:
在这里插入图片描述
用tensorflow实现正则化:

tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))
#tf.add_to_collection把计算好的所有w正则化,加在losses集合中
loss = cem + tf.add_n(tf.get_collection('losses'))
#用tf.add_n可以把losses里的所有值相加,再加上交叉熵cem,就得到了总损失函数loss

实例感受正则化的作用
题目:用300个符合正态分布的点X[x0,x1]作为数据集,根据点X[x0,x1]计算生成标注Y_,将数据集标注为红点和蓝点。
标注Y_规则:当在这里插入图片描述,即如图:
在这里插入图片描述
我们尝试拟合一条曲线,把红色的点和蓝色的点分开。这里我们引入一个新模块matplotlib,它可帮助我们实现图形可视化

代码讲解用法及套用公式(不是例子):

import matplotlib.pyplot as plt #matplotlib帮助实现图形可视化

plt.scatter(x_label,y_label,c = 'color')    #可视化数据点,给出x坐标和y坐标,并给出这个坐标点打算显示的颜色
plt.show()  #把图像散点画出来

xx.yy = np.mgrid[start;end:step,start:end:step]
#用np.mgrid,x轴从起点开始到止点结束,以步长打点,y轴同理
#二者分别作为x坐标和y坐标,这样我们就找到了一个小区域,以步长为分辨率的行、列形成网格坐标点
grid = np.c_[xx.ravel(),yy.ravel()]
#用ravel()函数把xx坐标拉直,即降低它的维度,变成1行n列。yy坐标同理。
#再用np.c_把xx坐标、yy坐标对应位置配对,组成矩阵。
#这样我们就收集起这个区域内所有的网格坐标点。
#probs = sess.run(y,feed_dict = {x:grid})
#我们把所有收集来的坐标点喂入神经网络,经网络计算推送求得结果y,赋值给probs
#这个probs就是区域中所有坐标点偏红还是偏蓝的变化值,
#probs = probs.reshape(xx.shape)
#把probs整形,让它的形状和xx.shape一样
plt.contour(x_label,y_label,该点的高度,levels = [等高线的高度]) #这里语法有误,但仅是套用公式,不要误解
#然后用plt.contour()函数把x坐标、y坐标、各点的高度,用levels把各点描上颜色
plt.show()  #画出来

代码验证:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt #matplotlib帮助实现图形可视化

BATCH_SIZE = 30
seed = 2
rdm = np.random.RandomState(seed)   #基于seed产生随机数
#随机数返回300行2列的矩阵,表示300组坐标点(x0,x1)作为输入数据集
X = rdm.randn(300,2)
#从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值0
Y_ = [int(x0*x0 + x1*x1 <2) for (x0,x1) in X]
#遍历Y中的元素,1赋值'red',其余赋值'blue'。这样可视化显示时人可以直观区分
Y_c = [['red' if y else 'blue'] for y in Y_]
#对数据集X和标签Y进行shape整理,第一个元素为-1表示,随第二个参数计算得到。
#第二个元素表示多少列,把X整理为n行2列,把Y整理为n行1列。
#(np.vstack:按垂直方向(行顺序堆叠数组构成一个新的数组,文末有简书链接讲解))
X = np.vstack(X).reshape(-1,2)
Y_ = np.vstack(Y_).reshape(-1,1)
# print(X)
# print(Y_)
# print(Y_c)
#使用plt.scatter画出数据集X各行中第0列元素和第1列元素的点,即各行的(x0,x1),
#用各行Y_c对应的值表示颜色
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   #输出层不过激活relu

#定义损失函数
loss_mse = tf.reduce_mean(tf.square(y - y_))
loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))
#定义反向传播方法:不含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_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:
            loss_mse_v = sess.run(loss_mse,feed_dict={x:X,y_:Y_})
            print('After %d steps,loss is: %f'%(i,loss_mse_v))
    #xx在-3到3之间以步长为0.01,yy在-3到3之间以步长为0.01,生成二维网络坐标点
    xx,yy = np.mgrid[-3:3:0.01,-3:3:0.01]
    #将xx,yy拉直,并合成一个2列的矩阵,得到一个网络坐标点的集合
    grid = np.c_[xx.ravel(),yy.ravel()]
    #将网络坐标点喂入神经网络,probs为输出
    probs = sess.run(y,feed_dict={x:grid})
    #probs的shape调整成xx的样子
    probs = probs.reshape(xx.shape)
    #把probs整形,让它的形状和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))  #可视化数据点,给出x坐标和y坐标,并给出这个坐标点打算显示的颜色
plt.contour(xx,yy,probs,levels = [.5])  #然后用plt.contour()函数把x坐标、y坐标、各点的高度,用levels把各点描上颜色
plt.show()  #把图像散点画出来

#定义反向传播方法:包含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_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:
            loss_v = sess.run(loss_total,feed_dict={x:X,y_:Y_})
            print('After %d steps,loss is: %f'%(i,loss_v))
    #xx在-3到3之间以步长为0.01,yy在-3到3之间以步长为0.01,生成二维网络坐标点
    xx,yy = np.mgrid[-3:3:0.01,-3:3:0.01]
    #将xx,yy拉直,并合成一个2列的矩阵,得到一个网络坐标点的集合
    grid = np.c_[xx.ravel(),yy.ravel()]
    #将网络坐标点喂入神经网络,probs为输出
    probs = sess.run(y,feed_dict={x:grid})
    #probs的shape调整成xx的样子
    probs = probs.reshape(xx.shape)
    #把probs整形,让它的形状和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))  #可视化数据点,给出x坐标和y坐标,并给出这个坐标点打算显示的颜色
plt.contour(xx,yy,probs,levels = [.5])  #然后用plt.contour()函数把x坐标、y坐标、各点的高度,用levels把各点描上颜色
plt.show()  #把图像散点画出来

首先,数据可视化,
在这里插入图片描述
如图所示:
在这里插入图片描述
其次,实现无正则化的训练过程:
在这里插入图片描述
最后,实现正则化的训练过程:
在这里插入图片描述
对比无正则化与有正则化模型的训练结果,可看出有正则化模型的拟合曲线平滑,模型具有更好的泛化能力。

【跑代码的坑:运行代码的时候,由于那时候还没有看全网课,自己先码了代码,跑出来第一张图后迟迟没有看到第二张图的出现。以为是代码有bug就检查了好几遍,最后发现是应该一张图出现以后,关掉这张图,程序才会继续运行。然后出现第二张图、关掉第二张图、程序继续运行、出现第三张图。。。百度了一些办法能不能同时出现几张图绘制图形,没有找到有效的解决办法。。。其实在用python、matplotlib绘图的时候感觉和matlab有点像,但是没有找到解决问题的办法也是比较遗憾吧。】

代码中出现了一个np.vstack()函数,由于我隔了一段时间看这个,有些记不清了,所以就百度了一下,找到一个简书不错,链接附给大家:
python基础之np.vstack()&np.hstack()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值