当前位置: 首页 > news >正文

深度学习 - 41.Word2vec、EGES 负采样实现 By Keras

目录

一.引言

二.实现思路

1.样本构建

2.Word2vec 架构

3.EGES 架构

4.基于 NEG 的 Word2vec 架构

三.Keras 实现 Word2vec

1.样本构建

2.模型构建

3.向量获取

四.keras 实现 EGES

1.样本构建

2.模型构建

3.Dot Layer 详解

3.1 init 方法

3.2 call 方法

3.3 完整代码

4.向量获取

4.1 计算 sku 相似度

4.2 商品 sku 冷启动

4.3 侧信息重要性分析

4.4 引入预训练模型

五.总结


一.引言

前面介绍了基于 Gensim 的 Word2vec 实现以及 EGES 的理论与样本准备,由于 EGES 是在 Word2vec 的基础上为 (Target, Context) 中的 Target 增加 SideInfo 侧信息增加表达能力,所以这里先实现 Word2vec,再加入侧信息实现 EGES,二者实现思路相近。

Tips:

本文实现方式为 Skip-Gram,CBOW 同学们可以基于下面思路自己实现。

二.实现思路

1.样本构建

由于实现形式为 Skip-Gram,所以是 (Target, Context) 即 (中心词, 上下文) 的形式,通过 window_size 可以控制我们从序列 Seq 样本中获取的样本对数量。

2.Word2vec 架构

样本为 (Target, Context),输入为仅 Target 对应位置为 1 的 one-hot 向量,通过 Hidden-Layer 获取 Target 对应的 K 维向量,随后与 SoftMax 输出层的 KxN 的参数矩阵相乘的到 N 维向量,对 N 维向量取 Softmax 并与仅 Target  为 1 的 one-hot label 进行 Loss 的计算并梯度回传。

Tips:

由于 Target 中心词所在词库大小 N 通常很大,所以最后一步的 Softmax 计算相对比较耗时,论文中提出了两种优化方法:

• 层次 Softmax

层次 softmax 基于霍夫曼树生成的词库,优化了 dot 计算的数量与高频词的计算数量。

• 负采样

Negative Sample 这个方法非常简单粗暴但是好用,每次为 Target 生成 ns 个非 Context 的词作为负样本,这样计算量直接从 N 缩减至 ns,一般推荐 ns 为 5-20

由于层次 softmax 构造相对复杂,这里我们采用更好实现的 Negative Sample 即负采样。 

3.EGES 架构

这里 SI 0 代表 Item 即 (Target, Context) 里的 Context,S1 1 - S1 n 为 n 类 SideInfo 侧信息,针对每一个 SI 0 都有一个 Alpha 权重向量,通过 ∑ α * Emb 的形式得到加权平均的 Embedding,后面的计算同 Word2vec 一致。 N 和 P 代表随机采样的 Negative Sample 和 Context 对应的 Positive Sample。

Tips:

这里把图歪过来,架构就很相似了,简单分下下 Word2vec 与 EGES 的区别:

• 样本构造

EGES 采用 Session 截取用户历史行为,Word2vec 基于用户完整历史行为游走。

• Hidden 层输入

EGES 加入 SideInfo 加权得到隐层的输入,Word2vec 直接 lookup 得到 Target Embedding 输入隐层。

4.基于 NEG 的 Word2vec 架构

直接通过 Embedding 层 lookup 获取 (Target, Context) 对应的 K 维度 Embedding,随后执行 Dot 计算并通过 Sigmoid 得到 0-1 的值,将多分类的 Category_Crossentropy 转换为了二分类 Binary_Crossentropy 的问题。其样本构造也很简单,针对正样本 (Target, Context) 其 Label 为 1,再基于 Target 生成 ns 个 (Target, Negative Word) 的负样本,其 Label 为 0。最后获取 Embedding 的向量作为词向量即可,如果是 EGES 则是增加 Weight Merge 即加权求和操作即可。

三.Keras 实现 Word2vec

1.样本构建

    word_target, word_context = zip(*all_pairs)word_target = np.array(word_target, dtype="int32")word_context = np.array(word_context, dtype="int32")

上篇数据预处理的文章中我们已经基于编码后的 sku 商品序列游走获取了如上图的样本形式,后续将基于该样本与 NEG 的架构实现 Word2vec 与 EGES。

Tips:

注意数据类型的 dtype,否则会报错,因为我们处理完的为字符类型,训练需要 int32 or int64。

 

2.模型构建

- Embedding 层

  input_target = Input((1,))input_context = Input((1,))embedding = Embedding(sku_num, args.emb_dim, input_length=1, name="embedding")# 获取 Embtarget = embedding(input_target)target = Reshape((args.emb_dim, 1))(target)context = embedding(input_context)context = Reshape((args.emb_dim, 1))(context)

直接构建 Embedding 层获取 (Target, Context) 的 K 维向量。

- Dot 层

  # now perform the dot product operation to get a similarity measuredot_product = Dot(axes=1)([target, context])dot_product = Reshape((1,))(dot_product)# add the sigmoid output layeroutput = Dense(1, activation='sigmoid')(dot_product)

直接 Dot 计算内积。

- Model 层

  # create the primary training modelmodel = Model([input_target, input_context], output)model.summary()model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

选择 binary_crossentroy 进行模型编译:

Tips:

同样需要注意把 labels 用 np.array 包装起来,否则训练无法进行。

 

3.向量获取

  model.fit((word_target, word_context), np.array(labels), epochs=10, batch_size=128)# 获取训练后的 Embeddingemb = np.array(embedding.get_weights()[0])print("商品数量 %d 词向量数量: %s" % (sku_num, emb.shape))print(emb[:10])

跑 10 个 epoch 看看:

最后查看商品数量和 Emb 数量是否一致,随后将 Emb 按索引反映射到 word 即 sku 商品上,即实现了每个 sku 对应一个 Embedding:

 

四.keras 实现 EGES

1.样本构建

(Target, Context) 与上面 Word2vec 一致,这里需要给 Target 增加 SideInfo,将样本修改为 ([Target, SI 1, SI 2, SI N], Context) 的形式,其中 SI N 代表第 N 个 SideInfo。本例中 sku 商品共包含 3 个 SideInfo 分别为: brand-品牌、shop_id-店铺、cate-标签。

  word_target = np.array(word_target, dtype="int32")word_context = np.array(word_context, dtype="int32")word_target_with_side_info = []for word in word_target:# 获取侧信息并追加side_info = sku_side_info[sku_side_info['sku_id'] == word].values[0]word_target_with_side_info.append(np.array(side_info, dtype='int32'))word_target_with_side_info = np.array(word_target_with_side_info, dtype='int32')

sku_side_info 是上文数据预处理中生成的 Sku 信息的 DataFrame,这里获取 values 并添加到新的样本集合中:

sku、brand、shop_id 与 cate 对应的 Dim 数为样本中对应特征 Unique 去重后的数量。 

2.模型构建

- 输入层

  # 添加 SideInfo: brand,shop_id,cateinput_target = Input((4,))input_context = Input((1,))

 由于添加了 3 类 SideInfo,所以 Input 增加 3 维。

- Dot 层

    dot_layer = EGES_model(feat_num_list, args.emb_dim)([input_target, input_context])

这里 dot_layer 需要实现 EGES 加权求和获取 Merge 合并后 Embedding 的工作,篇幅较长,我们放在后面统一分析。

- Model 层

  # add the sigmoid output layeroutput = Dense(1, activation='sigmoid')(dot_layer)# create the primary training modelmodel = Model([input_target, input_context], output)model.summary()model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

3.Dot Layer 详解

dot_layer 实现继承 tensorflow.python.keras.models.Model 实现,主要包含 init 初始化与 call 调用两个方法的实现。其中 call 方法如下图红框所示,基本包含了 EGES 前置的全部逻辑。

 

3.1 init 方法

根据上图我们分析模型需要如下参数:

• SI 0 参数矩阵

SI 0 为 sku 对应的 Embedding 层,其维度为 len(unique(sku)) x K

• SI 1-N 参数矩阵

SI 1-N 为 Side Info 对应的 Embedding 层,其维度分别为 len(unique(SI I)) x K

• Alpha 权重矩阵

针对每个 sku 有 1+s 个 alpha 权重,所以共需要 len(unique(sku)) x (1+s) 个参数

A.参数准备

这里 embedding_list 存储 SI 0-N 的 Embedding 层参数,feat_num = 1 + s 即总特征数,dim = K 代表 Embedding 维度,sku_num = len(unique(sku_id)) 为全部商品的数量。

B.参数初始化

Sku Num: 34048
Feat && Dim: [['sku_id', 34048], ['brand', 3663], ['shop_id', 4786], ['cate', 80]]

根据每个 Feat 的维度构建其 Embedding 层参数,最后构建 sku_num x feat_num 的 alpha 权重层参数。 

 

3.2 call 方法

根据上图我们再分析下如何实现 call 方法:

• 依次获取 Embedding

按照样本书序从对应 embedding_list 中 lookup 即可获取对应向量

• 拼接 Embedding

tf.stack 直接将获取的向量拼接在一起

• 加权求和 Embedding

lookup 获取 alpha 向量,与 stack 拼接的向量对位相乘再 reduce_sum 求和即可

A.Target && Side 向量获取

原始样本为 None x 4,lookup 后 stack 在一起得到 None x 4 x 128。

B.Alpha 权重向量获取

获取对应 sku 的 1+s 维 Alpha 权重向量,为了保证每个权重的非负性,这里采用 exp 转正并通过 Softmax 的形式对每个权重参数进行了归一化。

C.reduce_sum 加权求和

直接对位相乘再除以求和后的 α 即可。

 

D.Dot 获取内积

加权求和 merge 后的 embedding 与 lookup 得到的 1xK 的 context 即目标词的 embedding 进行内积,最终得到 None x 1 输出到下一层。

 

3.3 完整代码

from abc import ABCimport tensorflow as tf
from tensorflow.python.keras.models import *
from tensorflow.python.keras.layers import *class EGES_model(Model, ABC):def __init__(self, feat_num_list, emb_dim):super(EGES_model, self).__init__()# Embedding 矩阵self.embedding_list = []self.feat_num = len(feat_num_list)self.dim = emb_dimself.sku_num = feat_num_list[0][1]print("Sku Num:", self.sku_num)print("Feat && Dim:", feat_num_list)# word embeddingfor i in range(self.feat_num):feat_name = feat_num_list[i][0]feat_num = feat_num_list[i][1]self.embedding_list.append(self.add_weight(name=feat_name,shape=(feat_num, emb_dim),initializer='he_normal',trainable=True))# alpha weight embedding [id x 4]self.alpha_weight = self.add_weight(name='weight',shape=(self.sku_num, self.feat_num),initializer='he_normal',trainable=True)def call(self, pairs):(word_with_side_info, context_info) = pairs# 获取侧信息 Embedding 用户3个侧信息  None x 4 x 128embed_list = []for i in range(self.feat_num):# [N x Emb] 10x128index = tf.cast(word_with_side_info[:, i], dtype='int32')emb_var = tf.nn.embedding_lookup(self.embedding_list[i], index)[:, :self.dim]embed_list.append(emb_var)# (None, 128, 4)combine_emb = tf.stack(embed_list, axis=-1)# (None, 4, 128)combine_emb = tf.reshape(combine_emb, shape=(-1, self.feat_num, self.dim))# 加权求和# (None, ) (None, 4) (None, )sku_index = tf.cast(word_with_side_info[:, 0], dtype='int32')sku_alpha_emb = tf.nn.embedding_lookup(self.alpha_weight, sku_index)[:, :]alpha_sum = tf.expand_dims(tf.reduce_sum(tf.exp(sku_alpha_emb), axis=-1), axis=1)# (None, 4, 128)add_weight_emb = combine_emb * tf.exp(tf.expand_dims(sku_alpha_emb, axis=-1))# (None, 128)merge_emb = tf.reduce_sum(add_weight_emb, axis=1) / alpha_sum# 上下文变量# (None, 1, 128)context_emb = tf.nn.embedding_lookup(self.embedding_list[0], tf.cast(context_info, dtype='int32'))[:, :self.dim]# (None, 128)context_emb = tf.reshape(context_emb, shape=(-1, self.dim))# None x 1dot_product = Dot(axes=1)([merge_emb, context_emb])return dot_product

4.向量获取

    model.fit([word_target_with_side_info, word_context], np.array(labels), epochs=10, batch_size=128)

跑 10 个 epoch,同样注意把 labels 用 np.array 包起来:

训练完我们从 EGES_model 对应的 dot 层获取向量即可:

  # 获取训练后的 Embeddingweight_list = model.layers[2].get_weights()weight_map = {}for i in range(len(feat_num_list)):feat_name = feat_num_list[i][0]feat_emb = weight_list[i]weight_map[feat_name] = feat_emb

针对 SI 0 - sku 和 SI 1-3 三个侧信息,我们可以获取 4 个向量矩阵,根据后续任务的不同,我们可以做如下事情:

4.1 计算 sku 相似度

使用 sku Embedding 计算内积寻找不同 sku 的相似度,也可以降维观察不同 sku 的分布

 

4.2 商品 sku 冷启动

在冷启动时引入商品对应侧信息优化冷启动商品的初始 Embedding

 

4.3 侧信息重要性分析

    print(np.array(weight_list[-1]))

通过 alpha 参数矩阵,我们使用 exp 归一化可以分析不同 sku 的向量偏好,根据色阶图看以分析不同特征对结果的重要程度

4.4 引入预训练模型

可以将不同特征的 Embedding 用于后续 Deep 任务的参数初始化,例如 FNN 使用 FM 预训练的向量一样

五.总结

当年还未深度接触 DeepLearning 时,总觉得 word2vec 很复杂,但是通过前面的分析、再到框架最后到具体实现,我们发现其思路清晰实现也很简洁,如果把 dot 层的计算更换为其他相似度计算例如 Cos 余弦相似度,那上面的架构就和 DSSM 很类似。

word2vec 是 Google 于 2013 年开源的获取 word vector 的算法包,距今已经10年、EGES 是 2018 年由阿里巴巴算法团队提出,距今也已经5年,在算法日新月异的今天,已经算的是很"古老"的知识了,但是其 Embedding 的思想一直影响着后面深度学习的发展,因此把它搞清楚对于很多 DeepLearning 的知识理解也很有帮助。

上面利用负采样的方法实现了 Skip-gram,除了负采样的优化方法外,源码中还有很多实现的细节:

• σ(x) 的近似计算

sigmoid 函数在 x < -6 或者 x > -6  时变化已经微乎其微,实际计算中,除了 Softmax 计算量巨大外,sigmoid 函数计算也很多,可以通过细分区间缓存 σ(x) 的近似值,从而将计算切换为查表,优化计算速度。

• 向量相似度检索

由于词库的大小 N 通常很大,每次计算都匹配所有向量并内积计算相似度会非常耗时,线上无法接受,可以通过缓存 item-item 之间的相似度做的快速查找,常用的方法有 LSH(局部敏感哈希)算法。

• 低频词与高频词

利用语料构建词库时,开发者可以通过 min_count 控制每个词出现过多少次才能收到到词库中。低频词出现次数较少,但其独一无二的性质有时可以精准描述某些特定场景,而高频词虽然出现很多但却意义不大,例如 '的'、'是' 这些,因此实际场景中,除了过滤停用词外,还需要分析低频词的代表性以及高频词的实际意义。可以通过 SubSampleing 的技巧对高频词做处理,其思想是有一定概率不计算当前高频词从而优化计算速度,就像是 Dropout 一样。当然使用层次 Softmax 也可以很好地解决高频词的效率问题。

• 窗口与上下文

根于 Target 与 window_size ,我们会生成 [-window_size,window_size] -1 个样本,源码中采取先对 [1, window_size] 随机一个整数 c,然后再生成 [-c,c] -1 个样本,相当于 window_size 其实也是随机变化的。

参考:

Word2vec 的一些思考:word2vec的一些遗留思考

Word2vec 的一些理论:word2vec 中的数学原理详解

Word2cec 的一些代码:基于keras实现word2vec

相关文章:

深度学习 - 41.Word2vec、EGES 负采样实现 By Keras

目录 一.引言 二.实现思路 1.样本构建 2.Word2vec 架构 3.EGES 架构 4.基于 NEG 的 Word2vec 架构 三.Keras 实现 Word2vec 1.样本构建 2.模型构建 3.向量获取 四.keras 实现 EGES 1.样本构建 2.模型构建 3.Dot Layer 详解 3.1 init 方法 3.2 call 方法 3.3 完…...

研发管理风险控制

软件研发过程中需要做好风险控制&#xff0c;保证项目按计划发布&#xff0c;下面说明一下个人对软件风险控制的看法 一、规划、技术选型、架构方面提前规避风险 1.选择最熟悉、使用最多的技术 “一个新项目里最好不要使用超过30%的新技术”&#xff0c;我觉得这句话是有一定…...

母婴品牌内容输出怎么做?“四板斧”送你

新媒体时代&#xff0c;信息大爆炸&#xff0c;人们的注意力有限&#xff0c;有噱头和亮点的内容才能博得注意&#xff0c;成为用户关注的焦点。 母婴行业重视品牌效益和产品的质量&#xff0c;毕竟类似“三聚氰胺”的惨剧谁也不希望再发生。母婴产品的质量依赖技术和生产线支…...

【视频】视频存储技术

1、NVR NVR是(网络硬盘录像机)的缩写。NVR最主要的功能是通过网络接收IPC(网络摄像机)设备传输的数字视频码流, 并进行存储、管理,从而实现网络化带来的分布式架构优势。简单来说,通过NVR,可以同时观看、浏览、回放、管理、存储多个网络摄像机。NVR是x86架构储存+监控软…...

【C/C++】MySQL 为什么选择 B+ 树作为底层数据结构

为什么MySQL底层数据结构选择B树&#xff1f;&#xff08;而不是B树等其他数据结构&#xff09; B树非叶子节点&#xff0c;不存放数据记录&#xff0c;仅存放指针与关键字&#xff0c;所以一个B树非叶子节点可以存放更多子节点信息&#xff0c;有利于降低树高度&#xff0c;从…...

17、嵌入式Servlet容器

文章目录 1、切换嵌入式Servlet容器1.1、默认支持的webServer1.2、切换服务器 2、原理2.1、ServletWebServerApplicationContext2.2、作用2.3、ServletWebServerFactoryAutoConfiguration2.4、作用2.5、ServletWebServerFactoryConfiguration 配置类2.6、web服务器工厂作用 3、…...

倾斜摄影三维模型转换3DTILTES格式遇到的常见问题

倾斜摄影三维模型转换3DTILTES格式遇到的常见问题 将倾斜摄影三维模型从OSGB格式转换为3DTILES格式时&#xff0c;常见的问题包括&#xff1a; 1、3D Tiles生成时间较长&#xff1a;由于3D Tiles是一种高效的地理数据存储格式&#xff0c;能够支持海量的空间数据呈现和查询&am…...

手机如何访问电脑文件?(iOS和Android)

可以通过手机访问电脑文件吗&#xff1f; “我需要在我的电脑上查看一个文件&#xff0c;但我现在在外面无法实际访问它。我可以通过手机访问我的电脑文件吗&#xff1f;” 答案当然是可以的&#xff0c;无论您使用的是iOS设备还是Android设备&#xff0c;您都可以通过手机…...

TI在物联网和AI边缘计算中落伍了吗?

摘要&#xff1a;本文介绍一下TI在边缘计算工作中所做的努力。 发明“人工智能”这个term的老头儿也不会想到人工智能在中国有多火。 不管是懂还是不懂&#xff0c;啥东西披上“人工智能“的面纱都能瞬间成为大项目。 学习AI 的年轻人认识NVIDIA&#xff0c;可能不太知道DSP是…...

LoadRunner参数化最佳实践:让你的性能测试更加出色!

距离上次使用loadrunnr 已经有一年多的时间了。初做测试时在项目中用过&#xff0c;后面项目中用不到&#xff0c;自己把重点放在了工具之外的东西上&#xff0c;认为性能测试不仅仅是会用工具&#xff0c;最近又想有一把好的利器毕竟可以帮助自己更好的完成性能测试工作。这算…...

软件测试工程师需要达到什么水平才能顺利拿到 20k 无压力?

最近有粉丝朋友问&#xff1a;软件测试员需要达到什么水平才能顺利拿到 20k 无压力&#xff1f; 这里写一篇文章来详细说说&#xff1a; 目录 扎实的软件测试基础知识&#xff1a;具备自动化测试经验和技能&#xff1a;熟练掌握编程语言&#xff1a;具备性能测试、安全测试、全…...

RabbitMQ-高级篇

服务异步通信-高级篇 消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6S1iAs7-1681919354777)(assets/image-20210718155003157.png)] 1.消息可靠性 消息从发送&#x…...

深度学习_Learning Rate Scheduling

我们在训练模型时学习率的设置非常重要。 学习率的大小很重要。如果它太大&#xff0c;优化就会发散&#xff0c;如果它太小&#xff0c;训练时间太长&#xff0c;否则我们最终会得到次优的结果。其次&#xff0c;衰变率同样重要。如果学习率仍然很大&#xff0c;我们可能会简…...

snmp服务利用(端口:161、199、391、705、1993)

服务介绍 简单网络管理协议 是一种广泛应用于TCP/IP网络的网络管理标准协议(应用层协议),它提供了一种通过运行网络管理软件的中心计算机(即网络管理工作站)来监控和管理计算机网络的标准化管理框架(方法)。目前已颁布了SNMPv1、SNMPv2c和SNMPv3三个版本,广泛应用于网…...

MyBatis(二)—— 进阶

一、详解配置文件 1.1 核心配置文件 官方建议命名为mybatis-config.xml&#xff0c;核心配置文件里可以进行如下的配置&#xff1a; <environments> 和 <environment> mybatis可以配置多套环境&#xff08;开发一套、测试一套、、、&#xff09;&#xff0c; 在…...

婚恋交友app开发中需要注意的安全问题

前言 随着移动设备的普及&#xff0c;婚恋交友app已经成为了人们生活中重要的一部分。但是&#xff0c;这些应用的开发者需要确保应用的安全性&#xff0c;以保护用户的隐私和数据免受攻击。本文将介绍在婚恋交友app开发中需要注意的安全问题。 在当今数字化时代&#xff0c;…...

相机的内参和外参介绍

注&#xff1a;以下相机内参与外参介绍除来自网络整理外全部来自于《视觉SLAM十四讲从理论到实践 第2版》中的第5讲&#xff1a;相机与图像&#xff0c;为了方便查看&#xff0c;我将每节合并到了一幅图像中 相机与摄像机区别&#xff1a;相机着重于拍摄静态图像&#x…...

Node【包】

文章目录 &#x1f31f;前言&#x1f31f;Nodejs包&#x1f31f;什么是包&#xff1f;&#x1f31f;自定义包&#x1f31f;包配置文件&#x1f31f;示例&#x1f31f;Package.json 属性说明&#x1f31f;语义化版本号&#x1f31f;package.json示例 &#x1f31f;符合CommonJS规…...

CHAPTER 2: 《BACK-OF-THE-ENVELOPE ESTIMATION》 第2章 《初略的估计》

CHAPTER 2: BACK-OF-THE-ENVELOPE ESTIMATION 在系统设计面试中&#xff0c;有时您会被要求估计系统容量或使用粗略估计的性能需求。根据杰夫迪恩的说法&#xff0c;谷歌高级研究员&#xff0c;“粗略的计算是你使用结合思想实验和常见的性能数字&#xff0c;以获得良好的感觉…...

RocketMQ高级概念

一 RocketMQ核心概念 1.消息模型&#xff08;Message Model&#xff09; RocketMQ主要由 Producer、Broker、Consumer 三部分组成&#xff0c;其中Producer 负责⽣产消息&#xff0c;Consumer 负责消费消息&#xff0c;Broker 负责存储消息。Broker 在实际部署过程中对应⼀台…...

eureka注册中心和RestTemplate

eureka注册中心和restTemplate的使用说明 eureka的作用 消费者该如何获取服务提供者的具体信息 1.服务者启动时向eureka注册自己的信息 2.eureka保存这些信息 3.消费者根据服务名称向eureka拉去提供者的信息 如果有多个服务提供者&#xff0c;消费者该如何选择&#xff1f; 服…...

redis复制的设计与实现

一、复制 1.1旧版功能的实现 旧版Redis的复制功能分为 同步&#xff08;sync&#xff09;和 命令传播。 同步用于将从服务器更新至主服务器的当前状态。命令传播用于 主服务器状态变化时&#xff0c;让主从服务器状态回归一致。 1.1.1同步 当客户端向服务端发送slaveof命令…...

Docker更换国内镜像源

什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全…...

【网络编程】网络套接字,UDP,TCP套接字编程

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 特别说明&#xff1a;本文分享的代码运行结果…...

海斯坦普Gestamp EDI 需求分析

海斯坦普Gestamp&#xff08;以下简称&#xff1a;Gestamp&#xff09;是一家总部位于西班牙的全球性汽车零部件制造商&#xff0c;目前在全球23个国家拥有超过100家工厂。Gestamp的业务涵盖了车身、底盘和机电系统等多个领域&#xff0c;其产品范围包括钣金、车身结构件、车轮…...

gpt写文章批量写文章-gpt3中文生成教程

怎么用gpt写文章批量写文章 批量写作文章是很多网站、营销人员、编辑等需要的重要任务&#xff0c;GPT可以帮助您快速生成大量自然、通顺的文章。下面是一个简单的步骤介绍&#xff0c;告诉您如何使用GPT批量写作文章。 步骤1&#xff1a;选择好训练模型 首先&#xff0c;选…...

HashMap实现原理

HashMap是基于散列表的Map接口的实现。插入和查询的性能消耗是固定的。可以通过构造器设置容量和负载因子&#xff0c;一调整容易得性能。 散列表&#xff1a;给定表M&#xff0c;存在函数f(key)&#xff0c;对任意给定的关键字值key&#xff0c;代入函数后若能得到包含该关键字…...

【Java 数据结构】PriorityQueue(堆)的使用及源码分析

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…...

使用 Kubernetes 运行 non-root .NET 容器

翻译自 Richard Lander 的博客 Rootless 或 non-root Linux 容器一直是 .NET 容器团队最需要的功能。我们最近宣布了所有 .NET 8 容器镜像都可以通过一行代码配置为 non-root 用户。今天的文章将介绍如何使用 Kubernetes 处理 non-root 托管。 您可以尝试使用我们的 non-root…...

为什么大量失业集中爆发在2023年?被裁?别怕!失业是跨越职场瓶颈的关键一步!对于牛逼的人,这是白捡N+1!...

被裁究竟是因为自身能力不行&#xff0c;还是因为大环境不行&#xff1f; 一位网友说&#xff1a; 被裁后找不到工作&#xff0c;本质上还是因为原来的能力就配不上薪资。如果确实有技术在身&#xff0c;根本不怕被裁&#xff0c;相当于白送n1&#xff01; 有人赞同楼主的观点&…...