在做项目的过程中,我使用Pytorc和Sklearn和MLPRegressor写了相同结构的网络,但PyTorch的模型总是差很多。Pytorch的网络MSE为3.0,MLP的网络的MSE为2.0。
以下是Sklearn,MLP的代码
import torch
from sklearn.neural_network import MLPRegressor
clf = MLPRegressor(hidden_layer_sizes=(10), batch_size=5,shuffle=False)
clf.fit(x_train,y_train)
y_pred=clf.predict(x_test)
cost = torch.nn.MSELoss()
torch_y_pred = torch.FloatTensor(y_pred)
torch_y_test = torch.FloatTensor(y_test)
print("mse", cost(torch_y_pred, torch_y_test))
这是Pytorch的代码,其中Policy_Network是self.model的网络结构。
class Policy_Network(nn.Module):
def __init__(self):
super(Policy_Network, self).__init__()
self.layer = nn.Sequential(
nn.Linear(INPUT_DIM, 10),
nn.ReLU(True),
nn.Linear(10, 5),
nn.ReLU(True),
nn.Linear(5, 1),
)
self.to("cuda:0")
def __call__(self, x):
return self.layer(x)
for epoch in range(20):
sum_loss = 0
idx = 0
for idx, x in enumerate(self.train_loader):
# 正向传播计算误差
feature, label = self.control_input(x)
predict = self.model(feature).to('cpu')
loss = self.cost(label, predict)
sum_loss += loss.detach().numpy()
# 梯度反向传播更新模型
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
print(f"{epoch} train sum_loss = ", sum_loss / idx)
loss = self.eval()
在尝试过了许多方法,TM最终发现是loss计算时有问题。
为什么这样计算会出现问题呢?举例来说明
$$ pred - true = \begin{bmatrix} 1.1 & 1.5 \end{bmatrix}- \begin{bmatrix} 1 & 0 \end{bmatrix}=\begin{bmatrix} 0.1 & 1.5 \end{bmatrix} $$
$$ MSE( \begin{bmatrix} 0.1 & 1.5 \end{bmatrix}) = (0.01 + 2.25)/2 = 1.13 $$
如果是Pytorch计算Loss时:
$$ pred - true = \begin{bmatrix} 1.1 \\ 1.5\end{bmatrix}- \begin{bmatrix} 1 & 0 \end{bmatrix}=\begin{bmatrix} 0.1 & 1.1 \\ 0.5 & 1.5 \end{bmatrix} $$
$$ MSE(\begin{bmatrix} 0.1 & 1.1 \\ 0.5 & 1.5 \end{bmatrix}) = (0.01+1.21+0.25+2.25)/4=0.93 $$
解决方法:
我们只需要把true提高一个维度,即把$\begin{bmatrix} 1 & 0 \end{bmatrix}$变成$\begin{bmatrix} 1 \\ 0 \end{bmatrix}$即可。