利用python和TensorFlow将正则化应用在逻辑回归问题中

第一部分.正则化函数及其应用

通常使用的正则化方法包含L1正则化和L2正则化,介绍如下:

 

L1 正则化

L2 正则化

说明

直接在原来的损失函数基础上加上权重参数的绝对值和:

直接在原来的损失函数基础上加上权重参数的平方和:

函数

tf.contrib.layers.l1_regularizer(lamda)

lamda:正则化参数λ

tf.contrib.layers.l2_regularizer(lamda)

lamda:正则化参数λ

 

使用方式:

一般将正则化函数与需要正则化的变量联合起来,并将结果存入到一个有名称的集合中:

tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(0.5)(weight))

其中:

tf.add_to_collection  向集合’losses’中添加元素

‘losses’  名称为losses的集合

weight  需要被正则化的变量

介绍:

简单的说,正则函数l2_regularizer只是将weight中元素进行平方加和求均值,再乘以系数λ(如上0.5) ,将求出的结果返回。

 

使用示例:

import tensorflow as tf

import tensorflow.contrib as contrib

 

weight = tf.constant([[1.0, -2.0], [-3.0, 4.0]])  # 初始化一个常量weight

tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(0.5)(weight))  # 将常量weight进行正则化生成的新tensor存储到losses集中,即向losses中存入1/2*(1^2+(-2)^2+(-3)^2+4^2)*0.5=7.5

a=weight+1  # 建立a,a为[[2,-1],[-2,5]]

tf.add_to_collection('losses',tf.reduce_sum(a))  # 对a进行reduce_sum运算,将结果存入losses中,即存入2-1-2+5=4

b=tf.get_collection('losses')  # 取出losses中存储的数据集赋值给b

c=tf.add_n(b)  # 对b进行add_n操作,赋值给c

with tf.Session() as sess:  # 输出结果

    print(sess.run(weight))

    print(sess.run(a))

    print(sess.run(b))

    print(sess.run(c))

输出结果:

[[ 1. -2.]

 [-3.  4.]]

[[ 2. -1.]

 [-2.  5.]]

[7.5, 4.0]

11.5

注:

可以通过调整weight的结构和值、正则系数来观察正则化对结果的影响,从而更好的了解正则化。

 

参考:

https://blog.csdn.net/red_stone1/article/details/80755144

https://blog.csdn.net/lilong117194/article/details/79130032  讲的很详细

 

 

第二部分.在逻辑回归中应用正则化

以3.1中的程序为例,步骤如下:

步骤1. 建立数据源(样本库)——使用随机初始化的方式。由于需要进行逻辑分类,需要建立2个数据类,并合并在一起。如下:

num_points=1000  # 样本数目

vectors_set=[]

x1_PlotData=[]  # 用于后期绘图的数据

y1_PlotData=[]

x2_PlotData=[]

y2_PlotData=[]

for i in range(int(num_points/2)):

    x1=np.random.normal(0.0,0.55)   #横坐标,进行随机高斯处理化,以0为均值,以0.55为标准差

    y1=x1*0.1+0.3+np.random.normal(-0.03,0.03)   #纵坐标,数据点在y1=x1*0.1+0.3上小范围浮动

    vectors_set.append([x1,y1,0])

    x2 = np.random.normal(0.0, 0.55)

    y2 = x2 * 0.1 + 0.5 + np.random.normal(-0.03, 0.03)

    vectors_set.append([x2, y2,1])

    x1_PlotData.append(x1)

    y1_PlotData.append(y1)

    x2_PlotData.append(x2)

    y2_PlotData.append(y2)

x1_data=[v[0] for v in vectors_set]  # 使用np.mat将list转化为numpy中的矩阵格式

x2_data=[v[1] for v in vectors_set]

y_data=[v[2] for v in vectors_set]

 

步骤2.建立数据流图:新建变量theta(同时建立正则项),假设函数 ,代价函数(同时添加正则项),优化算法选择梯度下降法,并设置步长:

theta=tf.Variable(np.zeros([3,1]),dtype=tf.float32)  # 新建变量和占位符

tf.add_to_collection('cost',tf.contrib.layers.l2_regularizer(0.02)(theta))  # 将theta的正则项存储到'cost'中,正则系数为0.01

x_input=tf.placeholder(tf.float32,shape=[num_points,3])

y_input=tf.placeholder(tf.float32)

 

h_theta=1/(1+tf.exp(-tf.matmul(x_input,theta))) # 构建假设函数

 

cost_=-tf.reduce_mean(y_input*tf.log(h_theta)+(1-y_input)*tf.log(1-h_theta))  # 构建代价(损失)函数

tf.add_to_collection('cost',cost_)  # 将损失存储到'cost'集合中

cost=tf.add_n(tf.get_collection('cost'))  # 将'cost'集合内的元素进行加和运算,输出添加正则项的损失函数cost

optimizer = tf.train.GradientDescentOptimizer(0.99)  # 选择梯度下降法,并设置步长。

train_step = optimizer.minimize(cost)

 

步骤3.初始化流图:

sess = tf.Session()

init = tf.global_variables_initializer()

sess.run(init)

 

步骤4.开始训练,同时记录训练过程:

x_plot=[]

y_plot=[]

steps = 2000  # 训练次数

for i in range(steps):

    xs=np.column_stack((np.ones([num_points]), np.mat(x1_data).T,np.mat(x2_data).T))

    ys = np.mat(y_data).T

    feed = { x_input: xs, y_input: ys }

    sess.run(train_step, feed_dict=feed)

    if i % 100 == 0 :  # 每训练100次,记录训练结果

        print("After %d iteration:" % i)

        print("Theta:" ,sess.run(theta))

        print("Cost: %f" % sess.run(cost, feed_dict=feed))

        x_plot.append(i)

        y_plot.append(sess.run(cost, feed_dict=feed))

 

步骤5.输出训练结果,主要为训练参数theta和损失值(代价值):

print("Finnally Result")

print("Theta:" ,sess.run(theta))

print("Cost: %f" % sess.run(cost, feed_dict=feed))

 

步骤6.在样本集中绘制训练后的直线,和“训练次数-损失”曲线,一边观察训练结果:

x_result=[-2,2]

Theta_result=sess.run(theta)

y_result=[]

for x_temp in x_result:  # 如果直接赋值y_result=x_result*W+b,则y_result类型为Tensor,不能直接打印

    y_result.append((-Theta_result[0]-x_temp*Theta_result[1])/Theta_result[2])

plt.subplot(1,2,1)

plt.scatter(x1_PlotData,y1_PlotData,c='g')

plt.scatter(x2_PlotData,y2_PlotData,c='r')

plt.plot(x_result,y_result,'-y')

plt.subplot(1,2,2)

plt.plot(x_plot,y_plot,'-')

plt.show()

 

输出结果(通过更改步骤2中的,观察不同的正则系数对结果的影响):

正则系数为0.02:

正则系数为0.001:

注:

  1. 由以上两图可知,正则系数越大,拟合的阻力越大(即防止过拟合),容易发生欠拟合。
  2. 这个例子只是作为拟合函数的应用而展示的,由于是线性分类问题,正则化的作用不是很大。当分类的边界有多个弯曲时,正则化发挥的作用就会显现出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值