使用NumPy实现机器学习任务

使用最原始的的NumPy实现一个有关回归的机器学习任务,不使用PyTorch中的包或类。代码可能会多一点,但每一步都是透明的,有利于理解每一步的工作原理。

主要步骤如下:

1)首先,给出一个数组x,然后基于表达式 y = 3x^2 + 2,加上一些噪声数据到达另一组数据。

2)然后,构建一个机器学习模型,学习表达式 y = ax^2 + b 的两个参数a、b。利用数组x、y的数据训练模型。

3)最后,采用梯度下降法,通过多次迭代学习到a、b的值。

import numpy as np
import matplotlib.pyplot as plt

n = 10

# x:生成10个随机数,[0, 1)
x = np.random.rand(n)
print("*"*10 + " x " + "*"*10)
print(x)

# y:生成10个随机数,[0, 1)
y = np.random.rand(n)
print("*"*10 + " y " + "*"*10)
print(y)

# 画散点图
plt.scatter(x, y)
# plt.scatter(x, y, s=100, c='g', marker='*', alpha=0.5)
# x,y:散点的坐标
# s:散点的面积
# c:散点的颜色(默认值为蓝色,'b',其余颜色同plt.plot())
# marker:散点样式(默认值为实心圆,'o',其余样式同plt.plot())
# alpha:散点透明度([0, 1]之间的数,0:完全透明,1:完全不透明)
# linewidths:散点的边缘线宽
# edgecolors:散点的边缘颜色
plt.show()

PyTorch基础知识-新手笔记_数据

运行结果:

PyTorch基础知识-新手笔记_数据_02

PyTorch基础知识-新手笔记_NumPy_03

import numpy as np

# 设置随机数种子
np.random.seed(10)

# 输入数据x:从[-1, 1]均匀切分成10份,形状为10×1
x = np.linspace(-1, 1, 10).reshape(10, 1)
print("*"*10 + " x " + "*"*10)
print(x)

# 输出x中的元素个数
print("*"*10 + " x.size " + "*"*10)
print(x.size)

# 输出x的形状
print("*"*10 + " x.shape " + "*"*10)
print(x.shape)

# 生成值在[0, 1)之间,元素个数为x的元素个数
print("*"*10 + " np.random.rand(x.size) " + "*"*10)
print(np.random.rand(x.size))

# 生成值在[0, 1)之间,元素个数为x的元素个数,形状为10×1
print("*"*10 + " np.random.rand(x.size).reshape(10, 1) " + "*"*10)
print(np.random.rand(x.size).reshape(10, 1))

运行结果:

PyTorch基础知识-新手笔记_机器学习_04

# 编辑器:PyCharm  解释器:Python=3.9

# 使用NumPy实现机器学习任务
import numpy as np
from matplotlib import pyplot as plt

# 设置随机数种子,生成同一份数据,以便用多种方法比较
np.random.seed(100)

# 输入数据x:从[-1, 1]均匀切分成100份,形状为100×1
x = np.linspace(-1, 1, 100).reshape(100, 1)
print("*"*10 + " x " + "*"*10)
print(x)

# 目标数据y = 3x^2 + 2 + 噪声数据(生成值在[0, 1)之间,元素个数为x的元素个数,形状为100×1)
# y = 3*pow(x, 2) + 2 + 0.2*np.random.rand(x.size).reshape(10, 1)
# y = 3*pow(x, 2) + 2
# print("*"*10 + " y = 3*pow(x, 2) + 2 " + "*"*10)
# print(y)

# 画图:查看x,y的数据分布情况
# plt.scatter(x, y)
# plt.show()

y = 3*np.power(x, 2) + 2 + 0.2*np.random.rand(x.size).reshape(100, 1)
print("*"*10 + " y = 3*pow(x, 2) + 2 + 0.2*np.random.rand(x.size).reshape(10, 1) " + "*"*10)
print(y)

# 画图:查看x,y的数据分布情况
plt.scatter(x, y)
plt.show()

# 随机初始化参数a1
a1 = np.random.rand(1, 1)
print("*"*10 + " a1 " + "*"*10)
print(a1)

# 随机初始化参数b1
b1 = np.random.rand(1, 1)
print("*"*10 + " b1 " + "*"*10)
print(b1)

# 学习率
lr = 0.001
print("*"*10 + " lr " + "*"*10)
print(lr)

for i in range(800):
    # 正向传播
    y_pred = np.power(x, 2)*a1 + b1
    print("*" * 10 + " y_pred = np.power(x, 2)*a1 + b1 " + "*" * 10)
    print(y_pred)

    # 定义损失函数
    loss = 0.5*(y_pred-y) ** 2
    print("*" * 10 + " loss " + "*" * 10)
    print(loss)

    loss = loss.sum()
    print("*" * 10 + " loss.sum() " + "*" * 10)
    print(loss)

    # 计算梯度(求偏导):grad_a
    grad_a = np.sum((y_pred - y)*np.power(x, 2))
    print("*" * 10 + " grad_a " + "*" * 10)
    print(grad_a)

    # 计算梯度(求偏导):grad_b
    grad_b = np.sum((y_pred-y))
    print("*" * 10 + " grad_b " + "*" * 10)
    print(grad_b)

    # 使用梯度下降法学习参数,损失值最小
    a1 -= grad_a*lr
    print("*" * 10 + " a1 " + "*" * 10)
    print(a1)

    b1 -= grad_b*lr
    print("*" * 10 + " b1 " + "*" * 10)
    print(b1)

# 可视化结果:显示连线图
plt.plot(x, y_pred, 'r-', label='predict', linewidth=4)
# 可视化结果:显示散点图
plt.scatter(x, y, color='blue', marker='o', label='true')
# x的范围
plt.xlim(-1, 1)
# y的范围
plt.ylim(2, 6)
# 图例
plt.legend()
# 显示
plt.show()

# 打印输出预测值 a1,b1
print("*" * 10 + " a1, b1 " + "*" * 10)
print(a1, b1)

PyTorch基础知识-新手笔记_NumPy_05

运行结果:

NumPy实现的源数据

PyTorch基础知识-新手笔记_机器学习_06

可视化NumPy的学习结果:

predict:预测数据线(连线图)          true:源数据(散点图)

PyTorch基础知识-新手笔记_NumPy_07

结果部分截图:

PyTorch基础知识-新手笔记_数据_08

使用Tensor及autograd实现机器学习任务

使用PyTorch自动求导的autograd包及对应的Tensor,以利用自动反向传播来求梯度。

# 编辑器:PyCharm  解释器:Python=3.9

# 使用 Tensor 及 autograd 实现机器学习任务
# 1)导入需要的库
import torch
from matplotlib import pyplot as plt

# 2)生成训练数据,并可视化数据分布情况
# 设置随机数种子,生成同一份数据,以便用多种方法进行比较
torch.manual_seed(100)

# 定义数据类型为浮点型
dtype = torch.float

# 生成x坐标数据,x为tensor,形状为100×1,dim=1:最后形成1列(2维),范围[-1, 1],均匀切分成100份。
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
print("*" * 10 + " x " + "*" * 10)
print(x)

# 生成:y = 3x^2 + 2
# y = 3*x.pow(2) + 2
# print("*" * 10 + " y = 3x^2 + 2 " + "*" * 10)
# print(y)

# 打印输出x的形状
# print("*" * 10 + " x.size() " + "*" * 10)
# print(x.size())

# 打印输出x的形状
# print("*" * 10 + " x.shape " + "*" * 10)
# print(x.shape)

# 噪声:服从均匀分布的随机数,范围再[0,1),形状为x的形状,
# y = 0.2*torch.rand(x.size())
# print("*" * 10 + " y = 0.2*torch.rand(x.size()) " + "*" * 10)
# print(y)

# 生成y坐标数据,y为tensor,形状为100×1,另外加上一些噪声
y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size())
print("*" * 10 + " y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size()) " + "*" * 10)
print(y)

# 画图,把tensor数据转换为numpy数据,散点图
plt.scatter(x.numpy(), y.numpy())
plt.xlabel("x")
plt.ylabel("y")

plt.show()

# 3)初始化权重参数
# 随机初始化参数,参数a,b是需要学习的,故需设置为:requires_grad=True,自动求导
# a:服从标准正态分布,形状为1×1(二维),自动求导
a = torch.randn(1, 1, dtype=dtype, requires_grad=True)
print("*" * 10 + " a " + "*" * 10)
print(a)

# b:全0,形状为1×1(二维),自动求导
b = torch.zeros(1, 1, dtype=dtype, requires_grad=True)
print("*" * 10 + " b " + "*" * 10)
print(b)

# 4)训练模型
# 学习率
lr = 0.001
print("*" * 10 + " lr " + "*" * 10)
print(lr)

for i in range(800):
    # forward:计算loss
    # y_pred = x.pow(2).mm(a)
    # print("*" * 10 + " y_pred = ax^2 " + "*" * 10)
    # print(y_pred)

    # y_pred = ax^2 + b         pred:predict,预测
    y_pred = x.pow(2).mm(a) + b
    print("*" * 10 + " y_pred = x.pow(2).mm(a) + b " + "*" * 10)
    print(y_pred)

    # 定义损失函数:loss = 0.5*(y_pred-y)^2
    loss = 0.5 * (y_pred - y)**2
    print("*" * 10 + " loss = 0.5 * (y_pred - y)**2 " + "*" * 10)
    print(loss)

    loss = loss.sum()
    print("*" * 10 + " loss.sum() " + "*" * 10)
    print(loss)

    # backward:自动计算梯度
    loss.backward()

    # backward计算loss对a的偏导数
    print("*" * 10 + " a.grad " + "*" * 10)
    print(a.grad)

    # backward计算loss对b的偏导数
    print("*" * 10 + " b.grad " + "*" * 10)
    print(b.grad)

    # 手动更新参数,需要使用torch.no_grad()更新参数
    # 阻止 autograd 去跟踪那些标记为 requires_grad = True 的张量的历史记录 以及 不再自动计算张量的梯度值
    with torch.no_grad():
        # 梯度下降法更新参数 a = a - 学习率*偏导数
        a -= lr * a.grad
        print("*" * 10 + " a " + "*" * 10)
        print(a)

        # 梯度下降法更新参数 b = b - 学习率*偏导数
        b -= lr * b.grad
        print("*" * 10 + " b " + "*" * 10)
        print(b)

        # 因通过 autograd 计算的梯度会 自动累加 到grad中,故每次循环需要把梯度清零
        # a梯度值清零
        a.grad.zero_()
        print("*" * 10 + " a.grad " + "*" * 10)
        print(a.grad)

        # b梯度值清零
        b.grad.zero_()
        print("*" * 10 + " b.grad " + "*" * 10)
        print(b.grad)

print("*" * 10 + " x.requires_grad " + "*" * 10)
print(x.requires_grad)

print("*" * 10 + " y_pred.requires_grad " + "*" * 10)
print(y_pred.requires_grad)

# 5)查看可视化训练结果
# 绘制连线图:预测线
plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='predict', linewidth=4)
# plt.plot(x.numpy(), y_pred.numpy(), 'r-', label='predict', linewidth=4)

# 绘制散点图:目标函数
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true')

# 规定x的范围
plt.xlim(-1, 1)
plt.xlabel("x")

# 规定y的范围
plt.ylim(2, 6)
plt.ylabel("y")

# 是否显示 图表中的辅助信息(图例)
plt.legend()

# 是否显示图表
plt.show()

# 输出最终的预测值
print("*" * 10 + " a,b " + "*" * 10)
print(a, b)

运行结果:

可视化输入数据:目标函数+噪声数据 的 散点图

PyTorch基础知识-新手笔记_数据_09

使用autograd的结果:

PyTorch基础知识-新手笔记_机器学习_10

结果部分截图:

PyTorch基础知识-新手笔记_机器学习_11

使用优化器及自动微分实现机器学习任务

使用PyTorch 内置的损失函数、优化器 和 自动微分机制 等可大大简化整个机器学习的过程。

梯度更新简化为optimizer.step()

梯度清零optimizer.zero_grad()

PyTorch基础知识-新手笔记_数据_12

# 编辑器:PyCharm  解释器:Python=3.9

# 使用 优化器 及 自动微分 实现机器学习任务
# 1)导入需要的库
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

# 2)生成训练数据,并可视化数据分布情况
torch.manual_seed(100)
data_type = torch.float

# 生成x坐标数据,x为tensor,形状为100×1,二维数组,(把[-1, 1]均匀切分成100份,dim=1最后形成1列)
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
print("*"*10 + " x " + "*"*10)
print(x)

# 生成y坐标数据,y为tensor,形状为100×1,二维数组,y = 3x^2 + 2 + 噪声数据
y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size())

# 画图,把 tensor 数据转换为 numpy 数据,scatter:散点图
plt.scatter(x.numpy(), y.numpy())

# x轴坐标名称
plt.xlabel("x")

# y轴坐标名称
plt.ylabel("y")

# 是否显示散点图
plt.show()

# 生成形状为1×1(二维矩阵),数据类型为:浮点数,需要自动求导,服从 标准正态分布 的随机数,N~(0, 1)
a = torch.randn(1, 1, dtype=data_type, requires_grad=True)
print("*"*10 + " a " + "*"*10)
print(a)

# 生成形状为1×1(二维矩阵),数据类型为:浮点数,需要自动求导,全0
b = torch.zeros(1, 1, dtype=data_type, requires_grad=True)
print("*"*10 + " b " + "*"*10)
print(b)

# 3) 定义 损失函数 及 优化器
loss_func = nn.MSELoss()
print("*"*10 + " loss_func " + "*"*10)
print(loss_func)

# 定义 优化器
optimizer = torch.optim.SGD([a, b], lr=0.001)
print("*"*10 + " optimizer " + "*"*10)
print(optimizer)

# 4) 训练模型
for i in range(10000):
    # forward(正向传播),定义预测函数: y_pred = ax^2 + b
    y_pred = x.pow(2).mm(a) + b
    print("*" * 10 + " y_pred = x.pow(2).mm(a) + b " + "*" * 10)
    print(y_pred)

    # 计算损失函数( 相当于 NumPy 中的 定义损失函数 + 损失函数求和 )
    loss = loss_func(y_pred, y)
    print("*" * 10 + " loss " + "*" * 10)
    print(loss)

    # 自动计算梯度( 相当于 NumPy 中的 计算梯度,求 偏导值)
    loss.backward()

    # 输出 a.grad 的值
    print("*" * 10 + " a.grad " + "*" * 10)
    print(a.grad)

    # 输出 b.grad 的值
    print("*" * 10 + " b.grad " + "*" * 10)
    print(b.grad)

    # 更新参数( 相当于 NumPy 中的 使用梯度下降法,手动更新参数 )
    optimizer.step()
    # a = a - lr*a.grad
    # b = b - lr*b.grad

    # 输出更新参数a
    print("*" * 10 + " a " + "*" * 10)
    print(a)

    # 输出更新参数b
    print("*" * 10 + " b " + "*" * 10)
    print(b)

    # 通过 autograd 计算的梯度会 累加 到 grad 中, 故每次循环需要把梯度清零
    optimizer.zero_grad()

    # a.grad 清零: None
    print("*" * 10 + " a.grad " + "*" * 10)
    print(a.grad)

    # b.grad 清零: None
    print("*" * 10 + " b.grad " + "*" * 10)
    print(b.grad)

# 查看可视化运行结果
# 绘制 预测函数:y_pred 的图像
plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='predict', linewidth=4)

# 绘制 目标函数 的散点图
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true')

# 定义x轴的范围,名称
plt.xlim(-1, 1)
plt.xlabel("x")

# 定义y轴的范围,名称
plt.ylim(2, 6)
plt.ylabel("y")

# plt.legend() 需要放到 plt.show() 前面
# 显示图例
plt.legend()

# 显示图表
plt.show()

# 输出最终的预测值
print("*" * 10 + " a, b " + "*" * 10)
print(a, b)

运行结果:

可视化输入数据:目标函数+噪声数据

PyTorch基础知识-新手笔记_NumPy_13

使用优化器及自动微分(autograd)的结果:

PyTorch基础知识-新手笔记_NumPy_14

结果部分截图:

PyTorch基础知识-新手笔记_NumPy_15

把数据集转换为带批量处理功能的迭代器

把数据集转换为带批量处理功能的迭代器,这样训练时就可进行批量处理。如果数据量比较大,采用批量处理可提升训练模型的效率及性能。

# 编辑器:PyCharm  解释器:Python=3.9

# 把 数据集 转换为 带批量处理功能 的 迭代器
# 导入需要的库
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn

# 1)构建数据迭代器
# features:对应自变量x,labels:对应目标函数y,batch_size:对应每批需要处理的数据量
def data_iter(features, labels, batch_size=4):
    # 定义自变量的个数
    num_examples = len(features)
    print("*" * 10 + " num_examples " + "*" * 10)
    print(num_examples)

    # 定义自变量的下标
    indices = list(range(num_examples))
    print("*" * 10 + " indices " + "*" * 10)
    print(indices)

    # 打乱自变量的下标,使样本的读取顺序是随机的
    np.random.shuffle(indices)
    print("*" * 10 + " shuffle-indices " + "*" * 10)
    print(indices)

    # 按照 batch_size 批量输出数据
    for i in range(0, num_examples, batch_size):
        # 定义批量输出数据的下标,min:当未取整时,最后输出的下标为num_examples
        indexs = torch.LongTensor(indices[i: min(i + batch_size, num_examples)])
        print("*" * 10 + " for-i, i + batch_size, num_examples " + "*" * 10)
        print(i, i+batch_size, num_examples)

        # 输出打乱顺序后的下标值
        print("*" * 10 + " i, min(i + batch_size, num_examples " + "*" * 10)
        print(indices[i: min(i + batch_size, num_examples)])

        # 输出打乱顺序后的下标值
        print("*" * 10 + " for-indexs " + "*" * 10)
        print(indexs)

        # 输出打乱顺序后的 x 值
        print("*" * 10 + " x:features.index_select(0, indexs) " + "*" * 10)
        print(features.index_select(0, indexs))

        # 输出打乱顺序后的 y 值
        print("*" * 10 + " y:labels.index_select(0, indexs) " + "*" * 10)
        print(labels.index_select(0, indexs))

        # features -> x                         labels -> y
        # yield是一个类似于return的关键字,yield 返回的是一个 生成器。
        # 这里 yield 返回的时 打乱下标顺序后的 x的值 和 y的值。
        yield features.index_select(0, indexs), labels.index_select(0, indexs)

# 设置随机数种子,生成同一份数据,以便用多种方法进行比较
torch.manual_seed(100)

# 设置数据类型为浮点型
data_type = torch.float

# 生成x坐标数据,x为tensor,形状为100×1,二维数组,(把[-1, 1]均匀切分成100份,dim=1最后形成1列)
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
print("*"*10 + " x " + "*"*10)
print(x)

# 生成y坐标数据,y为tensor,形状为100×1,二维数组,y = 3x^2 + 2 + 噪声数据
y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size())
print("*"*10 + " y = 3x^2 + 2 + 0.2*torch.rand(x.size()) " + "*"*10)
print(y)

# 画图,把 tensor 数据转换为 numpy 数据,scatter:散点图
plt.scatter(x.numpy(), y.numpy())

# x轴坐标名称
plt.xlabel("x")

# y轴坐标名称
plt.ylabel("y")

# 是否显示散点图
plt.show()

# 生成形状为1×1(二维矩阵),数据类型为:浮点数,需要自动求导,服从 标准正态分布 的随机数,N~(0, 1)
a = torch.randn(1, 1, dtype=data_type, requires_grad=True)
print("*"*10 + " a " + "*"*10)
print(a)

# 生成形状为1×1(二维矩阵),数据类型为:浮点数,需要自动求导,全0
b = torch.zeros(1, 1, dtype=data_type, requires_grad=True)
print("*"*10 + " b " + "*"*10)
print(b)

# 定义 损失函数 及 优化器
# 定义 损失函数
loss_func = nn.MSELoss()
print("*"*10 + " loss_func " + "*"*10)
print(loss_func)

# 定义 优化器
optimizer = torch.optim.SGD([a, b], lr=0.001)
print("*"*10 + " optimizer " + "*"*10)
print(optimizer)

# 2)训练模型
for i in range(1000):
    # features:对应自变量x,labels:对应目标函数y,batch_size:对应每批需要处理的数据量,此处为10
    for features, labels in data_iter(x, y, 10):
        # forward(正向传播),定义预测函数:y_pred = ax^2 + b
        y_pred = features.pow(2).mm(a) + b
        print("*" * 10 + " y_pred = features.pow(2).mm(a) + b " + "x" * 10)
        print(y_pred)

        print("*" * 10 + " y_pred.size() " + "x" * 10)
        print(y_pred.size())

        print("*" * 10 + " x.size() " + "x" * 10)
        print(x.size())

        # 计算损失函数( 相当于NumPy中的 定义损失函数 + 损失函数求和 )
        loss = loss_func(y_pred, labels)
        print("*" * 10 + " loss " + "x" * 10)
        print(loss)

        # 自动计算梯度( 相当于 NumPy 中的 计算梯度,求 偏导值)
        loss.backward()

        # 输出 a.grad 的值
        print("*" * 10 + " a.grad " + "*" * 10)
        print(a.grad)

        # 输出 b.grad 的值
        print("*" * 10 + " b.grad " + "*" * 10)
        print(b.grad)

        # 更新参数( 相当于 NumPy 中的 使用梯度下降法,手动更新参数 )
        optimizer.step()
        # a = a - lr*a.grad
        # b = b - lr*b.grad

        # 输出更新参数a
        print("*" * 10 + " a " + "*" * 10)
        print(a)

        # 输出更新参数b
        print("*" * 10 + " b " + "*" * 10)
        print(b)

        # 通过 autograd 计算的梯度会 累加 到 grad 中, 故每次循环需要把梯度清零
        optimizer.zero_grad()

        # a.grad 清零: None
        print("*" * 10 + " a.grad " + "*" * 10)
        print(a.grad)

        # b.grad 清零: None
        print("*" * 10 + " b.grad " + "*" * 10)
        print(b.grad)

# 3)查看可视化运行结果
# 绘制 预测函数:y_pred 的图像
# plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='predict', linewidth=4)

# 显示 y_predict.size() 形状
y_predict = x.pow(2).mm(a) + b
print("*" * 10 + " y_predict.size() " + "*" * 10)
print(y_predict.size())

# 使 y_p.size() 与 x.size() 的形状相同,以及 自动求导 的 参数分离
y_p = x.pow(2).mm(a).detach().numpy() + b.detach().numpy()

# 绘制 预测函数:y_pred 的图像
plt.plot(x.numpy(), y_p, 'r-', label='predict', linewidth=4)

# 绘制 目标函数 的散点图
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true')

# 定义x轴的范围,名称
plt.xlim(-1, 1)
plt.xlabel("x")

# 定义y轴的范围,名称
plt.ylim(2, 6)
plt.ylabel("y")

# plt.legend() 需要放到 plt.show() 前面
# 显示图例
plt.legend()

# 显示图表
plt.show()

# 输出最终的预测值
print("*" * 10 + " a, b " + "*" * 10)
print(a, b)

运行结果:

可视化输入数据:目标函数+噪声数据

PyTorch基础知识-新手笔记_NumPy_16

使用数据迭代器、优化器和自动微分(autograd)的结果:

PyTorch基础知识-新手笔记_NumPy_17

结果部分截图:

PyTorch基础知识-新手笔记_数据_18

使用 TensorFlow2 实现机器学习任务

使用TensorFlow2实现这个任务

# 编辑器:PyCharm      解释器:python=3.8     框架:tensorflow2.13

# 1) 导入库
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'
# 设置log输出信息,程序运行时系统的打印的信息。
# 0:输出 INFO + WARNING + ERROR + FATAL
# 1:输出 WARNING + ERROR + FATAL
# 2:输出 ERROR + FATAL
# 3:输出 FATAL
# https://blog.csdn.net/qq_40549291/article/details/85274581

# 2) 生成 训练数据 并 初始化参数

# 生成训练数据
# 设置随机数种子,生成同一份数据,以便用多种方法进行比较
np.random.seed(100)

# 生成x坐标数据,把[-1, 1]均匀切分成100份,形状为100×1,二维数组
x = np.linspace(-1, 1, 100).reshape(100, 1)
print("*" * 10 + " x " + "*" * 10)
print(x)

# 生成噪声数据
y = 0.2 * np.random.rand(x.size).reshape(100, 1)
print("*" * 10 + " y = np.random.rand(x.size).reshape(10, 1) " + "*" * 10)
print(y)

# 生成y坐标数据,y = 3x^2 + 2 + 噪声数据, 形状为100×1,二维数组,
y = 3*np.power(x, 2) + 2 + 0.2 * np.random.rand(x.size).reshape(100, 1)
print("*" * 10 + " y = 3x^2 + 2 + 0.2 * np.random.rand(x.size).reshape(10, 1) " + "*" * 10)
print(y)

# 画散点图:scatter
plt.scatter(x, y)

# x轴坐标名称
plt.xlabel("x")

# y轴坐标名称
plt.ylabel("y")

# 是否显示散点图
plt.show()

# 创建权重变量a和b,并用随机值初始化
# 形状:[1],服从区间[0, 1.0) 上的均匀分布
a = tf.Variable(tf.random.uniform([1], 0, 1.0))
print("*" * 10 + " a " + "*" * 10)
print(a)

# 形状:[1],全0
b = tf.Variable(tf.zeros([1]))
print("*" * 10 + " b " + "*" * 10)
print(b)

# 3)构建模型

# 定义模型
class CustNet:
    def __call__(self, x):
        # 定义预测函数
        y_pre = np.power(x, 2) * a + b
        print("*" * 10 + " y_pre = np.power(x, 2)*a + b " + "*" * 10)
        print(y_pre)

        # 返回预测函数 y_pre = ax^2 + b
        return np.power(x, 2)*a + b

    # 定义损失函数:y_true:目标函数  y_pred:预测函数
    def loss_func(self, y_true, y_pred):
        # 降维 或者 计算平均值
        return tf.reduce_mean((y_true - y_pred)**2/2)

# 定义模型变量
model = CustNet()
print("*" * 10 + " model " + "*" * 10)
print(model)

# 4) 训练模型
# 定义最大的训练次数
epochs = 24000
print("*" * 10 + " epochs " + "*" * 10)
print(epochs)

# for循环范围:[1, epochs)
for epoch in tf.range(1, epochs):
    # tf.GradientTape():TensorFlow提供的自动微分接口,tape:磁带
    with tf.GradientTape() as tape:
        # 打印现在处于第几轮模型训练
        print("*" * 10 + " epoch " + "*" * 10)
        print(epoch)

        # 定义 预测函数
        predictions = model(x)
        print("*" * 10 + " predictions " + "*" * 10)
        print(predictions)

        # 调用 损失函数,y:目标函数  predictions:预测函数
        loss = model.loss_func(y, predictions)
        print("*" * 10 + " loss " + "*" * 10)
        print(loss)

        # 反向传播求梯度,分别对a,b求偏导。
        da, db = tape.gradient(loss, [a, b])
        print("*" * 10 + " da " + "*" * 10)
        print(da)

        print("*" * 10 + " db " + "*" * 10)
        print(db)

        # 梯度下降法更新参数a
        a.assign(a - 0.001*da)
        print("*" * 10 + " a " + "*" * 10)
        print(a)

        # 梯度下降法更新参数b
        b.assign(b - 0.001*db)
        print("*" * 10 + " b " + "*" * 10)
        print(b)

        # tensorflow:梯度值不需要清零。

# 可视化结果
# 打印多张图片
# plt.figure()

# 画散点图:目标函数
plt.scatter(x, y, color='blue', marker='o', label='ture')

# 画连线图:预测函数
plt.plot(x, b+a*x**2, 'r-', label='predict', linewidth=4)

# 设置x坐标轴的范围
plt.xlim(-1, 1)

# 设置x坐标轴 标签
plt.xlabel("x")

# 设置y坐标轴的范围
plt.ylim(2, 6)

# 设置y坐标轴 标签
plt.ylabel("y")

# 显示图片
plt.show()

# 打印输出a,b的预测值
print("*" * 10 + " a, b " + "*" * 10)
print(a, b)

运行结果:

可视化输入数据:目标函数+噪声数据

PyTorch基础知识-新手笔记_机器学习_19

使用 TensorFlow 的结果:

PyTorch基础知识-新手笔记_NumPy_20

结果部分截图:

PyTorch基础知识-新手笔记_数据_21

小结

PyTorch基础知识是后续章节的重要支撑,介绍了PyTorch的安装配置(GPU版),PyTorch的重要数据结构Tensor。Tensor是类似于NumPy的数据结构,但Tensor提供了GPU加速及自动求导等技术。分别用NumPy、Tensor、autograd、优化器和TensorFlow2等技术分别实现了同一个机器学习的任务。