web-dev-qa-db-ja.com

nn.CrossEntropyLoss()のPytorch入力

単純な0,1ラベル付きデータセットに対してPyTorchでロジスティック回帰を実行しようとしています。基準または損失はcriterion = nn.CrossEntropyLoss()として定義されます。モデルは次のとおりです。model = LogisticRegression(1,2)

ペアのデータポイントがあります:dat = (-3.5, 0)、最初の要素はデータポイント、2番目は対応するラベルです。
次に、入力の最初の要素をテンソルに変換します:tensor_input = torch.Tensor([dat[0]])
次に、モデルをtensor_inputに適用します:outputs = model(tensor_input)
次に、ラベルをテンソルに変換します:tensor_label = torch.Tensor([dat[1]])
今、これを行おうとすると、loss = criterion(outputs, tensor_label)が壊れます。与えるとエラー:RuntimeError: Dimension out of range (expected to be in range of [-1, 0], but got 1)

import torch
import torch.nn as nn

class LogisticRegression(nn.Module):
    def __init__(self, input_size, num_classes):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(input_size, num_classes) 

    def forward(self, x):
        out = self.linear(x)
        return out

model = LogisticRegression(1,2)
criterion = nn.CrossEntropyLoss()
dat = (-3.5,0)
tensor_input = torch.Tensor([dat[0]])
outputs = binary_model(tensor_input)
tensor_label = torch.Tensor([dat[1]])
loss = criterion(outputs, tensor_label)

私の人生でそれを理解することはできません。

ほとんどの場合、PyTorchのドキュメントはさまざまな機能を説明する素晴らしい仕事をしています。通常、予想される入力ディメンションといくつかの簡単な例が含まれます。
_nn.CrossEntropyLoss()here の説明があります。

特定の例を見ていくために、予想される入力ディメンションを見てみましょう。

入力:(N、C)ここで、C =クラスの数。 [...]

これに追加するために、[〜#〜] n [〜#〜]は通常、バッチサイズ(サンプル数)を指します。これを現在のものと比較するには:

_outputs.shape
>>> torch.Size([2])
_

つまり現在、PyTorchで期待されているように、入力ディメンションは_(2,)_のみであり、_(1,2)_ではありません。次のように.unsqueeze()を使用するだけで、現在のテンソルに「フェイク」ディメンションを追加することで、これを軽減できます。

_outputs = binary_model(tensor_input).unsqueeze(dim=0)
outputs.shape
>>> torch.Size([1,2])
_

それが得られたので、ターゲットの予想される入力を見てみましょう。

ターゲット:(N)[...]

そのため、私たちはすでにこれに適した形をとっています。ただし、これを試しても、エラーが発生します。

_RuntimeError: Expected object of scalar type Long but got scalar type Float 
              for argument #2 'target'.
_

繰り返しますが、エラーメッセージはかなり表現力豊かです。ここでの問題は、PyTorchテンソル(デフォルト)が_torch.FloatTensors_として解釈されることですが、入力は整数(またはLong)である必要があります。テンソル作成中に正確なタイプを指定することにより、これを簡単に行うことができます。

_tensor_label = torch.LongTensor([dat[1]])
_

Linux fyiでPyTorch 1.0を使用しています。

3
dennlinger

PyTorchでロジスティック回帰を実行するには、3つのことが必要です。

  • 0または1としてエンコードされたラベル(ターゲット)。
  • 最後の層のシグモイド活性化、したがって出力の数は1になります。
  • 損失関数としてのバイナリクロスエントロピー。

最小限の例を次に示します。

import torch
import torch.nn as nn


class LogisticRegression(nn.Module):
    def __init__(self, n_inputs, n_outputs):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(n_inputs, n_outputs)
        self.sigmoid = nn.Sigmoid()


    def forward(self, x):
        x = self.linear(x)
        return self.sigmoid(x)


# Init your model
# Attention!!! your num_output will be 1, because logistic function returns one value in range (0, 1) 
model = LogisticRegression(n_inputs=1, n_outputs=1)
# Define Binary Cross Entropy Loss:
criterion = nn.BCELoss()

# dummy data
data = (42.0, 0)
tensor_input = torch.Tensor([data[0]])
tensor_label = torch.Tensor([data[1]])

outputs = model(tensor_input)

loss = criterion(outputs, tensor_label)

print(loss.item())
0
trsvchn