深度学习入门(2)-线性单元和梯度下降
什么是线性单元:
感知器有一个问题,当面对的数据集不是线性可分的时候,『感知器规则』可能无法收敛,这意味着我们永远也无法完成一个感知器的训练。为了解决这个问题,我们使用一个可导的线性函数来替代感知器的阶跃函数,这种感知器就叫做线性单元。线性单元在面对线性不可分的数据集时,会收敛到一个最佳的近似上。
为了简单起见,我们可以设置线性单元的激活函数f为:
f
(
x
)
=
x
f(x) = x
f(x)=x
这样替换了激活函数之后,线性单元将返回一个实数值而不是0,1分类。因此线性单元用来解决回归问题而不是分类问题。
线性单元模型:
当我们说模型时,我们实际上在谈论根据输入预测输出的算法。比如,可以是一个人的工作年限,可以是他的月薪,我们可以用某种算法来根据一个人的工作年限来预测他的收入。比如:
y
=
h
(
x
)
=
w
∗
x
+
b
y=h(x)=w*x+b
y=h(x)=w∗x+b
当x为一个多维向量时候,w也应该为一个多维向量,此时式子就可以表示为:
y
=
h
(
x
)
=
w
1
∗
x
1
+
w
2
∗
x
2
+
w
3
∗
x
3
+
w
4
∗
x
4
+
b
y=h(x)=w1*x1+w2*x2+w3*x3+w4*x4+b
y=h(x)=w1∗x1+w2∗x2+w3∗x3+w4∗x4+b
我们还可以把上式写成向量的形式:
y
=
h
(
x
)
=
w
T
∗
x
y=h(x)=wT*x
y=h(x)=wT∗x
长成这种样子的模型就叫做线性模型,因为输出y就是输入特征*x1,x2,x3,…*的线性组合
监督学习和无监督学习的概念:
- 监督学习:它是说为了训练一个模型,我们要提供这样一堆训练样本:每个训练样本既包括输入特征**x***,也包括对应的输出y***(y也叫做标记,label)。也就是说,我们要找到很多人,我们既知道他们的特征(工作年限,行业…),也知道他们的收入。简单来说,就是既知道输入又知道输出。
- 无监督学习:这种方法的训练样本中只有***x***而没有***y***。模型可以总结出特征***x***的一些规律,但是无法知道其对应的答案***y***。
实现线性单元:
对于上一个感应器和线性单元,二者的实现其实没有本质的不同,只是激励函数换成可以求导的函数。
from functools import reduce
import matplotlib.pyplot as plt
import numpy as np
def acti_fun(x):
return x
class perceptron(object):
def __init__(self, input_num):
self.weight = [0.0] * input_num
self.b = 0.0
def train(self, input_vecs, labels, times, rate): # 设置训练的输入向量,标签,次数还有学习速率
for i in range(times):
for input_vec, label in zip(input_vecs, labels):
output = acti_fun(sum(np.array(input_vec) * self.weight) + self.b)
delta = label - output
self.weight += rate * delta * np.array(input_vec)
self.b += rate * delta
return self.weight, self.b
def predict(self, input_data):
input_data = np.array(input_data)
pre = []
for data in input_data:
pre_data = acti_fun(sum(np.array(data) * np.array(self.weight)))
pre.append(pre_data)
return pre
def get_training_dataset(): # 设置数据训练的线性单元
input_vecs = [[5], [3], [8], [1.4], [10.1]]
labels = [5500, 2300, 7600, 1800, 11400]
return input_vecs, labels
def train_linear_uint():
lu = perceptron(1)
input_data, labels = get_training_dataset()
lu.train(input_data, labels, 100, 0.1)
return lu
# 画图
def plot(linearUnit):
input_data, labels = get_training_dataset()
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(input_data, labels)
weights = linearUnit.weight
b = linearUnit.b
x = range(0, 15, 1)
y = list(map(lambda x: weights[0] * x + b, x))
ax.plot(x, y)
plt.show()
if __name__ == "__main__":
# 创建线性单元
linear_unit = train_linear_uint()
# 打印权重
print(linear_unit)
# 测试
print(linear_unit.predict([3.4]))
print(linear_unit.predict([15]))
print(linear_unit.predict([1.5]))
print(linear_unit.predict([6.3]))
plot(linear_unit)
比较感知器模型和线性单元模型:
由上图可知,除了激活函数f不同外,两者的模型和训练规则是一样的。那么,只需要把感知器的激活函数进行替换即可。
小结:
事实上,机器学习算法其实只有两部分:
- 模型从出入特征x预测输入y的函数h(x)
- 目标函数目标函数取最小(最大)值时所对应的参数值,就是模型的参数的最优值。很多时候我们只能获得目标函数的局部最小(最大)值,因此也只能得到模型参数的局部最优值。
参考文章:
https://www.zybuluo.com/hanbingtao/note/448086
https://blog.csdn.net/IT_job/article/details/80315364