一. 吴恩达深度学习第五课第二周
2.1 词汇表征
独热编码的词汇不能表示各种单词之间的接近关系,于是可以采取词嵌入的方法将这些词映射为一些特征向量。
可视化这些嵌入表示,用t-SNE算法将300维空间变到二维空间,则可以进行可视化。
2.2 使用词嵌入
迁移学习与词嵌入
- 从大量的文本语料库中学习词嵌入(或者下载预训练好的嵌入模型)
- 将这些嵌入迁移到你正在做的数据集任务上
- 可选的步骤:继续用新数据微调模型(只有当你的第二步的数据集相对够大时,才可以微调。如果比较小,则不需在词嵌入微调上花费太多力气)
个人理解:模型微调就是迁移学习的最后一步。
2.3 词嵌入的特性
类比推理法求出e_w.相似度函数可以采用余弦相似度。
2.4 嵌入矩阵
嵌入矩阵乘以对应单词的one-hot向量就可以得到对应单词的嵌入向量。
2.5 学习词嵌入
实践证明,建立一个语言模型是学习词嵌入的好方法。
神经语言模型,此处没有采用RNN,而是普通的神经网络。输入前四个词,预测下一个词是什么。
在训练语言模型的过程中,顺带学习词嵌入矩阵。
语言模型是利用前面的几个词得到预测词。如果不以训练语言模型为任务,也可以取预测词上下文前后各四个词来得到预测词,这样也可以学习嵌入矩阵。
2.6 word2vec
构造一个skip-grams学习任务,抽取上下文和目标词进行配对,来得到一个监督学习的问题。随机选择上下文词,然后在该词前后5个或者10个词内挑选一个词作为目标词。
构造这样的一个监督学习问题,并不是想解决这个问题本身,而是想要使用这个学习问题来学到一个更好的词嵌入模型。
常规的softmax分母求和有10000次,非常耗时间。可以采取这种二分类的形式,在二分查找上加入哈夫曼树,能更快得到softmax分类的值。
word2vec的两种形式:skip-grams与CBOW。
CBOW:得到目标词两边的上下文,利用上下文来预测中心目标词。
2.7 负采样
为了减小softmax需要求10000个词汇的和而进行负采样。
一个正样本加上k个负样本,由10000类的分类器变成k+1个逻辑回归分类器(这里的逻辑回归分类器随机挑选),极大减少训练花费。
如何选择负采样的样本?
依据上面的公式得出的词库中每个单词的概率进行采样,其中f为词汇在实际文本中出现的频率。
2.8 Glove词向量
xij表示单词i在目标词j的上下文出现的次数。
f表示权重,这个公式用thetai和ej的内积来逼近logXij。
经过学习得到的嵌入向量每一维特征可能不具有可解释性。
2.9 情感分类
第一种方法,将所有情感词的嵌入表示求和取平均,这样完全没考虑词序的影响,比如左下角的句子,本来是一个差评,会把它判为好评。
第二使用RNN,就可以考虑词序的影响。
2.10词嵌入除偏
词嵌入会有偏见,由爸爸是医生得到妈妈是护士。因为机器学习在生活中的广泛应用,消除这些非预期类型的偏见是十分重要的。机器学习算法会在辅助社会中的重要决策用的越来越多,消除非预期偏差很重要。
目前消除bias的一些方法:
- 识别偏差趋势,对he/she,male,female这样的词作差,取平均,就可以看出某些
- 中和步,对没有明确定义性别的词(如doctor),需要避免bias,往中立靠拢。
- 均衡步(中立词与那些性别词之间的距离两者要相等)
二. CCFCSP
- 小明上学
#include <iostream>
#include <set>
#include <utility>
#include <algorithm>
# include <algorithm>
#include <vector>
using namespace std;
const int MAX = 100010;
int n;
int r,y,g;
int k,t;
int sum=0;
int main(){
scanf("%d%d%d",&r,&y,&g);
scanf("%d",&n);
for(int i =1; i <= n;i++){
scanf("%d%d",&k,&t);
switch (k){
case 0:
sum+=t;
break;
case 1:
sum += t;
break;
case 2:
sum += t + r;
break;
case 3:
break;
}
}
printf("%d",sum);
return 0;
}
- 小明放学(只有60分,待AC)
#include <iostream>
#include <set>
#include <utility>
#include <algorithm>
# include <algorithm>
#include <vector>
using namespace std;
const int MAX = 100010;
int n;
int r,y,g;
int rec;
int k,t;
int sum=0;
int temp;
int main(){
scanf("%d%d%d",&r,&y,&g);
scanf("%d",&n);
rec = r + y + g;
for(int i =1; i <= n;i++){
scanf("%d%d",&k,&t);
temp = sum % rec;
switch (k){
case 0:
sum+=t;
break;
case 1:
if(temp <= t) sum += t - temp;
else{
if(temp > t && temp <= t + g) sum = sum;
else if(temp > t + g && temp <= t + g +y)
sum += t + g +y - temp + r;
else
sum += r - (temp - (t+g+y));
}
break;
case 2:
if(temp <= t) sum += t - temp + r ;
else{
if(temp > t && temp <= t + r) sum += t + r - temp;
else if(temp > t + r && temp <= t + r +g)
sum = sum;
else
sum += y - (temp - (t+r+g)) + r;
}
break;
case 3:
if(temp <= t) sum = sum;
else{
if(temp > t && temp <= t + y) sum += t + y - temp + r;
else if(temp > t + y && temp <= t + y + r)
sum += t + y + r - temp;
else
sum = sum ;
}
break;
}
}
printf("%d",sum);
return 0;
}
|