任务:预测提供的灾难推文是否真实。已经将文本数据转换为张量,并创建了train_loader。所有需要的代码如下所示。
我的模型架构
class RealOrFakeLSTM(nn.Module): def __init__(self, input_size, output_size, embedding_dim, hidden_dim, n_layers, bidirec, drop_prob): super().__init__() self.output_size=output_size self.n_layers=n_layers self.hidden_dim=hidden_dim self.bidirec=True; self.embedding=nn.Embedding(vocab_size, embedding_dim) self.lstm1=nn.LSTM(embedding_dim, hidden_dim, n_layers, dropout=drop_prob, batch_first=True, bidirectional=bidirec) #self.lstm2=nn.LSTM(hidden_dim, hidden_dim, n_layers, dropout=drop_prob, batch_first=True) self.dropout=nn.Dropout(drop_prob) self.fc=nn.Linear(hidden_dim, output_size) self.sigmoid=nn.Sigmoid() def forward(self, x): batch=len(x) hidden1=self.init_hidden(batch) #hidden2=self.init_hidden(batch) embedd=self.embedding(x) lstm_out1, hidden1=self.lstm1(embedd, hidden1) #lstm_out2, hidden2=self.lstm2(lstm_out1, hidden2) lstm_out1=lstm_out1.contiguous().view(-1, self.hidden_dim) # make it lstm_out2, if you un comment the other lstm cell. out=self.dropout(lstm_out1) out=self.fc(out) sig_out=self.sigmoid(out) sig_out=sig_out.view(batch, -1) sig_out=sig_out[:, -1] return sig_out def init_hidden(self, batch): if (train_on_gpu): if self.bidirec==True: hidden=(torch.zeros(self.n_layers*2, batch, self.hidden_dim).cuda(),torch.zeros(self.n_layers*2, batch, self.hidden_dim).cuda()) else: hidden=(torch.zeros(self.n_layers, batch, self.hidden_dim).cuda(),torch.zeros(self.n_layers, batch, self.hidden_dim).cuda()) else: if self.bidirec==True: hidden=(torch.zeros(self.n_layers*2, batch, self.hidden_dim),torch.zeros(self.n_layers*2, batch, self.hidden_dim)) else: hidden=(torch.zeros(self.n_layers, batch, self.hidden_dim),torch.zeros(self.n_layers, batch, self.hidden_dim)) return hidden
超参数和训练
learning_rate=0.005epochs=50vocab_size = len(vocab_to_int)+1 # +1 for the 0 paddingoutput_size = 2embedding_dim = 300hidden_dim = 256n_layers = 2batch_size=23net=RealOrFakeLSTM(vocab_size, output_size, embedding_dim, hidden_dim, n_layers, True, 0.3)net.to(device)criterion=nn.BCELoss()optimizer=torch.optim.Adam(net.parameters(),lr=learning_rate)net.train()loss_arr=np.array([])lossPerEpoch=np.array([])for i in range(epochs): total_loss=0; for input,label in train_loader: if train_on_gpu: input=input.to(device) label=label.to(device) optimizer.zero_grad() input=input.clone().detach().long() out=net(input) loss=criterion(out.squeeze(),label.float()) loss_arr=np.append(loss_arr,loss.cpu().detach().numpy()) loss.backward() optimizer.step() total_loss+=loss total_loss=total_loss/len(train_loader) lossPerEpoch=np.append(lossPerEpoch,total_loss.cpu().detach().numpy()) print("Epoch ",i,": ",total_loss) torch.save(net.state_dict(), Path+"/RealOrFakeLSTM.pt") torch.save(net, Path+"/RealOrFakeLSTM.pth")current_time=str(time.time())torch.save(net.state_dict(), Path+"/pt/RealOrFakeLSTM"+'_pt_'+current_time+".pt")torch.save(net, Path+"/pth/RealOrFakeLSTM"+'_pth_'+current_time+".pth")
总损失值几乎相同,测试数据集中的所有结果概率完全相同。我对这个领域比较新手,所以在调整超参数时,我有点采取了蛮力法,但似乎没有任何效果。我认为问题不在于架构,而在于训练部分,因为所有预测结果都是完全相同的。
回答:
据我所知,你在每次前向传递中都初始化了hidden1=self.init_hidden(batch)。这应该是错误的。在每次前向传递中初始化一个层可以解释你描述的行为。