1. 找到这个算法的预测函数, 比如线性回归的预测函数形式为:y = wx + b,
2. 找到这个算法的损失函数 , 比如线性回归算法的损失函数为最小二乘法
3. 找到让损失函数求得最小值的时候的系数, 这时一般使用梯度下降法.
机器学习中的监督学习本质上是给定一系列训练样本(xi,yi) ,尝试学习x→y 的映射关系,使得给定一个x ,即便这个x 不在训练样本中,也能够得到尽量接近真实y 的输出 。而损失函数(Loss Function)则是这个过程中关键的一个组成部分,用来衡量模型的输出y_pred 与真实的 y之间的差距,给模型的优化指明方向。
1. 使用TensorFlow中的变量将算法的预测函数, 损失函数定义出来.
2. 使用梯度下降法优化器求损失函数最小时的系数
3. 分批将样本数据投喂给优化器,找到最佳系数
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import tensorflow as tf
# 生成线性数据
x = np.linspace(0, 10, 20) + np.random.randn(20)
y = np.linspace(0, 10, 20) + np.random.randn(20)
# W, B 定义为变量
W = tf.Variable(initial_value=np.random.randn())
B = tf.Variable(initial_value=np.random.randn())
# 定义线性模型, TensorFlow2.x没有占位符了.把线性模型封装为一个函数, x作为参数传入
def linear_regression(x):
return W * x + B
# 定义损失函数
def mean_square_loss(y_pred, y_true):
return tf.reduce_sum(tf.square(y_pred - y_true)) / 20
# 优化器 随机梯度下降法
optimizer = tf.optimizers.SGD(0.01)
# 定义优化过程
def run_optimization():
# 把计算过程放在梯度带中执行,可以实现自动微分
with tf.GradientTape() as g:
pred = linear_regression(x)
loss = mean_square_loss(pred, y)
# 计算梯度
gradients = g.gradient(loss, [W, B])
# 更新W和B
optimizer.apply_gradients(zip(gradients, [W, B]))
# 训练
for step in range(1, 5001):
# 每次训练都要更新W和B
run_optimization()
# 展示结果
if step % 100 == 0:
pred = linear_regression(x)
loss = mean_square_loss(pred, y)
print(f'step: {step}, loss: {loss}, W: {W.numpy()}, B: {B.numpy()}')
# 分解写法
#w = torch.randn(1, requires_grad=True)*0.02
w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
#学习率
learning_rate = 0.001
#取数据 data.Education--series属性 .value取出值,一维数值,
#再用reshape变为2维,再用.type()直接修改数据类型,上节课知识点
X = torch.from_numpy(data.Education.values.reshape(-1, 1)).type(torch.FloatTensor)
Y = torch.from_numpy(data.Income.values).type(torch.FloatTensor)
这里y要不要改变维度,Tensorflow不用改变维度
目录
实现一个算法主要从以下三步入手:
使用TensorFlow实现算法的基本套路:
pytorch中的线性回归
注意:原先的w定义后*0.02,那w就不是叶子节点了,所以求w.grad会报错
封装起来
对比numpy
np.random.randn()#返回一个随机值,即标量,没有[]
np.random.randn(1)#返回含有1个元素的一维数值
注意:原先的w定义后乘以0.02,那此时w就不是叶子节点了,所以求w.grad会报错
# 定义训练过程
for epoch in range(5000):
for x, y in zip(X, Y):
y_pred = torch.matmul(x, w) + b
# 损失函数
loss = (y - y_pred).pow(2).sum()
# pytorch对一个变量多次求导, 求导的结果会累加起来.
if w.grad is not None:
# 重置w的导数
w.grad.data.zero_()
if b.grad is not None:
b.grad.data.zero_()
# 反向传播, 即求w,b的导数
loss.backward()
# 更新w,b
with torch.no_grad():
w.data -= w.grad.data * learning_rate
b.data -= b.grad.data * learning_rate
查看拟合结果效果
plt.scatter(data.Education, data.Income)
plt.plot(X.numpy(), (torch.matmul(X, w) + b).data.numpy(), c='r')
from torch import nn
# 和tensorflow中的Dense一个意思
# 实现的功能就是一个线性模型:wx + b
model = nn.Linear(1, 1)
# 定义损失函数
loss_fn = nn.MSELoss()
model.parameters()# 即W
# 定义优化器
# 优化器的第一个参数必须是要更新的模型中的参数
opt = torch.optim.SGD(model.parameters(), lr=0.001)
# 训练
for epoch in range(5000):
for x, y in zip(X, Y):
y_pred = model(x)
loss = loss_fn(y, y_pred)
# 梯度清零操作
opt.zero_grad()
loss.backward()
# 更新操作
opt.step()
model:Linear(in_features=1, out_features=1, bias=True)