如何在PyTorch中创建类似于Tensorflow顺序模型的等效模型?

huangapple go评论125阅读模式
英文:

How to make the equivalent of Tensorflow sequential model in PyTorch?

问题

I have a simple shallow model in Tensorflow for multiclass classification.

  1. model = tf.keras.models.Sequential([
  2. tf.keras.layers.Dense(64, input_shape=(384,), activation="relu"),
  3. tf.keras.layers.Dense(36, activation="softmax", use_bias=False)
  4. ])
  5. model.summary()

我想在PyTorch中复制它,其中我在前向函数中使用softmax。

  1. # 基本模型 - 它可以工作,但精度很低。需要添加更多层。
  2. class LR(torch.nn.Module):
  3. def __init__(self, n_features):
  4. super(LR, self).__init__()
  5. self.lr = torch.nn.Linear(n_features, 36)
  6. nn.ReLU()
  7. def forward(self, x):
  8. out = torch.softmax(self.lr(x), dim=1, dtype=None)
  9. return out
  10. # 参数
  11. n_features = 384
  12. n_classes = 36
  13. optim = torch.optim.SGD(model.parameters(), lr=0.1)
  14. criterion = torch.nn.CrossEntropyLoss()
  15. accuracy_fn = Accuracy(task="multiclass", num_classes=36)

我尝试修改我的基本模型,如下所示,但后来出现错误。

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(n_features, 64)
  5. self.lr = nn.ReLU()
  6. self.lr = torch.nn.Linear(64, 36)
  7. def forward(self, x):
  8. out = torch.softmax(self.lr(x), dim=1, dtype=None)
  9. return out
  10. epochs = 15
  11. def train(model, optim, criterion, x, y, epochs=epochs):
  12. for e in range(1, epochs + 1):
  13. optim.zero_grad()
  14. out = model(x)
  15. loss = criterion(out, y)
  16. loss.backward()
  17. optim.step()
  18. print(f"Loss at epoch {e}: {loss.data}")
  19. return model
  20. model = LR(n_features)
  21. model = train(model, optim, criterion, X_train, y_train)

出现以下错误:

  1. RuntimeError: mat1 and mat2 shapes cannot be multiplied (155648x384 and 64x36)

我的数据形状是:

  1. X_train.shape
  2. torch.Size([155648, 384])
  3. y_train.shape
  4. torch.Size([155648])

有人可以帮我解决我的LR类和train函数吗?

英文:

I have a simple shallow model in Tensorflow for multiclass classification.

  1. model = tf.keras.models.Sequential([
  2. tf.keras.layers.Dense(64, input_shape = (384,), activation = "relu"),
  3. tf.keras.layers.Dense(36, activation="softmax", use_bias = False)
  4. ])
  5. model.summary()
  6. Model: "sequential_5"
  7. _________________________________________________________________
  8. Layer (type) Output Shape Param #
  9. =================================================================
  10. dense_13 (Dense) (None, 64) 24640
  11. dense_14 (Dense) (None, 36) 2304

I want to replicate it in PyTorch where I am using softmax in the forward function.

  1. # base model - it works but gives v low accuracy. need to add more layers.
  2. class LR(torch.nn.Module):
  3. def __init__(self, n_features):
  4. super(LR, self).__init__()
  5. self.lr = torch.nn.Linear(n_features, 36)
  6. nn.ReLU()
  7. def forward(self, x):
  8. out = torch.softmax(self.lr(x),dim = 1,dtype=None)
  9. return out
  10. # parameters
  11. n_features = 384
  12. n_classes = 36
  13. optim = torch.optim.SGD(model.parameters(), lr=0.1)
  14. criterion = torch.nn.CrossEntropyLoss()
  15. accuracy_fn = Accuracy(task="multiclass", num_classes=36)

I have tried modifying my base model like so and it gives me an error later on.

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(n_features, 64)
  5. self.lr = nn.ReLU()
  6. self.lr = torch.nn.Linear(64, 36)
  7. def forward(self, x):
  8. out = torch.softmax(self.lr(x),dim = 1,dtype=None)
  9. return out
  10. epochs = 15
  11. def train(model, optim, criterion, x, y, epochs=epochs):
  12. for e in range(1, epochs + 1):
  13. optim.zero_grad()
  14. out = model(x)
  15. loss = criterion(out, y)
  16. loss.backward()
  17. optim.step()
  18. print(f"Loss at epoch {e}: {loss.data}")
  19. return model
  20. model = LR(n_features)
  21. model = train(model, optim, criterion, X_train, y_train)
  22. ---------------------------------------------------------------------------
  23. RuntimeError Traceback (most recent call last)
  24. Cell In[175], line 18
  25. 12 # acc = accuracy_fn(out, y)
  26. 13 # acc.backward()
  27. 14 # optim.step()
  28. 15 # print(f"Acc at epoch {e}: {acc.data}")
  29. 16 return model
  30. ---> 18 model = train(model, optim, criterion, X_train, y_train)
  31. Cell In[175], line 6, in train(model, optim, criterion, x, y, epochs)
  32. 4 for e in range(1, epochs + 1):
  33. 5 optim.zero_grad()
  34. ----> 6 out = model(x)
  35. 7 loss = criterion(out, y)
  36. 8 loss.backward()
  37. File /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501, in Module._call_impl(self, *args, **kwargs)
  38. 1496 # If we don't have any hooks, we want to skip the rest of the logic in
  39. 1497 # this function, and just call forward.
  40. 1498 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
  41. 1499 or _global_backward_pre_hooks or _global_backward_hooks
  42. 1500 or _global_forward_hooks or _global_forward_pre_hooks):
  43. -> 1501 return forward_call(*args, **kwargs)
  44. 1502 # Do not call functions when jit is used
  45. 1503 full_backward_hooks, non_full_backward_hooks = [], []
  46. Cell In[172], line 10, in LR.forward(self, x)
  47. 9 def forward(self, x):
  48. ---> 10 out = torch.softmax(self.lr(x),dim = 1,dtype=None)
  49. 11 return out
  50. File /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501, in Module._call_impl(self, *args, **kwargs)
  51. 1496 # If we don't have any hooks, we want to skip the rest of the logic in
  52. 1497 # this function, and just call forward.
  53. 1498 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
  54. 1499 or _global_backward_pre_hooks or _global_backward_hooks
  55. 1500 or _global_forward_hooks or _global_forward_pre_hooks):
  56. -> 1501 return forward_call(*args, **kwargs)
  57. 1502 # Do not call functions when jit is used
  58. 1503 full_backward_hooks, non_full_backward_hooks = [], []
  59. File /usr/local/lib/python3.10/site-packages/torch/nn/modules/linear.py:114, in Linear.forward(self, input)
  60. 113 def forward(self, input: Tensor) -> Tensor:
  61. --> 114 return F.linear(input, self.weight, self.bias)
  62. RuntimeError: mat1 and mat2 shapes cannot be multiplied (155648x384 and 64x36)

my data shapes are:

  1. X_train.shape
  2. torch.Size([155648, 384])
  3. y_train.shape
  4. torch.Size([155648]).

Can someone give me a hand with my class LR and train function?

答案1

得分: 2

在你的Torch模型中,你两次覆盖了self.lr属性。

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(n_features, 64)
  5. self.lr = nn.ReLU() # 在这里覆盖了lr
  6. self.lr = torch.nn.Linear(64, 36) # 还有在这里

所以你最终得到的模型只有这个:

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(64, 36)

如果你想要等效于Keras模型,你可以使用:

  1. from torch import nn
  2. model = nn.Sequential(
  3. nn.Linear(384, 64),
  4. nn.ReLU(),
  5. nn.Linear(64, 36, bias=False),
  6. nn.Softmax()
  7. )

如果你想要为你的模型构建一个类,你可以使用:

  1. import torch.nn as nn
  2. class Model(nn.Module):
  3. def __init__(self):
  4. super().__init__()
  5. self.L1 = nn.Linear(384, 64),
  6. self.RLU = nn.ReLU()
  7. self.L2 = nn.Linear(64, 36, bias=False)
  8. def forward(self, x):
  9. x = self.L1(x)
  10. x = self.RLU(x)
  11. x = self.L2(x)
  12. return x

我没有加上softmax,因为CrossEntropyLoss会自动应用log-softmax。如果你要进行预测,可以单独应用softmax。

英文:

In your Torch model, you have overwritten the self.lr attribute 2 times.

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(n_features, 64)
  5. self.lr = nn.ReLU() # lr is over-written here
  6. self.lr = torch.nn.Linear(64, 36) # and here

So you end up with a model that is just this:

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Linear(64, 36)

If you want the equivalent of the Keras model, you can use:

  1. from torch import nn
  2. model = nn.Sequential(
  3. nn.Linear(384, 64),
  4. nn.ReLU()
  5. nn.Linear(64, 36, bias=False)
  6. nn.Softmax()
  7. )

If you want to build a class for your model, you can use:

  1. import torch.nn as nn
  2. class Model(nn.Module):
  3. def __init__(self):
  4. super().__init__()
  5. self.L1 = nn.Linear(384, 64),
  6. self.RLU = nn.ReLU()
  7. self.L2 = nn.Linear(64, 36, bias=False)
  8. def forward(self, x):
  9. x = self.L1(x)
  10. x = self.RLU(x)
  11. x = self.L2(x)
  12. return x

I left off the softmax because the CrossEntropyLoss applies a log-softmax on it's own. If you are making predictions, you can apply a softmax separately.

答案2

得分: 2

你可以使用Sequential来实现以下内容:

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Sequential(
  5. torch.nn.Linear(n_features, 64),
  6. torch.nn.ReLU(),
  7. torch.nn.Linear(64, 36, bias=False),
  8. torch.nn.Softmax(dim=1),
  9. )
  10. def forward(self, x):
  11. return self.lr(x)

这可以与以下方式一起使用:

  1. x = torch.ones(1, 1000)
  2. lr = LR(x.shape[1])
  3. lr(x)
英文:

You could do (using the Sequential), the following:

  1. class LR(torch.nn.Module):
  2. def __init__(self, n_features):
  3. super(LR, self).__init__()
  4. self.lr = torch.nn.Sequential(
  5. torch.nn.Linear(n_features, 64),
  6. torch.nn.ReLU(),
  7. torch.nn.Linear(64, 36, bias=False),
  8. torch.nn.Softmax(dim=1),
  9. )
  10. def forward(self, x):
  11. return self.lr(x)

This could be used with, e.g.,

  1. x = torch.ones(1, 1000)
  2. lr = LR(x.shape[1])
  3. lr(x)

huangapple
  • 本文由 发表于 2023年7月31日 20:35:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803694.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定