Neural network Pytorch:NN函数逼近器,2合1输出
[请注意以下编辑历史记录,因为主要问题陈述已更改。] 我们试图在pytorch中实现一个神经网络,它近似于函数f(x,y)=z。所以有两个实数作为输入,一个作为输出,因此我们需要在输入层有两个节点,在输出层有一个节点。我们构建了一个由5050个样本组成的测试集,在带有Tensorflow后端的Keras中获得了相当好的结果,有3个隐藏层,节点配置如下:2(in)-4-16-4-1(out);和所有隐藏层上的ReLU激活函数,线性输入和输出 现在,在Pytorch中,我们试图实现一个类似的网络,但我们的损失函数仍在爆炸:它在最初的几个步骤中发生变化,然后收敛到10^7左右的某个值。在Keras中,我们的误差约为10%。我们已经尝试了不同的网络配置,但没有任何改进。也许有人可以看看我们的代码并提出任何修改建议 解释:tr_数据是一个列表,包含5050个2*1 numpy数组,这些数组是网络的输入。tr_标签是一个列表,包含5050个数字,这些数字是我们想要了解的输出。loadData()只需加载这两个列表Neural network Pytorch:NN函数逼近器,2合1输出,neural-network,pytorch,Neural Network,Pytorch,[请注意以下编辑历史记录,因为主要问题陈述已更改。] 我们试图在pytorch中实现一个神经网络,它近似于函数f(x,y)=z。所以有两个实数作为输入,一个作为输出,因此我们需要在输入层有两个节点,在输出层有一个节点。我们构建了一个由5050个样本组成的测试集,在带有Tensorflow后端的Keras中获得了相当好的结果,有3个隐藏层,节点配置如下:2(in)-4-16-4-1(out);和所有隐藏层上的ReLU激活函数,线性输入和输出 现在,在Pytorch中,我们试图实现一个类似的网络,但
import torch.nn as nn
import torch.nn.functional as F
BATCH_SIZE = 5050
DIM_IN = 2
DIM_HIDDEN_1 = 4
DIM_HIDDEN_2 = 16
DIM_HIDDEN_3 = 4
DIM_OUT = 1
LEARN_RATE = 1e-4
EPOCH_NUM = 500
class Net(nn.Module):
def __init__(self):
#super(Net, self).__init__()
super().__init__()
self.hidden1 = nn.Linear(DIM_IN, DIM_HIDDEN_1)
self.hidden2 = nn.Linear(DIM_HIDDEN_1, DIM_HIDDEN_2)
self.hidden3 = nn.Linear(DIM_HIDDEN_2, DIM_HIDDEN_3)
self.out = nn.Linear(DIM_HIDDEN_3, DIM_OUT)
def forward(self, x):
x = F.relu(self.hidden1(x))
x = F.tanh(self.hidden2(x))
x = F.tanh(self.hidden3(x))
x = self.out(x)
return x
model = Net()
loss_fn = nn.MSELoss(size_average=False)
optimizer = torch.optim.Adam(model.parameters(), lr=LEARN_RATE)
tr_data,tr_labels = loadData()
tr_data_torch = torch.zeros(BATCH_SIZE, DIM_IN)
tr_labels_torch = torch.zeros(BATCH_SIZE, DIM_OUT)
for i in range(BATCH_SIZE):
tr_data_torch[i] = torch.from_numpy(tr_data[i])
tr_labels_torch[i] = tr_labels[i]
for t in range(EPOCH_NUM):
labels_pred = model(tr_data_torch)
loss = loss_fn(labels_pred, tr_labels_torch)
#print(t, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
我必须说,这是我们在Pytorch的第一步,所以如果有一些明显的、愚蠢的错误,请原谅我。我感谢任何帮助或暗示,
谢谢大家!
编辑1------------------------------------------------------------------
根据注释和答案,我们改进了代码。损失函数现在第一次有了合理的值,大约250。我们的新类定义如下所示:
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
#super().__init__()
self.hidden1 = nn.Sequential(nn.Linear(DIM_IN, DIM_HIDDEN_1), nn.ReLU())
self.hidden2 = nn.Sequential(nn.Linear(DIM_HIDDEN_1, DIM_HIDDEN_2), nn.ReLU())
self.hidden3 = nn.Sequential(nn.Linear(DIM_HIDDEN_2, DIM_HIDDEN_3), nn.ReLU())
self.out = nn.Linear(DIM_HIDDEN_3, DIM_OUT)
def forward(self, x):
x = self.hidden1(x)
x = self.hidden2(x)
x = self.hidden3(x)
x = self.out(x)
return x
损失函数:
loss_fn = nn.MSELoss(size_average=True, reduce=True)
如前所述,我们已经在tensorflow后端的keras中获得了更令人满意的结果。损失函数约为30,具有类似的网络配置。我在这里分享我们的keras代码的基本部分(!):
model = Sequential()
model.add(Dense(4, activation="linear", input_shape=(2,)))
model.add(Dense(16, activation="relu"))
model.add(Dense(4, activation="relu"))
model.add(Dense(1, activation="linear" ))
model.summary()
model.compile ( loss="mean_squared_error", optimizer="adam", metrics=["mse"] )
history=model.fit ( np.array(tr_data), np.array(tr_labels), \
validation_data = ( np.array(val_data), np.array(val_labels) ),
batch_size=50, epochs=200, callbacks = [ cbk ] )
谢谢你的帮助!如果有人仍然有改进网络的建议,我们会很高兴的。由于已经有人要求提供数据,我们希望在此处共享pickle文件:
连同访问它的代码:
import pickle
f=open("data.pcl","rb")
tr_data=pickle.load ( f )
tr_labels=pickle.load ( f )
val_data=pickle.load ( f )
val_labels=pickle.load ( f )
f.close()
您应该有兴趣指出
torch.nn
和torch.nn.functional
之间的区别(请参阅)。从本质上讲,可能是由于不同的规范,您的反向传播图的执行可能不是100%正确
正如前面的评论所指出的,我建议定义您的层,包括激活。我个人最喜欢的方法是使用nn.Sequential()
,它允许您指定链接在一起的多个操作,如下所示:
self.hidden1 = nn.Sequential(nn.Linear(DIM_IN, DIM_HIDDEN1), nn.ReLU())
然后稍后只需调用self.hidden1
(无需将其包装在F.relu()
中)
我还想问一下,你为什么不把注释过的称为super(Net,self)。\uuu init\uuuu()
(这是通常推荐的方式)?
此外,如果这不能解决问题,您是否可以将Keras的代码进行比较?为什么使用
F.tanh
而不是ReLU
?为什么用函数代替模块?也就是说,为什么不使用self.activation=nn.ReLU()
和x=self.activation(self.hidden(x))
?此外,为什么要使用size\u average=False
进行MSELoss?我建议您调整学习率并改变批量大小。是否可以共享数据集,以便我可以运行您的代码来查看发生了什么!!你好感谢您的帮助,我们将tanh改为ReLU,不再使用F,特别是将size_average改为True,这真的帮了大忙!损失函数现在约为12。很抱歉,我的意思是损失函数约为250。到目前为止比以前好了很多,但仍然不是很令人满意。你的keras模型在第一层有一个线性激活函数。你故意改变了吗?嗨!谢谢你的帮助。我们现在按照您的建议使用顺序代码,它工作得更好。我们也使用超级(网络,自我)。。。按照您的建议编写代码,但这不会有什么区别,因为python3会自动添加这些参数。我们的损失函数现在大约是12,这已经好得多了。我将用当前代码和keras代码更新我的原始帖子!对不起,我的意思是大约有250英镑,而且还有损失。到目前为止比以前好了很多,但仍然不太令人满意。