词向量及文本向量

news2024/11/22 5:14:54

文章目录

  • 引言
  • 1. 文本向量化
  • 2. one-hot编码
  • 3. 词向量-word2vec
    • 3.1 词向量-基于语言模型
  • 4 词向量 - word2vec基于窗口
    • 4.1 词向量-如何训练
  • 5. Huffman树
  • 6. 负采样-negative sampling
  • 7. Glove基于共现矩阵
    • 7.1 Glove词向量
    • 7.2 Glove对比word2vec
  • 8. 词向量训练总结
  • 9. 词向量应用
    • 9.1词向量应用-寻找近义词
    • 9.2 词向量应用-句向量或文本向量
    • 9.3 词向量应用-KMeans
  • 10. 词向量总结

引言

词向量和文本向量是自然语言处理(NLP)中用于表达文本数据的数学模型。

词向量:

  1. One-Hot 编码: 每个词都用一个很长的向量表示,向量的长度是词典的大小,其中只有一个元素是1,其他都是0。
  2. TF-IDF: 考虑词在文档中的频率和在整个语料库中的逆文档频率。
  3. Word2Vec: 通过神经网络模型来学习词的向量,使得语义上相近的词在向量空间中也相近。
  4. GloVe: 全局向量,基于共现矩阵和相关词的相对比例来生成词向量。
  5. FastText: 类似于Word2Vec,但考虑了词内字符的子结构。

文本向量:

  1. 词袋模型(BoW): 文本被表示为词的集合,不考虑词的顺序。
  2. TF-IDF: 文本中的每个词都由其TF-IDF值来表示。
  3. 段落向量(Doc2Vec): 相似于Word2Vec,但是整个文档有一个独立的向量。
  4. 平均词向量: 一个文本中所有词的词向量的平均值。
    10.BERT, GPT: 使用预训练的语言模型,获取每个词或整个句子/段落的嵌入向量。
  5. RNN, LSTM, GRU: 对于序列文本,这些循环网络能够捕获文本中的时序信息,输出整个序列的表示。

词向量和文本向量广泛应用于文本分类、信息检索、情感分析、机器翻译等NLP任务。它们可以有效地捕捉文本的语义信息,并用于各种机器学习模型。

1. 文本向量化

  • 对于机器来说,字符是没有含义的,只是有区别
  • 只使用字符无法去刻画字与字、词与词、文本与文本之间的关系
  • 文本转化为向量可以更好地刻画文本之间的关系
  • 向量化后,可以启用大量的机器学习算法,具有很高的价值
  • 文本是由词和字组成的,想将文本转化为向量,首先要能够把词和字转化为向量
  • 所有向量应该有同一维度n,我们可以称这个n维空间是一个语义空间

我 [0.78029002 0.77010974 0.07479124 0.4106988 ]
爱 [0.14092194 0.63690971 0.73774712 0.42768218]
北京 [0.95780568 0.51903789 0.76615855 0.6399924 ]
天安门 [0.73861383 0.49694373 0.13213538 0.41237077]

2. one-hot编码

One-Hot编码是一种用于表示类别变量的方法,常用于自然语言处理和其他机器学习应用。在这种编码方案中,每个唯一的类别或词都由一个全为0的向量表示,除了一个位置为1。这个"1"的位置通常由词或类别在词汇表或类别列表中的索引决定。

例如,如果我们有一个词汇表:[‘苹果’, ‘香蕉’, ‘橙子’],对应的One-Hot编码可能如下:
‘苹果’:[1, 0, 0]
‘香蕉’:[0, 1, 0]
‘橙子’:[0, 0, 1]

One-Hot编码的优点是简单、有效,但也有缺点,比如它不能捕捉词之间的关系(例如,"苹果"和"香蕉"都是水果)。此外,当词汇表很大时,One-Hot编码会非常占用存储空间和计算资源,因为每个词都需要一个与词汇表大小相等的向量。

在对文本向量化时,也可以考虑词频
不错 [0, 0, 0, 1, 0]
不错 不错 [0, 0, 0, 2, 0]

有时也可以不事先准备词表,临时构建
如做文本比对任务,成对输入,此时维度可随时变化
在这里插入图片描述

one-hot编码-缺点

  • 如果有很多词,编码向量维度会很高,而且向量十分稀疏(大部分位置都是零),计算负担很大(维度灾难)
  • 编码向量不能反映字词之间的语义相似性,只能做到区分

3. 词向量-word2vec

Word2Vec是一种用于生成词向量的模型,由Google的研究人员Mikolov等人于2013年提出。与One-Hot编码不同,Word2Vec生成的是稠密的、低维度的向量,这些向量能够捕捉词与词之间的语义关系。

Word2Vec主要有两种架构:

  1. Skip-gram:给定一个词,预测其上下文。
  2. Continuous Bag of Words (CBOW):给定一个上下文,预测中间的词。

Word2Vec通过大量的文本数据进行训练,以捕捉词之间的共现关系,并将这些信息编码到低维向量中。这些向量有许多有趣的性质,例如相似的词会被映射到向量空间中相近的点。

例如,Word2Vec能够捕捉到类比关系,比如“国王 - 男人 + 女人 = 女王”。

Word2Vec的优点包括:

  • 捕捉复杂的词关系。
  • 向量维度相对较低,节省存储和计算资源。

缺点包括:

  • 需要大量的数据进行训练。
  • 不能很好地处理文本中的多义词。

我们希望得到一种词向量,使得向量关系能反映语义关系,比如:
cos(你好, 您好) > cos(你好,天气)
即词义的相似性反映在向量的相似性

国王 - 男人 = 皇后 -女人
即向量可以通过数值运算反映词之间的关系

同时,不管有多少词,向量维度应当是固定的

3.1 词向量-基于语言模型

基于语言模型的词向量生成方法与Word2Vec等词嵌入技术有本质区别。在这类方法中,词向量是作为预训练语言模型的副产品而生成的。这些模型包括长短时记忆(LSTM)、门控循环单元(GRU)或者更先进的架构如Transformer。

语言模型的主要任务是给定一个词序列,预测下一个词。这种预测是基于整个词序列的上下文信息。在训练过程中,模型学习到的词向量能够捕捉到丰富的语义和语法信息。

ELMo(Embeddings from Language Models)和BERT(Bidirectional Encoder Representations from Transformers)是两个典型的基于语言模型的词向量生成方法。

优点:

  1. 能捕捉更丰富、更复杂的语义信息,包括词义消歧。
  2. 由于是基于完整的上下文进行预测,所生成的词向量通常更为准确。
  3. 适用于各种NLP任务,包括但不限于文本分类、命名实体识别和问答系统。

缺点:

  1. 计算复杂度高,需要更多的计算资源。
  2. 由于模型架构的复杂性,需要有一定的专业知识来进行调优。

基于语言模型的词向量因其高度的灵活性和准确性在许多NLP应用中得到了广泛应用。

4 词向量 - word2vec基于窗口

4.1 词向量-如何训练

做出假设:
如果两个词在文本中出现时,它的前后出现的词相似,则这两个词语义相似。

如:
在这里插入图片描述

基于前述思想,我们尝试用窗口中的词(或者说周围词)来表示(预测)中间词
在这里插入图片描述

或用中间词来表示周围词
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

词向量-训练的问题

  1. 输出层使用one-hot向量会面临维度灾难,因为词表可能很大。
  2. 收敛速度缓慢

代码
cbow.py

#coding:utf8

import torch
import torch.nn as nn
import numpy as np


"""
基于pytorch的词向量CBOW
模型部分
"""

class CBOW(nn.Module):
    def __init__(self, vocab_size, embedding_size, window_length):
        super(CBOW, self).__init__()
        self.word_vectors = nn.Embedding(vocab_size, embedding_size)
        self.pooling = nn.AvgPool1d(window_length)
        self.projection_layer = nn.Linear(embedding_size, vocab_size)

    def forward(self, context):
        context_embedding = self.word_vectors(context)
        context_embedding = self.pooling(context_embedding.transpose(1, 2)).squeeze()
        pred = self.projection_layer(context_embedding)
        return pred

vocab_size = 8  #词表大小
embedding_size = 4  #人为指定的向量维度
window_length = 4  #窗口长度
model = CBOW(vocab_size, embedding_size, window_length)
#假如选取一个词窗口【1,2,3,4,5】·
context = torch.LongTensor([[1,2,4,5]])
pred = model(context)  #训练目标是输出3
print("预测值:", pred)

print("词向量矩阵")
print(model.state_dict()["word_vectors.weight"])

5. Huffman树

对所有词进行二进制编码,使其符合以下特点

  1. 不同词编码不同
  2. 每个词的编码不会成为另一个词编码的前缀,即如果某个词编码为011,则不能有词的编码是0111或0110或011001等
  3. 构造出的词编码总体长度最小,且越高频词编码越短

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

"""
    构建霍夫曼树
"""


class HuffmanNode:
    def __init__(self, word_id, frequency):
        self.word_id = word_id  # 叶子结点存词对应的id, 中间节点存中间节点id
        self.frequency = frequency  # 存单词频次
        self.left_child = None
        self.right_child = None
        self.father = None
        self.Huffman_code = []  # 霍夫曼码(左1右0)
        self.path = []  # 根到叶子节点的中间节点id


class HuffmanTree:
    def __init__(self, wordid_frequency_dict):
        self.word_count = len(wordid_frequency_dict)  # 单词数量
        self.wordid_code = dict()
        self.wordid_path = dict()
        self.root = None
        unmerge_node_list = [HuffmanNode(wordid, frequency) for wordid, frequency in
                             wordid_frequency_dict.items()]  # 未合并节点list
        self.huffman = [HuffmanNode(wordid, frequency) for wordid, frequency in
                        wordid_frequency_dict.items()]  # 存储所有的叶子节点和中间节点
        # 构建huffman tree
        self.build_tree(unmerge_node_list)
        # 生成huffman code
        self.generate_huffman_code_and_path()

    def merge_node(self, node1, node2):
        sum_frequency = node1.frequency + node2.frequency
        mid_node_id = len(self.huffman)  # 中间节点的value存中间节点id
        father_node = HuffmanNode(mid_node_id, sum_frequency)
        if node1.frequency >= node2.frequency:
            father_node.left_child = node1
            father_node.right_child = node2
        else:
            father_node.left_child = node2
            father_node.right_child = node1
        self.huffman.append(father_node)
        return father_node

    def build_tree(self, node_list):
        while len(node_list) > 1:
            i1 = 0  # 概率最小的节点
            i2 = 1  # 概率第二小的节点
            if node_list[i2].frequency < node_list[i1].frequency:
                [i1, i2] = [i2, i1]
            for i in range(2, len(node_list)):
                if node_list[i].frequency < node_list[i2].frequency:
                    i2 = i
                    if node_list[i2].frequency < node_list[i1].frequency:
                        [i1, i2] = [i2, i1]
            father_node = self.merge_node(node_list[i1], node_list[i2])  # 合并最小的两个节点
            if i1 < i2:
                node_list.pop(i2)
                node_list.pop(i1)
            elif i1 > i2:
                node_list.pop(i1)
                node_list.pop(i2)
            else:
                raise RuntimeError('i1 should not be equal to i2')
            node_list.insert(0, father_node)  # 插入新节点
        self.root = node_list[0]

    def generate_huffman_code_and_path(self):
        stack = [self.root]
        while len(stack) > 0:
            node = stack.pop()
            # 顺着左子树走
            while node.left_child or node.right_child:
                code = node.Huffman_code
                path = node.path
                node.left_child.Huffman_code = code + [1]
                node.right_child.Huffman_code = code + [0]
                node.left_child.path = path + [node.word_id]
                node.right_child.path = path + [node.word_id]
                # 把没走过的右子树加入栈
                stack.append(node.right_child)
                node = node.left_child
            word_id = node.word_id
            word_code = node.Huffman_code
            word_path = node.path
            self.huffman[word_id].Huffman_code = word_code
            self.huffman[word_id].path = word_path
            # 把节点计算得到的霍夫曼码、路径  写入词典的数值中
            self.wordid_code[word_id] = word_code
            self.wordid_path[word_id] = word_path

    # 获取所有词的正向节点id和负向节点id数组
    def get_all_pos_and_neg_path(self):
        positive = []  # 所有词的正向路径数组
        negative = []  # 所有词的负向路径数组
        for word_id in range(self.word_count):
            pos_id = []  # 存放一个词 路径中的正向节点id
            neg_id = []  # 存放一个词 路径中的负向节点id
            for i, code in enumerate(self.huffman[word_id].Huffman_code):
                if code == 1:
                    pos_id.append(self.huffman[word_id].path[i])
                else:
                    neg_id.append(self.huffman[word_id].path[i])
            positive.append(pos_id)
            negative.append(neg_id)
        return positive, negative


def main():
    words = "你 我 他 你们 我们 他们 它们"
    freqs = "50 10 8 7 6 3 2"
    word_to_id = dict((word, i) for i, word in enumerate(words.split()))
    print(word_to_id)
    word_frequency = dict((word_to_id[x], int(y)) for x, y in zip(words.split(), freqs.split()))
    tree = HuffmanTree(word_frequency)
    word_code = dict((word, tree.wordid_code[word_to_id[word]]) for word in words.split())
    print(word_code)


if __name__ == '__main__':
    main()

6. 负采样-negative sampling

词向量训练最终采取softmax作为激活函数,得到预测词的分布
于一个数组V
如果V中元素很多,则该计算非常耗时
反向传播时,所有权重一起更新非常耗时

替代方案
不再计算所有词的概率,只挑选某些词计算其概率
在这里插入图片描述

使用sigmoid函数逐个计算概率,代替softmax
只更新选择的部分词的权重矩阵
在这里插入图片描述

在这里插入图片描述

7. Glove基于共现矩阵

7.1 Glove词向量

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 问题转化:
  • 给定三个词的词向量,Va, Vb, Vc三者的通过某个函数映射后,其比值应接近ABC的共现概率比
  • 即目标为找到向量使得 f(Va, Vb, Vc) = P(A|B)/P(A|C)
  • 预测数值,属于回归问题, 损失函数使用均方差
  • f的设计论文中给出的是f(Va, Vb, Vc) = (Va - Vb )·Vc

7.2 Glove对比word2vec

Glove通过共现矩阵,让模型看到了整个文本的信息,而word2vec模型一直在看某个窗口
在这里插入图片描述

8. 词向量训练总结

  1. 根据词与词之间关系的某种假设,制定训练目标
  2. 设计模型,以词向量为输入
  3. 随机初始化词向量,开始训练
  4. 训练过程中词向量作为参数不断调整,获取一定的语义信息
  5. 使用训练好的词向量做下游任务

词向量存在的问题:

  • 词向量是“静态”的。每个词使用固定向量,没有考虑前后文
  • 一词多义的情况。西瓜 - 苹果 - 华为
  • 影响效果的因素非常多
    维度选择、随机初始化、skip-gram/cbow/glove、分词质量、词频截断、未登录词、窗口大小、迭代轮数、停止条件、语料质量等
  • 没有好的直接评价指标。常需要用下游任务来评价

9. 词向量应用

9.1词向量应用-寻找近义词

在这里插入图片描述

9.2 词向量应用-句向量或文本向量

  1. 将一句话或一段文本分成若干个词
  2. 找到每个词对应的词向量
  3. 所有词向量加和求平均或通过各种网络模型,得到文本向量
  4. 使用文本向量计算相似度或进行聚类等

9.3 词向量应用-KMeans

  • 随机选择k个点作为初始质心
  • repeat
  • 将每个点指派到最近的质心,形成k个簇
  • 重新计算每个簇的质心
  • until
  • 质心不发生变化

代码
kmeans.py

import numpy as np
import random
import sys
'''
Kmeans算法实现
原文链接:https://blog.csdn.net/qingchedeyongqi/article/details/116806277
'''

class KMeansClusterer:  # k均值聚类
    def __init__(self, ndarray, cluster_num):
        self.ndarray = ndarray
        self.cluster_num = cluster_num
        self.points = self.__pick_start_point(ndarray, cluster_num)

    def cluster(self):
        result = []
        for i in range(self.cluster_num):
            result.append([])
        for item in self.ndarray:
            distance_min = sys.maxsize
            index = -1
            for i in range(len(self.points)):
                distance = self.__distance(item, self.points[i])
                if distance < distance_min:
                    distance_min = distance
                    index = i
            result[index] = result[index] + [item.tolist()]
        new_center = []
        for item in result:
            new_center.append(self.__center(item).tolist())
        # 中心点未改变,说明达到稳态,结束递归
        if (self.points == new_center).all():
            sum = self.__sumdis(result)
            return result, self.points, sum
        self.points = np.array(new_center)
        return self.cluster()

    def __sumdis(self,result):
        #计算总距离和
        sum=0
        for i in range(len(self.points)):
            for j in range(len(result[i])):
                sum+=self.__distance(result[i][j],self.points[i])
        return sum

    def __center(self, list):
        # 计算每一列的平均值
        return np.array(list).mean(axis=0)

    def __distance(self, p1, p2):
        #计算两点间距
        tmp = 0
        for i in range(len(p1)):
            tmp += pow(p1[i] - p2[i], 2)
        return pow(tmp, 0.5)

    def __pick_start_point(self, ndarray, cluster_num):
        if cluster_num < 0 or cluster_num > ndarray.shape[0]:
            raise Exception("簇数设置有误")
        # 取点的下标
        indexes = random.sample(np.arange(0, ndarray.shape[0], step=1).tolist(), cluster_num)
        points = []
        for index in indexes:
            points.append(ndarray[index].tolist())
        return np.array(points)

x = np.random.rand(100, 8)
kmeans = KMeansClusterer(x, 10)
result, centers, distances = kmeans.cluster()
print(result)
print(centers)
print(distances)

word2vec_kmeans.py

#!/usr/bin/env python3  
#coding: utf-8

#基于训练好的词向量模型进行聚类
#聚类采用Kmeans算法
import math
import re
import json
import jieba
import numpy as np
from gensim.models import Word2Vec
from sklearn.cluster import KMeans
from collections import defaultdict

#输入模型文件路径
#加载训练好的模型
def load_word2vec_model(path):
    model = Word2Vec.load(path)
    return model

def load_sentence(path):
    sentences = set()
    with open(path, encoding="utf8") as f:
        for line in f:
            sentence = line.strip()
            sentences.add(" ".join(jieba.cut(sentence)))
    print("获取句子数量:", len(sentences))
    return sentences

#将文本向量化
def sentences_to_vectors(sentences, model):
    vectors = []
    for sentence in sentences:
        words = sentence.split()  #sentence是分好词的,空格分开
        vector = np.zeros(model.vector_size)
        #所有词的向量相加求平均,作为句子向量
        for word in words:
            try:
                vector += model.wv[word]
            except KeyError:
                #部分词在训练中未出现,用全0向量代替
                vector += np.zeros(model.vector_size)
        vectors.append(vector / len(words))
    return np.array(vectors)


def main():
    model = load_word2vec_model("model.w2v") #加载词向量模型
    sentences = load_sentence("titles.txt")  #加载所有标题
    vectors = sentences_to_vectors(sentences, model)   #将所有标题向量化

    n_clusters = int(math.sqrt(len(sentences)))  #指定聚类数量
    print("指定聚类数量:", n_clusters)
    kmeans = KMeans(n_clusters)  #定义一个kmeans计算类
    kmeans.fit(vectors)          #进行聚类计算

    sentence_label_dict = defaultdict(list)
    for sentence, label in zip(sentences, kmeans.labels_):  #取出句子和标签
        sentence_label_dict[label].append(sentence)         #同标签的放到一起
    for label, sentences in sentence_label_dict.items():
        print("cluster %s :" % label)
        for i in range(min(10, len(sentences))):  #随便打印几个,太多了看不过来
            print(sentences[i].replace(" ", ""))
        print("---------")

if __name__ == "__main__":
    main()


KMeans优点:

  • 速度很快,可以支持很大量的数据
  • 样本均匀特征明显的情况下,效果不错

KMeans缺点:
人为设定聚类数量
初始化中心影响效果,导致结果不稳定
对于个别特殊样本敏感,会大幅影响聚类中心位置
不适合多分类或样本较为离散的数据

KMeans一些使用技巧:

  • 先设定较多的聚类类别
  • 聚类结束后计算类内平均距离
  • 排序后,舍弃类内较低的类别
  • 计算距离时可以尝试欧式距离、余弦距离或其他距离
  • 短文本的聚类记得先去重,以及其他预处理

10. 词向量总结

  1. 质变:将离散的字符转化为连续的数值
  2. 通过向量的相似度代表语义的相似度
  3. 词向量的训练基于很多不完全正确的假设,但是据此训练的词向量是有意义的
  4. 使用无标注的文本的一种好方法

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker安装与部署java项目

文章目录 Docker安装与部署java项目 用的宝塔服务器查看容器命令部署 java 项目这是别人用的 用这个要保证 自己docker 有 jdk1.8这个是我自己的 宝塔安装的 jdk1.8 注意 需要把 jshepr 替换成自己的 jar 名字 要小写下面命令有关于 jshepr 都要改成 上面写地自己的jar3&#x…

优质内容竞争时代,爱奇艺踏进「质变」进行时

作者 | 方怡 来源 | 洞见新研社 各大企业半年报接连发布的热闹关头&#xff0c;爱奇艺给出了意料之中的喜人成绩。 财报显示&#xff0c;今年二季度&#xff0c;爱奇艺总营收为78亿元&#xff0c;同比增长17%。其中&#xff0c;包括会员服务、广告收入、内容发行和其他收入在…

Nuxt 菜鸟入门学习笔记三:视图

文章目录 入口文件组件 Components页面 Pages布局 Layouts Nuxt 官网地址&#xff1a; https://nuxt.com/ Nuxt 提供多个组件层来实现应用程序的用户界面。 入口文件 App.vue组件 Components页面 Pages布局 Layouts 下面逐一进行介绍。 入口文件 默认情况下&#xff0c;Nu…

「MySQL-00」MySQL在Linux上的安装、登录与删除

目录 一、安装MySQL 0. 安装前请先执行一遍删除操作&#xff0c;把预装或残留的MySQL删除掉 1. 安装yum源 &#xff08;解决了在哪里找MySQL的问题&#xff09; 2. 安装哪个版本的MySQL 二、启动和登录MySQL 三、删除MySQL / MariaDB 安装与卸载前&#xff0c;建议先将用户切换…

21-JQuery

JQuery 1 JQuery基础 1.1 概念 Jquery是一个第三方的JavaScript函数库,里面包含了大量写好的函数,可以让开发人员更快捷的操作dom。JQuery目前版本是4.x,国内一般用的是3.5.11.2 使用 在页面中引入jquery文件,即可使用jquery的语法 <script src="https://code.jqu…

漏洞利用和权限提升

使用Kali Linux进行漏洞利用和权限提升是渗透测试过程中的一部分&#xff0c;用于评估系统的安全性。 漏洞利用&#xff1a; 选择目标&#xff1a; 首先&#xff0c;确定 要进行漏洞利用的目标系统。这可能是一个具有已知漏洞的应用程序、服务或操作系统。 收集信息&#xff…

光伏+旅游景区

传统化石燃料可开发量逐渐减少&#xff0c;并且对环境造成的危害日益突出。全世界都把目光投向了可再生能源&#xff0c;希望可再生能源能够改变人类的能源结构。丰富的太阳能取之不尽、用之不竭&#xff0c;同时对环境没有影响&#xff0c;光伏发电是近些年来发展最快&#xf…

STL——map和set

一、set的介绍 1、set是按照一定次序存储元素的容器&#xff1b; 2、在set中&#xff0c;元素的value也标识它(value就是key&#xff0c;类型为T)&#xff0c;并且每个value必须是唯一的&#xff0c;set中的元素不能在容器中修改(元素总是const)&#xff0c;但是可以从容器中插…

改进YOLO系列:5.添加CBAM注意力机制

添加CBAM注意力机制 1. CBAM注意力机制论文2. CBAM注意力机制原理3. CBAM注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. CBAM注意力机制论文 论文题目:CBAM: Convolutional Block Attention Module 论文链接:CBAM: Convolutional Block Attenti…

iOS逆向:越狱及相关概念的介绍

在上一篇内容中我们介绍了App脱壳的技术&#xff0c;今天我们来介绍一个和iOS逆向密切相关的知识&#xff1a;越狱。 iOS操作系统的封闭性一直是开发者们关注的焦点之一。为了突破Apple的限制&#xff0c;越狱技术应运而生。本文将深入探讨iOS越狱&#xff0c;包括可越狱的版本…

-bash: tree: command not found 的解决方法

在学习git操作时发现使用命令tree .git时显示错误 在网上查阅资料后&#xff0c;发现可能是没有安装生成tree的应用&#xff0c;所以我们使用命令安装应用即可 sudo yum install -y tree像这样就是安装成功了 我们再来试试 问题解决了&#xff0c;成功显示出树形结构

Qt 打开文件列表选择文件,实现拖拽方式打开文件

1. 实现打开文件列表选择文件 1.1. 创建 Qt 工程&#xff0c;并添加几个简单控件 这里笔者选用的是 QMainWindow&#xff0c;创建好工程后在 ui 界面设计中添加 QLineEdit、QPushBtton至少这两个控件&#xff0c;如下图摆放。 1.2. 头文件中添加相关操作 在 mainwindow.h 中…

研磨设计模式day12命令模式

目录 定义 几个参数 场景描述 代码示例 参数化设置 命令模式的优点 本质 何时选用 定义 几个参数 Command&#xff1a;定义命令的接口。 ConcreteCommand:命令接口的实现对象。但不是真正实现&#xff0c;是通过接收者的功能来完成命令要执行的操作 Receiver&#x…

桌面软件开发框架

一、Qt 官网&#xff1a;https://www.qt.io/ C 领域最流行的跨平台桌面端软件开发框架&#xff0c;Qt 有界面描述语言&#xff08;XML 描述界面&#xff09;&#xff0c;可以通过设计器拖拽空间设计界面&#xff0c;编译期界面描述语言被转义成 C 代码 Python 基于 PyQt 做 Q…

【android12-linux-5.1】【ST芯片】驱动与HAL移植后数据方向异常

ST的传感器驱动与HAL一直成功后&#xff0c;能拿到数据了&#xff0c;但是设备是横屏&#xff0c;系统默认是竖屏。就会出现屏幕自动转动时方向是错的的情况&#xff0c;设备横立展示的是竖屏&#xff0c;设备竖立展示的是横屏。 这个是PCB上设计的传感器贴片方向和横屏不一致…

Linux:基础指令

目录 Linux的基础指令 1.ls指令 2.pwd指令 3.cd指令 4.touch指令 5.mkdir指令 6.rmdir指令和rm指令 7.man指令&#xff08;重要&#xff09; 8.cp指令&#xff08;重要&#xff09; 9.mv指令&#xff08;重要&#xff09; 10.cat指令 11.nano指令 12.more指令 13.…

7个用于机器学习和数据科学的基本 Python 库

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建3D应用场景 这篇文章针对的是刚开始使用Python进行AI的人&#xff0c;以及那些有经验的人&#xff0c;但对下一步要学习什么有疑问的人。我们将不时花点时间向初学者介绍基本术语和概念。如果您已经熟悉它们&#xff0c;我们鼓…

Moonbeam生态跨链互操作项目汇总

立秋已过&#xff0c;今年的夏天已经接近尾声&#xff0c;即将迎来凉爽的秋天。Moonbeam生态一同以往持续成长&#xff0c;在8月也举办了不少活动、完成集成合作以及协议更新。让我们一同快速了解Moonbeam生态项目近期发生的大小事件吧&#xff01; Moonwell Moonwell是一个建…

《Kubernetes故障篇:Container runtime network not ready》

一、环境信息 操作系统K8S版本containerd版本Centos7.6v1.24.17v1.6.12 二、背景信息 1、通过以下命令检查网络插件的状态&#xff0c;发现网络插件coredns处于pending状态 2、通过以下命令检查kubelet服务状态&#xff0c;发现Container runtime network not ready等报错 三…

yolov5添加SimAM注意力机制(yolov7同理)

SimAM注意力机制简介 关于SIMAM注意力机制的原理这里不再详细解释,这篇发在Proceeddings of the 38th Internation Conference on Machine Learning.论文参考如下论文链接here   yolov5中添加SimAM注意力机制 注意力机制分为接收通道数和不接受通道数两种。这次属于不接受通…