深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)

news2024/9/25 21:10:01

目录

🍔 RNN 概述

1.1 循环神经网络

1.2 自然语言处理

🍔 词嵌入层

2.1 词嵌入层的使用

2.2 关于词嵌入层的思考

2.3 小节

🍔 循环网络层

3.1 RNN 网络原理

3.1.1 RNN计算过程

3.1.2 如何计算神经元内部

3.2 PyTorch RNN 层的使用

3.3 小节

🍔 案例-文本生成

4.1 构词词典

4.2 构建数据集对象

4.3 构建网络模型

4.4 构建训练函数

4.5 构建预测函数

4.6 小节

🍔 RNN 概述

1.1 循环神经网络

🐼 循环神经网络(Recurrent Nearal Networks, RNN)是一种专门用于处理序列数据的神经网络架构。它通过引入循环连接,使得网络能够捕捉序列中的时间依赖性和上下文信息。

在RNN中,每个时间步的隐藏层不仅接收当前输入,还接收来自上一时间步隐藏层的输出,这种机制允许网络“记忆”过去的信息,从而有效处理如文本、语音、时间序列等序列数据。

RNN广泛应用于自然语言处理(如机器翻译、情感分析)、语音识别、时间序列预测等领域,展现了强大的序列建模能力。

1.2 自然语言处理

🐼 自然语言处理(Nature language Processing, NLP)研究的主要是通过计算机算法来理解自然语言。对于自然语言来说,处理的数据主要就是人类的语言,例如:汉语、英语、法语等,由于该类型的数据不像我们前面接触的过的结构化数据、或者图像数据可以很方便的进行数值化。所以,在本章节,我们主要学习如何将文本数据进行数值化的词嵌入技术、以及如何对文本数据建模的循环网络模型。

最后,我们会通过使用学习到的技术完成文本生成任务,即:输入一个词,由模型预测出指定长度的歌词。

🍔 词嵌入层

学习目标

🍀 知道词嵌入概念

🍀 掌握PyTorch词嵌入api


我们在进行文本数据处理时,需要将文本进行数据值化,然后进行后续的训练工作。词嵌入层的作用就是将文本转换为向量的。

2.1 词嵌入层的使用

词嵌入层首先会根据输入的词的数量构建一个词向量矩阵,例如: 我们有 100 个词,每个词希望转换成 128 维度的向量,那么构建的矩阵形状即为: 100*128,输入的每个词都对应了一个该矩阵中的一个向量。

在 PyTorch 中,我们可以使用 nn.Embedding 词嵌入层来实现输入词的向量化。接下来,我们将会学习如何将词转换为词向量。

其步骤如下:

💘 先将语料进行分词,构建词与索引的映射,我们可以把这个映射叫做词表,词表中每个词都对应了一个唯一的索引;

💘 然后使用 nn.Embedding 构建词嵌入矩阵,词索引对应的向量即为该词对应的数值化后的向量表示。

例如,我们的文本数据为: "北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途。",接下来,我们看下如何使用词嵌入层将其进行转换为向量表示。

步骤如下:

💘 首先,将文本进行分词;

💘 然后,根据词构建词表;

💘 最后,使用嵌入层将文本转换为向量表示。

nn.Embedding 对象构建时,最主要有两个参数:

  1. num_embeddings 表示词的数量
  2. embedding_dim 表示用多少维的向量来表示每个词
nn.Embedding(num_embeddings=10, embedding_dim=4)

接下来,我们就实现下刚才的需求💯

import torch
import torch.nn as nn
import jieba


if __name__ == '__main__':

    text = '北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途。'

    # 1. 文本分词
    words = jieba.lcut(text)
    print('文本分词:', words)

    # 2. 构建词表
    index_to_word = {}
    word_to_index = {}

    # 分词去重并保留原来的顺序
    unique_words = list(set(words))
    for idx, word in enumerate(unique_words):
        index_to_word[idx] = word
        word_to_index[word] = idx

    # 3. 构建词嵌入层
    # num_embeddings: 表示词表词的总数量
    # embedding_dim: 表示词嵌入的维度
    embed = nn.Embedding(num_embeddings=len(index_to_word), embedding_dim=4)

    # 4. 文本转换为词向量表示
    print('-' * 82)
    for word in words:
        # 获得词对应的索引
        idx = word_to_index[word]
        # 获得词嵌入向量
        word_vec = embed(torch.tensor(idx))
        print('%3s\t' % word, word_vec)

程序输出结果💯 :

文本分词: ['北京', '冬奥', '的', '进度条', '已经', '过半', ',', '不少', '外国', '运动员', '在', '完成', '自己', '的', '比赛', '后', '踏上', '归途', '。']
----------------------------------------------------------------------------------
 北京  tensor([-0.9270, -0.2379, -0.6142, -1.4764], grad_fn=<EmbeddingBackward>)
 冬奥  tensor([ 0.3541, -0.4493,  0.7205,  0.1818], grad_fn=<EmbeddingBackward>)
  的  tensor([-0.4832, -1.4191,  0.6283,  0.0977], grad_fn=<EmbeddingBackward>)
进度条  tensor([ 1.4518, -0.3859, -0.6866,  1.1921], grad_fn=<EmbeddingBackward>)
 已经  tensor([ 0.3793,  1.6623, -0.2279, -0.2272], grad_fn=<EmbeddingBackward>)
 过半  tensor([ 0.0732,  1.4832, -0.7802,  0.6884], grad_fn=<EmbeddingBackward>)
  ,  tensor([ 0.6126,  1.0175, -0.4427,  0.6719], grad_fn=<EmbeddingBackward>)
 不少  tensor([ 1.0787, -0.2942, -1.0300, -0.6026], grad_fn=<EmbeddingBackward>)
 外国  tensor([-0.0484, -0.1542,  1.0033, -1.2332], grad_fn=<EmbeddingBackward>)
运动员  tensor([-1.3133,  0.3807,  0.3957,  1.1283], grad_fn=<EmbeddingBackward>)
  在  tensor([ 0.0146, -1.7078, -0.9399,  1.5368], grad_fn=<EmbeddingBackward>)
 完成  tensor([-0.1084, -0.0734, -0.1800, -0.5065], grad_fn=<EmbeddingBackward>)
 自己  tensor([ 0.8480, -0.4750, -0.1357,  0.4134], grad_fn=<EmbeddingBackward>)
  的  tensor([-0.4832, -1.4191,  0.6283,  0.0977], grad_fn=<EmbeddingBackward>)
 比赛  tensor([0.0928, 0.8925, 1.1197, 2.5525], grad_fn=<EmbeddingBackward>)
  后  tensor([ 0.8835,  0.7304,  1.3754, -1.7842], grad_fn=<EmbeddingBackward>)
 踏上  tensor([ 1.0809, -0.3135,  0.6346,  0.3923], grad_fn=<EmbeddingBackward>)
 归途  tensor([ 0.1834, -1.2411, -0.9244, -0.0265], grad_fn=<EmbeddingBackward>)
  。  tensor([ 0.0290,  0.1881, -1.3138,  0.6514], grad_fn=<EmbeddingBackward>)

2.2 关于词嵌入层的思考

我们的词嵌入层默认使用的是均值为 0,标准差为 1 的正态分布进行初始化,也可以理解为是随机初始化。

🐻 有些同学可能就想,这个用来表示词的文本真的能够表达出词的含义吗?

  1. nn.Embedding 中对每个词的向量表示都是随机生成的
  2. 当一个词输入进来之后,会使用随机产生的向量来表示该词
  3. 该词向量参与到下游任务的计算
  4. 下游任务计算之后,会和目标结果进行对比产生损失
  5. 接下来,通过反向传播更新所有的网络参数,这里的参数就包括了 nn.Embedding 中的词向量表示

这样通过反复的前向计算、反向传播、参数更新,最终我们每个词的向量表示就会变得更合理。

2.3 小节

🍬 本小节主要讲解了在自然语言处理任务中,经常使用的词嵌入层的使用。它的主要作用就是将输入的词映射为词向量,便于在网络模型中进行计算。

🍬 需要注意的是,:词嵌入层中的向量表示是可学习的,并不是固定不变的。

🍔 循环网络层

学习目标

🍀 掌握RNN网络原理

🍀 掌握PyTorch RNN api


我们前面学习了词嵌入层,可以将文本数据映射为数值向量,进而能够送入到网络进行计算。但是,还存在一个问题,文本数据是具有序列特性的,例如: "我爱你", 这串文本就是具有序列关系的,"爱" 需要在 "我" 之后,"你" 需要在 "爱" 之后, 如果颠倒了顺序,那么可能就会表达不同的意思。

为了能够表示出数据的序列关系我们需要使用循环神经网络(Recurrent Nearal Networks, RNN) 来对数据进行建模,RNN 是一个具有记忆功能的网络,它作用于处理带有序列特点的样本数据。

本小节,我们将会带着大家深入学习 RNN 循环网络层的原理、计算过程,以及在 PyTorch 中如何使用 RNN 层。

3.1 RNN 网络原理

3.1.1 RNN计算过程

当我们希望使用循环网络来对 "我爱你" 进行语义提取时,RNN 是如何计算过程是什么样的呢?

上图中 h 表示隐藏状态, 每一次的输入都会有包含两个值: 上一个时间步的隐藏状态、当前状态的输入值,输出当前时间步的隐藏状态。

上图中,为了更加容易理解,虽然我画了 3 个神经元, 但是实际上只有一个神经元,"我爱你" 三个字是重复输入到同一个神经元中。

接下来,我们举个例子来理解上图的工作过程,假设我们要实现文本生成,也就是输入 "我爱" 这两个字,来预测出 "你",其如下图所示:

我们将上图展开成不同时间步的形式,如下图所示:

我们首先初始化出第一个隐藏状态,一般都是全0的一个向量,然后将 "我" 进行词嵌入,转换为向量的表示形式,送入到第一个时间步,然后输出隐藏状态 h1,然后将 h1 和 "爱" 输入到第二个时间步,得到隐藏状态 h2, 将 h2 送入到全连接网络,得到 "你" 的预测概率。

那么,你可能会想,循环网络只能有一个神经元吗?

我们的循环网络网络可以有多个神经元,如下图所示:

我们依次将 "我爱你" 三个字分别送入到每个神经元进行计算,假设词嵌入时,"我爱你" 的维度为 128,经过循环网络之, "我爱你" 三个字的词向量维度就会变成 4. 所以, 我们理解了循环神经网络的的神经元个数会影响到输出的数据维度。

3.1.2 如何计算神经元内部

上述公式中:

  1. Wih 表示输入数据的权重
  2. bih 表示输入数据的偏置
  3. Whh 表示输入隐藏状态的权重
  4. bhh 表示输入隐藏状态的偏置

最后对输出的结果使用 tanh 激活函数进行计算,得到该神经元你的输出。

3.2 PyTorch RNN 层的使用

接下来,我们学习 PyTorch 的 RNN 层的用法.

注意: RNN 层输入的数据为三个维度: (seq_len, batch_size, input_size).

示例代码如下💯 :

import torch
import torch.nn as nn


# 1. RNN 送入单个数据
def test01():

    # 输入数据维度 128, 输出维度 256
    rnn = nn.RNN(input_size=128, hidden_size=256)

    # 第一个数字: 表示句子长度
    # 第二个数字: 批量个数
    # 第三个数字: 表示数据维度
    inputs = torch.randn(1, 1, 128)
    hn = torch.zeros(1, 1, 256)

    output, hn = rnn(inputs, hn)
    print(output.shape)
    print(hn.shape)


# 2. RNN层送入批量数据
def test02():

    # 输入数据维度 128, 输出维度 256
    rnn = nn.RNN(input_size=128, hidden_size=256)

    # 第一个数字: 表示句子长度
    # 第二个数字: 批量个数
    # 第三个数字: 表示数据维度
    inputs = torch.randn(1, 32, 128)
    hn = torch.zeros(1, 32, 256)

    output, hn = rnn(inputs, hn)
    print(output.shape)
    print(hn.shape)


if __name__ == '__main__':
    test01()
    test02()

程序输出结果💯 :

torch.Size([1, 1, 256])
torch.Size([1, 1, 256])
torch.Size([1, 32, 256])
torch.Size([1, 32, 256])

3.3 小节

🍬 在本章节中我们学习了 RNN 层及其原理,并学习了 PyTorch 中 RNN 网络层的基本使用。

🍔 案例-文本生成

学习目标

🍀 掌握文本生成模型构建流程


文本生成任务是一种常见的自然语言处理任务,输入一个开始词能够预测出后面的词序列。本案例将会使用循环神经网络来实现周杰伦歌词生成任务。

数据集如下:

想要有直升机
想要和你飞到宇宙去
想要和你融化在一起
融化在宇宙里
我每天每天每天在想想想想著你
这样的甜蜜
让我开始相信命运
感谢地心引力
让我碰到你
漂亮的让我面红的可爱女人

数据集共有 5819 行。

4.1 构词词典

我们在进行自然语言处理任务之前,首要做的就是就是构建词表。所谓的词表就是将语料进行分词,然后给每一个词分配一个唯一的编号,便于我们送入词嵌入层。

最终,我们的词典主要包含了:

  1. word_to_index: 存储了词到编号的映射
  2. index_to_word: 存储了编号到词的映射

一般构建词表的流程如下:

  1. 语料清洗, 去除不相关的内容
  2. 对语料进行分词
  3. 构建词表

接下来, 我们对周杰伦歌词的语料数据按照上面的步骤构建词表💯:

# 构建词典
def build_vocab():

    file_name = 'data/jaychou_lyrics.txt'


    # 1. 清洗文本
    clean_sentences = []
    for line in open(file_name, 'r'):

        line = line.replace('〖韩语Rap译文〗','')
        # 去除中文、英文、数字、部分标点符号外的其他字符
        line = re.sub(r'[^\u4e00-\u9fa5 a-zA-Z0-9!?,]', '', line)
        # 连续空格替换成1个
        line = re.sub(r'[ ]{2,}', '', line)
        # 去除两侧空格、换行
        line = line.strip()
        # 去除单字的行
        if len(line) <= 1:
            continue

        # 去除重复行
        if line not in clean_sentences:
            clean_sentences.append(line)

    # 2. 预料分词
    index_to_word, all_sentences = [], []

    for line in clean_sentences:
        words = jieba.lcut(line)
        all_sentences.append(words)
        for word in words:
            if word not in index_to_word:
                index_to_word.append(word)

    # 词到索引映射
    word_to_index = {word: idx for idx, word in enumerate(index_to_word)}
    # 词的数量
    word_count = len(index_to_word)
    # 句子索引表示
    corpus_idx = []
    for sentence in all_sentences:
        temp = []
        for word in sentence:
            temp.append(word_to_index[word])
        # 在每行歌词之间添加空格隔开
        temp.append(word_to_index[' '])
        corpus_idx.extend(temp)


    return index_to_word, word_to_index, word_count, corpus_idx

def test01():

    index_to_word, word_to_index, word_count, corpus_idx = build_vocab()
    print(word_count)
    print(index_to_word)
    print(word_to_index)
    print(corpus_idx)

4.2 构建数据集对象

我们在训练的时候,为了便于读取语料,并送入网络,所以我们会构建一个 Dataset 对象,并使用该对象构建 DataLoader 对象,然后对 DataLoader 对象进行迭代可以获取语料,并将其送入网络。

话不多说,代码演示💯:

class LyricsDataset:

    def __init__(self, corpus_idx, num_chars):
        # 语料数据
        self.corpus_idx = corpus_idx
        # 语料长度
        self.num_chars = num_chars
        # 词的数量
        self.word_count = len(self.corpus_idx)
        # 句子数量
        self.number =  self.word_count // self.num_chars


    def __len__(self):
        return self.number

    def __getitem__(self, idx):

        # 修正索引值到: [0, self.word_count - 1]
        start = min(max(idx, 0),  self.word_count - self.num_chars - 2)

        x = self.corpus_idx[start: start + self.num_chars]
        y = self.corpus_idx[start + 1: start + 1 + self.num_chars]

        return torch.tensor(x), torch.tensor(y)


def test02():

    _, _, _, corpus_idx = build_vocab()
    lyrics = LyricsDataset(corpus_idx, 5)
    lyrics_dataloader = DataLoader(lyrics, shuffle=False, batch_size=1)

    for x, y in lyrics_dataloader:
        print('x:', x)
        print('y:', y)
        break

4.3 构建网络模型

我们用于实现《歌词生成》的网络模型,主要包含了三个层:

  1. 词嵌入层: 用于将语料转换为词向量
  2. 循环网络层: 提取句子语义
  3. 全连接层: 输出对词典中每个词的预测概率

我们前面学习了 Dropout 层,它具有正则化作用,所以在我们的网络层中,我们会对词嵌入层、循环网络层的输出结果进行 Dropout 计算。

示例代码如下💯 :

class TextGenerator(nn.Module):

    def __init__(self, vocab_size):
        super(TextGenerator, self).__init__()
        # 初始化词嵌入层
        self.ebd = nn.Embedding(vocab_size, 128)
        # 循环网络层
        self.rnn = nn.RNN(128, 128, 1)
        # 输出层
        self.out = nn.Linear(128, vocab_size)

    def forward(self, inputs, hidden):

        # 输出维度: (1, 5, 128)
        embed = self.ebd(inputs)

        # 正则化层
        embed = F.dropout(embed, p=0.2)

        # 修改维度: (5, 1, 128)
        output, hidden = self.rnn(embed.transpose(0, 1), hidden)

        # 正则化层
        embed = F.dropout(output, p=0.2)

        # 输入维度: (5, 128)
        # 输出维度: (5, 5682)
        output = self.out(output.squeeze())

        return output, hidden

    def init_hidden(self):
        return torch.zeros(1, 1, 128)


def test03():
    index_to_word, word_to_index, word_count, corpus_idx = build_vocab()

    _, _, _, corpus_idx = build_vocab()
    lyrics = LyricsDataset(corpus_idx, 5)
    lyrics_dataloader = DataLoader(lyrics, shuffle=False, batch_size=1)
    model = TextGenerator(word_count)

    for x, y in lyrics_dataloader:
        hidden = model.init_hidden()
        print(x.shape)
        model(x, hidden)
        break

4.4 构建训练函数

前面的准备工作完成之后, 我们就可以编写训练函数。训练函数主要负责编写数据迭代、送入网络、计算损失、反向传播、更新参数,其流程基本较为固定。

由于我们要实现文本生成,文本生成本质上,输入一串文本,预测下一个文本,也属于分类问题,所以,我们使用多分类交叉熵损失函数。优化方法我们学习过 SGB、AdaGrad、Adam 等,在这里我们选择学习率、梯度自适应的 Adam 算法作为我们的优化方法。

训练完成之后,我们使用 torch.save 方法将模型持久化存储。

def train():

    # 构建词典
    index_to_word, word_to_index, word_count, corpus_idx = build_vocab()
    # 数据集
    lyrics = LyricsDataset(corpus_idx, 32)
    # 初始化模型
    model = TextGenerator(word_count)
    # 损失函数
    criterion = nn.CrossEntropyLoss()
    # 优化方法
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    # 训练轮数
    epoch = 200
    # 迭代打印
    iter_num = 300
    # 训练日志
    train_log = 'lyrics_training.log'
    file = open(train_log, 'w')

    # 开始训练
    for epoch_idx in range(epoch):

        # 数据加载器
        lyrics_dataloader = DataLoader(lyrics, shuffle=True, batch_size=1)
        # 训练时间
        start = time.time()
        # 迭代次数
        iter_num = 0
        # 训练损失
        total_loss = 0.0

        for x, y in lyrics_dataloader:

            # 隐藏状态
            hidden = model.init_hidden()
            # 模型计算
            output, hidden = model(x, hidden)
            # 计算损失
            loss = criterion(output, y.squeeze())
            # 梯度清零
            optimizer.zero_grad()
            # 反向传播
            loss.backward()
            # 参数更新
            optimizer.step()

            iter_num += 1
            total_loss += loss.item()

        message = 'epoch %3s loss: %.5f time %.2f' % \
                  (epoch_idx + 1,
                   total_loss / iter_num,
                   time.time() - start)
        print(message)
        file.write(message + '\n')

    file.close()

    # 模型存储
    torch.save(model.state_dict(), 'model/lyrics_model_%d.bin' % epoch)

4.5 构建预测函数

到了最后一步,我们从磁盘加载训练好的模型,进行预测。预测函数,输入第一个指定的词,我们将该词输入网路,预测出下一个词,再将预测的出的词再次送入网络,预测出下一个词,以此类推,知道预测出我们指定长度的内容。

def predict(start_word, sentence_length):

    # 构建词典
    index_to_word, word_to_index, word_count, _ = build_vocab()
    # 构建模型
    model = TextGenerator(vocab_size=word_count)
    # 加载参数
    model.load_state_dict(torch.load('model/lyrics_model_200.bin'))

    # 隐藏状态
    hidden = model.init_hidden()
    # 词转换为索引
    word_idx = word_to_index[start_word]
    generate_sentence = [word_idx]
    for _ in range(sentence_length):
        output, hidden = model(torch.tensor([[word_idx]]), hidden)
        word_idx = torch.argmax(output)
        generate_sentence.append(word_idx)

    for idx in generate_sentence:
        print(index_to_word[idx], end='')
    print()


if __name__ == '__main__':
    predict('分手', 50)

程序运行结果:

分手的话像语言暴力 我已无能为力再提起 决定中断熟悉 周杰伦 周杰伦 一步两步三步四步望著天 看星星 一颗两颗三颗四颗 连成线一步两步三步四步望著天 看星星 一颗两颗三颗四颗 

4.6 小节

本小节,带着大家使用学习到的循环神经网络的知识,构建了一个《歌词生成》的项目。

该项目的实现流程如下:

🍬 构建词汇表

🍬 构建数据对象

🍬 编写网络模型

🍬 编写训练函数

🍬 编写预测函数

佬~若文章对您有帮助,留下您的关注哟~您的关注是我最大的动力!

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

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

相关文章

机器学习(前六关大总结)生动讲解+代码实例

老粉都知道&#xff08;还不点关注&#xff09;我这机器学习已经有几天没更了&#xff0c;主要是最近忙碌比赛&#xff0c;所以时间紧张 那么我为大家总结一下&#xff0c;之前的机器学习知识点&#xff0c;让大家更好了解机器学习领域。 在此阅读前&#xff0c;感谢大家的关…

HTMl标签;知识回忆;笔记分享;

HTML标签是用于定义和组织网页内容的基础构建块。每个标签都有特定的作用。 一&#xff0c;标准结构标签&#xff1a; HTML文档标准结构&#xff1a; <html><head></head><body>this is my second html... </body> </html> 【1】htm…

代码随想录 | day 15 | 二叉树part03

完全二叉树的节点个数 方法一&#xff1a;可以用递归法遍历一遍左子树和右子树的个数之和再加1等于全部节点个数 class Solution { public:int getcount(TreeNode* cur){if(curNULL) return 0;int leftcount getcount(cur->left);int rightcount getcount(cur->right…

Python3.11二进制AI项目程序打包为苹果Mac App(DMG)-应用程序pyinstaller制作流程(AppleSilicon)

众所周知&#xff0c;苹果MacOs系统虽然贵为Unix内核系统&#xff0c;但由于系统不支持N卡&#xff0c;所以如果想在本地跑AI项目&#xff0c;还需要对相关的AI模块进行定制化操作&#xff0c;本次我们演示一下如何将基于Python3.11的AI项目程序打包为MacOS可以直接运行的DMG安…

90. UE5 RPG 实现技能的装配

在上一篇里&#xff0c;我们实现了在技能面板&#xff0c;点击技能能够显示出技能的相关描述以及下一级的技能的对应描述。 在这一篇里&#xff0c;我们实现一下技能的装配。 在之前&#xff0c;我们实现了点击按钮时&#xff0c;在技能面板控制器里存储了当前选中的技能的相关…

企业高性能web服务器(nginx)

目录 Web服务器基础介绍 正常情况下的单次web服务器访问流程 Apache 经典的 Web服务端 Apache prefork 模型 Apache work模型 Apache event模型 服务端的I/O流程 服务器的I/O 磁盘I/O 网络I/O 网络I/O处理过程 I/O模型 I/O模型相关概念 同步/异步 阻塞/非阻塞 网…

Ant-Design-Vue快速入门+排坑全攻略:打造炫酷Vue应用的s实用指南!

Ant-Design-Vue 是一个基于 Vue.js 的高质量 UI 组件库&#xff0c;适用于企业级后台产品的快速开发。下面将提供一份快速上手指南&#xff0c;并分享一些常见的“坑”和解决方案。 一、Ant-Design-Vue 快速上手指南 1. 安装与引入 确保安装了 Node.js&#xff08;推荐使用最新…

数据结构基础详解(C语言): 栈与队列的详解附完整代码

数据结构 栈 栈的核心重点&#xff1a; 栈是只能从表尾插入和删除的数据结构。 栈的顺序存储结构由两部分组成&#xff0c;top指针和数组。 链栈其实本质就是单链表头插法 文章目录 数据结构 栈1.栈的基本概念1.1 栈的常用操作 2.栈的存储结构2.1 栈的顺序存储结构2.1.1 栈的定…

环境配置1-MobaXterm服务器中Anaconda、Pytorch的安装

①登录 Login as 输入密码时密码不显示&#xff0c;正常输入即可 ②进入指定的下载目录 出现类似界面后&#xff0c;键盘操作Ctrlc即可进行输入 cd / …….(要下载到的目录名称)/ Anaconda的安装 ①输入wget https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux…

如何M3U8视频切片保存到本地,见过视频被别人拿走了吗?

一、数据来源分析 1.明确需求 网址:https://v.qq.com/x/cover/mzc002006n62s11/e0045s2g2eg.html 数据&#xff1a;视频 2.抓包分析 F12 刷新网站 搜索关键字找到对应的数据位置 M3U8 https://vd6.l.qq.com/proxyhttp 二、代码实现步骤 发送请求 …

Linux磁盘操作之df命令

Linux使用df命令&#xff0c;可以查看系统中每个文件系统的总容量、已使用空间、可用空间和使用率。这对于了解磁盘空间的使用情况以及判断是否需要清理或扩展磁盘空间非常有用。 参数说明 df是一个用于显示磁盘空间使用情况的命令&#xff0c;df是disk free的缩写&#xff0…

Kafka事件(消息、数据、日志)的存储

1、查看有关kafka日志配置文件的信息 2、查看kafka全部主题的日志文件 3、查看每个主题的日志文件 4、__consumer_offsets-xx文件夹的作用 package com.power;public class Test {public static void main(String[] args) {int partition Math.abs("myTopic".hashCo…

穿越时光的经典:从LeNet到ResNet,机器学习中的CNN架构进化史

在机器学习的浩瀚星空中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Networks, CNNs&#xff09;无疑是最为耀眼的星辰之一&#xff0c;它们以其卓越的图像处理能力&#xff0c;在计算机视觉领域书写了无数辉煌篇章。从最初的简单架构到如今复杂而高效的模型&am…

嵌入式UI开发-lvgl+wsl2+vscode系列:9、控件(Widgets)(二)

一、前言 接下来我们总结第二部分的控件。 二、示例 1、image&#xff08;图像&#xff09; 1.1、示例1 #include "../../lv_examples.h" #if LV_USE_IMAGE && LV_BUILD_EXAMPLESvoid lv_example_image_1(void) {LV_IMAGE_DECLARE(img_cogwheel_argb);lv…

【算法进阶2-动态规划】最长公共子序列、欧几里得算法-分数、RSA算法-密码于加密

1 最长公共子序列 2 欧几里得算法 2.1 欧几里得算法-分数 3 RSA算法-密码于加密 1 最长公共子序列 -个序列的子序列是在该序列中删去若干元素后得 到的序列。 例:“ABCD”和“BDF”都是“ABCDEFG”的子序列最长公共子序列(LCS)问题:给定两个序列X和Y&#xff0c;求X和Y长度最大…

请你谈谈:async与await是如何控制异步操作的执行顺序

async/await 是 JavaScript 中用于处理异步操作的一种语法糖&#xff0c;它使得异步代码的编写、阅读和维护变得更加容易和直观。async 和 await 关键字是在 ES2017&#xff08;ES8&#xff09;中引入的&#xff0c;旨在简化基于 Promise 的异步操作。 1 async async 是一个函…

Pytorch如何指定device(cuda or cpu)例子解析

代码示例&#xff1a; 在PyTorch中&#xff0c;指定设备&#xff08;CPU或CUDA&#xff09;是一个非常重要的步骤&#xff0c;特别是当你在进行深度学习训练时。以下是一些指定设备的详细例子&#xff1a; 检查CUDA是否可用: 首先&#xff0c;你需要检查你的机器是否支持CUDA&…

【C++ Primer Plus习题】5.9

问题: 解答: #include <iostream> #include <cstring> using namespace std;#define SIZE 20int main() {string words[SIZE];string done "done";int count 0;while (true){cout << "请输入单词:" << endl;cin >> words…

2054. 骑马修栅栏

代码 #include<bits/stdc.h> using namespace std; int mp[505][505]; queue<int> ans; int du[505]; int n0,m,u,v;void dfs(int i) {for(int j1;j<n;j){if(mp[i][j]>1){mp[i][j]--;mp[j][i]--;dfs(j);}}ans.push(i); } int main() {cin>>m;for(int …

javaSpringBootmysql的大学生心理健康管理系统39182-计算机毕业设计项目选题推荐(附源码)

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;高校当然也不例外。大学生心理健康管理系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c…