PyTorch 深度学习实践-循环神经网络(高级篇)

news2024/12/28 22:29:26

视频指路
参考博客笔记
参考笔记二

文章目录

  • 上课笔记
  • 总代码
  • 练习


上课笔记

个人能力有限,重看几遍吧,第一遍基本看不懂

在这里插入图片描述

名字的每个字母都是一个特征x1,x2,x3…,一个名字是一个序列

rnn用GRU

在这里插入图片描述

用ASCII表作为词典,长度为128,每一个值对应一个独热向量,比如77对应128维向量中第77个位置为1其他位置为0,但是对于embed层只要告诉它哪个是1就行,这些序列长短不一,需要padding到统一长度

在这里插入图片描述

把国家的名字变成索引标签,做成下图所示的词典

在这里插入图片描述
数据集构建

class NameDataset(Dataset):
    def __init__(self, is_train=True):
        # 文件读取
        filename = './dataset/names_train.csv.gz' if is_train else './dataset/names_test.csv.gz'
        with gzip.open(filename, 'rt') as f:  # rt表示以只读模式打开文件,并将文件内容解析为文本形式
            reader = csv.reader(f)
            rows =list(reader)  # 每个元素由一个名字和国家组成
        # 提取属性
        self.names = [row[0] for row in rows]
        self.len = len(self.names)
        self.countries = [row[1] for row in rows]
        # 编码处理
        self.country_list = list(sorted(set(self.countries)))  # 列表,按字母表顺序排序,去重后有18个国家名
        self.country_dict = self.get_countries_dict()  # 字典,国家名对应序号标签
        self.country_num = len(self.country_list)

    def __getitem__(self, item):
        # 索引获取
        return self.names[item], self.country_dict[self.countries[item]]  # 根据国家去字典查找索引

    def __len__(self):
        # 获取个数
        return self.len

    def get_countries_dict(self):
        # 根据国家名对应序号
        country_dict = dict()
        for idx, country_name in enumerate(self.country_list):
            country_dict[country_name] = idx
        return country_dict

    def idx2country(self, index):
        # 根据索引返回国家名字
        return self.country_list[index]

    def get_countries_num(self):
        # 返回国家名个数(分类的总个数)
        return self.country_num

双向RNN,从左往右走一遍,把得到的值和逆向计算得到的hN拼到一起,比如最后一个 [ h 0 b , h n f ] [h^b_0, h^f_n] [h0b,hnf]

		self.n_directions = 2 if bidirectional else 1

        self.gru = torch.nn.GRU(hidden_size, hidden_size, num_layers=n_layers, bidirectional=bidirectional)#bidirectional双向神经网络

在这里插入图片描述

h i d d e n = [ h N f , h N b ] hidden = [h{^f_N},h{^b_N}] hidden=[hNf,hNb]

# 进行打包(不考虑0元素,提高运行速度)首先需要将嵌入数据按长度排好
gru_input = pack_padded_sequence(embedding, seq_lengths)

pack_padded_sequence:这是 PyTorch 提供的一个函数,用于将填充后的序列打包。其主要目的是跳过填充值,并且在 RNN 中只处理实际的序列数据。它会将填充后的嵌入和实际序列长度作为输入,并返回一个打包后的序列,便于 RNN 处理。可以只把非零序列提取出来放到一块,也就是把为0的填充量都丢掉,这样将来fru就可以处理长短不一的输入序列

在这里插入图片描述

首先要根据序列长度进行排序,然后再经过嵌入层

在这里插入图片描述

如下图所示:这样用gru的时候效率就会更高,因为可以方便去掉好多padding的数据

在这里插入图片描述

双向RNN要拼接起来

if self.n_directions == 2:
            hidden_cat = torch.cat([hidden[-1], hidden[-2]], dim=1)  # hidden[-1]的形状是(1,256,100),hidden[-2]的形状是(1,256,100),拼接后的形状是(1,256,200)

总代码

import csv
import time
import matplotlib.pyplot as plt
import numpy as np
import math
import gzip  # 用于读取压缩文件
import torch
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torch.nn.utils.rnn import pack_padded_sequence

# 1.超参数设置
HIDDEN_SIZE = 100
BATCH_SIZE = 256
N_LAYER = 2  # RNN的层数
N_EPOCHS = 100
N_CHARS = 128  # ASCII码的个数
USE_GPU = False


# 工具类函数
# 把名字转换成ASCII码,    b  返回ASCII码值列表和名字的长度
def name2list(name):
    arr = [ord(c) for c in name]
    return arr, len(arr)


# 是否把数据放到GPU上
def create_tensor(tensor):
    if USE_GPU:
        device = torch.device('cuda:0')
        tensor = tensor.to(device)
    return tensor


def timesince(since):
    now = time.time()
    s = now - since
    m = math.floor(s / 60)  # math.floor()向下取整
    s -= m * 60
    return '%dmin %ds' % (m, s)  # 多少分钟多少秒


# 2.构建数据集
class NameDataset(Dataset):
    def __init__(self, is_train=True):
        # 文件读取
        filename = './dataset/names_train.csv.gz' if is_train else './dataset/names_test.csv.gz'
        with gzip.open(filename, 'rt') as f:  # rt表示以只读模式打开文件,并将文件内容解析为文本形式
            reader = csv.reader(f)
            rows =list(reader)  # 每个元素由一个名字和国家组成
        # 提取属性
        self.names = [row[0] for row in rows]
        self.len = len(self.names)
        self.countries = [row[1] for row in rows]
        # 编码处理
        self.country_list = list(sorted(set(self.countries)))  # 列表,按字母表顺序排序,去重后有18个国家名
        self.country_dict = self.get_countries_dict()  # 字典,国家名对应序号标签
        self.country_num = len(self.country_list)

    def __getitem__(self, item):
        # 索引获取
        return self.names[item], self.country_dict[self.countries[item]]  # 根据国家去字典查找索引

    def __len__(self):
        # 获取个数
        return self.len

    def get_countries_dict(self):
        # 根据国家名对应序号
        country_dict = dict()
        for idx, country_name in enumerate(self.country_list):
            country_dict[country_name] = idx
        return country_dict

    def idx2country(self, index):
        # 根据索引返回国家名字
        return self.country_list[index]

    def get_countries_num(self):
        # 返回国家名个数(分类的总个数)
        return self.country_num


# 3.实例化数据集
train_set = NameDataset(is_train=True)
train_loader = DataLoader(train_set, shuffle=True, batch_size=BATCH_SIZE, num_workers=2)
test_set = NameDataset(is_train=False)
test_loder = DataLoader(test_set, shuffle=False, batch_size=BATCH_SIZE, num_workers=2)
N_COUNTRY = train_set.get_countries_num()  # 18个国家名,即18个类别


# 4.模型构建
class GRUClassifier(torch.nn.Module):
    def __init__(self, input_size, hidden_size, output_size, n_layers=1, bidirectional=True):
        super(GRUClassifier, self).__init__()
        self.hidden_size = hidden_size
        self.n_layers = n_layers
        self.n_directions = 2 if bidirectional else 1

        # 词嵌入层,将词语映射到hidden维度
        self.embedding = torch.nn.Embedding(input_size, hidden_size)
        # GRU层(输入为特征数,这里是embedding_size,其大小等于hidden_size))
        self.gru = torch.nn.GRU(hidden_size, hidden_size, num_layers=n_layers, bidirectional=bidirectional)#bidirectional双向神经网络
        # 线性层
        self.fc = torch.nn.Linear(hidden_size * self.n_directions, output_size)

    def _init_hidden(self, bath_size):
        # 初始化权重,(n_layers * num_directions 双向, batch_size, hidden_size)
        hidden = torch.zeros(self.n_layers * self.n_directions, bath_size, self.hidden_size)
        return create_tensor(hidden)

    def forward(self, input, seq_lengths):
        # 转置 B X S -> S X B
        input = input.t()  # 此时的维度为seq_len, batch_size
        batch_size = input.size(1)
        hidden = self._init_hidden(batch_size)

        # 嵌入层处理 input:(seq_len,batch_size) -> embedding:(seq_len,batch_size,embedding_size)
        embedding = self.embedding(input)

        # 进行打包(不考虑0元素,提高运行速度)需要将嵌入数据按长度排好
        gru_input = pack_padded_sequence(embedding, seq_lengths)

        # output:(*, hidden_size * num_directions),*表示输入的形状(seq_len,batch_size)
        # hidden:(num_layers * num_directions, batch, hidden_size)
        output, hidden = self.gru(gru_input, hidden)
        if self.n_directions == 2:
            hidden_cat = torch.cat([hidden[-1], hidden[-2]], dim=1)  # hidden[-1]的形状是(1,256,100),hidden[-2]的形状是(1,256,100),拼接后的形状是(1,256,200)
        else:
            hidden_cat = hidden[-1]  # (1,256,100)
        fc_output = self.fc(hidden_cat)
        return fc_output


# 3.数据处理(姓名->数字)
def make_tensors(names, countries):
    # 获取嵌入长度从大到小排序的seq_tensor(嵌入向量)、seq_lengths(对应长度)、countries(对应顺序的国家序号)-> 便于pack_padded_sequence处理
    name_len_list = [name2list(name) for name in names]  # 每个名字对应的1列表
    name_seq = [sl[0] for sl in name_len_list]  # 姓名列表
    seq_lengths = torch.LongTensor([sl[1] for sl in name_len_list])  # 名字对应的字符个数
    countries = countries.long()   # PyTorch 中,张量的默认数据类型是浮点型 (float),这里转换成整型,可以避免浮点数比较时的精度误差,从而提高模型的训练效果

    # 创建全零张量,再依次进行填充
    # 创建了一个 len(name_seq) * seq_length.max()维的张量
    seq_tensor = torch.zeros(len(name_seq), seq_lengths.max()).long()
    for idx, (seq, seq_len) in enumerate(zip(name_seq, seq_lengths)):
        seq_tensor[idx, :seq_len] = torch.LongTensor(seq)

    # 为了使用pack_padded_sequence,需要按照长度排序
    # perm_idx是排序后的数据在原数据中的索引,seq_tensor是排序后的数据,seq_lengths是排序后的数据的长度,countries是排序后的国家
    seq_lengths, perm_idx = seq_lengths.sort(dim=0, descending=True)  # descending=True 表示按降序进行排序,即从最长的序列到最短的序列。
    seq_tensor = seq_tensor[perm_idx]
    countries = countries[perm_idx]

    return create_tensor(seq_tensor), create_tensor(seq_lengths), create_tensor(countries)


# 训练循环
def train(epoch, start):
    total_loss = 0
    for i, (names, countries) in enumerate(train_loader, 1):
        inputs, seq_lengths, target = make_tensors(names, countries)  # 输入、每个序列长度、输出
        output = model(inputs, seq_lengths)
        loss = criterion(output, target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_loss += loss.item()
        if i % 10 == 0:
            print(f'[{timesince(start)}] Epoch {epoch} ', end='')
            print(f'[{i * len(inputs)}/{len(train_set)}] ', end='')
            print(f'loss={total_loss / (i * len(inputs))}')  # 打印每个样本的平均损失

    return total_loss


# 测试循环
def test():
    correct = 0
    total = len(test_set)
    print('evaluating trained model ...')
    with torch.no_grad():
        for i, (names, countries) in enumerate(test_loder, 1):
            inputs, seq_lengths, target = make_tensors(names, countries)
            output = model(inputs, seq_lengths)
            pred = output.max(dim=1, keepdim=True)[1]  # 返回每一行中最大值的那个元素的索引,且keepdim=True,表示保持输出的二维特性
            correct += pred.eq(target.view_as(pred)).sum().item()  # 计算正确的个数
        percent = '%.2f' % (100 * correct / total)
        print(f'Test set: Accuracy {correct}/{total} {percent}%')

    return correct / total  # 返回的是准确率,0.几几的格式,用来画图


if __name__ == '__main__':
    model = GRUClassifier(N_CHARS, HIDDEN_SIZE, N_COUNTRY, N_LAYER)
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    device = 'cuda:0' if USE_GPU else 'cpu'
    model.to(device)
    start = time.time()
    print('Training for %d epochs...' % N_EPOCHS)
    acc_list = []
    # 在每个epoch中,训练完一次就测试一次
    for epoch in range(1, N_EPOCHS + 1):
        # Train cycle
        train(epoch, start)
        acc = test()
        acc_list.append(acc)

    # 绘制在测试集上的准确率
    epoch = np.arange(1, len(acc_list) + 1)
    acc_list = np.array(acc_list)
    plt.plot(epoch, acc_list)
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy')
    plt.grid()
    plt.show()

在准确率最高点save模型

保存整个模型:

torch.save(model,'save.pt')

只保存训练好的权重:

torch.save(model.state_dict(), 'save.pt')

练习

数据集地址,判断句子是哪类(0-negative,1-somewhat negative,2-neutral,3-somewhat positive,4-positive)情感分析

import pandas as pd
import torch
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.optim as optim
from sklearn.preprocessing import LabelEncoder
from torch.nn.utils.rnn import pad_sequence
from torch.nn.utils.rnn import pack_padded_sequence
import zipfile


# 超参数设置
BATCH_SIZE = 64
HIDDEN_SIZE = 100
N_LAYERS = 2
N_EPOCHS = 10
LEARNING_RATE = 0.001

# 数据集路径
TRAIN_ZIP_PATH = './dataset/train.tsv.zip'
TEST_ZIP_PATH = './dataset/test.tsv.zip'

# 解压缩文件
def unzip_file(zip_path, extract_to='.'):
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(extract_to)

unzip_file(TRAIN_ZIP_PATH)
unzip_file(TEST_ZIP_PATH)

# 数据集路径
TRAIN_PATH = './train.tsv'
TEST_PATH = './test.tsv'

# 自定义数据集类
class SentimentDataset(Dataset):
    def __init__(self, phrases, sentiments=None):
        self.phrases = phrases
        self.sentiments = sentiments

    def __len__(self):
        return len(self.phrases)

    def __getitem__(self, idx):
        phrase = self.phrases[idx]
        if self.sentiments is not None:
            sentiment = self.sentiments[idx]
            return phrase, sentiment
        return phrase

# 加载数据
def load_data():
    train_df = pd.read_csv(TRAIN_PATH, sep='\t')
    test_df = pd.read_csv(TEST_PATH, sep='\t')
    return train_df, test_df

train_df, test_df = load_data()

# 数据预处理
def preprocess_data(train_df, test_df):
    le = LabelEncoder()
    train_df['Sentiment'] = le.fit_transform(train_df['Sentiment'])
    train_phrases = train_df['Phrase'].tolist()
    train_sentiments = train_df['Sentiment'].tolist()
    test_phrases = test_df['Phrase'].tolist()
    return train_phrases, train_sentiments, test_phrases, le

train_phrases, train_sentiments, test_phrases, le = preprocess_data(train_df, test_df)

# 构建词汇表
def build_vocab(phrases):
    vocab = set()
    for phrase in phrases:
        for word in phrase.split():
            vocab.add(word)
    word2idx = {word: idx for idx, word in enumerate(vocab, start=1)}
    word2idx['<PAD>'] = 0
    return word2idx

word2idx = build_vocab(train_phrases + test_phrases)

# 将短语转换为索引
def phrase_to_indices(phrase, word2idx):
    return [word2idx[word] for word in phrase.split() if word in word2idx]

train_indices = [phrase_to_indices(phrase, word2idx) for phrase in train_phrases]
test_indices = [phrase_to_indices(phrase, word2idx) for phrase in test_phrases]

# 移除长度为0的样本
train_indices = [x for x in train_indices if len(x) > 0]
train_sentiments = [y for x, y in zip(train_indices, train_sentiments) if len(x) > 0]
test_indices = [x for x in test_indices if len(x) > 0]

# 数据加载器
def collate_fn(batch):
    phrases, sentiments = zip(*batch)
    lengths = torch.tensor([len(x) for x in phrases])
    phrases = [torch.tensor(x) for x in phrases]
    phrases_padded = pad_sequence(phrases, batch_first=True, padding_value=0)
    sentiments = torch.tensor(sentiments)
    return phrases_padded, sentiments, lengths

train_dataset = SentimentDataset(train_indices, train_sentiments)
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, collate_fn=collate_fn)

test_dataset = SentimentDataset(test_indices)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, collate_fn=lambda x: pad_sequence([torch.tensor(phrase) for phrase in x], batch_first=True, padding_value=0))

# 模型定义
class SentimentRNN(nn.Module):
    def __init__(self, vocab_size, embed_size, hidden_size, output_size, n_layers):
        super(SentimentRNN, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embed_size, padding_idx=0)
        self.lstm = nn.LSTM(embed_size, hidden_size, n_layers, batch_first=True, bidirectional=True)
        self.fc = nn.Linear(hidden_size * 2, output_size)

    def forward(self, x, lengths):
        x = self.embedding(x)
        x = pack_padded_sequence(x, lengths.cpu(), batch_first=True, enforce_sorted=False)
        _, (hidden, _) = self.lstm(x)
        hidden = torch.cat((hidden[-2], hidden[-1]), dim=1)
        out = self.fc(hidden)
        return out

vocab_size = len(word2idx)
embed_size = 128
output_size = len(le.classes_)

model = SentimentRNN(vocab_size, embed_size, HIDDEN_SIZE, output_size, N_LAYERS)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

# 训练和测试循环
def train(model, train_loader, criterion, optimizer, n_epochs):
    model.train()
    for epoch in range(n_epochs):
        total_loss = 0
        for phrases, sentiments, lengths in train_loader:
            optimizer.zero_grad()
            output = model(phrases, lengths)
            loss = criterion(output, sentiments)
            loss.backward()
            optimizer.step()
            total_loss += loss.item()
        print(f'Epoch: {epoch+1}, Loss: {total_loss/len(train_loader)}')

def generate_test_results(model, test_loader, test_ids):
    model.eval()
    results = []
    with torch.no_grad():
        for phrases in test_loader:
            lengths = torch.tensor([len(x) for x in phrases])
            output = model(phrases, lengths)
            preds = torch.argmax(output, dim=1)
            results.extend(preds.cpu().numpy())
    return results

train(model, train_loader, criterion, optimizer, N_EPOCHS)

test_ids = test_df['PhraseId'].tolist()
preds = generate_test_results(model, test_loader, test_ids)

# 保存结果
output_df = pd.DataFrame({'PhraseId': test_ids, 'Sentiment': preds})
output_df.to_csv('sentiment_predictions.csv', index=False)

引入随机性:重要性采样,对分类的样本按照它的分布来进行随机采样

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

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

相关文章

系统架构设计师教程 第3章 信息系统基础知识-3.5 专家系统-解读

系统架构设计师教程 第3章 信息系统基础知识-3.5 专家系统(ES) 3.5.1 人工智能3.5.1.1 人工智能的特点3.5.1.2 人工智能的主要分支3.5.2 ES的概念3.5.2.1 ES 概述3.5.2.2 与传统程序的区别3.5.3 ES的特点3.5.4 ES的组成3.5.4.1 知识库3.5.4.2 综合数据库3.5.4.3 推理机3.5.4.…

【干货】光学检测技术及应用

光学检测技术涵盖了多种方法和应用&#xff0c;主要可以分为以下几类&#xff1a; 光学测量 结合光电技术与机械测量的高科技方法&#xff0c;利用计算机技术实现快速准确的测量&#xff0c;广泛应用于现代工业检测&#xff0c;如检测产品的形位公差和数值孔径等。 光学分析方…

腾讯元宝上线“3D角色梦工厂”:快速生成专属3D角色!

7月16日&#xff0c;腾讯旗下大模型应用“腾讯元宝”上线“3D角色梦工厂”&#xff0c;允许用户通过上传一张五官清晰的正面头像&#xff0c;并选择不同的角色模板&#xff0c;迅速生成个人3D角色&#xff01; 技术特点 “3D角色梦工厂”将大模型生成技术与3D应用相结合&#…

LeetCode 394, 61, 100

目录 394. 字符串解码题目链接标签思路代码 61. 旋转链表题目链接标签思路代码 100. 相同的树题目链接标签思路代码递归版前序遍历层序遍历 394. 字符串解码 题目链接 394. 字符串解码 标签 栈 递归 字符串 思路 本题可以使用两个栈来解决&#xff0c;一个栈 timesStack …

嵌入式物联网在医疗行业中的应用——案例分析

作者主页: 知孤云出岫 目录 嵌入式物联网在医疗行业中的应用——案例分析引言1. 智能病房监控1.1 实时患者监控系统 2. 智能医疗设备管理2.1 设备使用跟踪与维护 3. 智能药物管理3.1 药物分配与跟踪 4. 智能远程医疗4.1 远程患者监控与诊断 总结 嵌入式物联网在医疗行业中的应…

3、宠物商店智能合约实战(truffle智能合约项目实战)

3、宠物商店智能合约实战&#xff08;truffle智能合约项目实战&#xff09; 1-宠物商店环境搭建、运行2-webjs与宠物逻辑实现3-领养智能合约初始化4-宠物领养实现5-更新宠物领养状态 1-宠物商店环境搭建、运行 https://www.trufflesuite.com/boxes/pet-shop 这个还是不行 或者…

Blender4.2版本正式上线,新版本的5个主要功能!

​Blender刚刚推出了备受瞩目的 Blender 4.2 版本&#xff0c;这款软件专为那些在视觉特效、动画制作、游戏开发和可视化设计领域工作的艺术家们量身打造。作为最新的长期稳定更新&#xff0c;Blender 4.2 不仅稳定可靠&#xff0c;还引入了备受期待的“Eevee Next”实时渲染引…

【BUG】已解决:zipfile.BadZipFile: File is not a zip file

已解决&#xff1a;zipfile.BadZipFile: File is not a zip file 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发…

channle介绍

通道在Java NIO&#xff08;New Input/Output&#xff09;中扮演着核心角色&#xff0c;它们是与Buffer&#xff08;缓冲区&#xff09;交互的入口点&#xff0c;用于从外部资源读取数据到内存或从内存写入数据到外部资源。通道可以看作是访问文件数据和其他I/O资源&#xff08…

JVM:MAT内存泄漏检测原理

文章目录 一、介绍 一、介绍 MAT提供了称为支配树&#xff08;Dominator Tree&#xff09;的对象图。支配树展示的是对象实例间的支配关系。在对象引用图中&#xff0c;所有指向对象B的路径都经过对象A&#xff0c;则认为对象A支配对象B。 支配树中对象本身占用的空间称之为…

谷歌浏览器自动填充密码时,el-input样式错乱

使用到谷歌浏览器的记忆功能&#xff0c;选择的内容为浏览器保存的内容时 会导致element-plus的el-input样式改变 只需要增加一个css样式&#xff0c;就可以解决问题 :deep .el-input__inner {box-shadow: 0 0 0 1000px #fff inset; }修改后

深入理解ADB:Android调试桥详解与使用指南

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Android ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. 什么是ADB&#xff1f; ADB的基本原理&#xff1a; 2. ADB的安装与配置 安装ADB工具集&#xff1a; 配置ADB环境变量&am…

注册安全分析报告:东方航空

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

进程与线程(一)进程相关

目录 一. 概念二 . 组成进程控制块程序段数据段 三. 特征四. 进程的状态与转换五. 进程控制进程创建进程终止进程阻塞与进程唤醒进程切换 六. 进程通信共享存储消息传递管道通信 一. 概念 多道程序环境下&#xff0c;允许多个程序并发执行&#xff0c;此时它们将失去封闭性&…

Unity 导入MRTK,使用URP 升级材质,MRTK的材质还是洋红色

控制台显示信息 ToggleBackground material was not upgraded. There’s no upgrader to convert Mixed Reality Toolkit/Standard shader to selected pipeline UnityEditor.Rendering.Universal.UniversalRenderPipelineMaterialUpgrader:UpgradeProjectMaterials() (at 点击…

出现 Welcome to nginx! If you see this page, 的解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法 前言 对于Nginx的知识点推荐阅读&#xff1a; Nginx从入门到精通&#xff08;全&#xff09;Nginx配置静态网页访问&#xff08;图文界面&#xff09;Nginx将https重定向为http进行访问的配置&#xff08;附Demo&#xff09; 由…

经典神经网络(14)T5模型原理详解及其微调(文本摘要)

经典神经网络(14)T5模型原理详解及其微调(文本摘要) 2018 年&#xff0c;谷歌发布基于双向 Transformer 的大规模预训练语言模型 BERT&#xff0c;而后一系列基于 BERT 的研究工作如春笋般涌现&#xff0c;预训练模型也成为了业内解决 NLP 问题的标配。 2019年&#xff0c;谷歌…

【BUG】已解决:ModuleNotFoundError: No module named ‘torch‘

已解决&#xff1a;ModuleNotFoundError: No module named ‘torch‘ 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市…

UE4-蓝图(可视化编程)学习

一.开关门交互实现 1.需要用到的模板和内容包 2.给门添加碰撞 进入第三人称模板场景&#xff0c;找到门的模型&#xff0c;并将门的模型添加到我们的场景中&#xff1a; 此时我们运行游戏&#xff0c;会发现我们的角色可以穿过我们门的模型&#xff0c;说明我们没有给门添加碰…

MAVSDK-Java开源库的SDK库macOS平台编译

1.先安装好JDK17 2.克隆MAVSDK-Java源码 3.检测工程./gradlew check 发现未安装protoc-gen-mavsdk 安装后要添加到环境变量 4.安装protoc-gen-mavsdk pip3 install protoc-gen-mavsdk安装路径为: /opt/anaconda3/lib/python3.11/site-packages/protoc_gen_mavsdk