字节AL LAB nlp 日常实习面试失败

面试失败

公司:字节跳动

职位 : AL lab 的NLP方向

面试时长 :1h

一面就失败了,没有二面,

面试官非常年轻,感觉字节面试官都很年轻。面试官因为疫情也是在居家远程办公,虽然最后没面过,但就像东京喰种里面所说,世界上一切的不利都是当事人能力不足所导致的,跟面试官没什么关系。

刚开始自我介绍一下,xx大学读研,研一下,NLP方向,想找个日常实习,没论文,项目也都不是纯NLP方向的,比赛经历,最近在搞京东GAIIC 赛道二的复赛,其他去年参加过百度的两个比赛,都没取得什么名次。

研究方向的话NER比较熟一些,做过一些文本摘要,情感分析任务,其他也尝试过翻译,生成,问答等任务,其实大多就是找几个模型跑一下,看看效果,大多一知半解没有深入研究过。

然后面试官就直接问了一些这个GAIIC比赛一些详细情况,什么类型的任务呀,数据集什么样,模型选择为什么选择nezha+globalpointer,其他模型尝试过哪些,效果怎么样,f1值能到多少。然后就深入的挖一些知识。

先问了bert直接用于ner任务,和bert+biLstm用于有哪些区别,biLstm接在Bert后有什么好处,这块我有些模糊,知道bert+bilstm,比普通bilstm好因为bert相当于一个更好的特征提取器,得到更好词向量特征表示。而bert+bilstm比bert更好的原因可能是因为bert中多层self-attention弱化了原本序列中的位置信息,可能虽然有position-embedding,但对于序列标注问题对位置和方向信息要求较多,最后接bilstm能学到更多序列依赖信息吧。

然后针对NER任务解码器进行询问,当然最开始就问,softmax解码和crf解码有什么区别,为什么crf好一点。这softmax直接取概率最高的进行解码,crf则是通过不断学习得到一个转移矩阵,根据转移矩阵加强前后序列潜在关系,比如start到start标签,O到I标签都会学习为0,能更好学习到标注序列潜在规则。

然后询问用mrc完成NER任务怎么做的,就是使用指针网络完成NER任务,找到合适的start,end指针。mrc任务一般只需要一个答案,一般直接从bert最后一层hidden-state后接一个全连接层,从【bs,max_len,768]到【bs,max_len,2],然后通过tensor.split,和squeeze(-1)将其变为2个【bs,max_len】,分别用于预测start和end的指针位置,而用于NER任务中,由于NER任务往往不止需要识别一个实体,而且还需要标记实体tag,需要多层span网络进行预测,在代码上表现就是从bert最后hidden_state开始,【bs,len,768】先经过两个全连接层预测多类start和end,跟序列标注一样,如果共k个实体,则得到【bs,len,k+1】的结果,通过序列标注,判断为第几类实体的start或end,不是实体边界。

下面问了一下Baffine解码器的是什么样的,比span解码器效果好吗,好在哪里,这个我记得是因为span解码中start和end指针位置无法交互,所以学习到边界信息不足,想办法让start和end进行交互,提出了使用一种矩阵乘法方式,学习一个双仿射变换中间的参数矩阵,我们叫做Baffine矩阵,即从代码来看,bert最后hidden_state开始,【bs,len,768】经过两个全连接层,为了分别学习start和end的信息,然后还是【bs,len,768】,这里768我觉得差不多一个数字也ok,反正一会都会被乘没,但也不能太小丢失很多信息,太大计算复杂。我们这样想最后需要得到一个矩阵【bs,len,len,tags】维度,那么我们现在有两个【bs,len,768】分别表示start和end的边界信息。那么中间baffine矩阵的维度为【768,num_tags,768】,最后得到【bs,len,len,tags】输出,这样的好处不仅可以交互start,end信息,而且还可以对嵌套实体进行预测。最后的结果成为(n*(n+1))/2的m分类问题。

最后还问了最后一个GlobalPointer解码器是怎么样,为什么他效果最好,这里我就有点忘记,当时看苏神博客就没仔细看,就回答了把NER问题,转换为判断实体位置的问题,长度为n的句子可能实体span有(n*(n+1))/2个,m分类问题,没错,到这面试官就提出了,那这跟Baffine有什么区别,我当时也觉得好像就是换个说法,最后也是得到【bs,len,len,tags】的输出,可能苏老师加了一个RoPE的位置编码,然后面试官问,bert本身不就又position embedding,那这解码再加个类似的位置编码有什么好处吗,这又问到我了,我就简单说可能attention让位置信息弱化了,然后实体识别,对位置要求很高,需要再加一个位置编码增强效果,,

问了一些其他NER问题,这个比赛实体类别分布怎么样,你分析过吗,其实我是没分析实体类别分布,我就简单说了稍微看了一下训练集各个实体占比,还是很不均衡的,需要用一些trick解决,比如focal loss,dice loss啥的,也没展开说。

然后针对nezha预训练模型,问了bert预训练模型策略,MLM,NSP,然后问nezha预训练策略,我当时看的时候好像就记得比bert没改变啥,就加了几个小trick换个语料吧,我好像就说好像差不多,具体nezha预训练改变地方不太记得,刚才看了一下好像就是把bert位置编码从绝对的参数位置编码,改成一种相对函数位置编码,然后使用全词mask,还进行了一些spanmask来增加预训练任务难度,其他就是增加语料,混合精度fp16训练。最后问了一下针对NER任务,设计一个预训练模型预训练任务,你有什么想法,我就回答像ernie那样mask一些实体,然后再多学一下词的,实体的边界信息。

然后看我还做过文本分类,但就用了一些简单模型,又问了lstm做文本分类和textCNN文本分类哪个效果好,各有什么优点,我对textCNN也不记得啥了,就记得好像也是把[seq,embedding]作为图片2维特征,进入CNN网络,然后通过几个类似multi-head的矩阵变化,然后最后展平,求softmax的。至于优点,就说了lstm对序列位置学习更好,对长序列任务好一些,textCNN,毕竟是CNN更能提取到局部特征,但一般不够深就提取不到长距离文字特征交互,短文本的文本分类还是textCNN好些。

到这差不多45分钟过去了,他看时间差不多仍了到算法题,好像是求字符序列最长无重复子串,后来自己找了一下,原来是leetcode第三题。

比如’abcabcddd’ 输出4 abcd

​ ‘bbbbbbbbb’ 输出 1 b

​ ‘pwpqw’ 输出 3 pqw

开始我理解错了,随便写了个输出无重复的序列,忘记是子串必须连续的了,有点尴尬。

然后想了会,最近没怎么刷题,就想的很慢,想使用动态规划,把包含第i个字符的最长无重复子串长度计算一下,然后max一下整个数组,最后我也就这么做的,然后他问我时间复杂度多少,我看了一眼两个for循环,说大概最多是n方吧,但后来才发现,里面for循环最长也就是26,所以应该是n复杂度吧,他还问能不能用滑动窗口改进一下,我想了一会,当时被问的脑子有点懵,就没想出来,然后就结束了。

最后我看了一下leetcode我觉得滑动窗口时间复杂度应该差不多吧,大致思路就是双指针,一个指针子序列头一个指针子序列尾,每次移动子序列尾部,如果s[j]不在该子序列中,继续移动,如果在就删除s[i]直到不在序列中。

def slide_winow(strings):
	strings=list(strings)
	if len(strings)==0:
		return 0
		
	max_length=1
	s=0
	e=1
	while e<len(strings):
		if strings[e] not in strings[s:e]:
			e+=1
			max_length=max(max_length,e-s)
		else:
			s+=1
	return max_length
			

刚刚的力扣得分为:
字节AL LAB nlp 日常实习面试失败_第1张图片

而我应该是这样写的

def no_repeat_string(strings):
	strings=list(strings)
	if len(strings)==0:
		return 0
	
	max_length=[1]
	for i in range(1,len(strings)):
		for j in range(1,max_length[i-1]+1):
			if strings[i]==strings[i-j]: #有重复
				max_length.append(j)
				break
			if len(max_length)==i: #无重复
				max_length.append(max_length[-1]+1)
	return max(max_length)

刚刚的结果为
字节AL LAB nlp 日常实习面试失败_第2张图片

好吧,我是个小垃圾,写的时间复杂度太高了。

最后面试官按例,问我有没有想问他的,我就还是问问了部门最近主要做哪方面内容,感觉面试官不太想好好回答,随口说了帮其他部分优化一些算法啥的,我就感觉自己应该凉了,结果果不其然,第二天(今天)下午就收到一面失败的消息。

总结

的,我就还是问问了部门最近主要做哪方面内容,感觉面试官不太想好好回答,随口说了帮其他部分优化一些算法啥的,我就感觉自己应该凉了,结果果不其然,第二天就收到一面失败的消息。

总结

总结一下失败经验吧,刷题太少,连leetcode第3题都磕磕巴巴,太不熟练了,感觉可能我算法题熟练过关应该就能过一面了,然后做研究想的太少,学习的时候不够认真,求实。这次失败经验很宝贵,希望暑假之前能找个实习吧,虽然我三年研究生,不跟他们暑期实习的抢,但也想着可以带薪学习,hh。

你可能感兴趣的:(日常,自然语言处理,面试,人工智能)