无论文勇闯算法岗!—— 淘天一面
(没准备还是不行啊哈哈哈)
一、基础知识
梯度 优化器 一阶动量 二阶动量 是啥
梯度:
- 梯度的反方向就是参数的更新方向
一阶动量:梯度的指数加权平均
- 公式:
- 作用:平滑梯度,减少更新方向的抖动
二阶动量:梯度平方的指数加权平均
- 公式:
- 作用:自适应调整学习率大小
adam 总体公式:
模型初始化方法有哪些?
- 全零初始化
- ReLU的激活函数,梯度是0
- sigmoid的激活函数,每层的神经元的输出相同,梯度相同(不为0),那么更新后的参数也相同,模型学不到任何特征
- 随机初始化 (Random Initialization)
- 目的: 打破对称性,确保不同神经元学习到不同的特征。
- 缺点: 随机数过大或过小都可能导致梯度消失或梯度爆炸
- He 初始化(针对ReLU优化的初始化方法)
- W 初始化服从正态分布,方差和输入神经元个数有关
全0的初始化会有什么问题 ?
二、项目
(面试官:“所以就是做了一个SFT + GRPO是吧”)
可能我的简历写太大了,导致面试官期望太高
也可能是我没有提前准备好难点
GRPO里边的kl散度和clip的区别是什么?
下次应该这么回答:
kl散度是对整体模型参数进行的约束,主要作用是防止策略在多步更新后整体漂移过远(长期稳定性)
clip 是针对token级别的约束,当某个token的概率变化巨大的时候,会强制截断
kl散度意义不大,更多的是实验性的结论,因为RL更新很多步之后,最后的策略可能和开始的相差巨大,如果训练足够稳定,其实不需要KL散度的惩罚。
三、做题
# 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。 # 返回所有可能的结果。答案可以按 任意顺序 返回。 # 输入:s = "()())()" # 输出:["(())()","()()()"]
这题其实不难,太久没刷题了,回溯写了半天,括号匹配也写了半天
一共花了40min写成了这样:
# 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。 # 返回所有可能的结果。答案可以按 任意顺序 返回。 # 输入:s = "()())()" # 输出:["(())()","()()()"] import copy s = "()())()" ans = [] def is_valid(path): my_stack = [] for c in path: if len(my_stack)!=0: if my_stack[-1]=='(': if c==')': my_stack.pop() else: my_stack.append(c) else: if c==')': return False else: my_stack.append(c) if len(my_stack)==0: return True else: return False def back_track(path, i): if i==len(s): if is_valid(path): if path not in ans: ans.append(copy.copy(path)) return back_track(path,i+1) path = path+s[i] back_track(path,i+1) path = path[:-1] return back_track('',0) print(ans)
主要问题
- 没有找到最小删除数量的解 - 代码找到了所有有效组合,但没有筛选出删除最少字符的结果
- 字符串修改方式有问题 -
path
= path+s[i]
和path
= path[:-
1
]
不会影响递归调用中的path值(暴露了基础pyhon语法不牢靠了) - is_valid函数逻辑冗余 - 可以简化
gpt给的优化思路:
def removeInvalidParentheses_optimized(s): # 预计算需要删除的左右括号数量 def calculate_removals(): left_remove = right_remove = 0 for c in s: if c == '(': left_remove += 1 elif c == ')': if left_remove > 0: left_remove -= 1 else: right_remove += 1 return left_remove, right_remove left_remove, right_remove = calculate_removals() result = set() def backtrack(index, path, left_rem, right_rem, open_count): # 剪枝1: 如果需要删除的括号数量为负,直接返回 if left_rem < 0 or right_rem < 0: return # 剪枝2: 如果右括号数量超过左括号,直接返回 if open_count < 0: return if index == len(s): if left_rem == 0 and right_rem == 0 and open_count == 0: result.add(path) return char = s[index] if char == '(': # 选择删除左括号 if left_rem > 0: backtrack(index + 1, path, left_rem - 1, right_rem, open_count) # 选择保留左括号 backtrack(index + 1, path + char, left_rem, right_rem, open_count + 1) elif char == ')': # 选择删除右括号 if right_rem > 0: backtrack(index + 1, path, left_rem, right_rem - 1, open_count) # 选择保留右括号 if open_count > 0: backtrack(index + 1, path + char, left_rem, right_rem, open_count - 1) else: # 字母 # 字母总是保留 backtrack(index + 1, path + char, left_rem, right_rem, open_count) backtrack(0, "", left_remove, right_remove, 0) return list(result) if result else [""]
总结:
面试容易紧张,一紧张战斗力下滑50%
感觉面试官不感兴趣就有点犯怵
后面加油吧,不管面试官啥态度都尽力发挥到最好,干爆面试官!