一、机器学习大致框架
1、Dataset(构建数据集,准备训练数据)
2、Model(搭建模型)
3、Training(使用搭建的模型对数据进行训练)
4、inferring(根据训练结果推理预测结果)
机器学习拿到数据集进行训练,训练好后拿训练后的模型对输入进行预测得到预测结果。
对于知道输出值和输出真实值的训练模型称为有监督学习
所有的模型训练好后都需要使用测试集进行测试,而测试集的正确输出结果是不能够让模型在预测前提前看到的。
一般来说拿到数据集之后需要先将其分为两部分,一部分用于训练,另一部分用于测试训练好的模型的性能,即作为测试集使用。
二、线性模型(Linear Model)
线性模型一般可以作为最基本的模型架构。
f(x)=wx+b=>y_hat=wx+b
一般在机器学习的计算中,为求出权重w和偏置b,会先给w和b一个随机的初始值,这时权重可能大也可能小,因此需要对这个权重进行评估,评估这个权重所表示的模型和数据集中的数据之间偏移程度也就是误差有多大。
这个评估模型在机器学习中就被称为损失,也就是Loss
loss=(y_hat-y)2= [(x*w+b)-y]2(y_hat为预测值;y为真实值)
不断尝试不同的权重w和偏置b,使平均损失尽可能最小。
MSELoss即为平均平方误差
三、代码实现
1.引入库
import numpy as np
import matplotlib.pyplot as plt
这里引入的两个包主要用于绘图
2.准备数据
自己构造一个简单数据集用于训练
x_data=[1.0,2.0,3.0]
y_data=[3.0,5.0,7.0]
3.构造简单的线性模型
构造一个简单的线性模型(前馈)
Linear Model: y_hat=x*w+b
def forward(x):
return (x*w+b)
4.定义损失函数
这里计算的损失函数就是按照“二”中loss的计算公式求得的
loss=(y_hat-y)2= [(x*w+b)-y]2(y_hat为预测值;y为真实值)
def loss(x,y):
y_pred=forward(x)
return (y_pred-y)*(y_pred-y)
代码中引入前馈函数的作用就是通过线性模型求出在当前权重下根据输入求出的预测值,用于与真实值对比计算损失。
5.更新权重
w_list=[]
b_list=[]
mse_list=[]
for w in np.arange(0.0,4.1,0.1):
for b in np.arange(0.0,2.1,0.1):
print('w=',w)
print('b=',b)
l_sum=0
for x_val,y_val in zip(x_data,y_data):
y_pred_val=forward(x_val)
loss_val=loss(x_val,y_val)
l_sum+=loss_val
print('\t',x_val,y_val,y_pred_val,loss_val)
print('MSE=',l_sum/3)
if b not in b_list:
b_list.append(b)
mse_list.append(l_sum/3)
w_list.append(w)
w_list[ ] 用于存储所有的权重值
b_list[ ] 用于存储所有的偏移值
mse_list[ ] 用于存储每一对w和b的组合所对应的平均损失
首先代码中两个for循环,以0.1的步长遍历w和b;
然后在循环内逐个读取自己定义的数据集的数据,将x输入模型(forward)计算出当前权重下的预测输出;
然后根据再将预测输出和数据集中的真实输出输入损失函数,计算出损失;
当数据集中的所有数据全部遍历完成,计算这一轮预测的平均损失;
最后将w、b和平均损失mse全部存入对应的数组,便于后续绘图操作。
6.绘图
#3D
fig = plt.figure() #定义新的三维坐标轴
ax3 = plt.axes(projection='3d')
W, B = np.meshgrid(w_list, b_list)
l_sum1=0
for x_val,y_val in zip(x_data,y_data):
Y = np.full((21, 41), y_val, dtype=float)
y_pred_val=x_val*W+B
loss_val=(y_pred_val-Y)*(y_pred_val-Y)
l_sum1+=loss_val
Z = l_sum1/3
#print(Z)
max_item = max(max(row) for row in Z)
print('max=',max_item)
min_item = min(min(row) for row in Z)
print('min=',min_item)
ax3.plot_surface(W,B,Z,cmap='rainbow')
plt.show()
绘制三维坐标,以w和b做x轴和y轴,平均损失mse作为z轴
最好的绘图方式是在训练过程中实时的绘制这种训练损失图,可以使用Facebook开源的Visdom绘图工具,可以远程web访问绘制的图形。
四、完整代码
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 27 17:54:25 2021
@author: LENOVO
"""
import numpy as np
import matplotlib.pyplot as plt
x_data=[1.0,2.0,3.0]
y_data=[3.0,5.0,7.0]
def forward(x):
return (x*w+b)
def loss(x,y):
y_pred=forward(x)
return (y_pred-y)*(y_pred-y)
w_list=[]
b_list=[]
mse_list=[]
for w in np.arange(0.0,4.1,0.1):
for b in np.arange(0.0,2.1,0.1):
print('w=',w)
print('b=',b)
l_sum=0
for x_val,y_val in zip(x_data,y_data):
y_pred_val=forward(x_val)
loss_val=loss(x_val,y_val)
l_sum+=loss_val
print('\t',x_val,y_val,y_pred_val,loss_val)
print('MSE=',l_sum/3)
if b not in b_list:
b_list.append(b)
mse_list.append(l_sum/3)
w_list.append(w)
#print(w_list)
#b_list=np.unique(b_list)
#print(b_list)
print('max=',max(mse_list))
print('min=',min(mse_list))
#二维绘图
# plt.plot(w_list,mse_list)
# plt.ylabel('Loss')
# plt.xlabel('w')
# plt.show()
# plt.plot(b_list,mse_list)
# plt.ylabel('Loss')
# plt.xlabel('b')
# plt.show()
#3D
fig = plt.figure() #定义新的三维坐标轴
ax3 = plt.axes(projection='3d')
W, B = np.meshgrid(w_list, b_list)
l_sum1=0
for x_val,y_val in zip(x_data,y_data):
Y = np.full((21, 41), y_val, dtype=float)
y_pred_val=x_val*W+B
loss_val=(y_pred_val-Y)*(y_pred_val-Y)
l_sum1+=loss_val
Z = l_sum1/3
#print(Z)
max_item = max(max(row) for row in Z)
print('max=',max_item)
min_item = min(min(row) for row in Z)
print('min=',min_item)
ax3.plot_surface(W,B,Z,cmap='rainbow')
plt.show()