【Matlab】应急物资调度多目标优化算法实现
2026/7/13 17:40:34
@浙大疏锦行
核心目标:
nn.Module,亲手搭建一个多层感知机 (MLP)。涉及知识点:
torch.Tensor,nn.Module,nn.Linear,nn.ReLU.torch.optim.SGD(随机梯度下降).nn.CrossEntropyLoss(交叉熵).场景类比:
fit)就能吃(predict),但口味固定。场景描述:
神经网络对数据非常敏感。
Tensor。特征通常是FloatTensor(浮点数),分类标签必须是LongTensor(长整型)。任务:
MinMaxScaler进行归一化。importtorchimportnumpyasnpfromsklearn.datasetsimportload_irisfromsklearn.model_selectionimporttrain_test_splitfromsklearn.preprocessingimportMinMaxScaler# 1. 加载数据iris=load_iris()X=iris.data y=iris.target# 2. 划分数据X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# 3. 归一化 (神经网络标准动作)scaler=MinMaxScaler()X_train=scaler.fit_transform(X_train)X_test=scaler.transform(X_test)# 4. 转换为 Tensor (关键步骤)# 特征转为 FloatTensor (32位浮点), 标签转为 LongTensor (64位整型,交叉熵要求)X_train_tensor=torch.FloatTensor(X_train)y_train_tensor=torch.LongTensor(y_train)X_test_tensor=torch.FloatTensor(X_test)y_test_tensor=torch.LongTensor(y_test)print(f"训练集 Tensor 形状:{X_train_tensor.shape}")print(f"标签 Tensor 类型:{y_train_tensor.dtype}")训练集 Tensor 形状: torch.Size([120, 4]) 标签 Tensor 类型: torch.int64场景描述:
我们要搭建一个简单的MLP (多层感知机)来处理 Iris 分类。
输入是 4 个特征,输出是 3 个类别。中间加一层隐藏层(比如 10 个神经元)和激活函数。
PyTorch 建模八股文:
nn.Module。__init__里定义有哪些层(零件)。forward里定义数据怎么流向(组装)。任务:
定义SimpleMLP类,包含:输入层(4)->隐藏层(10)->ReLU->输出层(3)。
importtorch.nnasnnclassSimpleMLP(nn.Module):def__init__(self):super(SimpleMLP,self).__init__()# 标准起手式# 定义层 (零件)# 4 -> 10self.fc1=nn.Linear(in_features=4,out_features=10)# 激活函数self.relu=nn.ReLU()# 10 -> 3 (输出层)self.fc2=nn.Linear(in_features=10,out_features=3)defforward(self,x):# 定义前向传播路径 (组装)# x -> fc1 -> relu -> fc2 -> outputout=self.fc1(x)out=self.relu(out)out=self.fc2(out)# 注意:这里不需要 Softmax,因为 CrossEntropyLoss 自带了returnout# 实例化模型model=SimpleMLP()print(model)SimpleMLP( (fc1): Linear(in_features=4, out_features=10, bias=True) (relu): ReLU() (fc2): Linear(in_features=10, out_features=3, bias=True) )场景描述:
这是 PyTorch 最劝退也最核心的部分。
不同于model.fit()一键搞定,我们需要手写循环:
任务:
CrossEntropyLoss和 优化器SGD。importtorch.optimasoptimimportmatplotlib.pyplotasplt# 1. 定义 Loss 和 Optimizercriterion=nn.CrossEntropyLoss()# 学习率 lr=0.1optimizer=optim.SGD(model.parameters(),lr=0.1)# 2. 开始训练epochs=1000loss_history=[]print("🚀 开始训练...")forepochinrange(epochs):# --- A. 前向传播 ---outputs=model(X_train_tensor)loss=criterion(outputs,y_train_tensor)# --- B. 反向传播与优化 (核心三件套) ---optimizer.zero_grad()# 1. 梯度清零loss.backward()# 2. 反向传播求梯度optimizer.step()# 3. 更新参数# 记录 Lossloss_history.append(loss.item())if(epoch+1)%100==0:print(f"Epoch [{epoch+1}/{epochs}], Loss:{loss.item():.4f}")# 3. 可视化训练过程plt.plot(loss_history)plt.title("Training Loss")plt.xlabel("Epoch")plt.ylabel("Loss")plt.show()print("✅ 训练完成!")🚀 开始训练... Epoch [100/1000], Loss: 0.5708 Epoch [200/1000], Loss: 0.3821 Epoch [300/1000], Loss: 0.2937 Epoch [400/1000], Loss: 0.2323 Epoch [500/1000], Loss: 0.1876 Epoch [600/1000], Loss: 0.1555 Epoch [700/1000], Loss: 0.1325 Epoch [800/1000], Loss: 0.1160 Epoch [900/1000], Loss: 0.1040 Epoch [1000/1000], Loss: 0.0951✅ 训练完成!恭喜你完成了第一个 PyTorch 神经网络!
今天我们最大的收获是打破了黑盒。
sklearn vs PyTorch 对照表:
| 动作 | sklearn (黑盒) | PyTorch (白盒) |
|---|---|---|
| 定义模型 | clf = MLPClassifier() | class MyNet(nn.Module): ... |
| 训练 | clf.fit(X, y) | 写for循环 (前向+反向+更新) |
| 数据 | Numpy 数组 | torch.Tensor |
虽然代码变多了,但你现在拥有了无限的自由。你可以随意修改层数、随意改变数据流向、随意自定义损失函数。这就是深度学习的魅力。
Next Level:
既然有了模型,怎么评估它的好坏?怎么保存它?明天我们将继续完善这个工程!