【发布时间】:2021-05-03 23:10:19
【问题描述】:
我对构建深度学习模型比较陌生,我似乎完全被与形状和大小相关的错误所困扰。
这是 LSTM 模型和相关代码:
class LSTMTagger(nn.Module):
def __init__(self):
super(LSTMTagger, self).__init__()
self.embedding =
nn.Embedding(wv.vectors.shape[0],512)#embedding_matrix.shape[1])
self.lstm1 = nn.LSTM(input_size = 512, hidden_size = 64, dropout =
0.1,batch_first=True,bidirectional = True)
self.dropout = nn.Dropout(p = 0.25)
self.linear1 = nn.Linear(in_features = 128, out_features = 64)
self.dropout = nn.Dropout(p = 0.25)
self.linear2 = nn.Linear(in_features = 64, out_features = 1)
self.sigmoid = nn.Sigmoid()
def forward(self, X):
X_embed = self.embedding(X)
outr1, _ = self.lstm1(X_embed)
xr = self.dropout(outr1)
xr= self.linear1(xr)
xr = self.dropout(xr)
xr= self.linear2(xr)
outr4 = self.sigmoid(xr)
outr4 = outr4.view(1,-1)
return outr4
model = LSTMTagger()
torch.multiprocessing.set_sharing_strategy('file_system')
if torch.cuda.device_count() > 1:
print("Using ", torch.cuda.device_count(), " GPUs")
# dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs
# model =model.load_state_dict(torch.load('best_model_state.bin'))
model = nn.DataParallel(model, device_ids=[0]) #py r
torch.cuda.empty_cache()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
def train_epoch(
model,
data_loader,
loss_fn,
optimizer,
device,
scheduler,
n_examples
):
model = model.train()
losses = []
correct_predictions = 0
for d in data_loader:
print(f"Input ids: {np.shape(d['input_ids'])}\n len: {len(d['input_ids'][0])}")
input_ids = d["input_ids"].to(device)
targets = d["targets"].to(device)
outputs = model(input_ids)
_, preds = torch.max(outputs, dim=1)
print(f"outputs is {np.shape(outputs)}")
print(f"targets is {targets}")
# continue
loss = criterion(outputs.squeeze(), targets)
# loss.backward()
# nn.utils.clip_grad_norm_(model.parameters(), clip)
# optimizer.step()
# loss = loss_fn(outputs, targets)
correct_predictions += torch.sum(preds == targets)
losses.append(loss.item())
loss.backward()
nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
scheduler.step()
optimizer.zero_grad()
return correct_predictions.double() / n_examples, np.mean(losses)
EPOCHS = 6
optimizer = optim.Adam(model.parameters(), lr=2e-5)
total_steps = len(data_train) * EPOCHS
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)
loss_fn = nn.CrossEntropyLoss().to(device)
history = defaultdict(list)
best_accuracy = 0
criterion = nn.BCELoss()
print('starting training')
# exit()
for epoch in range(EPOCHS):
print(f'Epoch {epoch + 1}/{EPOCHS}')
print('-' * 10)
train_acc, train_loss = train_epoch(
model,
data_train,
loss_fn,
optimizer,
device,
scheduler,
len(df_train)
)
在这种情况下,样本输入是一个大小为:torch.Size([1, 512]) ,看起来像这样:
tensor([[44561, 972, 7891, 94, 2191, 131, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0]], device=‘cuda:0’)
并输出标签(来自 train_epoch 函数的目标),以防只是张量形式的简单 1 或 0 标签,例如 tensor([1], device='cuda:0')。
我一直面临这种方法的问题。最初的输出是 1x512x1。所以,我加了
outr4 = outr4.view(1,-1)
在 sigmoid 层之后。然后,输出形状减少到 1x512,我使用了挤压功能,但我仍然面临如下错误:
ValueError: Using a target size (torch.Size([1])) that is different to the input size (torch.Size([512])) is deprecated. Please ensure they have the same size.
我花了很多时间试图弄清楚发生了什么,但无济于事。输出不应该是 1 还是 0,而不是 1x512 形状的张量?
我对构建模型比较陌生,所以请原谅我缺乏知识。
【问题讨论】:
-
你想在这里完成什么?您正在输出 512 个值,然后尝试将 BCELoss 与单个目标一起使用?你期望这是什么计算? BCE 损失期望每个输出都有一个目标,这就是它的定义方式。
-
感谢回复,根据需要更改问题。
-
你能给我们你整个模型的输入形状吗?另外,为什么您的
__init__中有前向定义? -
更正了转发功能。我正在传递一堆句子向量,每个句子向量被分类为 1 或 0。每个句子向量的形状是 1x512。我最初传递了 200 个这样的向量来测试模型并确保在我真正开始训练之前一切正常。但是,批量大小为 1,因此对于每个前向/后向传递,输入为 1x512。我在上面的问题中发布了示例输入张量。
标签: python deep-learning neural-network nlp pytorch