线性模型与逻辑回归

线性模型

x − > L i n e a r − > y ^ x->Linear->\hat{y} x>Linear>y^
模型
y i ^ = w x i + b \hat{y_i}=wx_i+b yi^=wxi+b
loss:
1 n ∑ i = 1 n ( y i ^ − y ) 2 \frac 1 n \sum_ {i=1}^n (\hat{y_i}-y)^2 n1i=1n(yi^y)2

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

### 线性模型

# 数据导入
x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],
                    [9.779], [6.182], [7.59], [2.167], [7.042],
                    [10.791], [5.313], [7.997],[3.1]], dtype=np.float32)
y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],
                    [3.366], [2.596], [2.53], [1.221], [2.827],
                    [3.465], [1.65], [2.904], [1.3]], dtype=np.float32)

# 转化为tensor
x = tf.constant(x_train, name='x')
y = tf.constant(y_train, name='y')

## 模型定义
# 参数
w = tf.Variable(initial_value=tf.random_normal(shape=(), seed=2017), dtype=tf.float32, name='weight')
b = tf.Variable(initial_value=0, dtype=tf.float32, name='biase')
# 线性模型
with tf.variable_scope('Linear_Model'):
    y_pred = w * x + b
    
# 开启交互式会话
sess = tf.InteractiveSession()
# 初始化变量
sess.run(tf.global_variables_initializer())

## 优化模型
# 模型误差
loss = tf.reduce_mean(tf.square(y - y_pred))
print(loss.eval(session=sess))
## 优化参数
w_grad, b_grad = tf.gradients(loss, [w, b])
lr = 1e-2
w_update = w.assign_sub(lr * w_grad)
b_update = b.assign_sub(lr * b_grad)
sess.run([w_update, b_update])

# 查看一次更新后的效果
%matplotlib inline
y_pred_numpy = y_pred.eval(session=sess)
plt.plot(x_train, y_train, 'bo', label='real')
plt.plot(x_train, y_pred_numpy, 'ro', label='estimated')
plt.legend()

# 查看迭代更新后的效果
%matplotlib notebook
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
sess.run(tf.global_variables_initializer())
for e in range(10):
    sess.run([w_update, b_update])
    y_pred_numpy = y_pred.eval(session=sess)
    loss_numpy = loss.eval(session=sess)
    ax.clear()
    ax.plot(x_train, y_train, 'bo', label='real')
    ax.plot(x_train, y_pred_numpy, 'ro', label='estimated')
    ax.legend()
    fig.canvas.draw()
    plt.pause(0.5)
    print('epoch: {}, loss: {}'.format(e, loss_numpy))

Logistic回归(解决分类问题)模型

x − > L i n e a r − > S i g m o i d − > y ^ x->Linear->Sigmoid->\hat{y} x>Linear>Sigmoid>y^
模型
y i ^ = σ ( w x i + b ) \hat{y_i} = \sigma(wx_i+b) yi^=σ(wxi+b)
σ \sigma σ:sigmoid函数;   σ = 1 1 + e − x \sigma=\frac 1 {1+e^{-x}} σ=1+ex1
loss:
− 1 n ∑ i = 1 n ( y i l o g y i ^ + ( 1 − y i ) l o g ( 1 − y i ^ ) ) -\frac 1 n \sum_ {i=1}^n (y_ilog\hat{y_i}+(1-y_i)log(1-\hat{y_i})) n1i=1n(yilogyi^+(1yi)log(1yi^))

  • y i y_i yi是真实的label,只能有0 和1两个值
y i = 0 y_i=0 yi=0 − 1 n ∑ i = 1 n l o g ( 1 − y i ^ ) -\frac 1 n \sum_{i=1}^nlog(1-\hat{y_i}) n1i=1nlog(1yi^)
y i = 1 y_i=1 yi=1 − 1 n ∑ i = 1 n l o g y i ^ -\frac 1 n \sum_{i=1}^nlog\hat{y_i} n1i=1nlogyi^

参数更新的推导:
在这里插入图片描述当真实的 y i y_i yi为0时,我们希望预测的 y i ^ \hat{y_i} yi^也是接近0的数,这样才能使loss尽可能小(注意:loss前有负号);
当真实的 y i y_i yi为1时,我们希望预测的 y i y_i yi也是接近1的数,这样才能使loss尽可能的小。

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

### 逻辑回归

## 获取数据
# 从data.txt中读入数据
with open('data/logistic_regression.txt', 'r') as f:
    data_list = [i.split('\n')[0].split(',') for i in f.readlines()]
    data = [(float(i[0]), float(i[1]), float(i[2])) for i in data_list]
# 标准化
x0_max = max([i[0] for i in data])
x1_max = max([i[1] for i in data])
data = [(i[0]/x0_max, i[1]/x1_max, i[2]) for i in data]
x0 = list(filter(lambda x: x[-1] == 0.0, data)) # 选择第一类的点
x1 = list(filter(lambda x: x[-1] == 1.0, data)) # 选择第二类的点   
plot_x0 = [i[0] for i in x0] # 标签为0的点
plot_y0 = [i[1] for i in x0]
plot_x1 = [i[0] for i in x1] # 标签为1的点
plot_y1 = [i[1] for i in x1]

# 将数据转换为tensor
np_data = np.array(data, dtype='float32') # 转换成 numpy array
x_data = tf.constant(np_data[:, 0:2], name='x') # 转换成 Tensor, 大小是 [100, 2]
y_data = tf.expand_dims(tf.constant(np_data[:, -1]), axis=-1) # 转换成 Tensor,大小是 [100, 1]

## 模型定义
# 参数
w = tf.get_variable(initializer=tf.random_normal_initializer(seed=2017), shape=(2, 1), name='weights')
b = tf.get_variable(initializer=tf.zeros_initializer(), shape=(1), name='bias')
# 逻辑回归
def logistic_regression(x):
    # 使用 tf.sigmoid 将结果映射到 [0, 1] 区间
    return tf.sigmoid(tf.matmul(x, w) + b)

# 开启交互式会话
sess = tf.InteractiveSession()
# 初始化变量
sess.run(tf.global_variables_initializer())

## 优化模型
# 模型误差
def binary_loss(y_pred, y):
    logit = tf.reduce_mean(y * tf.log(y_pred) + (1 - y) * tf.log(1 - y_pred))
    return -logit

y_pred = logistic_regression(x_data)
loss = binary_loss(y_pred, y_data)

## 优化参数方法1
# w_grad, b_grad = tf.gradients(loss, [w, b])
# lr = 0.1
# w_update = w.assign_sub(lr * w_grad)
# b_update = b.assign_sub(lr * b_grad)
# sess.run([w_update, b_update])
## 优化参数方法2
# 首先从tf.train中定义一个优化方法
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1, name='optimizer')
# 利用这个优化方法去优化一个损失函数, 得到的这个`op`就是我们想要的
train_op = optimizer.minimize(loss)

# 查看分类误差率
import time
sess.run(tf.global_variables_initializer())
start = time.time()
for e in range(1000):
    sess.run(train_op)
    if (e + 1) % 200 == 0:
        # 计算正确率
        y_true_label = y_data.eval(session=sess)
        y_pred_numpy = y_pred.eval(session=sess)
        y_pred_label = np.greater_equal(y_pred_numpy, 0.5).astype(np.float32)
        accuracy = np.mean(y_pred_label == y_true_label)
        loss_numpy = loss.eval(session=sess)
        print('Epoch %d, Loss: %.4f, Acc: %.4f' % (e + 1, loss_numpy, accuracy))
print('manual_GD cost time: %.4f' % (time.time() - start))
 
 # 查看最终的分类效果
 %matplotlib inline
w_numpy = w.eval(session=sess)
b_numpy = b_eval(session=sess)
w0 = w_numpy[0]
w1 = w_numpy[1]
b0 = b_numpy[0]
plot_x = np.arange(0.2,1, 0.01)
plot_y = (-w0*plot_x-b)/w1
plt.plot(plot_x, plot_y,'g', label = 'cutting line')
plt.plot(plot_x0,plot_y0,'ro',label='x_0')
plt.plot(plot_x1,plot_y1,'bo',label='x_1')
plt.legend(loc='best')
plt.show()

##  补充
# 模型优化,使用自带loss函数
loss1 = tf.losses.log_loss(predictions=y_pred, labels=y_data)
optimizer1 = tf.train.GradientDescentOptimizer(learning_rate=lr)
train_op1 = optimizer.minize(loss1)

参考
https://blog.csdn.net/v_JULY_v/article/details/78121924

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值