import torch
import matplotlib.pyplot as plt
x_data = torch.Tensor([ [1.0],[2.0],[3.0] ])
y_data = torch.Tensor([ [2.0],[4.0],[6.0] ])
损失如果计算为向量是无法构建计算图
第一个参数 1 表示输入特征的数量,也就是模型接收的每个样本的特征数量。在这个例子中,输入特征的数量为 1。 第二个参数 1 表示输出特征的数量,也就是线性层输出的特征数量。在这个例子中,输出特征的数量为 1。
class LinearModel(torch.nn.Module): # 所有的类都要继承自moudledef __init__(self): # initial他的构造函数# 初始化对象时候所构造的函数super(LinearModel,self).__init__() # 调用父类的initself.linear = torch.nn.Linear(1,1) # 类后加括号构造对象,权重与偏置# linear也是继承自moudle,可以自动进行反向传播def forward(self , x): # 必须药叫做forwardy_pred = self.linear(x)# 对象后面加括号是实现一个可调用对象return y_pred
model = LinearModel()
是的,你说得对。在PyTorch中,通常将模型的前向传播分成两部分:
可调用的forward方法:这部分实现了模型的计算部分,即将输入数据通过模型的各个层进行前向传播,从而生成模型的输出。在这个过程中,forward方法定义了模型的具体计算逻辑,包括数据的传递、变换和计算。这部分通常位于模型的内部,即模型类的定义中。
外部调用的forward方法:这部分主要用于将模型的计算结果返回给用户。在PyTorch中,通常不直接调用模型的forward方法,而是通过调用模型对象来触发前向传播过程。当你调用模型对象时(例如model(x)),PyTorch会自动调用内部的forward方法,完成模型的计算,并将计算结果返回给用户。这部分通常位于模型的外部,即模型对象被调用的地方。
综上所述,可调用的forward方法实现了模型的计算部分,而外部调用的forward方法则实现了返回计算结果部分。这种分工使得模型的定义更加清晰和灵活,同时也方便了模型的使用。
在你的代码中,你对模型的前向传播方法命名为testt而不是约定俗成的forward。这样的话,PyTorch会认为你没有定义模型的前向传播方法,而是定义了一个新的方法testt。因此,在使用模型进行前向传播时,你将无法使用model(x)的方式调用,而需要使用model.testt(x)。
这会导致两个问题:
不符合PyTorch的约定:PyTorch规定模型的前向传播方法必须命名为forward,这样才能让PyTorch在调用时自动识别并执行前向传播逻辑。
使用不便:将前向传播方法命名为非约定俗成的名字会导致使用不便,因为你需要记住不同模型的不同方法名称,并且不能够直接通过model(x)的方式调用。
因此,建议你将前向传播方法的名字改为forward,这样符合PyTorch的约定,也更加方便使用。
损失函数和优化器
criterion = torch.nn.MSELoss(size_average = False)
reduction='sum’表示将每个样本的损失相加,得到总的损失值。这意味着对每个样本的损失不做平均处理,而是直接相加,得到整个批次的总损失。这种方式适用于需要对整个批次的损失进行分析的情况,例如在训练过程中进行梯度更新时。
除了sum之外,reduction参数还支持其他几种选项,包括:
‘mean’:对每个样本的损失求平均值。 ‘none’:不进行汇总,保留每个样本的损失值。这种方式适用于需要对每个样本的损失进行单独处理的情况。
criterion = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
# learning rate
model.parameters()
list(model.parameters())
[Parameter containing:tensor([[-0.9493]], requires_grad=True),Parameter containing:tensor([0.3216], requires_grad=True)]
第一个参数是权重(weight),它是一个张量,形状为(1, 1),即一个标量。 第二个参数是偏置(bias),也是一个张量,形状为(1,),即一个标量。 这些参数的值是随机初始化的,因为你在代码中没有指定初始值,所以PyTorch会使用默认的初始化策略来初始化这些参数。在训练过程中,这些参数的值会随着反向传播算法的执行而不断更新,以最小化损失函数。
for epoch in range(100):y_pred = model(x_data)loss = criterion(y_pred,y_data)print(epoch,loss.item())plt.scatter(epoch,loss.data)optimizer.zero_grad() # 所有权重的梯度归零loss.backward() # 反向传播optimizer.step() # 更新
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)