深度学习之逻辑回归


一个最简单的分类,是在平面上画一条直线,左边为类0,右边为类1,直线表示为z=ax+by+c这是一个分类器,输入(x,y),那么,要求的参数有三个:a,b,c。另外注意c的作用,如果没有c,这条直线一定会过原点。

第一步:将线性方程转化为矩阵计算之后代入Sigmoid函数

将该直线转换为:z=w1x1+w2x2+w3*1形式。
使用矩阵代替线性方程组即:z=XW


Sample


矩阵X

Sample

系数W

但是,由于z的值可能为[−∞,+∞],为了方便处理,需要将其压缩到一个合理的范围。
需要代入sigmoid函数:g(z)=1/(1+e^-z)这样的激励函数,能够将刚才的区间,压缩到[0,1]。

处理二分类问题时:
我们根据伯努利分布(二项分布)分别计算z划分为类0,类1的概率为:

	p(z=0|X;W)=g(XW)=1/(1+e^-XW)
	p(z=1|X;W)=1-g(XW)=e^-XW/1+e^-XW

Sample

合并为z划分为某一类的概率为(每个样本点的概念):

	p(z|X;W)=g(XW)^(1-z)*(1-g(XW))^(z)

Sample

第二步:获取最大似然估计

L(z|X;W)=求乘操作(g(XW)(1-z)*(1-g(XW))(z))

Sample

但由于最大似然估计值每一个都是[0,1]之间的值,如果直接相乘那么导致的结果就是:计算机可以没有办法表示那么高的精确度。
为了让计算机可以表示该结果,因此对最大似然估计求对数:

根据对数法则:

	ln(AB)=lnA+lnB可知:
	ln(A^b)=blnA
	ln(A/B)=lnA-lnB
	ln1=0
	lne=1
	
	LL(z|X;W)=求和操作(ln(g(XW)^(1-z))+ln((1-g(XW))^(z)))

Sample

化简过程为:

Sample

第三步:计算W使得最大似然估计值最大

计算方式:梯度上升

	W0=W0+步长*梯度的方向

	其中:
		步长自己设定;
		梯度的方向=LL(z|X;W)的导数;
计算LL(z|X;W)的导数
	根据求导公式以及复合函数求导法则:

在这里插入图片描述
有关复合函数求导具体过程可以参照https://blog.csdn.net/angeliacmm/article/details/88188528里的复合函数求导。

LL(z|X;W)的导数的推导过程为:

Sample

在这个推导过程中第一部分属于复合函数求导,请参看上边那个链接,有具体的推导过程。

在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。
  梯度下降法和梯度上升法是可以互相转化的。比如我们需要求解损失函数f(θ)的最小值,这时我们需要用梯度下降法来迭代求解。但是实际上,我们可以反过来求解损失函数 -f(θ)的最大值,这时梯度上升法就派上用场了。

因此可以根据梯度下降的办法进行处理。

梯度下降法是按下面的流程进行的:

 1)首先对w赋值,这个值可以是随机的,也可以让w是一个全零的向量。

 2)改变w的值,使得LL(w)按梯度下降的方向进行减少。

 梯度方向由LL(w)对w的偏导数确定,由于求的是极大值,因此梯度方向是偏导数的正方向。结果为:

Sample

迭代更新的方式有两种,一种是批梯度下降,也就是对全部的训练数据求得误差后再对θ进行更新,另外一种是增量梯度下降,每扫描一步都要对θ进行更新。前一种方法能够不断收敛,后一种方法结果可能不断在收敛处徘徊。

有关梯度 下降的可以参考此文章https://www.cnblogs.com/pinard/p/5970503.html,说得很清楚详细。

第四步:编码实现

导入依赖的库

	import numpy as np
	import tensorflow as tf
	import matplotlib.pyplot as plt

装载数据

	np.random.seed(4)
	tf.set_random_seed(4)
	​
	​
	N = 20000
	def sigmoid(x):
	    return 1 / (1 + np.exp(-x))
	​
	def inputs():
	    x_data = np.random.randn(N, 2)
	    w_real = [0.3, 0.5]
	    b_real = -0.2
	    wxb = np.matmul(w_real, x_data.T) + b_real
	    y_data_pre_noise = sigmoid(wxb)
	    y_data = [1.0 if e >= 0. else 0.0 for e in wxb]
	    return x_data, np.expand_dims(y_data, 1)
	​
	x_vals, y_vals = inputs()
	    
	def draw(x, y):
	    x_true = []
	    x_false = []
	    z = zip(x, y)
	    filter(filter_fun, Z)
	    for (e1, e2) in z:
	        if e2[0] == 0.0:
	            x_true.append(e1)
	        else:
	            x_false.append(e1)
	    x_true = np.array(x_true)
	    x_false = np.array(x_false)
	    return x_true, x_false


	    x_true, x_false = draw(x_vals, y_vals)

	plt.plot(x_true[:, 0], x_true[:, 1], 'r.') 
	plt.plot(x_false[:, 0], x_false[:, 1], 'b.') 
	plt.title('Original Data')
	plt.xlabel('X1')
	plt.ylabel('X2')
	plt.show()

在这里插入图片描述

	np.random.seed(4)
	tf.set_random_seed(4)


	def get_batch():
	    batch_size = 50
	    rand_idx = np.random.choice(len(x_vals), batch_size)
	    rand_x_vals = x_vals[rand_idx]
	    rand_y_vals = y_vals[rand_idx]
	    return rand_x_vals, rand_y_vals
	    
	g = tf.Graph()
	with g.as_default():
	    x_data = tf.placeholder(tf.float32, shape=(None, 2), name='x_data')
	    y_data = tf.placeholder(tf.float32, shape=(None, 1), name='y_data')
	    
	    with tf.name_scope('inference') as scope:
	        w_data = tf.Variable(tf.random_normal((2, 1)), name='w_data')
	        b_data = tf.Variable(tf.random_normal(()), name='b_data')
	        y_pred = tf.sigmoid(tf.add(tf.matmul(x_data, w_data, name='xw'), b_data, name='add'))
	        
	    with tf.name_scope('loss') as scope:
	        entropy = -(y_data * tf.log(y_pred) + (1.0 - y_data) * tf.log(1.0-y_pred))
	        loss = tf.reduce_mean(entropy)

	    with tf.name_scope('train') as scope:
	        optimizer = tf.train.GradientDescentOptimizer(1e-3)
	        train_step = optimizer.minimize(loss, name='train')

	    with tf.name_scope('accuracy') as scope:
	        prediction = tf.round(y_pred)
	        prediction_correct = tf.cast(tf.equal(prediction, y_data), tf.float32)
	        accuracy = tf.reduce_mean(prediction_correct)
	        
	    train_acc = []
	    with tf.Session() as sess:
	        sess.run(tf.global_variables_initializer())
	        for step in range(8000):       
	            rand_x, rand_y = get_batch()
	            sess.run(train_step, feed_dict={x_data: rand_x,  y_data: rand_y})
	            acc = sess.run(accuracy, feed_dict={x_data: x_vals, y_data: y_vals})
	            train_acc.append(acc)
	        y_pred_vals = sess.run(prediction, feed_dict={x_data: x_vals})



	plt.plot(train_acc, 'r.')
	plt.title('My Code')
	plt.xlabel('Generation')
	plt.ylabel('Accuracy')
	plt.show()

在这里插入图片描述

	x_true, x_false = draw(x_vals, y_pred_vals)
	plt.plot(x_true[:, 0], x_true[:, 1], 'r.') 
	plt.plot(x_false[:, 0], x_false[:, 1], 'b.') 
	plt.title('My Result')
	plt.xlabel('X1')
	plt.ylabel('X2')
	plt.show()

在这里插入图片描述

	np.random.seed(4)
	tf.set_random_seed(4)

	def get_batch():
	    batch_size = 50
	    rand_idx = np.random.choice(len(x_vals), batch_size)
	    rand_x_vals = x_vals[rand_idx]
	    rand_y_vals = y_vals[rand_idx]
	    return rand_x_vals, rand_y_vals
	    
	g = tf.Graph()
	with g.as_default():
	    x_data = tf.placeholder(tf.float32, shape=(None, 2), name='x_data')
	    y_data = tf.placeholder(tf.float32, shape=(None, 1), name='y_data')
	    
	    with tf.name_scope('inference') as scope:
	        w_data = tf.Variable(tf.random_normal((2, 1)), name='w_data')
	        b_data = tf.Variable(tf.random_normal((1, 1)), name='b_data')
	        y_pred = tf.add(tf.matmul(x_data, w_data, name='xw'), b_data, name='add')
	        
	    with tf.name_scope('loss') as scope:
	        entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_data, logits=y_pred)
	        loss = tf.reduce_mean(entropy)

	    with tf.name_scope('train') as scope:
	        optimizer = tf.train.GradientDescentOptimizer(1e-3)
	        train_step = optimizer.minimize(loss, name='train')

	    with tf.name_scope('accuracy') as scope:
	        prediction = tf.round(tf.sigmoid(y_pred))
	        prediction_correct = tf.cast(tf.equal(prediction, y_data), tf.float32)
	        accuracy = tf.reduce_mean(prediction_correct)
	        
	    train_acc = []
	    with tf.Session() as sess:
	        sess.run(tf.global_variables_initializer())
	        for step in range(8000):       
	            rand_x, rand_y = get_batch()
	            sess.run(train_step, feed_dict={x_data: rand_x,  y_data: rand_y})
	            acc = sess.run(accuracy, feed_dict={x_data: x_vals, y_data: y_vals})
	            train_acc.append(acc)
	        y_pred_vals = sess.run(prediction, feed_dict={x_data: x_vals})

	plt.plot(train_acc, 'r.')
	plt.title('Other Code')
	plt.xlabel('Generation')
	plt.ylabel('Accuracy')
	plt.show()

在这里插入图片描述

	x_true, x_false = draw(x_vals, y_pred_vals)
	plt.plot(x_true[:, 0], x_true[:, 1], 'r.') 
	plt.plot(x_false[:, 0], x_false[:, 1], 'b.') 
	plt.title('Other Result')
	plt.xlabel('X1')
	plt.ylabel('X2')
	plt.show()

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值