《前后端面试题
》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux... 。

文章目录
- 一、本文面试题目录
-
-
- [111. 对比Transformer与BERT、GPT的适用场景,说明各自的优缺点。](#111. 对比Transformer与BERT、GPT的适用场景,说明各自的优缺点。)
- [112. 为什么Transformer在NLP领域几乎取代了RNN,但在语音处理中仍与RNN共存?](#112. 为什么Transformer在NLP领域几乎取代了RNN,但在语音处理中仍与RNN共存?)
- [113. 请设计一个基于Transformer的多模态情感分析模型(输入文本+图像)。](#113. 请设计一个基于Transformer的多模态情感分析模型(输入文本+图像)。)
- [114. 如何将Transformer应用于时间序列预测任务(如股票价格、气象数据)?](#114. 如何将Transformer应用于时间序列预测任务(如股票价格、气象数据)?)
- [115. 分析Transformer在小样本学习(Few-Shot Learning)中的表现及改进方向。](#115. 分析Transformer在小样本学习(Few-Shot Learning)中的表现及改进方向。)
- [116. 什么是"Prompt Tuning"?它与传统微调相比有何优势?](#116. 什么是“Prompt Tuning”?它与传统微调相比有何优势?)
-
- 原理说明
- [示例代码(Prompt Tuning实现)](#示例代码(Prompt Tuning实现))
- [117. Transformer模型的"涌现能力(Emergent Abilities)"指什么?举例说明。](#117. Transformer模型的“涌现能力(Emergent Abilities)”指什么?举例说明。)
- [118. 探讨Transformer在可解释性(Interpretability)方面的挑战。](#118. 探讨Transformer在可解释性(Interpretability)方面的挑战。)
- [119. 如何利用Transformer实现零样本(Zero-Shot)任务迁移?](#119. 如何利用Transformer实现零样本(Zero-Shot)任务迁移?)
- [120. 总结Transformer对深度学习领域的影响,以及它的局限性。](#120. 总结Transformer对深度学习领域的影响,以及它的局限性。)
-
- 二、120道Transformer面试题目录列表
一、本文面试题目录
111. 对比Transformer与BERT、GPT的适用场景,说明各自的优缺点。
原理说明
Transformer是基础架构,而BERT、GPT是基于Transformer的具体模型变体,适用场景和特性如下:
模型 | 核心结构 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
Transformer | Encoder-Decoder | 机器翻译、文本摘要(Seq2Seq任务) | 兼顾双向上下文与生成能力,并行计算效率高 | 结构复杂,训练成本高 |
BERT | 仅Encoder(双向) | 文本分类、NER、问答(理解任务) | 强双向上下文理解,微调效果好 | 无生成能力,长序列处理效率低 |
GPT | 仅Decoder(单向) | 文本生成、对话、续写(生成任务) | 自回归生成流畅,零样本泛能力强 | 双向上下文理解弱,推理速度慢 |
示例代码(任务适配性对比)
python
from transformers import pipeline
# 1. BERT适合文本分类(理解任务)
classifier = pipeline("text-classification", model="bert-base-uncased-finetuned-sst-2-english")
print(classifier("This movie is great!")) # 输出情感分类结果
# 2. GPT用于文本生成(生成任务)
generator = pipeline("text-generation", model="gpt2")
print(generator("The future of AI is", max_length=50)) # 生成续写文本
# 3. Transformer(T5)用于翻译(Seq2Seq任务)
translator = pipeline("translation", model="t5-small", src_lang="en", tgt_lang="fr")
print(translator("Hello world")) # 输出法语翻译结果
112. 为什么Transformer在NLP领域几乎取代了RNN,但在语音处理中仍与RNN共存?
原理说明
-
NLP中Transformer取代RNN的原因:
- 自注意力机制可直接建模长距离依赖,解决RNN的梯度消失问题。
- 并行计算能力远超RNN,适合处理大规模文本数据。
- 预训练+微调模式在NLP任务中表现卓越。
-
语音处理中两者共存的原因:
- 语音数据的时序连续性更强(如语调、节奏依赖相邻帧),RNN的循环结构更自然适配。
- 语音序列通常极长(如10分钟语音含百万级帧),Transformer的(O(L^2))复杂度成本过高。
- RNN(如LSTM)在低延迟场景(如实时语音识别)更高效,无需等待完整序列。
- 混合模型(如Transformer+RNN)结合两者优势(如用RNN处理局部时序,Transformer捕捉全局依赖)。
示例(语音处理混合模型示意)
python
import torch
import torch.nn as nn
class SpeechModel(nn.Module):
def __init__(self, input_dim, hidden_dim, num_classes):
super().__init__()
# RNN处理局部时序特征
self.rnn = nn.LSTM(input_dim, hidden_dim, num_layers=2, bidirectional=True)
# Transformer捕捉全局依赖
self.transformer = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=hidden_dim*2, nhead=4),
num_layers=2
)
self.fc = nn.Linear(hidden_dim*2, num_classes)
def forward(self, x):
# x: (seq_len, batch, input_dim)
rnn_out, _ = self.rnn(x) # (seq_len, batch, hidden_dim*2)
transformer_out = self.transformer(rnn_out.permute(1, 0, 2)) # (batch, seq_len, hidden_dim*2)
return self.fc(transformer_out.mean(dim=1)) # 分类输出
113. 请设计一个基于Transformer的多模态情感分析模型(输入文本+图像)。
原理说明
多模态情感分析需融合文本语义与图像视觉特征,模型设计核心:
- 模态特征提取:文本用BERT提取语义特征,图像用CNN(如ResNet)提取视觉特征。
- 跨模态注意力:用Transformer的自注意力机制建模文本token与图像区域的关联(如"开心"文本与笑脸图像区域的匹配)。
- 融合分类:将融合特征输入分类头,预测情感标签(如积极、消极、中性)。
示例代码
python
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
from torchvision.models import resnet50
class MultimodalTransformer(nn.Module):
def __init__(self, num_classes=3):
super().__init__()
# 文本特征提取
self.text_encoder = BertModel.from_pretrained("bert-base-uncased")
self.text_proj = nn.Linear(768, 512) # 投影到512维
# 图像特征提取
self.img_encoder = resnet50(pretrained=True)
self.img_encoder.fc = nn.Identity() # 移除分类头
self.img_proj = nn.Linear(2048, 512) # 投影到512维
# 跨模态Transformer
self.transformer = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=512, nhead=8, batch_first=True),
num_layers=2
)
# 分类头
self.classifier = nn.Linear(512, num_classes)
def forward(self, text_inputs, images):
# 文本特征: (batch, seq_len, 768) → (batch, seq_len, 512)
text_feat = self.text_encoder(**text_inputs).last_hidden_state
text_feat = self.text_proj(text_feat)
# 图像特征: (batch, 3, H, W) → (batch, 1, 512)(假设单幅图像)
img_feat = self.img_encoder(images) # (batch, 2048)
img_feat = self.img_proj(img_feat).unsqueeze(1) # (batch, 1, 512)
# 融合特征: 文本token + 图像特征(拼接)
fused_feat = torch.cat([text_feat, img_feat], dim=1) # (batch, seq_len+1, 512)
# Transformer编码跨模态依赖
trans_out = self.transformer(fused_feat) # (batch, seq_len+1, 512)
# 全局池化后分类
global_feat = trans_out.mean(dim=1) # (batch, 512)
return self.classifier(global_feat)
# 测试模型
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
text = "I love this beautiful sunset!"
text_inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
images = torch.randn(1, 3, 224, 224) # 随机图像张量
model = MultimodalTransformer()
outputs = model(text_inputs, images)
print(f"情感预测概率: {torch.softmax(outputs, dim=1)}")
114. 如何将Transformer应用于时间序列预测任务(如股票价格、气象数据)?
原理说明
Transformer应用于时间序列预测需适配其序列特性:
1.** 输入表示 :将时间步特征(如价格、温度)作为token,添加时间戳编码(替代位置编码)。
2. 注意力机制 :用自注意力捕捉时间步间的依赖(如昨日与今日价格的关联)。
3. 解码器设计**:采用Seq2Seq结构,Encoder编码历史序列,Decoder生成未来序列(如预测未来7天温度)。
示例代码(股票价格预测)
python
import torch
import torch.nn as nn
import numpy as np
class TimeSeriesTransformer(nn.Module):
def __init__(self, input_dim, hidden_dim, num_layers, num_heads, pred_len):
super().__init__()
self.pred_len = pred_len
# 输入投影(将特征维度映射到hidden_dim)
self.input_proj = nn.Linear(input_dim, hidden_dim)
# 时间编码(替代位置编码)
self.time_encoding = nn.Embedding(1000, hidden_dim) # 假设最大时间步1000
# Encoder-Decoder
self.encoder = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=hidden_dim, nhead=num_heads, batch_first=True),
num_layers=num_layers
)
self.decoder = nn.TransformerDecoder(
nn.TransformerDecoderLayer(d_model=hidden_dim, nhead=num_heads, batch_first=True),
num_layers=num_layers
)
# 输出层(预测未来值)
self.output_proj = nn.Linear(hidden_dim, input_dim)
def forward(self, history):
# history: (batch, hist_len, input_dim)
batch_size, hist_len, input_dim = history.shape
# 输入投影 + 时间编码
hist_feat = self.input_proj(history) # (batch, hist_len, hidden_dim)
time_ids = torch.arange(hist_len, device=history.device).unsqueeze(0).repeat(batch_size, 1)
hist_feat += self.time_encoding(time_ids) # 加时间编码
# Encoder编码历史
enc_out = self.encoder(hist_feat) # (batch, hist_len, hidden_dim)
# Decoder输入:目标时间步的初始值(用历史最后一步初始化)
dec_input = torch.zeros(batch_size, self.pred_len, hidden_dim, device=history.device)
dec_input[:, 0] = hist_feat[:, -1] # 用历史最后一步初始化
# Decoder生成未来序列
dec_time_ids = torch.arange(hist_len, hist_len + self.pred_len, device=history.device).unsqueeze(0).repeat(batch_size, 1)
dec_input += self.time_encoding(dec_time_ids)
dec_out = self.decoder(dec_input, enc_out) # (batch, pred_len, hidden_dim)
# 预测未来值
pred = self.output_proj(dec_out) # (batch, pred_len, input_dim)
return pred
# 测试:预测未来3天股票价格
hist_len = 10 # 历史10天
pred_len = 3 # 预测未来3天
model = TimeSeriesTransformer(input_dim=1, hidden_dim=64, num_layers=2, num_heads=2, pred_len=pred_len)
history = torch.tensor(np.random.randn(2, hist_len, 1), dtype=torch.float32) # 2个样本
pred = model(history)
print(f"预测形状: {pred.shape}") # (2, 3, 1)
115. 分析Transformer在小样本学习(Few-Shot Learning)中的表现及改进方向。
原理说明
-** 小样本学习表现 **:
- 优势:预训练Transformer(如GPT、T5)通过大规模语料学习到通用模式,在小样本任务(如用5个样本微调分类器)中表现优于传统模型。
- 局限:当样本极少(如1-shot)时,性能显著下降,易受噪声样本影响;模型倾向于记忆训练分布,泛化到新类别能力弱。
-** 改进方向 :
1. 提示学习(Prompt Learning):将任务转化为完形填空(如"这是一个[类别]"),用自然语言提示激活预训练知识。
2. 元学习结合**:通过元训练(Meta-Training)学习"学习策略",快速适配新任务(如模型学会如何从少量样本中提取关键特征)。
3.** 数据增强**:对小样本进行多样化变换(如文本同义词替换、图像旋转),扩充有效数据量。
4.** 模型正则化**:加强Dropout、权重衰减,或使用知识蒸馏限制模型复杂度,避免过拟合。
示例代码(提示学习用于小样本分类)
python
from transformers import pipeline
# 小样本数据(2个积极,2个消极)
few_shot_examples = [
("The movie was fantastic!", "positive"),
("I loved every moment.", "positive"),
("Terrible experience, never again.", "negative"),
("Waste of time and money.", "negative")
]
# 构建提示模板
prompt = "Classify the sentence as positive or negative.\n"
for text, label in few_shot_examples:
prompt += f"Sentence: {text}\nLabel: {label}\n"
prompt += "Sentence: {}\nLabel:"
# 使用GPT-2进行零样本分类(小样本提示)
classifier = pipeline("text-generation", model="gpt2")
def classify(text):
input_text = prompt.format(text)
output = classifier(input_text, max_length=len(input_text)+10, num_return_sequences=1)
return output[0]["generated_text"].split("Label:")[-1].strip()
# 测试
print(classify("Amazing film, highly recommended!")) # 输出:positive
print(classify("Awful, I left early.")) # 输出:negative
116. 什么是"Prompt Tuning"?它与传统微调相比有何优势?
原理说明
Prompt Tuning 是一种轻量级微调方法,通过在输入中添加可学习的提示向量(Prompt Vectors),而非微调模型全部参数,来适配下游任务。
-
与传统微调的对比:
维度 传统微调(Full Fine-tuning) Prompt Tuning 参数更新 微调所有模型参数(如BERT的110M参数) 仅更新提示向量(通常<1M参数) 存储成本 高(每个任务需存储完整模型) 极低(仅存储提示向量) 多任务能力 差(任务间参数冲突) 强(多个提示向量可共享基础模型) 小样本表现 易过拟合 更稳健(依赖预训练知识) 计算效率 低(需更新全部参数) 高(仅优化少量参数) -
适用场景:多任务学习、资源受限场景、小样本任务。
示例代码(Prompt Tuning实现)
python
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
class PromptTuningModel(nn.Module):
def __init__(self, base_model_name, num_labels, prompt_length=10):
super().__init__()
self.base_model = BertModel.from_pretrained(base_model_name)
self.num_labels = num_labels
# 可学习的提示向量(形状:(prompt_length, hidden_dim))
self.prompt_vectors = nn.Parameter(
torch.randn(prompt_length, self.base_model.config.hidden_size)
)
# 分类头
self.classifier = nn.Linear(self.base_model.config.hidden_size, num_labels)
def forward(self, input_ids, attention_mask):
batch_size = input_ids.shape[0]
# 复制提示向量到批次维度:(batch, prompt_length, hidden_dim)
prompts = self.prompt_vectors.unsqueeze(0).repeat(batch_size, 1, 1)
# 编码原始输入:(batch, seq_len, hidden_dim)
input_feat = self.base_model(input_ids, attention_mask=attention_mask).last_hidden_state
# 拼接提示向量与输入特征
fused_feat = torch.cat([prompts, input_feat], dim=1) # (batch, prompt_len+seq_len, hidden_dim)
# 用[CLS] token或平均池化做分类
cls_feat = fused_feat.mean(dim=1) # 简单平均
return self.classifier(cls_feat)
# 初始化模型(仅提示向量可训练)
model = PromptTuningModel("bert-base-uncased", num_labels=2)
# 冻结基础模型参数
for param in model.base_model.parameters():
param.requires_grad = False
# 仅优化提示向量和分类头
optimizer = torch.optim.Adam([model.prompt_vectors, model.classifier.parameters()], lr=1e-4)
117. Transformer模型的"涌现能力(Emergent Abilities)"指什么?举例说明。
原理说明
涌现能力指当Transformer模型规模(参数量)超过某阈值后,突然展现出的、小模型不具备的复杂能力。这些能力无法通过小模型的性能线性外推获得,而是随规模增长"质变"产生。
-
典型例子:
- 零样本任务迁移:GPT-3(1750亿参数)可通过自然语言指令(如"将法语翻译成英语")完成未训练过的任务,而小模型(如1.3B参数)几乎无法做到。
- 思维链推理(Chain-of-Thought):大模型(如PaLM 540B)能通过分步推理解决数学问题(如"甲有5个苹果,乙比甲多3个,总共多少?"),小模型直接给出错误答案。
- 对抗鲁棒性提升:超大模型对简单对抗样本(如拼写错误)的容忍度显著提高,小模型易被干扰。
-
原因:大模型可学习更精细的模式和抽象知识,能组合基础能力解决复杂任务,而小模型容量有限,仅能拟合表面规律。
118. 探讨Transformer在可解释性(Interpretability)方面的挑战。
原理说明
Transformer的可解释性指理解模型决策依据的能力,核心挑战包括:
-
注意力权重的误导性:
- 高注意力权重不一定对应语义关联(如模型可能因数据偏见关注无关词)。
- 不同注意力头的功能重叠,难以单独解读某一头的作用。
-
深度黑箱特性:
- 数十亿参数的模型(如GPT-4)的决策路径难以追踪,中间层特征缺乏直观含义。
- 预训练与微调的知识传递机制不透明,无法解释"模型为何学到某规律"。
-
任务依赖性:
- 解释方法(如注意力可视化)在简单任务(如情感分析)中有效,但在复杂任务(如逻辑推理)中难以关联决策链。
-
缺乏标准评估:
- 无统一指标衡量解释的准确性(如"解释是否真的反映模型内部逻辑")。
- 改进方向:开发结构化注意力分析工具、因果推断方法分离真正影响决策的特征、设计可解释的注意力机制(如稀疏注意力)。
119. 如何利用Transformer实现零样本(Zero-Shot)任务迁移?
原理说明
零样本任务迁移指模型在未见过的任务上直接表现良好,Transformer通过以下机制实现:
- 通用语义表示:预训练Transformer(如T5、GPT)学习到跨任务的通用语言规律(如语法、逻辑、常识),可迁移到新任务。
- 任务指令(Instruction):用自然语言描述新任务(如"判断句子是否包含动物名称"),模型通过理解指令调用相关知识。
- 格式统一:将所有任务转化为统一格式(如"输入→输出"的文本生成),使模型无需修改结构即可适配。
示例代码(用T5实现零样本文本分类)
python
from transformers import T5Tokenizer, T5ForConditionalGeneration
# 加载T5模型(预训练时已学习多种任务格式)
tokenizer = T5Tokenizer.from_pretrained("t5-base")
model = T5ForConditionalGeneration.from_pretrained("t5-base")
def zero_shot_classify(text, labels, task_desc="Classify the text into one of the following categories:"):
# 构建任务指令
input_text = f"{task_desc} {', '.join(labels)}. Text: {text} Label:"
input_ids = tokenizer.encode(input_text, return_tensors="pt")
# 生成预测标签
outputs = model.generate(input_ids, max_length=50)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
# 零样本分类(未训练过的"情绪"分类任务)
text = "I'm so excited about the upcoming trip!"
labels = ["happy", "sad", "angry"]
print(zero_shot_classify(text, labels)) # 输出:happy
120. 总结Transformer对深度学习领域的影响,以及它的局限性。
原理说明
Transformer自2017年提出以来,彻底改变了深度学习的发展格局,但其固有的设计缺陷也限制了进一步应用。
对深度学习领域的影响
-
范式革新:从"任务专属设计"到"通用架构"
- 打破了NLP领域RNN/LSTM的垄断,通过自注意力机制实现并行计算,成为序列建模的通用框架。
- 扩展至计算机视觉(如ViT将图像分割为patch序列)、语音处理(如AST处理音频频谱)、蛋白质结构预测(如AlphaFold)等领域,推动"跨模态统一架构"的发展。
-
预训练革命:催生大模型时代
- 奠定"预训练+微调"模式的基础:通过大规模无标注数据预训练(如BERT、GPT系列),仅需少量标注数据微调即可适配下游任务,大幅降低任务落地门槛。
- 推动模型规模爆炸式增长(从千万级到万亿级参数),并发现"涌现能力"(如零样本推理、思维链),拓展了AI的能力边界。
-
工程与理论突破
- 促进分布式训练、混合精度计算、模型压缩等技术的进步,使超大规模模型训练成为可能。
- 启发对注意力机制、长距离依赖建模等问题的深入研究,推动深度学习理论的发展。
局限性
-
计算效率瓶颈
- 自注意力机制的时间复杂度为(O(L^2))((L)为序列长度),长序列(如10k+ token)处理时计算成本激增,难以应用于实时场景(如实时语音翻译)。
-
资源消耗巨大
- 训练千亿参数模型需数万GPU小时,能耗和成本极高(如训练一次GPT-3的成本超百万美元),且小机构难以参与,加剧技术垄断。
-
可解释性差
- 注意力权重无法完全反映语义关联(存在"虚假注意力"),深层网络的决策逻辑黑箱化,难以应用于医疗、法律等高风险领域。
-
数据依赖与偏见
- 性能高度依赖大规模高质量数据,在低资源语言、小样本场景中表现不佳。
- 易学习训练数据中的社会偏见(如性别、种族刻板印象),生成有害内容。
-
缺乏真正的推理能力
- 本质是基于统计模式的拟合,缺乏因果推理能力,面对逻辑复杂或对抗性输入时容易失效。
示例(Transformer与传统模型的效率对比)
python
import time
import torch
from transformers import BertModel, LSTM
# 对比Transformer与LSTM的长序列处理时间
seq_len = 1024
batch_size = 16
hidden_dim = 768
# Transformer(BERT-base)
bert = BertModel.from_pretrained("bert-base-uncased").cuda()
inputs_bert = torch.randint(0, 10000, (batch_size, seq_len)).cuda()
start = time.time()
with torch.no_grad():
bert(inputs_bert)
print(f"Transformer处理时间: {time.time() - start:.4f}秒") # 约0.1-0.3秒(GPU)
# LSTM(同维度)
lstm = LSTM(input_size=768, hidden_size=hidden_dim//2, num_layers=12, bidirectional=True).cuda()
inputs_lstm = torch.randn(batch_size, seq_len, hidden_dim).cuda()
start = time.time()
with torch.no_grad():
lstm(inputs_lstm)
print(f"LSTM处理时间: {time.time() - start:.4f}秒") # 约0.05-0.1秒(GPU,长序列下优势更明显)
结论:Transformer重塑了深度学习的发展路径,但效率、资源和可解释性等问题仍需突破,未来可能通过稀疏注意力、动态网络等技术实现优化。