Pytorch 实现情感分析

情感分析

情感分析是 NLP 一种应用场景,模型判断输入语句是积极的还是消极的,实际应用适用于评论、客服等多场景。情感分析通过 transformer 架构中的 encoder 层再加上情感分类层进行实现。

安装依赖

需要安装 Poytorch NLP 相关依赖

pip install torchtext==0.6.0

下载预训练的英文模型

import os
import urllib.request
import zipfile
import tarfile

#下载fastText官方英语已学习模型(650MB)。
url = "https://dl.fbaipublicfiles.com/fasttext/vectors-english/wiki-news-300d-1M.vec.zip"
save_path = "./data/wiki-news-300d-1M.vec.zip"
if not os.path.exists(save_path):
    urllib.request.urlretrieve(url, save_path)

#解压缩文件夹“data”中的“/维基-news-300d- 1m .vec.zip”

zip = zipfile.ZipFile("./data/wiki-news-300d-1M.vec.zip")
zip.extractall("./data/")  #解压缩ZIP
zip.close()  #关闭ZIP文件

准备数据

准备训练数据、测试数据,去掉空格以及标点符号,由于是英文数据,通过空格进行分词。

##保存为tsv格式的文件
import glob
import os
import io
import string


#创建训练数据的tsv文件

f = open('./data/IMDb_train.tsv', 'w')

path = './data/aclImdb/train/pos/'
for fname in glob.glob(os.path.join(path, '*.txt')):
    with io.open(fname, 'r', encoding="utf-8") as ff:
        text = ff.readline()

        #如果包含制表符就删除
        text = text.replace('\t', " ")

        text = text+'\t'+'1'+'\t'+'\n'
        f.write(text)

path = './data/aclImdb/train/neg/'
for fname in glob.glob(os.path.join(path, '*.txt')):
    with io.open(fname, 'r', encoding="utf-8") as ff:
        text = ff.readline()

        #如果包含制表符就删除
        text = text.replace('\t', " ")

        text = text+'\t'+'0'+'\t'+'\n'
        f.write(text)

f.close()

#创建测试数据

f = open('./data/IMDb_test.tsv', 'w')

path = './data/aclImdb/test/pos/'
for fname in glob.glob(os.path.join(path, '*.txt')):
    with io.open(fname, 'r', encoding="utf-8") as ff:
        text = ff.readline()

       #如果包含制表符就删除
        text = text.replace('\t', " ")

        text = text+'\t'+'1'+'\t'+'\n'
        f.write(text)


path = './data/aclImdb/test/neg/'

for fname in glob.glob(os.path.join(path, '*.txt')):
    with io.open(fname, 'r', encoding="utf-8") as ff:
        text = ff.readline()

        #如果包含制表符就删除
        text = text.replace('\t', " ")

        text = text+'\t'+'0'+'\t'+'\n'
        f.write(text)

f.close()

import string
import re

#将下列符号替换成空格符(除了句号和逗号之外)。
print("分隔符:", string.punctuation)
# !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

#预处理


def preprocessing_text(text):
    #预处理
    text = re.sub('<br />', '', text)

   #将逗号和句号以外的标点符号替换成空格符
    for p in string.punctuation:
        if (p == ".") or (p == ","):
            continue
        else:
            text = text.replace(p, " ")

    #在句号和逗号前后插入空格符
    text = text.replace(".", " . ")
    text = text.replace(",", " , ")
    return text

#用空格将单词隔开(这里的数据是英文的,用空格进行分隔)


def tokenizer_punctuation(text):
    return text.strip().split()


#定义用于预处理和分词处理的函数
def tokenizer_with_preprocessing(text):
    text = preprocessing_text(text)
    ret = tokenizer_punctuation(text)
    return ret


#确认执行结果
print(tokenizer_with_preprocessing('I like cats.'))


创建 Dataloader

创建两种类型的数据,TEXT:输入的评论,LABEL:类型标签

##定义在读取数据时,对读取内容所做的处理
import torchtext


# #同时准备文章和标签两种字段
max_length = 256
TEXT = torchtext.data.Field(sequential=True, tokenize=tokenizer_with_preprocessing, use_vocab=True,
                            lower=True, include_lengths=True, batch_first=True, fix_length=max_length, 
                            init_token="<cls>", eos_token="<eos>")
LABEL = torchtext.data.Field(sequential=False, use_vocab=False)
#从data文件夹中读取各个tsv文件
train_val_ds, test_ds = torchtext.data.TabularDataset.splits(
    path='./data/', train='IMDb_train.tsv',
    test='IMDb_test.tsv', format='tsv',
    fields=[('Text', TEXT), ('Label', LABEL)])

#确认执行结果
print('训练和验证数据的数量', len(train_val_ds))
print('第一个训练和验证的数据', vars(train_val_ds[0]))

切分训练数据和验证数据,20000 条训练集、5000 条验证:

import random
#使用torchtext.data.Dataset的split函数将Dataset切分为训练数据和验证数据

train_ds, val_ds = train_val_ds.split(
    split_ratio=0.8, random_state=random.seed(1234))

#确认执行结果
print('训练数据的数量', len(train_ds))
print('验证数据的数量', len(val_ds))
print('第一个训练数据', vars(train_ds[0]))

载入已经选练好的 fasttext 模型,并根据模型创建词汇表

#使用torchtext读取作为单词向量

from torchtext.vocab import Vectors

english_fasttext_vectors = Vectors(name='data/wiki-news-300d-1M.vec')


#确认单词向量中的内容
print("1个单词向量的维数:", english_fasttext_vectors.dim)
print("单词数量:", len(english_fasttext_vectors.itos))

#单词数量
TEXT.build_vocab(train_ds, vectors=english_fasttext_vectors, min_freq=10)

创建 dataloader

# DataLoaderを作成します(torchtextの文脈では単純にiteraterと呼ばれています)
train_dl = torchtext.data.Iterator(train_ds, batch_size=24, train=True)

val_dl = torchtext.data.Iterator(
    val_ds, batch_size=24, train=False, sort=False)

test_dl = torchtext.data.Iterator(
    test_ds, batch_size=24, train=False, sort=False)


# 動作確認 検証データのデータセットで確認
batch = next(iter(val_dl))
print(batch.Text)
print(batch.Label)

创建分类任务

创建 Transformer 模型

import math
import numpy as np
import random

import torch
import torch.nn as nn
import torch.nn.functional as F 
import torchtext

# Setup seeds
torch.manual_seed(1234)
np.random.seed(1234)
random.seed(1234)

class Embedder(nn.Module):
    '''将id代表的单词转换为向量'''

    def __init__(self, text_embedding_vectors):
        super(Embedder, self).__init__()

        self.embeddings = nn.Embedding.from_pretrained(
            embeddings=text_embedding_vectors, freeze=True)
        #指定freeze=True,可以防止反向传播造成的更新,保证数据不发生变化

    def forward(self, x):
        x_vec = self.embeddings(x)

        return x_vec


#确认代码的执行结果

#确认代码的执行结果
from utils.dataloader import get_IMDb_DataLoaders_and_TEXT
train_dl, val_dl, test_dl, TEXT = get_IMDb_DataLoaders_and_TEXT(
    max_length=256, batch_size=24)

#准备小批次
batch = next(iter(train_dl))

#构建模型
net1 = Embedder(TEXT.vocab.vectors)

#输入和输出
x = batch.Text[0]
x1 = net1(x) #将单词转换为向量

print("输入的张量尺寸:", x.shape)
print("输出的张量尺寸:", x1.shape)

## 定义 positionencoder
class PositionalEncoder(nn.Module):
    '''添加用于表示输入单词的位置的向量信息'''

    def __init__(self, d_model=300, max_seq_len=256):
        super().__init__()

        self.d_model = d_model   #单词向量的维度

      #创建根据单词的顺序(pos)和填入向量的维度的位置(i)确定的值的表pe
        pe = torch.zeros(max_seq_len, d_model)

       #如果GPU可用,则发送到GPU中,这里暂且省略此操作。在实际进行学习时可以使用
        # device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        # pe = pe.to(device)

        for pos in range(max_seq_len):
            for i in range(0, d_model, 2):
                pe[pos, i] = math.sin(pos / (10000 ** ((2 * i)/d_model)))
                pe[pos, i + 1] = math.cos(pos /
                                          (10000 ** ((2 * (i + 1))/d_model)))

      #将作为小批量维度的维度添加到pe的开头
        self.pe = pe.unsqueeze(0)

        #关闭梯度的计算
        self.pe.requires_grad = False

    def forward(self, x):

        #将输入x与Positonal Encoding相加
        #x比pe要小,因此需要将其放大
        ret = math.sqrt(self.d_model)*x + self.pe
        return ret
   
#创建Attention
class Attention(nn.Module):
    '''实际上,Transformer中使用的是多头Attention
   这里为了便于读者理解,采用的是单一Attention结构'''

    def __init__(self, d_model=300):
        super().__init__()

       #在Self-Attention GAN中使用的是1dConv,这次在全连接层中对特征量进行变换
        self.q_linear = nn.Linear(d_model, d_model)
        self.v_linear = nn.Linear(d_model, d_model)
        self.k_linear = nn.Linear(d_model, d_model)

        #输出时使用的全连接层
        self.out = nn.Linear(d_model, d_model)

        #用于调整Attention大小的变量
        self.d_k = d_model

    def forward(self, q, k, v, mask):
        #在全连接层中进行特征量变换
        k = self.k_linear(k)
        q = self.q_linear(q)
        v = self.v_linear(v)

        #计算Attention的值
        #直接与各个值相加得到的结果太大,因此除以root(d_k)来调整
        weights = torch.matmul(q, k.transpose(1, 2)) / math.sqrt(self.d_k)

        #在这里计算mask
        mask = mask.unsqueeze(1)
        weights = weights.masked_fill(mask == 0, -1e9)

        #使用softmax进行归一化处理
        normlized_weights = F.softmax(weights, dim=-1)

        #将Attention与Value相乘
        output = torch.matmul(normlized_weights, v)

        #使用全连接层进行特征量变换
        output = self.out(output)

        return output, normlized_weights

#创建feedforward 网络
class FeedForward(nn.Module):
    def __init__(self, d_model, d_ff=1024, dropout=0.1):
        '''负责将来自Attention层的输出通过两个全连接层进行特征量变换的组件'''
        super().__init__()

        self.linear_1 = nn.Linear(d_model, d_ff)
        self.dropout = nn.Dropout(dropout)
        self.linear_2 = nn.Linear(d_ff, d_model)

    def forward(self, x):
        x = self.linear_1(x)
        x = self.dropout(F.relu(x))
        x = self.linear_2(x)
        return x

#创建 Transformer
class TransformerBlock(nn.Module):
    def __init__(self, d_model, dropout=0.1):
        super().__init__()

        # LayerNormalization層层
        # https://pytorch.org/docs/stable/nn.html?highlight=layernorm
        self.norm_1 = nn.LayerNorm(d_model)
        self.norm_2 = nn.LayerNorm(d_model)

        # Attention层
        self.attn = Attention(d_model)

        #Attention后面的两个全连接层
        self.ff = FeedForward(d_model)

        # Dropout
        self.dropout_1 = nn.Dropout(dropout)
        self.dropout_2 = nn.Dropout(dropout)

    def forward(self, x, mask):
        #归一化与Attention
        x_normlized = self.norm_1(x)
        output, normlized_weights = self.attn(
            x_normlized, x_normlized, x_normlized, mask)
        
        x2 = x + self.dropout_1(output)

        #归一化与全连接层
        x_normlized2 = self.norm_2(x2)
        output = x2 + self.dropout_2(self.ff(x_normlized2))

        return output, normlized_weights

## 创建分类
class ClassificationHead(nn.Module):
    '''使用Transformer_Block的输出结果,最终实现分类处理'''

    def __init__(self, d_model=300, output_dim=2):
        super().__init__()

        #使用Transformer_Block的输出结果,最终实现分类处理
        self.linear = nn.Linear(d_model, output_dim)  #output_dim是正面/负面这两个维度

        #权重的初始化处理
        nn.init.normal_(self.linear.weight, std=0.02)
        nn.init.normal_(self.linear.bias, 0)

    def forward(self, x):
        x0 = x[:, 0, :]  #取出每个小批次的每个文章的开头的单词的特征量(300 维)
        out = self.linear(x0)

        return out
## 整合代码放到 TransformerClassification


class TransformerClassification(nn.Module):
    '''#最终的Transformer模型的类'''

    def __init__(self, text_embedding_vectors, d_model=300, max_seq_len=256, output_dim=2):
        super().__init__()

        #构建模型
        self.net1 = Embedder(text_embedding_vectors)
        self.net2 = PositionalEncoder(d_model=d_model, max_seq_len=max_seq_len)
        self.net3_1 = TransformerBlock(d_model=d_model)
        self.net3_2 = TransformerBlock(d_model=d_model)
        self.net4 = ClassificationHead(output_dim=output_dim, d_model=d_model)

    def forward(self, x, mask):
        x1 = self.net1(x)  #将单词转换为向量
        x2 = self.net2(x1)  #对Positon信息进行加法运算
        x3_1, normlized_weights_1 = self.net3_1(
            x2, mask) #使用Self−Attention进行特征量变换
        x3_2, normlized_weights_2 = self.net3_2(
            x3_1, mask)  #使用Self−Attention进行特征量变换
        x4 = self.net4(x3_2)  #使用最终输出的第0个单词,输出分类0~1的标量
        return x4, normlized_weights_1, normlized_weights_2

训练并验证

#导入软件包
import numpy as np
import random

import torch
import torch.nn as nn
import torch.optim as optim

import torchtext

# 设定随机数的种子,
torch.manual_seed(1234)
np.random.seed(1234)
random.seed(1234)

from utils.dataloader import get_IMDb_DataLoaders_and_TEXT

#载入数据
train_dl, val_dl, test_dl, TEXT = get_IMDb_DataLoaders_and_TEXT(
    max_length=256, batch_size=64)

#集中保存到字典对象中
dataloaders_dict = {"train": train_dl, "val": val_dl}


from utils.transformer import TransformerClassification

#构建模型
net = TransformerClassification(
    text_embedding_vectors=TEXT.vocab.vectors, d_model=300, max_seq_len=256, output_dim=2)

#定义网络的初始化操作


def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Linear') != -1:
       #Liner层的初始化
        nn.init.kaiming_normal_(m.weight)
        if m.bias is not None:
            nn.init.constant_(m.bias, 0.0)


#设置为训练模式
net.train()

#执行TransformerBlock模块的初始化操作
net.net3_1.apply(weights_init)
net.net3_2.apply(weights_init)


print('网络设置完毕')

#设置损失函数
criterion = nn.CrossEntropyLoss()

#设置最优化算法
learning_rate = 2e-5
optimizer = optim.Adam(net.parameters(), lr=learning_rate)

#创建用于训练模型的函数


def train_model(net, dataloaders_dict, criterion, optimizer, num_epochs):

    #确认是否能够使用GPU
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print("使用的设备:", device)
    print('-----start-------')
    #将网络载入GPU中
    net.to(device)

    #如果网络结构比较固定,则开启硬件加速
    torch.backends.cudnn.benchmark = True

    #epoch循环
    for epoch in range(num_epochs):
        #以epoch为单位进行训练和验证的循环
        for phase in ['train', 'val']:
            if phase == 'train':
                net.train()  #将模型设为训练模式
            else:
                net.eval()   #将模型设为训练模式

            epoch_loss = 0.0  #epoch的损失和
            epoch_corrects = 0  #epoch的准确率

            #从数据加载器中读取小批次数据的循环
            for batch in (dataloaders_dict[phase]):
                #batch是Text和Lable的字典对象

               #如果GPU可以使用,则将数据输送到GPU中
                inputs = batch.Text[0].to(device)  # 文章
                labels = batch.Label.to(device)  # 标签

                #初始化optimizer
                optimizer.zero_grad()

               #初始化optimizer
                with torch.set_grad_enabled(phase == 'train'):

                    # mask作成
                    input_pad = 1 #在单词ID中'<pad>': 1
                    input_mask = (inputs != input_pad)

                   #输入Transformer中
                    outputs, _, _ = net(inputs, input_mask)
                    loss = criterion(outputs, labels)  #计算损失值

                    _, preds = torch.max(outputs, 1)  #对标签进行预测

                    #训练时进行反向传播
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                    #计算结果
                    epoch_loss += loss.item() * inputs.size(0)  # lossの合計を更新
                    #更新正确答案的合计数量
                    epoch_corrects += torch.sum(preds == labels.data)

           #每轮epoch的loss和准确率
            epoch_loss = epoch_loss / len(dataloaders_dict[phase].dataset)
            epoch_acc = epoch_corrects.double(
            ) / len(dataloaders_dict[phase].dataset)

            print('Epoch {}/{} | {:^5} |  Loss: {:.4f} Acc: {:.4f}'.format(epoch+1, num_epochs,
                                                                           phase, epoch_loss, epoch_acc))

    return net

#执行学习和验证
num_epochs = 10
net_trained = train_model(net, dataloaders_dict,
                          criterion, optimizer, num_epochs=num_epochs)


在这里插入图片描述

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

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

相关文章

免费SSL证书?轻松申请攻略来了!

在当今的互联网时代&#xff0c;网络安全已经成为一个不容忽视的重要课题。随着在线交流和交易活动的增加&#xff0c;保护网站和用户信息的重要性日益突显。SSL证书&#xff0c;即安全套接字层证书&#xff0c;它为互联网通信提供了加密服务&#xff0c;确保数据的安全性和完整…

光伏远动通讯屏的组成

光伏远动通讯屏的组成 远动通讯屏主要用于电力系统数据采集与转发&#xff0c;远动通讯屏能够采集站内的各种数据&#xff0c;如模拟量、开关量和数字量等&#xff0c;并通过远动通讯规约将必要的数据上传至集控站或调度系统。这包括但不限于主变和输电线路的功率、电流、电压等…

怎么设置一天多个时间点的闹钟提醒?

在日常生活中&#xff0c;我们经常需要在一天的不同时间点完成特定的任务&#xff0c;如定时喝水、定时查看后台数据、定时吃药等。这时候&#xff0c;如果能有一款软件&#xff0c;可以在一条日程里轻松设置多个时间点的闹钟提醒&#xff0c;那将大大提高我们的工作效率和生活…

如何理解GTX接收通道相关模块?(高速收发器三)

前文讲解了GTX的时钟及发送通道相关内容&#xff0c;本文讲解GTX接收通道的一些功能及其IP配置&#xff0c;接收往往比发送设计更难&#xff0c;与调制解调&#xff0c;加密解密其实相差不大&#xff0c;后者难度都比前者高出很多。GTX的接收通道的功能相比发送通道更加重要&am…

西奥CHT-01软胶囊硬度测试仪:重塑行业标杆,引领硬度测试新纪元

西奥CHT-01软胶囊硬度测试仪&#xff1a;重塑行业标杆&#xff0c;引领硬度测试新纪元 在当今医药领域&#xff0c;软胶囊作为一种广泛应用的药品剂型&#xff0c;其品质的稳定性和安全性直接关系到患者的健康。而在确保软胶囊品质的各项指标中&#xff0c;硬度测试尤为关键。…

AIGC实战——多模态模型DALL.E 2

AIGC实战——多模态模型DALL.E 2 0. 前言1. 模型架构2. 文本编码器3. CLIP4. 先验模型4.1 自回归先验模型4.2 扩散先验模型 5. 解码器5.1 GLIDE5.2 上采样器 6. DALL.E 2 应用6.1 图像变体6.2 先验模型的重要性6.3 DALL.E 2 限制 小结系列链接 0. 前言 DALL.E 2 是 OpenAI 设计…

领域驱动设计架构演进

领域驱动设计由于其强调对领域的深入理解和关注业务价值,其架构演进依赖于领域的变化和特定领域中的技术实践。 初始阶段 一个单体架构,所有的功能都集成在一个应用程序中,领域模型可能还不完全清晰,甚至并未形成。这个阶段主要是为了验证产品的可行性,快速迭代并尽快推…

有没有国内个人可用的GPT平替?推荐5个AI工具

随着AI技术的快速发展&#xff0c;AI写作正成为创作的新风口。但是面对GPT-4这样的国际巨头&#xff0c;国内很多小伙伴往往望而却步&#xff0c;究其原因&#xff0c;就是它的使用门槛高&#xff0c;还有成本的考量。 不过&#xff0c;随着GPT技术的火热&#xff0c;国内也涌…

2023年度合肥市优秀知识产权服务机构评选申报主体条件、材料和时间程序须知

一、申报主体 在合肥市行政区域内登记注册的知识产权服务机构&#xff0c; 二、申报条件 (一)在合肥市登记注册时间满1年&#xff0c;营业执照经营范围包含知识产权代理、服务等相关内容; (二)在全国专利代理信息公示平台进行备案; (三)有稳定的专业服务人才队伍和服务对象…

【SSL证书】免费单域名SSL证书怎么申请

1、访问证书颁发机构&#xff08;CA&#xff09;&#xff1a;比如JoySSL、ZeroSSL、各大云平台等&#xff0c;这些机构提供免费的SSL证书申请&#xff0c;并支持单域名证书。在网站上注册账号&#xff0c;并根据提示选择单域名证书进行申请。 &#xff01;&#xff01;&#xf…

工厂模式应用实例

引言 设计模式概念 设计模式&#xff08;Design Pattern&#xff09;的官方概念可以表述为&#xff1a;在软件设计中&#xff0c;设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它是针对特定问题或特定场景的解决方案&#xff0c;是一种经过…

使用STM32CubeMX进行STM32F4的定时器配置

目录 1. Pin脚2. 配置2.1 时钟配置2.2 RCC配置2.3 Timer配置2.4 输出文件 3. 代码3.1 使能定时器3.2 回调函数 1. Pin脚 2. 配置 2.1 时钟配置 timer3时钟挂载在APB1上&#xff1a; 时钟配置如下&#xff1a; 外部使用8MHz晶振 开启内部16MHz晶振 使用锁相环 开启最高100MHz。…

揭秘依赖注入:软件开发人员的基本指南

Dependency injection (DI) is a design pattern and programming technique to manage dependencies between different components. 依赖注入&#xff08;DI&#xff09;是一种用于管理不同组件之间依赖关系的设计模式和编程技术。 In DI, the dependencies of a class or ot…

机台统一管理有多困难?但现在出现可行的解决方案了

机台的统一管理对于企业来说对提高生产效率、降低成本、优化资源配置以及保障生产安全等方面都具有至关重要的作用。但企业机台统一管理却存在实际的困难&#xff0c;主要体现在&#xff1a; 多样化的设备和运作模式&#xff1a;由于机台设备可能来自不同的厂商&#xff0c;其规…

如何描述自己的算法?

算法的表达 好的&#xff0c;让我们来一起探讨如何向别人介绍我们的算法。说话很简单&#xff0c;但要把话说清楚&#xff0c;说明白就不那么容易了。同样的道理&#xff0c;能够通俗易懂&#xff0c;直观清晰和严谨地描述一个算法&#xff0c;也是一项具有挑战性的任务。接下…

106短信群发平台在金融和法务行业的应用分析

一、金融行业应用 1.客户通知与提醒&#xff1a;银行、证券、保险等金融机构经常需要向客户发送各类通知和提醒&#xff0c;如账户余额变动、交易确认、扣费通知、理财产品到期提醒等。106短信群发平台可以快速、准确地将这些信息发送到客户的手机上&#xff0c;确保客户及时获…

.NET邮箱API发送邮件的步骤?怎么配置API?

.NET邮箱API发送邮件需要注意哪些&#xff1f;如何使用API发信&#xff1f; 在.NET环境中&#xff0c;使用邮箱API发送邮件是一个常见的需求。无论是企业级的邮件通知&#xff0c;还是个人项目中的邮件验证&#xff0c;都少不了.NET邮箱API的帮助。下面&#xff0c;AokSend将详…

我的创作纪念日(365天)

时间如白驹过隙&#xff0c;转眼间&#xff0c;我已经在技术写作这条路上走过了365个日夜。回望2023年5月9日&#xff0c;我敲下了第1篇技术博客的标题——《什么是代理IP&#xff1f;代理IP有什么用途》。那一天&#xff0c;平凡而又不平凡&#xff0c;因为我决定将自己的知识…

政安晨【零基础玩转各类开源AI项目】:基于Ubuntu系统本地部署使用GPT-SoVITS进行语音克隆与TTS语音生成

目录 介绍 什么是TTS 安装Miniconda 框架功能 测试通过的环境 开始 1. 安装好miniconda 2. 进入下载的GPT-SoVITS目录 3. 创建虚拟环境并执行脚本 4. 执行过程中可能会出错 5. 下载预训练模型 6. 训练过程中可能会报错 7. 使用过程中可能出错 8.以下是使用全过程…

信息安全管理体系介绍(含全套体系文档)

信息安全管理体系英文全称Information Security Management System&#xff0c;简称为ISMS&#xff0c;是1998年左右从英国发展起来的信息安全领域中的一个全新概念&#xff0c;是管理体系&#xff08;Management System&#xff0c;MS&#xff09;思想和方法在信息安全领域的应…