# 反向传播与 optimizer¶

oneflow.optim 中，有各类 optimizer，它们可以简化实现反向传播的代码。

## numpy 手工实现反向传播¶

import numpy as np

ITER_COUNT = 500
LR = 0.01

# 前向传播
def forward(x, w):
return np.matmul(x, w)

# 损失函数
def loss(y_pred, y):
return ((y_pred - y) ** 2).sum()

# 计算梯度
return np.matmul(x.T, 2 * (y_pred - y))

if __name__ == "__main__":
# 训练目标: Y = 2*X1 + 3*X2
x = np.array([[1, 2], [2, 3], [4, 6], [3, 1]], dtype=np.float32)
y = np.array([[8], [13], [26], [9]], dtype=np.float32)

w = np.array([[2], [1]], dtype=np.float32)
# 训练循环
for i in range(0, ITER_COUNT):
y_pred = forward(x, w)
l = loss(y_pred, y)
if (i + 1) % 50 == 0:
print(f"{i+1}/{500} loss:{l}")

print(f"w:{w}")


50/500 loss:0.0034512376878410578
100/500 loss:1.965487399502308e-06
150/500 loss:1.05524122773204e-09
200/500 loss:3.865352482534945e-12
250/500 loss:3.865352482534945e-12
300/500 loss:3.865352482534945e-12
350/500 loss:3.865352482534945e-12
400/500 loss:3.865352482534945e-12
450/500 loss:3.865352482534945e-12
500/500 loss:3.865352482534945e-12
w:[[2.000001 ]
[2.9999993]]


def gradient(x, y, y_pred):
return np.matmul(x.T, 2 * (y_pred - y))


grad = gradient(x, y, y_pred)


1. 模型根据输入、参数，计算得出预测值 (y_pred)
2. 计算 loss，即预测值与标签之间的误差
3. 求 loss 对参数的梯度
4. 更新参数

## 使用 oneflow.optim 中的优化器类¶

import oneflow as flow

x = flow.tensor([[1, 2], [2, 3], [4, 6], [3, 1]], dtype=flow.float32)
y = flow.tensor([[8], [13], [26], [9]], dtype=flow.float32)

class MyLrModule(flow.nn.Module):
def __init__(self, lr, iter_count):
super().__init__()
self.w = flow.nn.Parameter(flow.tensor([[2], [1]], dtype=flow.float32))
self.lr = lr
self.iter_count = iter_count

def forward(self, x):
return flow.matmul(x, self.w)

model = MyLrModule(0.01, 500)


### loss 函数¶

loss = flow.nn.MSELoss(reduction="sum")


### 构造 optimizer¶

optimizer = flow.optim.SGD(model.parameters(), model.lr)


### 训练¶

for i in range(0, model.iter_count):
y_pred = model(x)
l = loss(y_pred, y)
if (i + 1) % 50 == 0:
print(f"{i+1}/{model.iter_count} loss:{l.numpy()}")

l.backward()
optimizer.step()

print(f"\nw: {model.w}")


50/500 loss:0.003451163647696376
100/500 loss:1.965773662959691e-06
150/500 loss:1.103217073250562e-09
200/500 loss:3.865352482534945e-12
250/500 loss:3.865352482534945e-12
300/500 loss:3.865352482534945e-12
350/500 loss:3.865352482534945e-12
400/500 loss:3.865352482534945e-12
450/500 loss:3.865352482534945e-12
500/500 loss:3.865352482534945e-12

w: tensor([[2.],