线性模型
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=1∑n(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+e−x1
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=1∑n(yilogyi^+(1−yi)log(1−yi^))
- 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=1∑nlog(1−yi^) |
---|---|
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=1∑nlogyi^ |
参数更新的推导:
当真实的
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)