回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我问的是关于<a href="https://pytorch.org/docs/stable/nn.html?highlight=nllloss#torch.nn.NLLLoss" rel="noreferrer">NLLLoss</a>损失函数的C类</p>
<p>文件规定:</p>
<blockquote>
<p>The negative log likelihood loss. It is useful to train a classification problem with C classes.</p>
</blockquote>
<p>基本上,这一点之后的一切都取决于你是否知道什么是C类,我想我知道什么是C类,但是文档对我来说没有多大意义。特别是当它描述了<code>(N, C) where C = number of classes</code>的预期输入时。这就是我感到困惑的地方,因为我认为C类只引用<em>输出</em>。我的理解是C类是一个热门的分类向量。我经常在教程中发现<code>NLLLoss</code>经常与<code>LogSoftmax</code>配对以解决分类问题</p>
<p>我希望在以下示例中使用<code>NLLLoss</code>:</p>
<pre class="lang-py prettyprint-override"><code># Some random training data
input = torch.randn(5, requires_grad=True)
print(input) # tensor([-1.3533, -1.3074, -1.7906, 0.3113, 0.7982], requires_grad=True)
# Build my NN (here it's just a LogSoftmax)
m = nn.LogSoftmax(dim=0)
# Train my NN with the data
output = m(input)
print(output) # tensor([-2.8079, -2.7619, -3.2451, -1.1432, -0.6564], grad_fn=<LogSoftmaxBackward>)
loss = nn.NLLLoss()
print(loss(output, torch.tensor([1, 0, 0])))
</code></pre>
<p>以上内容在最后一行引发了以下错误:</p>
<blockquote>
<p>ValueError: Expected 2 or more dimensions (got 1)</p>
</blockquote>
<p>我们可以忽略错误,因为很明显我不明白我在做什么。在这里,我将解释我对上述源代码的意图</p>
<pre class="lang-py prettyprint-override"><code>input = torch.randn(5, requires_grad=True)
</code></pre>
<p>随机1D数组与一个热向量<code>[1, 0, 0]</code>配对进行训练。我试着对一个十进制数的热向量进行二进制位运算</p>
<pre class="lang-py prettyprint-override"><code>m = nn.LogSoftmax(dim=0)
</code></pre>
<p>关于<code>LogSoftmax</code>的文档说,输出的形状将与输入的形状相同,但我只看到了<code>LogSoftmax(dim=1)</code>的示例,因此我一直在努力实现这一点,因为我找不到相关的示例</p>
<pre class="lang-py prettyprint-override"><code>print(loss(output, torch.tensor([1, 0, 0])))
</code></pre>
<p>现在我有了NN的输出,我想知道分类<code>[1, 0, 0]</code>的损失。在这个例子中,数据是什么并不重要。我只想要一个表示分类的单热向量的损失</p>
<p>在这一点上,我陷入了试图解决与预期输出和输入结构相关的损失函数错误的困境。我尝试在输出和输入上使用<code>view(...)</code>来修复形状,但这只会导致其他错误</p>
<p>这又回到了我最初的问题,我将展示文档中的示例来解释我的困惑:</p>
<pre class="lang-py prettyprint-override"><code>m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()
input = torch.randn(3, 5, requires_grad=True)
train = torch.tensor([1, 0, 4])
print('input', input) # input tensor([[...],[...],[...]], requires_grad=True)
output = m(input)
print('train', output, train) # tensor([[...],[...],[...]],grad_fn=<LogSoftmaxBackward>) tensor([1, 0, 4])
x = loss(output, train)
</code></pre>
<p>同样,我们在{<cd3>}上有{<cd10>},这让我现在很困惑,因为看看{<cd12>}数据。这是一个<code>3x5</code>张量,我迷路了</p>
<p>以下是关于<code>NLLLoss</code>函数的第一个输入的文档:</p>
<blockquote>
<p>Input: (N, C)(N,C) where C = number of classes</p>
</blockquote>
<p>输入按类数分组</p>
<p>那么,张量输入的每一行<em>都与训练张量的每一个<em>元素</em>相关联</p>
<p>如果我改变输入张量的第二维度,那么没有任何东西会中断,我不明白发生了什么</p>
<pre class="lang-py prettyprint-override"><code>input = torch.randn(3, 100, requires_grad=True)
# 3 x 100 still works?
</code></pre>
<p>所以我不明白这里的C类是什么,我认为C类是一种分类(就像一个标签),只对NN的输出有意义</p>
<p>我希望你们理解我的困惑,因为NN输入的形状不应该独立于用于分类的一个热向量的形状吗</p>
<p>代码示例和文档都说输入的形状是由分类的数量定义的,我真的不明白为什么</p>
<p>我曾试图研究文档和教程,以了解我遗漏了什么,但在几天未能克服这一点后,我决定问这个问题。这让我很谦卑,因为我认为这将是一件更容易学习的事情</p>