网络定义与训练方式实践报错修改_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) 收藏 举报
浙公网安备 33010602011771号