Skip to content

Latest commit

 

History

History
68 lines (47 loc) · 2.71 KB

05_线性回归.md

File metadata and controls

68 lines (47 loc) · 2.71 KB

线性回归

​ 在PyTorch中,Tensor(张量)>是基本单元,它包含参数和损失函数关于这个参数的导数。

img

​ 下图的代码定义了一个,w 为 [1.0] 的Tensor,将requires_grad置为True表示这个参数需要计算梯度。默认为False。

​ 如果w需要计算梯度,那么通过w计算得到的a也需要计算梯度,其中w和a都是Tensor。Tensor之间的乘法可以直接用*进行,已经被重载过了。

img

代码示例

代码功能:使用pytorch实现线性回归

  • 需要注意的是,一旦执行过一次backward,就会释放原有的计算图,下次计算时需要创建一个新的计算图。这样设定的目的是因为每次迭代都可能使用不同的计算图。
  • 更新参数时一定记得要转换成标量后再去计算,否则会导致计算图的膨胀。
import torch

# 模拟训练集,这里 y = 2x
x_train = [1, 2, 3]
y_train = [2, 4, 6]

# 创建一个data为1.0的Tensor(张量)
w = torch.Tensor([1.0])
w.requires_grad = True


def forward(x, w):
    # 这里的w和x都是Tensor
    return w * x


def loss(x, y, w):
    y_pred = forward(x, w)
    return (y_pred - y) ** 2


# 训练100次
for epoch in range(100):
    # 这里为了方便理解,不使用向量化
    for x, y in zip(x_train, y_train):
        cost = loss(x, y, w)
        cost.backward()

        # 这里假设学习率为0.01
        # 须注意w.grad其实也是一个张量,更新参数时应该转换成标量来计算
        # 否则张量间的计算会构建计算图,循环多次后,可能会因为计算图过于庞大导致程序崩溃
        w.data = w.data - 0.01 * w.grad.data

        # 手动将原来的导数清零,如果不清零,就会保留原有的值,下次使用时会是 旧值+新值
        # 显然这样的设定是为了方便应用以后的各种优化方法
        w.grad.data.zero_()

    # cost.item()的返回值是一个int或float类型的数据
    # 这里输出的是上个训练集中最后一组数据的cost,并非总的cost
    # 如果要计算cost_total,应在上一个循环中使用sum += cost.item()
    # 如果使用sum_tensor += cost,那么会构建计算图来计算,性能不如直接进行标量运算
    # 但是sum == sum_tensor.item()为True
    print("epoch: ", epoch, ",\tcost: ", cost.item())

print(type(w.item()),w.item()) 	# <class 'float'> 1.9999996423721313
print(type(w.data),w.data) 		# <class 'torch.Tensor'> tensor([2.0000])
print(type(w),w) 				# <class 'torch.Tensor'> tensor([2.0000], requires_grad=True)