# 章末小测试 [[章末小测验]]

<CourseFloatingBanner
    chapter={2}
    classNames="absolute z-10 right-0 top-0"
/>

### 1. 自然语言处理流程的顺序是什么？
<Question
	choices={[
		{
			text: "首先是模型它处理文本并返回原始预测。然后 tokenizer 会对这些预测进行解释，并在将它们转换回文本",
			explain: "模型不能直接理解文本！必须首先使用 tokenizer 将文本转换为 id，之后才可以输入给模型。"
		},
		{
			text: "首先 Tokenizer 处理文本并返回 id。模型根据这些 id 并输出预测，可以是一些文本。",
			explain: "该模型的预测结果是 id 而不是文本。必须使用 tokenizer 才可以将预测转换回文本！"
		},
		{
			text: "Tokenizer 处理文本并返回 id。模型处理这些 id 并输出一个预测。然后可以再次使用 tokenizer 将这些预测转换回某些文本。",
			explain: "正确！Tokenizer 可以用于 id 与文本的相互转换。",
            correct: true
		}
	]}
/>

### 2. Transformer 模型的输出有的张量多少个维度，每个维度分别是什么？
<Question
	choices={[
		{
			text: "2 个维度，分别是：序列长度(Sequence Length)和批次大小(Batch Size)",
			explain: "错！该模型的张量输出还具有第三个维度：隐藏层大小(Hidden Size)。"
		},
		{
			text: "2 个维度，分别是：序列长度(Sequence Length)和隐藏层大小(Hidden Size)",
			explain: "错！所有 Transformer 模型都批量进行计算，即使是单个序列；那么也会有批次大小(Batch Size)的维度并且值为 1！"
		},
		{
			text: "3 个维度，分别是：序列长度(Sequence Length)、批次大小(Batch Size)和隐藏层大小(Hidden Size)",
			explain: "正确！",
            correct: true
		}
	]}
/>

### 3．下列哪一个是子词分词的例子（从分词的颗粒度来划分）？
<Question
	choices={[
		{
			text: "WordPiece",
			explain: "是的，这是一个子词分词的例子！",
            correct: true
		},
		{
			text: "基于单个字符的分词",
			explain: "基于单个字符的分词和子词分词的颗粒度是不同的。"
		},
		{
			text: "基于空格和标点符号的分割",
			explain: "这是一种基于单词的分词而不是子词分词！"
		},
		{
			text: "BPE(Byte Pair Encoding)",
			explain: "是的，这是一个子词分词的的例子！",
            correct: true
        },
		{
			text: "Unigram",
			explain: "是的，这是一个子词分词的例子！",
            correct: true
        },
		{
			text: "以上都不是",
			explain: "不对！"
        }
	]}
/>

### 4．什么是模型头（Haed 层）？
<Question
	choices={[
		{
			text: "原始 Transformer 网络的一种组件，直接将张量(Tensors)输入到到正确的层",
			explain: "不对！没有这样的组件。"
		},
		{
			text: "也称为自注意力(self-attention)机制，它会根据序列的其他 tokens 调整一个 token 的表示",
			explain: "不对！自注意力层确实包含“注意力头”，但是和模型头并不是同一个概念。"
		},
		{
			text: "一个附加组件，通常由一个或几个层组成，用于将 Transformer 的预测转换为特定于任务的输出",
			explain: "没错。它的全名是 Adaptation Heads，也被简单地称为模型的头部，在不同的任务上有不同的形式：语言模型头，问题回答头，序列分类头．",
			correct: true
		} 
	]}
/>

{#if fw === 'pt'}
### 5．什么是 AutoModel？
<Question
	choices={[
		{
			text: "根据你的数据自动进行训练的模型",
			explain: "错误。你可能把 AutoModel 与 Hugging Face 的<a href='https://huggingface.co/autotrain'>AutoTrain</a> 产品相混淆了？"
		},
		{
			text: "一个根据 checkpoint(检查点)返回模型体系结构的对象",
			explain: "确切地说：<code>AutoModel</code>只需要知道初始化的 checkpoint(检查点)名称就可以返回正确的体系结构。",
			correct: true
		},
		{
			text: "一种可以自动检测输入语言来加载正确权重的模型",
			explain: "不正确；虽然有些 checkpoint(检查点)和模型能够处理多种语言，但是没有内置的工具可以根据语言自动选择 checkpoint(检查点)。你应该前往 <a href='https://huggingface.co/models'>Model Hub</a> 寻找完成所需任务的最佳 checkpoint(检查点)！"
		} 
	]}
/>

{:else}
### 5．什么是 TFAutoModel？
<Question
	choices={[
		{
			text: "根据你的数据自动进行训练的模型",
			explain: "错误。你可能把 TFAutoModel 与 Hugging Face 的<a href='https://huggingface.co/autotrain'>AutoTrain</a> 产品相混淆了？"
		},
		{
			text: "一个根据 checkpoint(检查点)返回模型体系结构的对象",
			explain: "确切地说：<code>TFAutoModel</code>只需要知道初始化的 checkpoint(检查点)名称就可以返回正确的体系结构。",
			correct: true
		},
		{
			text: "一种可以自动检测输入语言来加载正确权重的模型",
			explain: "不正确；虽然有些 checkpoint(检查点)和模型能够处理多种语言，但是没有内置的工具可以根据语言自动选择 checkpoint(检查点)。你应该前往 <a href='https://huggingface.co/models'>Model Hub</a> 寻找完成所需任务的最佳 checkpoint(检查点)！"
		} 
	]}
/>

{/if}

### 6．当将不同长度的句子序列在一起批处理时，需要进行哪些处理？
<Question
	choices={[
		{
			text: "截短",
			explain: "是的，截断是一个正确的方式，截断可以将他们转化为一个固定长度的矩形序列。这是唯一的正确答案吗？",
			correct: true
		},
		{
			text: "直接将 Tensors 返回",
			explain: "在批处理序列时不可以直接返回长度不一致的 Tensors。(必须是固定长度)"
		},
		{
			text: "填充",
			explain: "是的，填充是一个正确的方式，可以将他们转化为一个固定长度的矩形序列。这是唯一的正确答案吗？",
			correct: true
		}, 
		{
			text: "注意力掩码(Attention masking)",
			explain: "当然！当处理不同长度的序列时，注意力掩码是最重要的。然而，仅仅使用注意力遮蔽是不够的。",
			correct: true
		} 
	]}
/>

### 7．使用 SoftMax 激活函数对序列分类(Sequence Classification)模型的 logits 输出进行处理有什么意义？
<Question
	choices={[
		{
			text: "它软化了 logits 输出，使结果更可靠。",
			explain: "不，SoftMax 激活函数不会影响结果的可靠性。"
		},
		{
			text: "它限定了上下界，使模型的输出结果可以被解释。",
			explain: "正确！结果值被压缩到了 0 和 1 之间。不过，这并不是我们使用 SoftMax 激活函数的唯一原因。",
            correct: true
		},
		{
			text: "输出的和是 1，从而产生一个可能的概率解释。",
			explain: "没错，但这并不是我们使用 SoftMax 激活函数的唯一原因。",
            correct: true
		}
	]}
/>

### 8.Tokenizer API 的核心方法是哪一个？
<Question
	choices={[
		{
			text: "<code>encode</code> 因为它可以将文本编码为 ID，将预测的 ID 解码为文本",
			explain: "错！虽然 <code>encode</code> 方法确实是 Tokenizer 中的方法之一，但是它并不是核心的方法，此外将预测 ID 解码为文本的是 decode。"
		},
		{
			text: "直接调用 Tokenizer 对象。",
			explain: "完全正确！ tokenizer (Tokenizer) 的 <code>__call__</code>方法是一个非常强大的方法，可以处理几乎任何事情。它同时也可以从模型中获取预测。",
			correct: true
		},
		{
			text: "<code>pad</code>(填充)",
			explain: "错！<code>pad</code>(填充)非常有用，但它只是 Tokenizer API 的一部分。"
		},
		{
			text: "<code>tokenize</code>",
			explain: "可以说，<code>tokenize</code>方法是最有用的方法之一，但它不是 Tokenizer API 的核心方法。"
		}
	]}
/>

### 9．这个代码示例中的 `result` 变量包含什么？
```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
result = tokenizer.tokenize("Hello!")
```

<Question
	choices={[
		{
			text: "字符串列表，每个字符串都是一个 token",
			explain: "正确！把 tokens 转换成 id 后，就可以传输给模型了！",
            correct: true
		},
		{
			text: "一个 ID 的列表",
			explain: "不正确；这是 <code>__call__</code> 或 <code>convert_tokens_to_ids</code>方法的作用！"
		},
		{
			text: "包含所有分词后的的字符串",
			explain: "这将是次优的答案，因为 tokenize 方法会将字符串拆分为多个 tokens 的列表。"
		}
	]}
/>

{#if fw === 'pt'}
### 10．下面的代码有什么错误吗？
```py
from transformers import AutoTokenizer, AutoModel

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
model = AutoModel.from_pretrained("gpt2")

encoded = tokenizer("Hey!", return_tensors="pt")
result = model(**encoded)
```

<Question
	choices={[
		{
			text: "不，看起来是对的。",
			explain: "将一个模型与一个在不同 checkpoint 训练的 tokenizer 耦合在一起并不是一个好主意。模型没有在这个这个 tokenizer 上训练来理解 tokenizer 的输出，因此模型的输出(如果它可以运行的话)会是错乱的。"
		},
		{
			text: "Tokenizer 和模型应该来自相同的 checkpoint。",
			explain: "对！",
            correct: true
		},
		{
			text: "由于模型输入需要是一个 Batch，因此可以使用 tokenizer 对其进行截断或填充来改进这段代码。",
			explain: "的确，模型输入需要是一个 Batch。然而，截断或填充这个序列并不一定有意义，这里只有一句话，而截断或填充这些技术是用来批处理一个句子列表使其长度一致的。"
		}
	]}
/>

{:else}
### 10．下面的代码有什么错误吗？
```py
from transformers import AutoTokenizer, TFAutoModel

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
model = TFAutoModel.from_pretrained("gpt2")

encoded = tokenizer("Hey!", return_tensors="pt")
result = model(**encoded)
```

<Question
	choices={[
		{
			text: "不，看起来是对的。",
			explain: "不幸的是，将一个模型与一个不同 checkpoint 训练的 tokenizer 耦合在并不是一个好主意。模型没有在这个这个 tokenizer 上训练来理解 tokenizer 的输出，因此模型的输出(如果它可以运行的话)会是错乱的。"
		},
		{
			text: "Tokenizer 和模型应该来自相同的 checkpoint。",
			explain: "对！",
            correct: true
		},
		{
			text: "由于每个输入都是一个 Batch，因此可以使用 tokenizer 对其进行平移和截断来改善这段代码。",
			explain: "的确，每个模型都需要 Batch 类型的输入。然而，截断或填充这个序列并不一定有意义，这里只有一句话，而这些技术是用来批处理一个句子列表的。"
		}
	]}
/>

{/if}


<EditOnGithub source="https://github.com/huggingface/course/blob/main/chapters/zh-CN/chapter2/8.mdx" />