2021-04-28

自然语言处理期末笔记

完全基于字典的,
给两个分词结果,是什么原因分成这个样子,原因是不是基于词典的方式,FMM、BMM(这俩是基于词典的方式)了解的深一些
基于统计的
算下条件概率,则会中n-grim的概率

利用n-grim的基本操作概念,未登录词怎么办(使用基于统计的汉字成词能力的hmm模型),hmm方法到底是基于什么判断的(基于统计)
为什么要前缀词典:利用前缀词典对输入句子进行切分,得到所有的切分可能,根据切分位置,构造一个有向无环图
到底是开头和结尾,知道成词概率怎么 bms啥意思,知道这几个东西
vecti算法(Viterbi算法实际上是用动态规划求解HMM模型预测问题,即用动态规划求概率路径最大(最优路径)。这时候,一条路径对应着一个状态序列。),好处,复杂度,为什么?下面的那个B层的图下面的

感知机的局限性?为什么要用激活函数?阶跃函数、sigmoid和tanh的异同;激活函数值域是否关于0对称有何影响?(对于 Sigmoid 函数来说,它的值域是 (0,1),因此又有如下特点 优点:可以作为概率,辅助模型解释缺点:输出值不以零为中心,可能导致模型收敛速度慢。tanh是关于0对称的,可以生成负值,在一定程度上防止梯度总是同为正,或者同为负。在 Sigmoid 函数中,输出值恒为正。这也就是说,如果上一级神经元采用 Sigmoid 函数作为激活函数,那么无法做到 x1 和x2 符号相反。

梯度下降中的梯度指的是代价函数对各个参数的偏导数,偏导数的方向决定了在学习过程中参数下降的方向,学习率(通常用α表示)决定了每步变化的步长,有了导数和学习率就可以使用梯度下降算法(Gradient Descent Algorithm)更新参数了。
感知机的缺点(感知机无法处理非线性情况),能做到什么?(解决线性可分问题)更新,梯度下降(梯度下降就是沿着代价函数的梯度减小代价函数的过程),因为有些缺点,引入了两层的神经网络,神经网络的结构,激活函数(从阶跃函数到激活函数)反向传播怎么回事?
激活函数的特点,数学特点,值域函数和求导之后的图?
tanh比sigmoid的好处是?值域和微分的图,为什么tanh一般会比sigmoid好,回答好几点
有时候参数更新会出现这种情况上下上下的,怎么出现的,怎么改进这个

词向量
Embedding在数学上表示一个函数 f: X -> Y,对于word embedding,就是将单词word映射到另外一个空间,可以认为是单词嵌入,就是把X所属空间的单词映射为到Y空间的多维向量,那么该多维向量相当于嵌入到Y所属空间中。 word embedding,就是找到一个函数,生成在一个新的空间上的表达,实际上就是word representation。
为什么要进行这样的embedding呢?主要是为了表示词的含义,meaning,可以把最终的Y空间想成是一些特征,通过这些特征来描述一个词。如果映射得当,像上面的图,在二维空间中,run和chase的位置比较接近,也就意味着它们两个对应的向量比较像;或者反过来说,如果我们能够得到词的合适的向量表示,词义相近的词向量表示相近,就能较好地体现它们的语义。word2vec中,Y空间大概有300维。也就是说,每个词使用300*1向量表示,这样,相比于One-hot,维度大大缩减。不过,一般来说,我们不清楚具体的每个维度所代表的特征到底是什么。即使这样,这种方法能够较好地表示出词语的意义。
进行word embedding的主要目的是为了表达词的含义,词汇之间的内在联系,实现对词语更精确的描述。

One-hot和word enbeding相比优缺点是什么,(one-hot向量维度很大,且仅仅与词汇在系统中的位置相关的编码方法没有办法表达词汇的意义。)
Wor2vec来训练,通过一个词代表另外一个?
网络非常简单就两层,基本的参数维度,输入维度、W矩阵维度

Skip-gerams和cbow这俩的判断?

hierarchical softmax用huffman树来取代隐藏层和输出层的结构,叶子节点对应着词表中的单词,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的作用。
哈夫曼树怎么建树,有什么好处。
得到Huffman树后我们会对叶子节点进行Huffman编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,
哈夫曼树的每一个内部节点都不对应一个单词,单词都是对应叶子节点,更新的都是内部节点的向量。归根到底更新的还是h。变化就是一开始需要更新每个词对应的向量,然后现在用哈夫曼树只用更新内部节点向量。
建哈夫曼树时,权重是词在词表中的概率,词频为权重,
哈夫曼树取代神经网络的右边那一层。大大降低了计算量。

为什么hiriarchical [ˌhaɪəˈrɑːkɪkl,它怎么实现的,使用哈夫曼树,为什么用哈夫曼树,(更新输出向量得似乎,需要更新单词表种的所有单词,也即是说对每个可能的单词都要计算和更新参数。对每个输入的训练向量都进行这样的操作是每场昂贵的,从而不适合推广到大的词库上面)用了之后
使用Huffman树之后,从隐藏层到输出的softmax层的计算量就得到了极大的改进。这样就避免了计算所有词的softmax概率,变成了一棵二叉Huffman树之后,softmax概率计算只需要沿着树形结构进行就可以了。
Huffman树的叶子节点并不像上面的模型中有一个对应的输出向量,而是所有内部节点具有一个对应的向量。我们要更新的是内部节点的对应向量。
同时,在Huffman树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,

一个改进方法是限制需要进行更新的输出层的向量数。那么到底更新哪些向量呢?一种选择的方法就是hierarchical softmax,一种是negative sampling。
hierarchical softmax用huffman树来取代隐藏层和输出层的结构,叶子节点对应着词表中的单词,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的作用。

Huffman树有什么好处呢?得到Huffman树后我们会对叶子节点进行Huffman编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。如何编码呢?一般对于一个霍夫曼树的节点(根节点除外),可以约定左子树编码为0,右子树编码为1。如上图,则可以得到c的编码是00。
使用huffman树对效率的改进有两方面,首先,由于是二叉树,之前计算量为V ,现在变成了 logV 。第二,由于huffman树中,高频的词靠近树根,这样高频词需要更少的时间会被找到,符合优化思想。

从输出层倒退到输入层的计算这个应该也不会考,
多文上下词,主要用到cbow和skip,一个拿上下文预测单词,这俩基本的区别、特点。
cbow从训练角度来说,高频词出现的次数更多也就意味着高频词对上下文的影响力要大得多,那么低频词在同样的上下文中就会收到歧视,在更新参数的时候,高频和低频一起更新,但受到高频词的影响,低频的更新次数要少些。
skip-gram进行预测的次数是要多于cbow的,因为每个词作为中心词时都要对上下文预测一次,都要进行2c次的预测、调整,当数据量较少的时候,或者生僻词出现次数少的情况下,这种多次的调整会使得词向量相对的更准确。

理解为什么skip-grim有这个特点,为什么要快好几倍。
基本的skip-grim的伪代码体现她俩区别的在哪里。一个上下文单词预测目标词,一个是目标词预测上下文
两个for循环,不是先把外面的,路径去拿,w还有c去拿目标词,wt是上下文词?去找的是目标词,更新的还是上下文单词。这里面两个for循环有嵌套关系,在小数量关系上好些
cbow拿上下文找目标词,更新的也是上下文。伪代码中上面的那个for循环

循环神经网络
rnn有记忆功能,为什么有记忆功能,输入层到隐藏层的权重多少
lstm为什么可以达到比较长的记忆功能。给一个循环单元图,问三个sigmoid的功能,问哪个是什么门

用和不用attention的seq2seq,qkv三个维度一样不一样?
transform里面的多头注意力时,q,k,v来源一样,计算后是不是一样
知道attention和self-attention的计算工程

transform考的好像挺多,多头注意力机制,是实验中的发现,应该主要考transform的结构,positional encoding,为什么引入,给出两个公式(sin,cos那俩)理解pe,为什么引入残差网络,norm归一化,还有yilenxin,但是没找到在图的哪里,
还有为什么要用mask,pading mask和tending mask,为撒一定要用
右下角的是self-attention。

后面两章应该只考一选择题,比如自己看见自己有什么影响

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个可能的Java实现: ```java import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; public class RentPlanGenerator { private static final double RENT_INCREASE_RATE = 0.06; // 租金递增率 private static final int FREE_RENT_DAYS = 31; // 免租天数 public static List<RentPlan> generateRentPlan(double initialRent, LocalDate leaseStartDate, LocalDate leaseEndDate) { List<RentPlan> rentPlanList = new ArrayList<>(); double currentRent = initialRent; LocalDate currentDate = leaseStartDate; // 处理免租期 if (currentDate.isBefore(leaseStartDate.plusDays(FREE_RENT_DAYS))) { currentDate = leaseStartDate.plusDays(FREE_RENT_DAYS); } while (currentDate.isBefore(leaseEndDate)) { LocalDate nextIncreaseDate = currentDate.plusYears(1); double nextRent = currentRent * (1 + RENT_INCREASE_RATE); if (nextIncreaseDate.isBefore(leaseStartDate.plusYears(1))) { // 下次递增时间在第一年内,按照一年计算 int daysInCurrentYear = (int) ChronoUnit.DAYS.between(currentDate, nextIncreaseDate); rentPlanList.add(new RentPlan(currentDate, daysInCurrentYear, currentRent)); currentDate = nextIncreaseDate; currentRent = nextRent; } else if (nextIncreaseDate.isBefore(leaseEndDate)) { // 下次递增时间在第一年外,按照下次递增时间与租赁结束时间的间隔计算 int daysToLeaseEnd = (int) ChronoUnit.DAYS.between(currentDate, leaseEndDate); rentPlanList.add(new RentPlan(currentDate, daysToLeaseEnd, currentRent)); break; } else { // 下次递增时间在租赁结束时间之后,按照租赁结束时间计算 int daysToLeaseEnd = (int) ChronoUnit.DAYS.between(currentDate, leaseEndDate); rentPlanList.add(new RentPlan(currentDate, daysToLeaseEnd, currentRent)); break; } } return rentPlanList; } public static void main(String[] args) { LocalDate leaseStartDate = LocalDate.of(2021, 3, 1); LocalDate leaseEndDate = LocalDate.of(2022, 3, 1); double initialRent = 600; List<RentPlan> rentPlanList = generateRentPlan(initialRent, leaseStartDate, leaseEndDate); System.out.printf("%-12s%-12s%-12s%n", "时间", "天数", "租金"); for (RentPlan rentPlan : rentPlanList) { System.out.printf("%-12s%-12d%-12.2f%n", rentPlan.getStartDate(), rentPlan.getDays(), rentPlan.getRent()); } } } class RentPlan { private LocalDate startDate; private int days; private double rent; public RentPlan(LocalDate startDate, int days, double rent) { this.startDate = startDate; this.days = days; this.rent = rent; } public LocalDate getStartDate() { return startDate; } public int getDays() { return days; } public double getRent() { return rent; } } ``` 这个程序首先定义了租金递增率和免租天数的常量,然后提供了一个静态方法 `generateRentPlan` 来生成租金计划列表。该方法接受三个参数:初始月租金、租赁开始时间和租赁结束时间。 具体实现时,我们使用循环来逐月生成租金计划。在每次循环中,我们首先计算下次递增租金的时间和金额。然后根据下次递增时间与租赁开始时间的间隔,决定本次循环处理的天数和租金金额。最后将这些信息保存到一个 `RentPlan` 对象中,并添加到租金计划列表中。 在主函数中,我们使用 `generateRentPlan` 方法生成租金计划列表,并以表格形式输出。输出结果如下: ``` 时间 天数 租金 2021-04-01 30 600.00 2021-05-01 31 636.00 2021-06-01 30 674.16 2021-07-01 31 713.57 2021-08-01 31 754.29 2021-09-01 30 796.39 2021-10-01 31 840.94 2021-11-01 30 887.02 2021-12-01 31 934.72 2022-01-01 31 984.12 2022-02-01 28 1035.30 ``` 可以看到,程序正确地根据递增周期和递增率生成了每个月的租金计划,并且考虑了免租期的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值