CS224N第二课作业--word2vec与skipgram

文章目录

CS224N: 作业2 word2vec (49 Points)

1. Math: 理解 word2vec

word2vec 的关键思想是: a word is known by the company it keeps.
给定一个中心词 c c c, 一个大小为 n n n 的窗口, 那么相对于 c c c 的上下文就是 O O O, 例如在文本: ... problems turning into banking crises as ... 中, 若 c c cbanking, n = 2 n=2 n=2, 则 O O Oturning into crises as 这4个单词.

因此, Skip-gram word2vec 的目的就是学习一个概率分布: P ( O ∣ C ) P(O|C) P(OC). 特别的, 对于一个特定的中心词 c c c 和一个特定的上下文单词 o o o, 我们有: P ( O = o ∣ C = c ) = exp ⁡ ( u o T v c ) Σ w ∈ V o c a b exp ⁡ ( u w T v c ) P(O=o|C=c)=\frac{\exp{(u_o^Tv_c)}}{\Sigma_{w\in Vocab}\exp{(u_w^Tv_c)}} P(O=oC=c)=ΣwVocabexp(uwTvc)exp(uoTvc)

这里, Vocab 是指词汇表, 它的长度为 N. 定义两个矩阵 UV, U 表示 outside word vectors, 大小为 (D, N), 也即该矩阵的列向量 U i U_i Ui 表示词表第 i 个单词的词向量, 词向量维数是 D. V 矩阵大小与 U 相同, 但他表示每个单词作为中心词时的词向量矩阵.

接下来根据优化目标来定义损失函数.
对于特定的 c c c o o o, 它的损失贡献是:
J n a i v e − s o f t m a x ( v c , o , U ) = − log ⁡ P ( O = o ∣ C = c ) J_{naive-softmax}(v_c, o, U) = −\log{P(O = o|C = c)} Jnaivesoftmax(vc,o,U)=logP(O=oC=c)

这可以视为 真实分布 y y y预测分布 y ^ \hat{y} y^ 之间的交叉熵损失(对于特定的 c c c o o o), 这里 y y y y ^ \hat{y} y^为N维向量, 第 k 个分量表示词汇表第k个词是指定中心词 c c coutside word 的条件概率. y y y 是一个 one-hot 向量, 它在实际 outside word 的分量处为1, 其它地方是0. y ^ \hat{y} y^ P ( O ∣ C = c ) P(O|C=c) P(OC=c) 给出. 因此很容易就能看出该损失函数实际上就是真实分布 y y y预测分布 y ^ \hat{y} y^ 之间的交叉熵损失

插播一条定义, 交叉熵的定义是:

  • Cross-Entropy Loss
    The cross-entropy loss between the true (discrete) probability distribution p p p and another distribution q q q is: − Σ i p i l o g ( q i ) -\Sigma_{i}p_ilog(q_i) Σipilog(qi)

计算 J n a i v e − s o f t m a x ( v c , o , U ) J_{naive-softmax}(v_c, o, U) Jnaivesoftmax(vc,o,U) 关于 v c v_c vc 的偏导数

结果只能使用 y y y y ^ \hat{y} y^ 以及 U U U 来表示, 请给出详细计算过程
∂ ( J ) ∂ ( v c ) = ∂ ∂ ( v c ) ( − log ⁡ P ( O = o ∣ C = c ) ) = ∂ ∂ ( v c ) ( log ⁡ ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) − u o T v c ) = − u o + 1 ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) ∂ ∂ ( v c ) ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) = − u o + ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) u w ∑ u x ∈ V o c a b ( exp ⁡ u x T v c ) = − u o + ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) ∑ u x ∈ V o c a b ( exp ⁡ u x T v c ) u w = − u o + ∑ u w ∈ V o c a b P ( O = w ∣ C = c ) u w = − u o + ∑ u w ∈ V o c a b y w ^ u w = − u o + U y ^ = U ( y ^ − y ) \begin{align*} \frac{\partial(J)}{\partial(v_c)} & = \frac{\partial}{\partial(v_c)}{(−\log P(O = o|C = c))} \\ & =\frac{\partial}{\partial(v_c)}(\log \sum_{u_w\in Vocab}(\exp{u_w^Tv_c})-u_o^Tv_c) \\ & = -u_o + \frac{1}{\sum_{u_w\in Vocab}(\exp{u_w^Tv_c})}\frac{\partial}{\partial(v_c)}\sum_{u_w\in Vocab}(\exp{u_w^Tv_c}) \\ & = -u_o + \frac{\sum_{u_w\in Vocab}(\exp{u_w^Tv_c})u_w}{\sum_{u_x\in Vocab}(\exp{u_x^Tv_c})} \\ & = -u_o + \sum_{u_w\in Vocab}\frac{(\exp{u_w^Tv_c})}{\sum_{u_x\in Vocab}(\exp{u_x^Tv_c})}u_w \\ & = -u_o + \sum_{u_w\in Vocab}P(O=w|C=c)u_w \\ & = -u_o + \sum_{u_w\in Vocab}\hat{y_w}u_w \\ & = -u_o + U\hat{y} = U(\hat{y}-y) \end{align*} (vc)(J)=(vc)(logP(O=oC=c))=(vc)(loguwVocab(expuwTvc)uoTvc)=uo+uwVocab(expuwTvc)1(vc)uwVocab(expuwTvc)=uo+uxVocab(expuxTvc)uwVocab(expuwTvc)uw=uo+uwVocabuxVocab(expuxTvc)(expuwTvc)uw=uo+uwVocabP(O=wC=c)uw=uo+uwVocabyw^uw=uo+Uy^=U(y^y)

  • When is the gradient you computed equal to zero?
    也即 $ U(\hat{y}-y)=0 $, 这是齐次线性方程组, 矩阵的行秩小于列秩, 此时方程组有无数解.

  • 计算得到的结果表现形式是一个差值的形式, 给出解释为什么当 v c v_c vc 减去这个偏导数后会提升 v c v_c vc 的表现.

计算 J n a i v e − s o f t m a x ( v c , o , U ) J_{naive-softmax}(v_c, o, U) Jnaivesoftmax(vc,o,U) 关于每一个 u w u_w uw 的偏导数

对上下文词向量 u w u_w uw求导
∂ ( J ) ∂ ( u w ) = ∂ ∂ ( u w ) ( − log ⁡ P ( O = o ∣ C = c ) ) = ∂ ∂ ( u w ) log ⁡ ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) − ∂ ∂ ( u w ) u o T v c \begin{align*} \frac{\partial(J)}{\partial(u_w)} &= \frac{\partial}{\partial(u_w)}{(−\log P(O = o|C = c))} \\ &= \frac{\partial}{\partial(u_w)}\log \sum_{u_w\in Vocab}(\exp{u_w^Tv_c})-\frac{\partial}{\partial(u_w)}u_o^Tv_c \end{align*} (uw)(J)=(uw)(logP(O=oC=c))=(uw)loguwVocab(expuwTvc)(uw)uoTvc
分为两部分计算, 对于前一部分 PartA:
p a r t A = exp ⁡ u w T v c ∑ u w ∈ V o c a b ( exp ⁡ u w T v c ) v c = P ( O = w ∣ C = c ) v c = y w ^ v c \begin{matrix} partA &=& \frac{\exp{u_w^Tv_c}}{\sum_{u_w\in Vocab}(\exp{u_w^Tv_c})}v_c=P(O=w|C=c)v_c=\hat{y_w}v_c \end{matrix} partA=uwVocab(expuwTvc)expuwTvcvc=P(O=wC=c)vc=yw^vc
对于后一个部分, 当 w 不等于 o 时, partB=0, 否则等于 v c v_c vc, 因此:
∂ ( J ) ∂ ( u w ) = ( y ^ w − y w ) v c \frac{\partial(J)}{\partial(u_w)}=(\hat{y}_w-y_w)v_c (uw)(J)=(y^wyw)vc

  • 计算 J n a i v e − s o f t m a x ( v c , o , U ) J_{naive-softmax}(v_c, o, U) Jnaivesoftmax(vc,o,U) 关于 U U U 的偏导数(也即把上面的结果表示为矩阵形式)
    ∂ ( J ) ∂ ( U ) = ⟨ ∂ ∂ ( u 1 ) , ∂ ∂ ( u 2 ) , … , ∂ ∂ ( u N ) ⟩ \begin{matrix} \frac{\partial(J)}{\partial(U)} & = \braket{\frac{\partial}{\partial(u_1)}, \frac{\partial}{\partial(u_2)}, \dots, \frac{\partial}{\partial(u_N)}} \end{matrix} (U)(J)=(u1),(u2),,(uN)

计算 The Leaky ReLU (Leaky Rectified Linear Unit) 的导函数

f ( x ) = max ⁡ ( α x , x ) ( 0 < α < 1 ) f(x) = \max(\alpha x, x) (0<\alpha<1) f(x)=max(αx,x)(0<α<1)
d d x f ( x ) = { α , x < = 0 1 , x > 0 \frac{d}{dx}f(x)= \begin{cases} \alpha, &x<=0 \\ 1, &x>0 \end{cases} dxdf(x)={α,1,x<=0x>0

计算 sigmoid function 的导函数

σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1+e^{-x}} σ(x)=1+ex1
σ ′ ( x ) = − 1 ( 1 + e − x ) 2 ∗ ( − e − x ) = e − x ( 1 + e − x ) 2 = σ ( x ) ( 1 − σ ( x ) ) \sigma'(x) = -\frac{1}{(1+e^{-x})^2}*(-e^{-x})=\frac{e^{-x}}{(1+e^{-x})^2}=\sigma(x)(1-\sigma(x)) σ(x)=(1+ex)21(ex)=(1+ex)2ex=σ(x)(1σ(x))

The Negative Sampling loss

考虑负采样的损失函数, 它是原生 softmax 损失的替代版, 假设先从词表中随机挑选 N 个负样本(单词), 标记为 w 1 , w 2 , … , w K w_1, w_2, \dots, w_K w1,w2,,wK, 它们的 outside vectors 是: u 1 , u 1 , … , u K u_1, u_1, \dots, u_K u1,u1,,uK. 注意, K个负样本互不相同, 上下文单词 o 不在这K个样本中. 那么对于指定的中心词c和外部词o, 损失函数是:
J n e g − s a m p l e ( v c , o , U ) = − log ⁡ ( σ ( u o T v c ) ) − ∑ s = 1 K log ⁡ ( σ ( − u s T v c ) ) J_{neg-sample(v_c, o, U)} = -\log(\sigma(u_o^Tv_c))-\sum_{s=1}^K \log{(\sigma(-u_s^Tv_c))} Jnegsample(vc,o,U)=log(σ(uoTvc))s=1Klog(σ(usTvc))

  • 计算 J 关于 v c v_c vc, u s u_s us 的偏导. 结果使用 v c v_c vc, u o u_o uo, u w s u_{w_s} uws来表达.
  • 依据链式求导法则, 反向传播算法在计算偏导时可以利用先前的计算以节省时间开销, 请结合偏导计算过程给出说明. 注意, 你可以使用如下符号: U o , { w 1 , … , w K } = [ u o , − u 1 , … , − u K ] U_{o,{\{w_1, \dots, w_K\}}}=[u_o, -u_1,\dots,-u_K] Uo,{w1,,wK}=[uo,u1,,uK] 和向量 1 \bf{1} 1(包含K+1个1).
  • 请用一句话说明为什么负采样损失要比原来的softmax损失更高效.

∂ ( J ) ∂ ( v c ) = ∂ ∂ ( v c ) ( − log ⁡ ( σ ( u o T v c ) ) ) + ∂ ( J ) ∂ ( v c ) ( − ∑ s = 1 K log ⁡ ( σ ( − u s T v c ) ) ) = A + B \begin{align*} \frac{\partial(J)}{\partial(v_c)} &= \frac{\partial}{\partial(v_c)}(-\log(\sigma(u_o^Tv_c))) + \frac{\partial(J)}{\partial(v_c)}(-\sum_{s=1}^K{\log(\sigma(-u_s^Tv_c))}) \\ &=A+B \end{align*} (vc)(J)=(vc)(log(σ(uoTvc)))+(vc)(J)(s=1Klog(σ(usTvc)))=A+B
计算 A:
A = − 1 σ ( u o T v c ) ∗ ( 1 − σ ( u o T v c ) ) σ ( u o T v c ) ∗ u o = ( σ ( u o T v c ) − 1 ) u o \begin{align*} A&=\frac{-1}{\sigma(u_o^Tv_c)}*(1-\sigma(u_o^Tv_c))\sigma(u_o^Tv_c)*u_o \\ &=(\sigma(u_o^Tv_c)-1)u_o \end{align*} A=σ(uoTvc)1(1σ(uoTvc))σ(uoTvc)uo=(σ(uoTvc)1)uo
计算 B:
B = ∑ s = 1 K − 1 σ ( − u s T v c ) ∗ σ ( − u s T v c ) ( 1 − σ ( − u s T v c ) ) ∗ ( − u s ) = ∑ s = 1 K ( 1 − σ ( − u s T v c ) ) u s \begin{align*} B&=\sum_{s=1}^K\frac{-1}{\sigma(-u_s^Tv_c)}*{\sigma(-u_s^Tv_c)}(1-\sigma(-u_s^Tv_c))*(-u_s)\\ &=\sum_{s=1}^K(1-\sigma(-u_s^Tv_c))u_s \end{align*} B=s=1Kσ(usTvc)1σ(usTvc)(1σ(usTvc))(us)=s=1K(1σ(usTvc))us
因此:
∂ ( J ) ∂ ( v c ) = ( σ ( u o T v c ) − 1 ) u o + ∑ s = 1 K ( 1 − σ ( − u s T v c ) ) u s \begin{align*} \frac{\partial(J)}{\partial(v_c)} &=(\sigma(u_o^Tv_c)-1)u_o+\sum_{s=1}^K(1-\sigma(-u_s^Tv_c))u_s \end{align*} (vc)(J)=(σ(uoTvc)1)uo+s=1K(1σ(usTvc))us
计算 J 关于 u s u_s us 的偏导数:
∂ ( J ) ∂ ( u s ) = ∂ ∂ ( u s ) ( − log ⁡ ( σ ( u o T v c ) ) ) + ∂ ( J ) ∂ ( u s ) ( − ∑ k = 1 K log ⁡ ( σ ( − u k T v c ) ) ) = − 1 σ ( − u s T v c ) ∗ σ ( − u s T v c ) ( 1 − σ ( − u s T v c ) ) ∗ ( − v c ) = ( 1 − σ ( − u s T v c ) ) v c \begin{align*} \frac{\partial(J)}{\partial(u_s)} &= \frac{\partial}{\partial(u_s)}(-\log(\sigma(u_o^Tv_c))) + \frac{\partial(J)}{\partial(u_s)}(-\sum_{k=1}^K{\log(\sigma(-u_k^Tv_c))}) \\ &= \frac{-1}{\sigma(-u_s^Tv_c)}*{\sigma(-u_s^Tv_c)}(1-\sigma(-u_s^Tv_c))*(-v_c) \\ &= (1-\sigma(-u_s^Tv_c))v_c \end{align*} (us)(J)=(us)(log(σ(uoTvc)))+(us)(J)(k=1Klog(σ(ukTvc)))=σ(usTvc)1σ(usTvc)(1σ(usTvc))(vc)=(1σ(usTvc))vc
计算 J 关于 u o u_o uo 的偏导数:
∂ ( J ) ∂ ( u o ) = ∂ ∂ ( u o ) ( − log ⁡ ( σ ( u o T v c ) ) ) = ( σ ( u o T v c ) − 1 ) v c \begin{align*} \frac{\partial(J)}{\partial(u_o)} &= \frac{\partial}{\partial(u_o)}(-\log(\sigma(u_o^Tv_c))) \\ &= (\sigma(u_o^Tv_c)-1)v_c \end{align*} (uo)(J)=(uo)(log(σ(uoTvc)))=(σ(uoTvc)1)vc

  • 负采样loss在计算导数时不需要遍历整个词表, 只需要K个负样本.

2. Code: 实现 word2vec

在这一部分,将实现word2vec模型,并使用随机梯度下降( SGD )训练自己的词向量。在开始之前,首先在任务目录内运行以下命令,以便创建合适的conda虚拟环境。这就保证了你有完成任务所必需的所有包。还需要注意的是,您可能希望在编写代码之前完成前面的数学部分,因为您将被要求在Python中实现数学函数。你可能会想按顺序实施和测试这一部分的每一部分,因为问题是循序渐进的。
对于每个需要实现的方法,我们在代码注释中包含了我们的解决方案大约有多少行代码。这些数字都包含在里面,用来指导你。你不必拘泥于它们,你可以随心所欲地编写更短或更长的代码。如果你认为你的实现比我们的实现长得多,那就表明你可以使用一些numpy方法来使你的代码既短又快。因为Python中的循环在使用大型数组时需要很长的时间才能完成,所以我们期望你使用numpy方法。我们将检查您的代码的效率。当你向Gradescope提交代码时,你就能看到自动评分器的结果,我们建议尽快提交代码。

(1). 我们将从 word2vec.py 入手开始实现方法。可以通过运行 python word2vec.py m 来测试特定的方法,其中m是您想要测试的方法。例如,可以通过运行python word2vec.py sigmoid来测试sigmoid方法。

a. Implement the sigmoid method, which takes in a vector and applies the sigmoid function to it.
b. Implement the softmax loss and gradient in the naiveSoftmaxLossAndGradient method.
c. Implement the negative sampling loss and gradient in the negSamplingLossAndGradient method.
d. Implement the skip-gram model in the skipgram method

When you are done, test your entire implementation by running python word2vec.py

(2). Complete the implementation for your SGD optimizer in the sgd method of sgd.py. Test your implementation by running python sgd.py

(3). 展示时间!现在我们要加载一些真实的数据,用你刚实现的一切来训练词向量!我们将使用Stanford Sentiment树库( SST )数据集来训练词向量,并将其应用到一个简单的情感分析任务中。首先需要获取数据集,为此,运行sh get dataset.sh。对于该部分没有额外编写的代码;只需运行 python run.py. 经过40,000次迭代后,脚本将完成,并出现一个词向量的可视化。也会以 word_vectors.png 的形式保存在项目目录中。将结果图片包含在你的作业中写出来。至多用三句话简要解释一下你在结果图片中看到的内容。这可能包括但不限于对聚类的观察和你希望聚类但没有聚类的单词。
以下贴出核心实现:

def naiveSoftmaxLossAndGradient(centerWordVec, outsideWordIdx, outsideVectors, datase):
	### YOUR CODE HERE (~6-8 Lines)
    y_hat = softmax(np.matmul(outsideVectors, centerWordVec))   # y_hat = P(O|C=c), (N,)
    y = np.zeros(y_hat.shape[0])
    y[outsideWordIdx] = 1                                       # y, one-hot vector, (N,)
    loss = -np.log(y_hat[outsideWordIdx])                       # loss = -log(y_hat[o]), scalar
    gradCenterVec = np.matmul(outsideVectors.T, y_hat-y)        # dJ/dv_c = U(y_hat-y), (D,)
    gradOutsideVecs = np.matmul((y_hat-y).reshape(-1,1), centerWordVec.reshape(1,-1))   # (N, D)
    ### END YOUR CODE
    return loss, gradCenterVec, gradOutsideVecs

def negSamplingLossAndGradient(centerWordVec, outsideWordIdx, outsideVectors, dataset, K=10):
    # Negative sampling of words is done for you. Do not modify this if you
    # wish to match the autograder and receive points!
    negSampleWordIndices = getNegativeSamples(outsideWordIdx, dataset, K)
    indices = [outsideWordIdx] + negSampleWordIndices

    ### YOUR CODE HERE (~10 Lines)
    gradCenterVec = np.zeros_like(centerWordVec)
    gradOutsideVecs = np.zeros_like(outsideVectors)
    # loss function
    loss = -np.log(sigmoid(outsideVectors[outsideWordIdx].dot(centerWordVec)))
    for idx in negSampleWordIndices:
        loss -= np.log(sigmoid(-outsideVectors[idx].dot(centerWordVec)))
    # gradient
    gradCenterVec -= (1 - sigmoid(centerWordVec.dot(outsideVectors[outsideWordIdx]))) * outsideVectors[outsideWordIdx]
    for k in negSampleWordIndices:
        gradCenterVec += (1 - sigmoid(-centerWordVec.dot(outsideVectors[k]))) * outsideVectors[k]
    gradOutsideVecs[outsideWordIdx] = -(1 - sigmoid(centerWordVec.dot(outsideVectors[outsideWordIdx]))) * centerWordVec
    for k in negSampleWordIndices:
        gradOutsideVecs[k] += (1 - sigmoid(-centerWordVec.dot(outsideVectors[k]))) * centerWordVec
    ### END YOUR CODE
    return loss, gradCenterVec, gradOutsideVecs

def skipgram(currentCenterWord, windowSize, outsideWords, word2Ind,
             centerWordVectors, outsideVectors, dataset,
             word2vecLossAndGradient=naiveSoftmaxLossAndGradient):
	loss = 0.0
    gradCenterVecs = np.zeros(centerWordVectors.shape)
    gradOutsideVectors = np.zeros(outsideVectors.shape)
    ### YOUR CODE HERE (~8 Lines)
    currentCenterIdx = word2Ind[currentCenterWord]
    for word in outsideWords:
        loss_w, grad_cv, grad_ov = word2vecLossAndGradient(
            centerWordVectors[currentCenterIdx],
            word2Ind[word],
            outsideVectors,
            dataset
        )
        loss += loss_w
        gradCenterVecs[currentCenterIdx] += grad_cv
        gradOutsideVectors += grad_ov
    ### END YOUR CODE
    return loss, gradCenterVecs, gradOutsideVectors

sgd部分:

### YOUR CODE HERE (~2 lines)
loss, grad = f(x)
x = x - step*grad
### END YOUR CODE

运行结果:

iter 39910: 9.324637
iter 39920: 9.284225
iter 39930: 9.298478
iter 39940: 9.296606
iter 39950: 9.313374
iter 39960: 9.317475
iter 39970: 9.330720
iter 39980: 9.410215
iter 39990: 9.418270
iter 40000: 9.367644
sanity check: cost at convergence should be around or below 10
training took 6372 seconds

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/538697.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】mybatis-plus实现增删改查

mapper继承BaseMapper service 继承ServiceImpl 使用方法新增 save,updateById新增和修改方法返回boolean值,或者使用saveOrUpdate方法有id执行修改操作,没有id 执行新增操作 案例 Service public class UserService extends ServiceImpl<UserMapper,User> {// Au…

第四百五十六回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 使用方法 3. 内容总结 我们在上一章回中介绍了"overlay_tooltip用法"相关的内容&#xff0c;本章回中将介绍onBoarding包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中介绍的onBo…

Python 以点生成均匀二维圆点数据

已知一个数&#xff0c;但这个数不是最对的&#xff0c;最对的可能在它附近&#xff0c;想要从附近随机生成一群数&#xff0c;放入模型中暴力查找最对的那个值。 以下是代码片段 n 800 # 个数 m 2 # 角度&#xff0c;只有2才是均匀的&#xff0c;1为半圆&#xff0c;以此类…

HashMap的常见问题

Entry中的hash属性为什么不直接使用key的hashCode()返回值呢&#xff1f; 不管是JDK1.7还是JDK1.8中&#xff0c;都不是直接用key的hashCode值直接与table.length-1计算求下标的&#xff0c;而是先对key的hashCode值进行了一个运算&#xff0c;JDK1.7和JDK1.8关于hash()的实现…

1. Django建站基础

1. Django建站基础 学习开发网站必须了解网站的组成部分, 网站类型, 运行原理和开发流程. 使用Django开发网站必须掌握Django的基本操作, 比如创建项目, 使用Django的操作指令以及开发过程中的调试方法.1.1 网站的定义及组成 网站(Website)是指在因特网上根据一定的规则, 使用…

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程 1.1、operator()的引入 现在需要完成这样一个需求&#xff1a;有一个函数每次调用返回的结果不一样。例如&#xff1a;两次调用的返回值都不一样那么就可以达到这种目的 1.1.1、简单点的写法 可以给一个全局的变量&#xff08;静态变量&#xff09;&#xff…

竞赛课第六周(树状数组的应用)

实验内容: HDU 1166 敌兵布阵【线段树】 线段树的应用 敌兵布阵 C国的死对头A国这段时间正在进行军事演习&#xff0c;所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取…

批量发送朋友圈还能自动同步朋友圈

现在不管是做服装店、水果店、化妆店、影楼、二手车房等各行各业来说&#xff0c;每天必不可少的就是发各种朋友圈&#xff0c;量大号又多还占手机内存&#xff0c;真!的!很!累! 没有人能拒绝一键转发带来的方便&#xff0c;有了它发朋友圈只需要点一下就复制到了你自己的朋友圈…

tkinter窗口

简单的窗口程序 导入所需的库 from tkinter import * import json 创建一个主窗口 app Tk() 设置窗口大小为 1048x2048 app.geometry(“1048x2048”) 设置窗口背景为灰色 app.configure(bg“gray”) 创建一个 Label 对象&#xff0c;显示 “账号&#xff1a;” 和红色…

finalshell连接VM虚拟机报错,java,net.ConnectException: Connection timed out: connect

适用于&#xff0c;所有第三方连接虚拟机报错。 java,net.ConnectException: Connection timed out: connect Xshell啊什么的。 解决方法&#xff1a; 首先&#xff0c;我想确认一下是否已经安装了finalshell软件并且要连接的CentOS 7服务器已经设置好了。连接不上的问题有很…

二叉树-认识树及堆,堆的实现

一、树的概念及结构 &#xff08;一&#xff09;树的概念 树是一种非线性的数据结构&#xff0c;是n(n≥0)个结点的有限集。当n0时&#xff0c;称为空树。在任意一颗非空树中应满足&#xff1a; 有且仅有一个特殊的结点&#xff0c;称为根结点&#xff0c;根节点没有前驱结点…

STM32F407+DHT11采集数据

1、DHT11简介 DHT11 与单片机之间能采用简单的单总线进行通信&#xff0c;仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机&#xff0c;数据采用校验和方式进行校验&#xff0c;有效的保证数据传输的准确性。DHT11 功耗很低&#xff0c;5V 电源电…

Java-Doc

Java-Doc javdoc命令是用来生成自己的API文档的 参数信息&#xff1a;author作者名version版本号since知名需要最早使用的jdk版本param参数名return返回值情况throws异常抛出情况 1.参数信息的使用&#xff1a; 未完待续... ...

mysql面试题 1

为什么要使用数据库 数据保存在内存 优点&#xff1a; 存取速度快缺点&#xff1a; 数据不能永久保存 数据保存在文件 优点&#xff1a; 数据永久保存缺点&#xff1a;1、速度比内存操作慢&#xff0c;频繁的IO操作。2、查询数据不方便 数据保存在数据库 数据永久保存使用SQL语…

阿里云服务器公网带宽费用全解析(不同计费模式)

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…

基于SSM+Vue实现的宠物销售系统

基于SSMVue实现的宠物销售系统 系统介绍 系统演示 点击查看视频演示 基于SSMVue实现的宠物销售系统&#xff0c;主要实现的功能有以下几点&#xff1a;管理员&#xff1b;首页、个人中心、宠物分类管理、商品分类管理、宠物用品管理、宠物商店管理、宠物领养管理、用户管理…

【刷题】图论——最小生成树:局域网

要想去除边&#xff0c;并且不改变连通性&#xff0c;而且去除的值最大&#xff0c;相当于保留最小生成树。 注意这题连通块有若干个&#xff0c;所以运行Kruskal相当于形成若干个最小生成树。 如果是prim只能事先处理好各个连通块&#xff0c;然后在连通块内部单独用prim 题目…

vueRouter动态路由(实现菜单权限控制)

一、权限控制管理&#xff1a; 对于企业级的项目, 我们可能需要对项目做权限控制管理, 实现不同角色的用户登录项目根据所拥有的权限访问不同的页面内容&#xff0c;此时就需要使用到动态路由来对权限页面做限制。 【使用vue-router实现动态路由&#xff0c;达到实现菜单权限…

阿里云2核2G服务器这么便宜,能用来做什么?

阿里云2核2G服务器这么便宜&#xff0c;能用来做什么&#xff1f;阿里云2核2G云服务器可以用来搭建网站、爬虫、邮件服务器、接口服务器、个人博客、企业官网、数据库应用、大数据计算、AI人工智能、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云2核2G服务…

四、SpringBoot3 整合 Druid 数据源

本章概要 创建程序引入依赖启动类配置文件编写编写 Controller启动测试问题解决 4.1 创建程序 4.2 引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://ww…