一面

2021.8.2 下午 15:00 一面。出师不捷,面试开始前几分钟电脑蓝屏了。。。好在最后面试官评价还不错的样子。。。大概是第一面一般都比较简单,之前 AML 一面问的简单,面试官评价也还不错,结果二面就凉了。。。

首先是自我介绍

然后是算法题

  • leetcode 84:柱状图中最大的矩形(hard)

    用单调栈做,以前看左程云的《程序员代码面试指南》对于有重复元素的单调栈,栈是存储 vector,就是把相同元素的下标存在同一个数组里。面试官没见过这种写法,然后说其实没必要,复杂化了,栈存 int 就行了,然后跟我一起讨论了下相同元素的处理方法,其实不用特意处理相同元素,因为最后计算面积的时候,相邻的相同高度的两根柱子可能计算面积会不一样?但肯定有一个会计算到对的面积 在面试最后问面试官我的不足和待改进的地方时,面试官说算法题写的挺快的。。。

然后是项目和基础知识

  • 天池这个比赛数据集大小?
  • 为什么用到蒸馏呢?
  • resnet 有什么特点?

    残差单元,缓解梯度消失问题

  • 有用过更深的模型吗?

    有,针对这个图片数量,再大些可能就会过拟合

  • 测试集数量,伪标签操作后新增的图片数量?

    不太记得了

  • 你这个训练集的图像数量貌似不是很多的样子,使用 resnet34 为什么不会过拟合呢?

    通过实验,resnet34比较好。介绍了下由于相同黑子群图像的相似性,因此图像数量其实相当于还更少。因此后面用了蒸馏,在有教师模型指导的情况下,resnet18 的能力就足够了

  • F1 score 怎么计算?精确率和召回率又怎么计算?

  • xgboost 的树节点是怎么分裂的?

    CART 树,基尼指数最小化

  • 以什么方式去选最优特征和最优切分点?

    并行计算各个切分点分裂的增益

  • 是遍历所有的切分点都计算增益吗?

    我说是的,面试官反问了一下,然后我就愣住了。然后说可以像随机森林一样列采样,在部分特征里选择最优特征。面试官说看运行环境,都有可能

  • xgboost 怎么处理缺失值?

    稀疏感知的切分点查找算法

  • 你这个数据集的特征有多少?

    每个样本有1000多个特征

  • 那怎么找到最优的超参数

    贝叶斯优化

  • 最后树的深度和个数是多少?

    没记

  • 数据有多少?

  • 这么少的数据和这么多的特征,如果最后生成的树很深,个数很多,不会过拟合吗

    没记,但结果还可以

  • xgboost 如何选择特征的重要性知道吗?

    不怎么了解

反问环节:

  • 日常实习一般都做些什么呢?

    目前在做xgboost相关的,因此问的这方面比较多。长期来看的话是做搜索算法

  • 您觉得我这场面是有什么不足和要改进的地方吗?

    面试官对我的评价很高,说是他面的里面算数一数二的(捂脸。问题回答的都不错,算法题写的也挺快。xgboost这块估计我是新了解的,可以再深入学习学习。

二面

2021.8.2 下午 16:30 二面。一面面试官评价挺好,还挺开心的,没多久就收到邮件,紧接着二面。结果二面面试官问的问题就稍微偏一点,针对我简历写的项目问的问题比较少,然后对 transformer 之类问的还比较多,我只是写了了解啊。感觉面得不太好的样子,头疼。。。想复盘结果手机出 bug 了录音没保存。。。

首先是自我介绍

然后是项目和基础知识
项目方面问的很少,我也想不起来都问了啥了

  • 介绍下天池这个比赛的背景
  • 按你说的各类别数据量是不平衡的,有做什么处理吗
  • 用的是 resnet34,有试过更大的模型吗?

然后是 transformer 连击,问的我都不太会。。。

  • 自注意力运算中缩放因子的作用
  • transformer 的 decoder 如果从右到左处理序列,mask 是怎么样的?

    问的从右到左的序列,和原来认知的从左到右反着来,然后我就画了个三角矩阵,貌似画错了,面试官说画的不对。。。然后说屏蔽的地方设为负无穷,别的地方设为 0,面试官又问不是负无穷吧,但我记得是负无穷呀。。。

  • transformer 的多头有什么用?

  • transformer 的全连接层有什么用

  • 随机森林和 boosting 集成学习方法的区别,各有什么优缺点?

  • 过拟合时方差和偏差分别有什么表现?
  • 深度学习一般怎么解决过拟合问题?
  • batch normalization 详细介绍一下?

    只知道是用一批数据对一个神经元进行归一化,具体的不记得了。

  • 深度学习的优化方法,说一下发展过程和各自的优缺点

    分别讲了下面的方法,写了公式

    • SGD:
    • 动量法:问了 vt 没有缩减系数吗,我说写了 γ 呀,又问和 η 没关联吗,回答如果要有关联,那么就一个 β,一个 1-β
    • AdaGrad:讲了下利用历史梯度平方和,优点是能让更新频率低的参数有较大的更新步伐。又问缺点,答错了,给了提示说是不是到后期更新不动了,因为梯度平方和越加越大,学习率变得很小
      • 又问RMSProp做了什么改进,我说这个不太记得了,能不能说说 Adam
    • Adam:问是那两个优化方法的结合,我说动量法和 AdaGrad的结合,他反问是这两个吗,动量法是的,Adam 的这个二阶和AdaGrad 一样吗?不是就是这两个的结合嘛。。。

最后两道算法题

  • 第一题怎么也想不起来是啥了,应该不怎么难吧,挺快过了的
  • leetcode 42 接雨水(hard)

    用双指针做的,面试官可能不知道这种做法,所以让我解释了每行代码的意思,然后说我这个应该不对(这个面试官真的很喜欢质问我。。。压力大),我给他解释了。又问如果数组是单调递减的,那实际装不了水,但你这个都加上了?整了个[321]的样例跟他讲,加上的是 rightMax-nums[right]=0,实际上并没有加

三面

2021.8.6 感觉三面面试官的问法才是最正常的,一开始问了两道算法题,然后按我简历上写的天池的这个比赛深挖,一直问的这个项目,问了很多,然后就没问别的。不像二面面试官就抓着我写了个了解的 transformer 一直问,然后对主要的项目倒不咋问。。。 最后面试官给的反馈说我表现很不错。。。(捂脸

首先,还是自我介绍

然后,两道算法题:

  • leetcode 22. 括号生成(medium)

    递归回溯。很快就做完了,面试官问之前有没有做过这题,我就说做过类似的,用回溯做的,但没刷过原题

  • 给定任意一棵树,举个例子,1号节点是根节点,有三个孩子:2、3、5,1 到 2的距离是2,1到3的距离是1,1到5的距离是4;5号节点有两个孩子:7、8,边长分别为3、2;2号节点有两个孩子4、6,边长分别为3、4。实现一个function,输入是根节点,求这棵树最远的两个点的距离,比如这个题6、7最远

    在 leetcode 没找到原题,但类似 ~~[leetcode 543.二叉树的直径](https://www.yuque.com/docs/share/75d838ff-a43e-46d8-a87a-af4cced59531?# 《[容易] 543. 二叉树的直径》),只不过换成了多叉树,而且边长有权重。~~ 应该是更像 [困难] 124. 二叉树中的最大路径和

  1. #include <iostream>
  2. #include<vector>
  3. using namespace std;
  4. class Node {
  5. public:
  6. int val; // 父节点到当前节点的边的权重
  7. vector<Node*> children;
  8. Node(int value)
  9. {
  10. val = value;
  11. }
  12. };
  13. int calDepth(Node* root, int& maxLen)
  14. {
  15. if(root == nullptr)
  16. return 0;
  17. int maxDepth = 0;
  18. int secondDepth = 0;
  19. for(int i = 0; i < root->children.size(); ++i)
  20. {
  21. int depth = calDepth(root->children[i], maxLen) + root->children[i]->val;
  22. if(depth > maxDepth)
  23. {
  24. secondDepth = maxDepth;
  25. maxDepth = depth;
  26. }
  27. else if(depth > secondDepth)
  28. secondDepth = depth;
  29. }
  30. maxLen = maxDepth + secondDepth;
  31. return maxDepth;
  32. }
  33. int main() {
  34. Node* root = new Node(0);
  35. Node* node2 = new Node(2);
  36. root->children.push_back(node2);
  37. Node* node3 = new Node(1);
  38. root->children.push_back(node3);
  39. Node* node5 = new Node(4);
  40. root->children.push_back(node5);
  41. Node* node7 = new Node(3);
  42. node5->children.push_back(node7);
  43. Node* node8 = new Node(2);
  44. node5->children.push_back(node8);
  45. Node* node4 = new Node(3);
  46. node2->children.push_back(node4);
  47. Node* node6 = new Node(4);
  48. node2->children.push_back(node6);
  49. int maxLen = 0;
  50. calDepth(root, maxLen);
  51. cout << maxLen << endl;
  52. }

然后是问项目,问的都是天池这个比赛的:

  • 先介绍一下这个项目
  • 数据集大小?
  • 最后投票是哪些模型进行融合?
  • 介绍一下怎么用的知识蒸馏
  • 写一些知识蒸馏的伪代码 ```python logit_t = teacher(x) logit_s = student(x) hard_output = softmax(logit_s, T=1) hard_target = y soft_output = softmax(logit_s, T=10) soft_target = softmax(logit_t, T=10)

hard_loss = -\sum hard_target log hard_output soft_loss = -\sum soft_target log(soft_target/soft_output) loss = alpha soft_loss + (1-alpha) hard_loss

  1. - 带温度 T softmax 写一下
  2. ```python
  3. \phi(z) = e^{z^i/T} / \sum_j e^{z^j/T}
  • 知识蒸馏的过程中有遇到哪些问题

    讲了下 T 的选择和 alpha 的选择

  • 不同的 T 有什么影响?

  • 写一下教师模型的代码

    说用的 resnet34,resnet 的具体细节不记得了,只记得用了残差单元

  • 知识蒸馏本来是用来压缩模型的,为什么反而能导致学生模型性能更好呢?

  • 用了哪些数据增强的方法?
  • 半监督学习是怎么做的?

后面的问题不记得了,来了个电话,录音中断了

End

2021.8.9 晚,收到 offer 啦 ~