• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

tintin7790

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

网络定义与训练方式实践报错修改_01

第一次修改

最开始的代码:

import torch
import torch.nn as nn
from torch.optim import SGD
import torch.utils.data as Data
from sklearn.datasets import load_diabetes
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

test_X,text_Y=load_diabetes(return_X_y=True)
print("test_X.shape:",test_X.shape)#test_X.shape: (442, 10)
plt.figure()
plt.hist(test_X,bins=20)
plt.show()

ss=StandardScaler(with_mean=True,with_std=True)
test_Xs=ss.fit_transform(test_X)
train_xt=torch.from_numpy(test_Xs.astype(np.float32))
train_yt=torch.from_numpy(text_Y.astype(np.float32))
train_data=Data.TensorDataset(train_xt,train_yt)

train_loader=Data.DataLoader(
    dataset=train_data,
    batch_size=128,
    shuffle=True,
    num_workers=0,
)
class MLPmodel(nn.Module):
    def __init__(self):
        super(MLPmodel,self).__init__()
        self.hidden1=nn.Linear(
            in_features=13,
            out_features=10,
            bias=True,
        )
        self.active1=nn.ReLU()
        self.hidden2=nn.Linear(10,10)
        self.active2=nn.ReLU()
        self.regression=nn.Linear(10,1)
    def forward(self,x):
        x=self.hidden1(x)
        x=self.active1(x)
        x=self.hidden2(x)
        x=self.active2(x)
        output=self.regression(x)
        return output
mlp1=MLPmodel()
print(mlp1)

optimizer=SGD(mlp1.parameters(),lr=0.001)
loss_finc=nn.MSELoss()
train_loss_all=[]
for eqoch in range(30):
    for step,(t_x,t_y) in enumerate(train_loader):
        output=mlp1.forward(t_x).flatten()
        train_loss=loss_finc(output,t_y)
        optimizer.zero_grad()
        train_loss.backward()
        optimizer.step()
        train_loss_all.append(train_loss.item())

plt.figure()
plt.plot(train_loss_all,"r-")
plt.title("train loss per iteration")
plt.show()

报错信息:

test_X.shape: (442, 10)
MLPmodel(
  (hidden1): Linear(in_features=13, out_features=10, bias=True)
  (active1): ReLU()
  (hidden2): Linear(in_features=10, out_features=10, bias=True)
  (active2): ReLU()
  (regression): Linear(in_features=10, out_features=1, bias=True)
)
Traceback (most recent call last):
  File "/Users/tintin7790/Code/Python/2026_08_15_BasePT/NetworkBase.py", line 56, in <module>
    output=mlp1.forward(t_x).flatten()
           ~~~~~~~~~~~~^^^^^
  File "/Users/tintin7790/Code/Python/2026_08_15_BasePT/NetworkBase.py", line 42, in forward
    x=self.hidden1(x)
  File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/torch/nn/modules/module.py", line 1778, in _wrapped_call_impl
    return self._call_impl(*args, **kwargs)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/torch/nn/modules/module.py", line 1789, in _call_impl
    return forward_call(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/torch/nn/modules/linear.py", line 134, in forward
    return F.linear(input, self.weight, self.bias)
           ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: mat1 and mat2 shapes cannot be multiplied (128x10 and 13x10)

问题1

这里

mat1 and mat2 shapes cannot be multiplied (128x10 and 13x10)

意思是我们

print("test_X.shape:",test_X.shape)#test_X.shape: (442, 10)

现在有442个样本,每一个样本10的特征;而数据加载起DataLoader是每次取出128个样本,所以现在每一批的 t_x.shape 就是[128,10]
但是Linear的第一层需要的是 (hidden1): Linear(in_features=13, out_features=10, bias=True) 输入的特征要求是13个,实际10个,故矛盾;

修改方法直接把hideen1改成(10,10)的就可以了

问题2

output=mlp1.forward(t_x).flatten()
不用mlp.forward(t_x),可以直接mlp(t_x)

问题3

output=mlp1.forward(t_x).flatten()
最好不要直接.flatten() 这个如果要变成只有一个维度的话,要求最后一维是1;
保险一点的方法是

mlp(t_x).squeeze(1) 

把所有的1维度都消掉

验证一些信息

for step, (t_x, t_y) in enumerate(train_loader):

    if step == 0:
        print("输入 shape:", t_x.shape)
        
        print("训练前 weight:")
        print(mlp1.hidden1.weight[0].detach().clone())

    output = mlp1(t_x).squeeze(1)
    loss = loss_func(output, t_y)

    optimizer.zero_grad()
    loss.backward()

    if step == 0:
        print("gradient:")
        print(mlp1.hidden1.weight.grad[0])

    optimizer.step()

    if step == 0:
        print("更新后的 weight:")
        print(mlp1.hidden1.weight[0].detach())
        break

输出:

test_X.shape: (442, 10)
tensor([-0.2486, -0.0022,  0.0016,  0.2443,  0.1218,  0.2509, -0.3026, -0.1832,
        -0.0650,  0.3139])
输入 shape: torch.Size([128, 10])
训练前 weight:
tensor([-0.2486, -0.0022,  0.0016,  0.2443,  0.1218,  0.2509, -0.3026, -0.1832,
        -0.0650,  0.3139])
gradient:
tensor([-0.6605, -1.8336, -2.8694, -5.8795, -3.9161, -3.8048,  2.3278, -3.8724,
        -3.9254, -5.9606])
更新后的 weight:
tensor([-0.2479, -0.0004,  0.0044,  0.2502,  0.1258,  0.2547, -0.3049, -0.1793,
        -0.0610,  0.3198])

从一个可以手写的例子来看看w和b是在程序中的变化

import torch
import torch.optim as optim
import torch.nn as nn

layer=nn.Linear(2,1)
print(layer.weight.shape)#torch.Size([1, 2])
print(layer.weight)
#Parameter containing:
#tensor([[-0.6154,  0.5851]], requires_grad=True)


print(layer.bias.shape)#torch.Size([1])
print(layer.bias)
#Parameter containing:
#tensor([0.5605], requires_grad=True)

with torch.no_grad():
    layer.weight[:] = torch.tensor([[2.0, 3.0]])
    layer.bias[:] = torch.tensor([1.0])

x=torch.tensor([[4.0,5.0]])
y=layer(x)

print(y)#tensor([[24.]], grad_fn=<AddmmBackward0>)
print(y.shape)
target=torch.tensor([[20.0]])

loss=(y-target)**2

loss.backward()
print("weight gradient:")
print(layer.weight.grad)

print("bias gradient:")
print(layer.bias.grad)
optimizer=optim.SGD(
    layer.parameters(),
    lr=0.01,
)

optimizer.step()

print(layer.weight)
print(layer.bias)

nn.Linear 中参数的创建、梯度计算与更新

以一个最简单的线性层为例:

import torch
import torch.nn as nn
from torch.optim import SGD

layer = nn.Linear(2, 1)

执行 nn.Linear(2, 1) 时,PyTorch 会自动创建这一层需要训练的参数:

layer
├── weight    # shape = [1, 2]
└── bias      # shape = [1]

它们都是 nn.Parameter:

print(type(layer.weight))
print(type(layer.bias))

输出:

<class 'torch.nn.parameter.Parameter'>
<class 'torch.nn.parameter.Parameter'>

SGD 参数更新示例

SGD 最基本的更新公式:

new_parameter = old_parameter - learning_rate × gradient

对于本例:

w1_old = 2
w2_old = 3
b_old  = 1

learning_rate = 0.01

dw1 = 32
dw2 = 40
db  = 8

因此第一个权重更新为:

w1_new
= w1_old - learning_rate × dw1
= 2 - 0.01 × 32
= 1.68

第二个权重:

w2_new
= w2_old - learning_rate × dw2
= 3 - 0.01 × 40
= 2.60

bias:

b_new
= b_old - learning_rate × db
= 1 - 0.01 × 8
= 0.92

因此执行:

optimizer.step()

之后:

weight = [[1.68, 2.60]]
bias   = [0.92]

也就是说:

loss.backward()
    ↓
得到 gradient

optimizer.step()
    ↓
parameter = parameter - lr × gradient
    ↓
原来的 weight / bias 被直接更新

posted on 2026-08-15 20:31  tintin7790  阅读(7)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3