深度学习入门---《白话机器学习的数学》笔记
创始人
2024-02-08 07:31:38

文章目录

    • 一、基础:回归的实现
        • 1、训练数据click.csv
        • 2、参考公式:
        • 3、代码实现:
        • 4、运行结果:
        • 5、验证:
    • 二、多项式回归
        • 1、参考公式
        • 2、代码实现
        • 3、运行结果
    • 三、随机梯度下降法的实现
        • 1、参考公式
          • 小批量(mini-batch)梯度下降法
        • 2、代码实现
        • 3、运行结果
    • 四、感知机
        • 1、训练数据images1.csv
        • 2、参考公式
          • 感知机模型
          • 判别函数
          • 权重向量的更新表达式
        • 3、代码实现
        • 4、运行结果
        • 5、验证
    • 五、分类——逻辑回归的实现
        • 1、训练数据images2.csv
        • 2、参考公式
          • sigmoid函数
          • 参数更新表达式
        • 3、代码实现
        • 4、运行结果
        • 5、验证
    • 六、线性不可分分类的实现
        • 1、训练数据data3.csv
        • 2、代码实现
        • 3、运行结果
          • 绘制精度上升曲线
        • 4、用随机梯度下降法实现
    • 七、正则化
        • 1、准备工作
        • 2、代码实现
        • 3、运行结果
          • 未应用正则化的实现
          • 应用了正则化的实现


一、基础:回归的实现

1、训练数据click.csv

x,y
235,591
216,539
148,413
35,310
85,308
204,519
49,325
25,332
173,498
191,498
134,392
99,334
117,385
112,387
162,425
272,659
159,400
159,427
59,319
198,522

2、参考公式:

首先把 fθ(x) 作为一次函数来实现
在这里插入图片描述
参数更新表达式:
在这里插入图片描述
学习率先设置为10−3 。

3、代码实现:

'''
回归的实现
'''
import numpy as np
import matplotlib.pyplot as plt# 读入训练数据
train = np.loadtxt('click.csv',delimiter=',',skiprows=1)
train_x = train[:,0]
train_y = train[:,1]# 参数初始化
theta0 = np.random.rand()
theta1 = np.random.rand()
# 预测函数
def f(x):return  theta0 + theta1 * x
# 目标函数
def E(x,y):return 0.5 * np.sum((y - f(x))**2)
# 标准化
mu = train_x.mean()
sigma = train_x.std()
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 绘图
# plt.plot(train_z,train_y,'o')
# plt.show()# 学习率
ETA = 1e-3
# 误差的差值
diff = 1
# 更新次数
count = 0# 直到误差的值小于0.01为止,重复参数更新
error = E(train_z, train_y)
while diff > 1e-2:# 更新结果保存到临时变量tmp0 = theta0 - ETA * np.sum((f(train_z) - train_y))tmp1 = theta1 - ETA * np.sum((f(train_z) - train_y) * train_z)# 更新参数theta0 = tmp0theta1 = tmp1# 计算与上一次误差的差值current_error = E(train_z,train_y)diff = error - current_errorerror = current_error# 输出日志count += 1log = '第{}次:theta0 = {:.3f},theta1 = {:.3f},差值 = {:.4f}'# print(log.format(count,theta0,theta1,diff))# 绘图确认
x = np.linspace(-3, 3, 100)
plt.plot(train_z,train_y,'o')
plt.plot(x,f(x))
# plt.show()
# print(f(standardize(100)))

4、运行结果:

在这里插入图片描述

5、验证:

在这里插入图片描述

二、多项式回归

提示:增加参数theta2,并替换预测函数
多重回归:将参数和训练数据都作为向量来处理,使计算变得简单

1、参考公式

在这里插入图片描述
将参数和训练数据都作为向量来处理,可以使计算变得更简单
在这里插入图片描述
由于训练数据有很多,所以我们把 1 行数据当作 1 个训练数据,以矩阵的形式来处理会更好
在这里插入图片描述

2、代码实现

'''
多项式回归
增加参数theta2,并替换预测函数
多重回归:将参数和训练数据都作为向量来处理,使计算变得简单
'''
import numpy as np
import matplotlib.pyplot as plt
# 读入训练数据
train = np.loadtxt('click.csv',delimiter=',',skiprows=1)
train_x = train[:,0]
train_y = train[:,1]
# 标准化
mu = train_x.mean()
sigma = train_x.std()
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 初始化参数
theta = np.random.rand(3)
# 学习率
ETA = 1e-3
# 误差的差值
diff = 1
# 均方误差的历史记录
errors = []# 创建训练数据的矩阵
def to_matrix(x):return  np.vstack([np.ones(x.shape[0]),x,x ** 2]).T
X = to_matrix(train_z)# 预测函数
def f(x):return np.dot(x,theta)
# 目标函数
def E(x,y):return 0.5 * np.sum((y - f(x))**2)
# 均方误差
def MSE(x, y):return (1 / x.shape[0]) * np.sum((y - f(x)) ** 2)# 重复学习
error = E(X, train_y)
errors.append(MSE(X, train_y))
while diff > 1e-2:# 更新参数theta = theta - ETA * np.dot(f(X) - train_y,X)# 计算与上一次误差的差值current_error = E(X, train_y)diff = error - current_errorerror = current_errorerrors.append(MSE(X, train_y))# diff = errors[-2] - errors[-1]# 绘制拟合曲线
x = np.linspace(-3,3,100)
plt.plot(train_z,train_y,'o')
plt.plot(x,f(to_matrix(x)))
plt.show()# 绘制误差变化图
x = np.arange(len(errors))
plt.plot(x, errors)
plt.show()

3、运行结果

在这里插入图片描述
绘制误差变化图:
在这里插入图片描述

三、随机梯度下降法的实现

1、参考公式

在随机梯度下降法中会随机选择一个训练数据并使用它来更新参数。表达式中的 k 就是被随机选中的数据索引。
在这里插入图片描述
随机梯度下降法由于训练数据是随机选择的,更新参数时使用的又是选择数据时的梯度,所以不容易陷入目标函数的局部最优解。

小批量(mini-batch)梯度下降法

前面提到了随机选择 1 个训练数据的做法,此外还有随机选择 m 个训练数据来更新参数的做法。设随机选择 m 个训练数据的索引的集合为 K:
在这里插入图片描述

2、代码实现

"""
随机梯度下降法的实现
"""
import numpy as np
import matplotlib.pyplot as plt
# 读入训练数据
train = np.loadtxt('click.csv',delimiter=',',skiprows=1)
train_x = train[:,0]
train_y = train[:,1]
# 标准化
mu = train_x.mean()
sigma = train_x.std()
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 初始化参数
theta = np.random.rand(3)
# 均方误差的历史记录
errors = []
# 误差的差值
diff = 1
# 学习率
ETA = 1e-3# 创建训练数据的矩阵
def to_matrix(x):return  np.vstack([np.ones(x.shape[0]),x,x ** 2]).T
X = to_matrix(train_z)# 预测函数
def f(x):return np.dot(x,theta)
# 目标函数
def E(x,y):return 0.5 * np.sum((y - f(x))**2)
# 均方误差
def MSE(x, y):return (1 / x.shape[0]) * np.sum((y - f(x)) ** 2)# 重复学习
errors.append(MSE(X, train_y))
while diff > 1e-2:# 为了调整训练数据的顺序,准备随机的序列permutationp = np.random.permutation(X.shape[0])# 随机取出训练数据,使用随机梯度下降法更新参数for x,y in zip(X[p,:],train_y[p]):theta = theta - ETA * (f(x) - y) * x# 计算与上一次误差的差值errors.append(MSE(X, train_y))diff = errors[-2] - errors[-1]x = np.linspace(-3,3,100)
plt.plot(train_z,train_y,'o')
plt.plot(x,f(to_matrix(x)))
plt.show()

3、运行结果

在这里插入图片描述

四、感知机

1、训练数据images1.csv

x1,x2,y
153,432,-1
220,262,-1
118,214,-1
474,384,1
485,411,1
233,430,-1
369,361,1
484,349,1
429,259,1
286,220,1
399,433,-1
403,340,1
252,34,1
497,472,1
379,416,-1
76,163,-1
263,112,1
26,193,-1
61,473,-1
420,253,1

2、参考公式

感知机模型

在这里插入图片描述

判别函数

根据参数向量 x 来判断图像是横向还是纵向的函数,即返回 1 或者 −1 的函数 fw(x)的定义如下。
在这里插入图片描述
内积是衡量向量之间相似程度的指标。结果为正,说明二者相似;为 0 则二者垂直;为负则说明二者不相似。

权重向量的更新表达式

在这里插入图片描述

3、代码实现

使权重向量成为法线向量的直线方程是内积为 0 的 x 的集合。所以对它进行移项变形,最终绘出以下表达式的图形即可。
在这里插入图片描述

"""
分类---感知机
"""
import numpy as np
import matplotlib.pyplot as plt
# 读入训练数据
train = np.loadtxt('images1.csv',delimiter=',',skiprows=1)
train_x = train[:,0:2]
train_y = train[:,2]
# print(list(zip(train_x,train_y)))# 权重初始化
# 返回一个或一组服从“0~1”均匀分布的随机样本值。随机样本取值范围是[0,1),不包括1
w = np.random.rand(2)
#判别函数
def f(x):if np.dot(w,x) >= 0:return 1else:return -1# 重复次数
epoch = 10
# 更新次数
count = 0
# 学习权重
for _ in range(epoch):for x,y in zip(train_x,train_y):if f(x) != y:w = w + y * x# 输出日志count += 1print("第{}次:w = {}".format(count,w))# 绘制直线:使权重向量称为法线向量的直线方程是内积为0的x的集合
x1 = np.arange(0,500)
plt.plot(train_x[train_y == 1,0], train_x[train_y == 1,1],'o')
plt.plot(train_x[train_y == -1,0], train_x[train_y == -1,1],'x')
plt.plot(x1, -w[0]/w[1]*x1,linestyle = 'dashed')
# plt.axis('scaled')
# plt.show()print(f([200,100]))

4、运行结果

在这里插入图片描述

5、验证

在这里插入图片描述

五、分类——逻辑回归的实现

1、训练数据images2.csv

x1,x2,y
153,432,0
220,262,0
118,214,0
474,384,1
485,411,1
233,430,0
369,361,1
484,349,1
429,259,1
286,220,1
399,433,0
403,340,1
252,34,1
497,472,1
379,416,0
76,163,0
263,112,1
26,193,0
61,473,0
420,253,1

2、参考公式

与感知机的不同之处在于,逻辑回归是把分类作为概率来考虑的。

sigmoid函数

在这里插入图片描述
在这里插入图片描述
决策边界:
从图中可以看出在 fθ(x) ⩾ 0.5 时,θTx ⩾ 0,反过来在 fθ(x) < 0.5 时,θTx < 0;
在这里插入图片描述

参数更新表达式

在这里插入图片描述

3、代码实现

首先初始化参数,然后对训练数据标准化。x1和 x2 要分别标准 化。另外不要忘了加一个 x0 列。
θTx = 0这条直线是决策边界
在这里插入图片描述

"""
分类:逻辑回归的实现
"""
import numpy as np
import matplotlib.pyplot as plt
# 读入训练数据
train = np.loadtxt('images2.csv',delimiter=',',skiprows=1)
train_x = train[:,0:2]
train_y = train[:,2]# 初始化参数
theta = np.random.rand(3)
# 标准化:对x1和x2分别取平均值和标准差,进行标准化
mu = train_x.mean(axis = 0)
sigma = train_x.std(axis = 0)
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 增加x0
def to_matrix(x):x0 = np.ones([x.shape[0], 1])return np.hstack([x0, x])X = to_matrix(train_z)# sigmoid函数
def f(x):return 1/(1 + np.exp(-np.dot(x, theta)))# 学习率
ETA = 1e-3
# 重复次数
epoch = 5000
# 更新次数
count = 0
# 重复学习
for _ in range(epoch):theta = theta - ETA * np.dot(f(X) - train_y, X)# 日志输出count += 1print('第{}次:theta = {}'.format(count,theta))# 验证:对预测数据进行标准化
# f(to_matrix(standardize([
#     [200,100], # 200x100的横向图像
#     [100,200]  # 100x200的纵向图像
# ])))
def classify(x):return (f(x) >= 0.5).astype(np.int)
rst = classify(to_matrix(standardize([[200,100], # 200x100的横向图像[100,200]  # 100x200的纵向图像
])))
# print(rst)
x1 = np.linspace(-2,2,100)
# 将标准化后的训练数据画成图
plt.plot(train_z[train_y == 1, 0], train_z[train_y == 1, 1], 'o')
plt.plot(train_z[train_y == 0, 0], train_z[train_y == 0, 1], 'x')
plt.plot(x1, -(theta[0] + theta[1] * x1) / theta[2], linestyle = "dashed")
plt.show()

4、运行结果

在这里插入图片描述

5、验证

在这里插入图片描述

六、线性不可分分类的实现

1、训练数据data3.csv

x1,x2,y
0.54508775,2.34541183,0
0.32769134,13.43066561,0
4.42748117,14.74150395,0
2.98189041,-1.81818172,1
4.02286274,8.90695686,1
2.26722613,-6.61287392,1
-2.66447221,5.05453871,1
-1.03482441,-1.95643469,1
4.06331548,1.70892541,1
2.89053966,6.07174283,0
2.26929206,10.59789814,0
4.68096051,13.01153161,1
1.27884366,-9.83826738,1
-0.1485496,12.99605136,0
-0.65113893,10.59417745,0
3.69145079,3.25209182,1
-0.63429623,11.6135625,0
0.17589959,5.84139826,0
0.98204409,-9.41271559,1
-0.11094911,6.27900499,0

2、代码实现

这个数据看上去不能用一条直线来分类,要用二次函数
对于有4个参数的公式变形:
在这里插入图片描述

"""
线性不可分分类的实现
"""
import numpy as np
import matplotlib.pyplot as plt# 读入训练数据
train = np.loadtxt('data3.csv',delimiter=',',skiprows=1)
train_x = train[:,0:2]
train_y = train[:,2]# 参数初始化
theta = np.random.rand(4)
# 标准化:对x1和x2分别取平均值和标准差,进行标准化
mu = train_x.mean(axis = 0)
sigma = train_x.std(axis = 0)
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 数据看上去确实不能用一条直线来分类,要用二次函数,在训练数据里加上 x1的平方 就能很好地分类了。
# 增加x0和x3
def to_matrix(x):x0 = np.ones([x.shape[0], 1])# 增加维度:np.newaxis 放在哪个位置,就会给哪个位置增加维度# x[:, np.newaxis] ,放在后面,会给列上增加维度x3 = x[:,0,np.newaxis] ** 2return np.hstack([x0, x, x3])X = to_matrix(train_z)# sigmoid函数
def f(x):return 1/(1 + np.exp(-np.dot(x, theta)))def classify(x):return (f(x) >= 0.5).astype(np.int64)# 学习率
ETA = 1e-3
# 重复次数
epoch = 5000
# 更新次数
count = 0
# 将重复次数作为横轴,精度作为纵轴来绘图,可以看到精度上升
# 精度的历史记录
accuracies = []
# 重复学习
for _ in range(epoch):theta = theta - ETA * np.dot(f(X) - train_y, X)# 日志输出count += 1# print('第{}次:theta = {}'.format(count,theta))# 计算现在的精度result = classify(X) == train_yaccurancy = len(result[result == True]) / len(result)accuracies.append(accurancy)# 将精度画成图
x = np.arange(len(accuracies))
plt.plot(x,accuracies)
plt.show()# 将结果画成图
x1 = np.linspace(-2, 2, 100)
x2 = -(theta[0] + theta[1]*x1 + theta[3] * x1 ** 2)/theta[2]
plt.plot(train_z[train_y == 1, 0], train_z[train_y == 1, 1], 'o')
plt.plot(train_z[train_y == 0, 0], train_z[train_y == 0, 1], 'x')
plt.plot(x1,x2,linestyle='dashed')
# plt.show()

3、运行结果

在这里插入图片描述

绘制精度上升曲线

根据公式:
在这里插入图片描述

在这里插入图片描述

4、用随机梯度下降法实现

"""
随机梯度下降法的实现
"""
import numpy as np
import matplotlib.pyplot as plt# 读入训练数据
train = np.loadtxt('data3.csv',delimiter=',',skiprows=1)
train_x = train[:,0:2]
train_y = train[:,2]# 参数初始化
theta = np.random.rand(4)
# 标准化:对x1和x2分别取平均值和标准差,进行标准化
mu = train_x.mean(axis = 0)
sigma = train_x.std(axis = 0)
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 增加x0和x3
def to_matrix(x):x0 = np.ones([x.shape[0], 1])# 增加维度x3 = x[:,0,np.newaxis] ** 2return np.hstack([x0, x, x3])X = to_matrix(train_z)
print(X)
# sigmoid函数
def f(x):return 1/(1 + np.exp(-np.dot(x, theta)))def classify(x):return (f(x) >= 0.5).astype(np.int64)# 学习率
ETA = 1e-3
# 重复次数
epoch = 5000
# 更新次数
count = 0
# 将重复次数作为横轴,精度作为纵轴来绘图,可以看到精度上升
# 精度的历史记录
accuracies = []
# 重复学习
for _ in range(epoch):# 使用随机梯度下降法更新参数p = np.random.permutation(X.shape[0])for x,y in zip(X[p,:], train_y[p]):theta = theta - ETA * (f(x) - y)*x# 将结果画成图
x1 = np.linspace(-2, 2, 100)
x2 = -(theta[0] + theta[1]*x1 + theta[3] * x1 ** 2)/theta[2]
plt.plot(train_z[train_y == 1, 0], train_z[train_y == 1, 1], 'o')
plt.plot(train_z[train_y == 0, 0], train_z[train_y == 0, 1], 'x')
plt.plot(x1,x2,linestyle='dashed')
plt.show()# Iris 数据集也可以用在分类上,可以用它进行更多尝试

运行结果:
在这里插入图片描述

七、正则化

1、准备工作

自定义函数,并加入一些噪声数据:
在这里插入图片描述虚线就是正确的 g(x) 的图形,圆点就是加入了一点噪声的训练数据:
在这里插入图片描述
假设用 10 次多项式来学习这个训练数据。10 次多项式,包括参数 θ0 在内,一共有 11 个参数。

2、代码实现

"""
正则化的实现
"""
import numpy as np
import matplotlib.pyplot as plt
# 真正的函数
def g(x):return 0.1 * (x ** 3 + x ** 2 + x)
# 随意准备一些向真正的函数加入了一点噪声的训练数据
train_x = np.linspace(-2,2,8)
train_y = g(train_x) + np.random.randn(train_x.size) * 0.05# 标准化
mu = train_x.mean(axis = 0)
sigma = train_x.std(axis = 0)
def standardize(x):return (x - mu)/sigma
train_z = standardize(train_x)# 创建训练数据的矩阵,假设我们用 10 次多项式来学习这个训练数据。
# 按垂直方向(行顺序)堆叠数组构成一个新的数组.堆叠的数组需要具有相同的维度
def to_matrix(x):return np.vstack([np.ones(x.size),x,x ** 2,x ** 3,x ** 4,x ** 5,x ** 6,x ** 7,x ** 8,x ** 9,x ** 10,]).TX = to_matrix(train_z)
# 参数初始化
# X.shape[1]:有几列
# randn是从标准正态分布中返回一个或多个样本值。正态分布,也即这些随机数的期望为0,方差为1;
# rand则会产生[0, 1)之间的随机数theta = np.random.randn(X.shape[1])
# 预测函数
def f(x):return np.dot(x, theta)# 绘图确认
x = np.linspace(-2,2,100)
# plt.plot(train_x,train_y,'o')
# plt.plot(x,g(x),linestyle='dashed')
# plt.ylim(-1,2)
# plt.show()# 学习率
ETA = 1e-4
# 误差
diff1 = 1
# 目标函数
def E(x,y):return 0.5 * np.sum((y - f(x)) ** 2)
# 重复学习
error = E(X, train_y)'''不应用正则化的实现'''
''''''
while diff1 > 1e-6:theta = theta - ETA * np.dot(f(X)-train_y,X)current_error1 = E(X, train_y)diff1 = error - current_error1error = current_error1z = standardize(x)
plt.plot(train_z,train_y,'o')
plt.plot(z, f(to_matrix(z)),linestyle='dashed')
plt.show()'''应用了正则化的实现'''
'''
# 保存未正则化的参数,然后再次参数初始化
theta1 = theta
theta = np.random.randn(X.shape[1])
# 正则化常量
LAMBDA = 1
# 误差
diff2 = 1while diff2 > 1e-6:# 正则化项。偏置项不适用正则化,所以为0reg_term = LAMBDA * np.hstack([0,theta[1:]])# 应用正则化项,更新参数theta = theta - ETA * (np.dot(f(X)-train_y,X) + reg_term)current_error2 = E(X, train_y)diff2 = error - current_error2error = current_error2# 对结果绘图
z = standardize(x)
plt.plot(train_z,train_y,'o')
plt.plot(z, f(to_matrix(z)))
plt.show()
'''

3、运行结果

未应用正则化的实现

在这里插入图片描述

应用了正则化的实现

在这里插入图片描述
绘制在一起进行比较:
在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...