pipeline方法关系抽取--课堂笔记

Pipeline方法课堂笔记

一、Pipeline方法原理

pipeline方法是指在实体识别已经完成的基础上再进行实体之间关系的抽取. 

pipeline方法流程:

先对输入的句子进行实体抽取,将识别出的实体分别组合;然后再进行关系分类.
注意:这两个子过程是前后串联的,完全分离.

pipeline方法的优缺点:

优点:
- 易于实现,实体模型和关系模型使用独立的数据集,不需要同时标注实体和关系的数据集.
- 两者相互独立,若关系抽取模型没训练好不会影响到实体抽取.
缺点:- 关系和实体两者是紧密相连的,互相之间的联系没有捕捉到.
- 容易造成误差积累、实体冗余、交互缺失.

二、BiLSTM+Attention的模型原理

BiLSTM+Attention算法思想

BiLSTM+Attention模型最初由Zhou等人在2016年的论文《Attention-Based Bidirectional Long Short-Term Memory Networks for Relation Classification》中提出. 
该模型结合了双向长短时记忆网络 (Bidirectional LSTM) 和注意力机制 (Attention) ,用于处理输入序列并提取关系信息. 该模型并被应用于关系分类任务. 

BiLSTM+Attention模型架构:
在这里插入图片描述


  • 基于上图模型架构所示: BiLSTM+Attention模型整体分为五个部分:

    • 输入层 (Input Layer) : 输入的是句子,可以是字符序列也可以是单词序列,或者两者相结合. 此外,对于句子中的两个实体,分别计算各个字符相对于实体的位置. 比如有如下样本:
    文本描述: “在《逃学威龙》这部电影中周星驰和吴孟达联合出演”
    在这个样本中,实体1为周星驰,实体2为吴孟达. 关系为合作关系. 对于第一个字符“在”字来说,其相对于实体1的距离为: “在”字在字符序列中的索引-实体1在字符序列中的索引. 相对于实体2的距离为: “在”字在字符序列中的索引-实体2在字符序列中的索引. 
    因此,模型的输入为子序列+字符的相对位置编码
    
    • 词嵌入层 (Embedding Layer) : 将每个单词映射到一个高维向量表示,包括: 字符或词嵌入以及相对位置编码的嵌入,可以使用预训练的词向量或从头开始训练.

    • 双向LSTM层 (BiLSTM Layer) : LSTM是一种递归神经网络,它可以对序列数据进行建模,用于从句子中提取特征. BiLSTM是一种双向LSTM,它能够同时捕捉上下文信息,包括前向和后向信息,因此在关系抽取任务中得到了广泛应用.

    • 注意力机制层 (Attention Layer) : 注意力机制可以让模型集中注意力于关键词或片段,有助于提高模型的性能. 这里注意力机制被用来确定每个句子中的单词对于关系分类的重要性. 具体来说,对于输入句子中的每个单词,注意力机制会为其分配一个权重,表示该单词对于关系分类的重要程度. 这些权重将被用于加权输入句子中每个单词的表示,以计算关系分类的输出. 本次注意力机制的实现是采用的基于注意力权重的加权平均池化方式.

      • 具体实现方式如下:

        • 第一步: 将 BiLSTM 网络的输出 HHH 经过一个 tanhtanhtanh 激活函数,得到一个矩阵MMM

        M=tanh(H) M = tanh(H) M=tanh(H)

        • 第二步: 将 MMM 作为输入,通过权重向量 wTw^TwT 和一个 softmax 函数,计算每个单词对于关系分类的重要程度,得到的结果是一个权重向量 ααα .

        α=softmax(wT∗M) α = softmax(w^T*M) α=softmax(wTM)

        • 第三步: 将BiLSTM网络的输出 HHH 和注意力权重 ααα 相乘得到一个加权和 rrr

        r=H∗αT r = H * α^T r=HαT

        • 第四步: 将第三步得到的结果 rrr ,经过一个 tanhtanhtanh 激活函数,得到最终加权后的输入句子中每个单词的表示,以方便后续计算关系分类的输出

      h∗=tanh(r) h^* = tanh(r) h=tanh(r)

    • 输出层 (Output Layer) : 根据任务的不同,输出层可以是分类层或回归层. 在关系抽取任务中,输出层通常是一个分类层,用于预测两个实体之间的关系类型.

三、基于BiLSTM+Attention模型的数据预处理

关系抽取项目数据预处理

  • 本项目中对数据部分的预处理步骤如下:
    • 第一步: 查看项目数据集
    • 第二步: 编写Config类项目文件配置代码
    • 第三步: 编写数据处理相关函数
    • 第四步: 构建DataSet类与dataloader函数

第一步: 查看项目数据集
  • 本次项目数据原始来源为公开的千言数据集https://www.luge.ai/#/,使用开源数据的好处,我们无需标注直接使用即可,本次项目的主要需要大家掌握实现关系抽取的思想。

  • 项目的数据集包括3个文件:

  • 第一个关系类型文件: relation2id.txt


导演 0
歌手 1
作曲 2
作词 3
主演 4

  • relation2id.txt中包含5个类别标签, 文件共分为两列,第一列是类别名称,第二列为类别序号,中间空格符号隔开
  • 第二个训练数据集:train.txt

今晚会在哪里醒来 黄家强 歌手 《今晚会在哪里醒来》是黄家强的一首粤语歌曲,由何启弘作词,黄家强作曲编曲并演唱,收录于2007年08月01日发行的专辑《她他》中似水流年 许晓杰 作曲 似水流年,由著名作词家闫肃作词,著名音乐人许晓杰作曲,张烨演唱交涉人 朝日电视台 出品公司 《交涉人》是日本朝日电视台制作并播出的8集悬疑推理电视剧生活启示录 闫妮 主演 05闫妮接到《生活启示录》之后,就向王丽萍推荐了胡歌北京北京 汪峰 歌手 ”汪峰我印象最深刻的是汪峰的《北京北京》蚀骨唱成烛骨千岁情人 王菲 主演 难怪春晚把那英秒成不一样很多人都不知道 王菲演 的这部《千岁情人》,是1993年的一部穿越剧
天使的咒语 魏雪漫 歌手 魏雪漫专辑《天使的咒语》的同名主打歌曲与青春有关的日子 白百何 主演 白百何的处女座是《与青春有关的日子》,合作的演员是佟大为、陈羽凡高高至上 秋言 作词 专辑曲目序号  曲目作词作曲编曲1高高至上秋言秋言彭飞2高高至上(伴奏)  秋言秋言彭飞

train.txt 中包含18267行样本, 每行分为4列元素,元素中间用空格隔开,第一列元素为实体1、第二列元素为实体2、第三列元素为关系类型、第四列元素是原始文本


  • 第三个测试数据集:test.txt

三生三世十里桃花 安悦溪 主演 当《三生三世》4位女星换上现代装: 第四,安悦溪在《三生三世十里桃花》中饰演少辛,安悦溪穿上现代装十分亮眼,气质清新脱俗失恋33天 白百何 主演 2011年,担任爱情片《失恋33天》的编剧,该片改编自鲍鲸鲸的同名小说,由文章、白百何共同主演6爱人们的故事 裴勇俊 主演 《爱人们的故事》是全基尚导演,裴勇俊、李英爱、李慧英等主演的18集爱情类型的电视剧为你叫好 吕薇 歌手 基本资料  歌曲名称: 为你叫好1歌手: 吕薇  所属专辑: 《但愿人长久》歌词  歌手: 吕薇  词: 清风 曲: 刘青卡拉是条狗 路学长 导演 个人生活李佳璇和导演路学长因拍摄《卡拉是条狗》而相识,2003年两人结婚上帝创造女人 简-路易斯·特林提格南特 主演 《上帝创造女人》是罗杰·瓦迪姆执导的粉红浪漫爱情影片,由碧姬·芭铎和简-路易斯·特林提格南特参加演出上帝创造女人 碧姬·芭铎 主演 《上帝创造女人》是罗杰·瓦迪姆执导的粉红浪漫爱情影片,由碧姬·芭铎和简-路易斯·特林提格南特参加演出

test.txt中包含5873行样本, 每行分为4列元素,元素中间用空格隔开,第一列元素为实体1、第二列元素为实体2、第三列元素为关系类型、第四列元素是原始文本



第二步:编写Config类项目文件配置代码
  • config.py

  • config文件目的: 配置项目常用变量,一般这些变量属于不经常改变的,比如: 训练文件路径、模型训练次数、模型超参数等等
# coding:utf-8
import torchclass Config(object):def __init__(self):self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')self.train_data_path = "训练文件绝对路径名称"self.test_data_path = "测试文件绝对路径名称"	 		          	self.rel_data_path = "关系类型文件绝对路径名称" self.embedding_dim = 128self.pos_dim = 32self.hidden_dim = 200self.epochs = 50self.batch_size = 32self.max_len = 70self.learning_rate = 1e-3

第三步: 编写数据处理相关函数
  • 数据处理相关函数process.py

  • 首选导入必备的工具包
# coding:utf-8
from config import *
from itertools import chain
from collections import Counterconf = Config()
# 获取关系类型字典
relation2id = {}
with open(conf.rel_data_path, 'r', encoding='utf-8')as fr:for line in fr.readlines():word, id = line.rstrip().split(' ')if word not in relation2id:relation2id[word] = id

  • 构建第一个数据处理相关函数sent_padding, 位于process.py中的独立函数.
def sent_padding(words, word2id):"""把句子 words 转为 id 形式,并自动补全为 max_len 长度。"""ids = []for word in words:if word in word2id:ids.append(word2id[word])else:ids.append(word2id['UNKNOW'])if len(ids) >= conf.max_len:return ids[:conf.max_len]ids.extend([word2id['BLANK']]*(conf.max_len-len(ids)))return ids

  • 构建第二个数据处理相关函数pos, 位于process.py中的独立函数.
def pos(num):'''将实体位置信息进行转换,因为pos_embedding不能出现负数'''if num < -70:return 0if num >= -70 and num <= 70:return num+70if num > 70:return 142

  • 构建第三个数据处理相关函数position_padding, 位于process.py中的独立函数.
def position_padding(pos_ids):'''"""把 pos位置信息 转为 id 形式,并自动补全为 max_len 长度。"""'''pos_ids = [pos(id) for id in pos_ids]if len(pos_ids) >= conf.max_len:return pos_ids[:conf.max_len]pos_ids.extend([142]*(conf.max_len - len(pos_ids)))return pos_ids

  • 构建第四个数据处理相关函数get_train_data, 位于process.py中的独立函数.
def get_txt_data(data_path):'''编码训练、测试数据集格式'''datas = []labels = []positionE1 = []positionE2 = []entities = []count_dict = {key: 0 for key, value in relation2id.items()}with open(data_path, 'r', encoding='utf-8')as tfr:for line in tfr.readlines():line = line.rstrip().split(' ', maxsplit=3)if line[2] not in count_dict:continueif count_dict[line[2]] > 2000:continueelse:entities.append([line[0], line[1]])sentence = []index1 = line[3].index(line[0])position1 = []index2 = line[3].index(line[1])position2 = []assert len(line) == 4for i, word in enumerate(line[3]):sentence.append(word)position1.append(i-index1)position2.append(i-index2)datas.append(sentence)labels.append(relation2id[line[2]])positionE1.append(position1)positionE2.append(position2)count_dict[line[2]] += 1return datas, labels, positionE1, positionE2, entities

  • 构建第五个数据处理相关函数get_word_id, 位于 process.py 中的独立函数.
def get_word_id(data_path):'''文本数字化表示处理,得到word2id, id2word'''datas, labels, positionE1, positionE2, entities = get_txt_data(data_path)data_list = list(set(chain(*datas)))word2id = {word: id for id, word in enumerate(data_list)}id2word = {id: word for id, word in enumerate(data_list)}word2id["BLANK"] = len(word2id)word2id["UNKNOW"] = len(word2id)id2word[len(id2word) + 1] = "BLANK"id2word[len(id2word) + 1] = "UNKNOW"return word2id, id2word

第四步: 构建DataSet类以及Dataloader函数
  • 代码路径为: data_loader.py

  • 首先导入相应的工具包
# coding:utf-8
import os
from torch.utils.data import DataLoader, Dataset
from utils.process import *
import torch

  • 构建第一个数据处理相关类MyDataset, 位于data_loader.py中的独立类.
class MyDataset(Dataset):def __init__(self, data_path):self.data = get_txt_data(data_path)def __len__(self):return len(self.data[0])def __getitem__(self, index):sequence = self.data[0][index]label = int(self.data[1][index])positionE1 = self.data[2][index]positionE2 = self.data[3][index]entites = self.data[4][index]return sequence, label, positionE1, positionE2, entites

  • 构建第二个数据处理相关函数collate_fn, 位于data_loader.py中的独立函数.

def collate_fn(datas):sequences = [data[0] for data in datas]labels = [data[1] for data in datas]positionE1 = [data[2] for data in datas]positionE2 = [data[3] for data in datas]entities = [data[4] for data in datas]word2id, id2word = get_word_id(conf.train_data_path)sequences_ids = []for words in sequences:ids = sent_padding(words, word2id)sequences_ids.append(ids)positionE1_ids = []positionE2_ids = []for pos_ids in positionE1:pos1_ids = position_padding(pos_ids)positionE1_ids.append(pos1_ids)for pos_ids in positionE2:pos2_ids = position_padding(pos_ids)positionE2_ids.append(pos2_ids)datas_tensor = torch.tensor(sequences_ids, dtype=torch.long, device=conf.device)positionE1_tensor = torch.tensor(positionE1_ids, dtype=torch.long, device=conf.device)positionE2_tensor = torch.tensor(positionE2_ids, dtype=torch.long, device=conf.device)labels_tensor = torch.tensor(labels, dtype=torch.long, device=conf.device)return datas_tensor, positionE1_tensor, positionE2_tensor, labels_tensor, sequences, labels, entities

  • 构建第三个数据处理相关函数get_loader_data, 位于data_loader.py中的独立函数.

def get_loader_data():train_data = MyDataset(conf.train_data_path)train_dataloader = DataLoader(dataset=train_data,batch_size=conf.batch_size,shuffle=False,collate_fn=collate_fn,drop_last=True)test_data = MyDataset(conf.test_data_path)test_dataloader = DataLoader(dataset=test_data,batch_size=conf.batch_size,shuffle=False,collate_fn=collate_fn,drop_last=True)return train_dataloader, test_dataloader

四、基于BiLSTM+Attention模型实现训练

BiLSTM+Attention模型搭建

  • 本项目中BiLSTN+Attention模型搭建的步骤如下:
    • 第一步: 编写模型类的代码
    • 第二步: 编写训练函数
    • 第三步: 编写使用模型预测代码的实现.

第一步: 编写模型类的代码
  • 构建BiLSTM_ATT模型类
  • 代码路径: bilstm_atten.py
# coding:utf8
import torch
import torch.nn as nn
import torch.nn.functional as Fclass BiLSTM_ATT(nn.Module):def __init__(self, conf, vocab_size, pos_size, tag_size):super(BiLSTM_ATT, self).__init__()self.batch = conf.batch_sizeself.device = conf.deviceself.vocab_size = vocab_sizeself.embedding_dim = conf.embedding_dimself.hidden_dim = conf.hidden_dimself.pos_size = pos_sizeself.pos_dim = conf.pos_dimself.tag_size = tag_sizeself.word_embeds = nn.Embedding(self.vocab_size,self.embedding_dim)self.pos1_embeds = nn.Embedding(self.pos_size,self.pos_dim)self.pos2_embeds = nn.Embedding(self.pos_size,self.pos_dim)self.lstm = nn.LSTM(input_size=self.embedding_dim + self.pos_dim * 2,hidden_size=self.hidden_dim // 2,num_layers=1,bidirectional=True)self.linear = nn.Linear(self.hidden_dim,self.tag_size)self.dropout_emb = nn.Dropout(p=0.2)self.dropout_lstm = nn.Dropout(p=0.2)self.dropout_att = nn.Dropout(p=0.2)self.att_weight = nn.Parameter(torch.randn(self.batch,1,self.hidden_dim).to(self.device))def init_hidden_lstm(self):return (torch.randn(2, self.batch, self.hidden_dim // 2).to(self.device),torch.randn(2, self.batch, self.hidden_dim // 2).to(self.device))def attention(self, H):M = F.tanh(H)a = F.softmax(torch.bmm(self.att_weight, M), dim=-1)a = torch.transpose(a, 1, 2)return torch.bmm(H, a)def forward(self, sentence, pos1, pos2):init_hidden = self.init_hidden_lstm()embeds = torch.cat((self.word_embeds(sentence), self.pos1_embeds(pos1), self.pos2_embeds(pos2)), 2)embeds = self.dropout_emb(embeds)embeds = torch.transpose(embeds, 0, 1)lstm_out, lstm_hidden = self.lstm(embeds, init_hidden)lstm_out = lstm_out.permute(1, 2, 0)lstm_out = self.dropout_lstm(lstm_out)att_out = F.tanh(self.attention(lstm_out))att_out = self.dropout_att(att_out).squeeze()result = self.linear(att_out)return result

第二步: 编写训练函数
  • 实现训练函数train.py

  • 代码位置: train.py

# coding:utf-8
from model.bilstm_atten import *
from utils.data_loader import *
from utils.process import *
import torch
import torch.nn as nn
import torch.optim as optim
import time
from tqdm import tqdmdef train(conf, vocab_size, pos_size, tag_size):# 加载数据集train_iter, test_iter = get_loader_data()print('训练数据集长度', len(train_iter))# 实例化Bilstm+attention模型ba_model = BiLSTM_ATT(conf, vocab_size, pos_size, tag_size).to(conf.device)print(ba_model)# 实例化优化器optimizer = optim.Adam(ba_model.parameters(), lr=conf.learning_rate)# 实例化损失函数criterion = nn.CrossEntropyLoss()# 实现模型训练ba_model.train()# 定义训练模型参数start_time = time.time()train_loss = 0  # 已经训练样本的损失train_acc = 0  # 已经训练样本的准确率total_iter_num = 0  # 训练迭代次数total_sample = 0 # 已经训练的样本数# 开始模型的训练for epoch in range(conf.epochs):for sentence, pos1, pos2, label, _, _, _ in tqdm(train_iter):# 将数据输入模型output = ba_model(sentence, pos1, pos2)# 计算损失loss = criterion(output, label)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 梯度更新optimizer.step()# 计算总损失total_iter_num += 1train_loss += loss.item()# 计算总准确率train_acc = train_acc + sum(torch.argmax(output, dim=1) == label).item()total_sample = total_sample + label.size()[0]# print(f'total_sample--->{total_sample}')# 每25次训练,打印日志if total_iter_num % 25 == 0:tmploss = train_loss / total_iter_numtmpacc = train_acc / total_sampleend_time = time.time()print('轮次: %d, 损失:%.6f, 时间:%d, 准确率:%.3f' % (epoch+1, tmploss, end_time-start_time, tmpacc))if epoch % 10 == 0:torch.save(ba_model.state_dict(), './save_model/20230228_new_model_%d.bin' % epoch)if __name__ == '__main__':word2id, id2word = get_word_id(conf.train_data_path)vocab_size = len(word2id)print(vocab_size)pos_size = 143tag_size = len(relation2id)train(conf, vocab_size, pos_size, tag_size)

  • 模型训练结果展示:

结论: BiLSTM+Attention模型在训练集上的最终表现是ACC:80%

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

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

相关文章

linux系统离线环境安装clickhouse客户端

1、下载离线安装包&#xff1a; 方式1&#xff1a;网站直接下载 链接&#xff1a;https://packagecloud.io/altinity/clickhouse 注意要下载同一版本的四个包 方式2&#xff1a;夸克网盘分享 链接&#xff1a;https://pan.quark.cn/s/7e77e6a1bc5f 2、将本地下载的安装包上传…

GPT-5的诞生之痛:AI帝国的现实危机

目录 前言 一、“俄里翁”的陨落&#xff1a;一场梦碎的代际飞跃 二、扎克伯格的“抄家式”突袭 三、天才的诅咒&#xff1a;当AI聪明到无法与我们对话 四、烧钱的无底洞与微软的影子 结语&#xff1a;AI帝国的黄昏&#xff0c;还是黎明前的黑暗&#xff1f; &#x1f3a…

探索设计模式的宝库:Java-Design-Patterns

在软件开发领域&#xff0c;设计模式是解决常见问题的经典方案&#xff0c;它们如同建筑师的蓝图&#xff0c;为开发者提供了经过验证的最佳实践。今天我要向大家介绍一个GitHub上的明星项目——java-design-patterns&#xff0c;这是一个全面、实用且持续更新的设计模式宝藏项…

JavaScript中的作用域、闭包、定时器 由浅入深

1. JavaScript中的作用域是什么&#xff1f; 作用域&#xff08;Scope&#xff09;是程序中定义变量的区域&#xff0c;它决定了变量的可访问性&#xff08;可见性&#xff09;。在JavaScript中&#xff0c;作用域主要分为三种&#xff1a;全局作用域、函数作用域和块级作用域&…

仓库管理系统-11-前端之头部区域Header的用户登录和退出功能

文章目录 1 登录功能 1.1 登录页面(Login.vue) 1.1.1 页面布局 1.1.2 初始化数据 1.1.3 confirm方法 1.1.4 UserController.java(登录接口) 1.1.5 Login.vue 1.2 登录页面的路由 1.2.1 创建路由文件(router/index.js) 1.2.2 注册路由器(main.js) 1.2.3 路由视图(App.vue) 2 退出…

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…

飞算科技:以自主创新引领数字科技浪潮,飞算JavaAI赋能产业智能化升级

技术创新已成为企业突破瓶颈、实现跨越式发展的核心驱动力。作为国家级高新技术企业&#xff0c;飞算数智科技&#xff08;深圳&#xff09;有限公司&#xff08;简称“飞算科技”&#xff09;凭借其深厚的互联网科技、大数据与人工智能技术积淀&#xff0c;以及在民生产业、中…

51单片机按键复位电路电压随着电容放电升高的分析

一、引言在单片机系统中&#xff0c;复位电路是一个至关重要的组成部分&#xff0c;它确保了单片机在特定情况下能够恢复到初始状态&#xff0c;从而避免程序运行错误或系统崩溃。对于51单片机而言&#xff0c;按键复位电路是一种常用的复位方式&#xff0c;它通过手动按下复位…

JVM学习日记(十五)Day15——性能监控与调优(二)

好了我们这一篇继续来说命令行监控指令&#xff0c;上一篇说了4个比较重要的指令&#xff0c;其中用的比较多的也就是jstat和jmap了。 jhat&#xff1a;堆转储分析工具 他是JDK自带的分析工具&#xff0c;分析我们上一篇说的jmap转存的内存快照&#xff0c;​​内置了一个微型…

Docker国内镜像列表

Docker 镜像源列表&#xff08;8月3日更新-长期&免费&#xff09;_docker国内镜像源-CSDN博客

Orange AI 管理平台单体版安装教程(Docker Compose 部署)

Orange AI 管理平台单体版安装教程&#xff08;Docker Compose 部署&#xff09; 本文介绍如何通过 Docker Compose 快速安装 Orange AI 管理平台单体版&#xff0c;适用于本地开发和测试环境。步骤简单&#xff0c;适合初学者和有一定运维经验的用户。 一、环境准备 已安装 …

PHP的魔术方法

一、介绍 ‌PHP魔术方法是以双下划线__开头的一组特殊方法&#xff0c;用于在对象生命周期、属性访问、方法调用等场景中实现自动化操作。‌简化面向对象编程。 二、17个现有的魔术方法 &#xff08;一&#xff09;、对象生命周期相关 1、__construct() 类的构造函数方法&a…

vue2实现类似chatgpt和deepseek的AI对话流打字机效果,实现多模型同时对话

实现多模型同时对话功能特点&#xff1a;1、抽离对话框成单独组件ChatBox.vue&#xff0c;在新增模型对比窗口时可重复利用2、通过sse与后台实时数据流&#xff0c;通过定时器实现打字效果3、适应深度思考内容输出&#xff0c;可点击展开与闭合4、可配置模型参数&#xff0c;本…

电脑上不了网怎么办?【图文详解】wifi有网络但是电脑连不上网?网络设置

一、问题背景 你有没有遇到过这种情况&#xff1a;电脑右下角的网络图标明明显示连接正常&#xff0c;可打开浏览器就是加载不出网页&#xff0c;聊天软件也刷不出新消息&#xff1f; 这种 "网络已连接但无法上网" 的问题特别常见&#xff0c;既不是没插网线&#xf…

思途Spring学习 0804

SpringBoot 核心概念与开发实践SpringBoot 是一个基于 Spring 框架的快速开发脚手架&#xff0c;通过约定大于配置的原则简化了传统 Spring 应用的初始化配置。其核心目标是整合 Spring 生态&#xff08;如 SSM&#xff09;并支持微服务架构开发。控制反转&#xff08;IoC&…

Hutool工具类:Java开发必备神器

Hutool工具类使用说明Hutool是一个Java工具类库&#xff0c;提供了丰富的功能模块&#xff0c;包括字符串处理、日期时间操作、IO流、加密解密、HTTP客户端等。以下是一些常用模块的具体使用方法。字符串工具&#xff08;StrUtil&#xff09;字符串处理是开发中的常见需求&…

Node.js中Buffer的用法

// Buffer 与字符串的转换示例 // Buffer 是 Node.js 中用于处理二进制数据的类&#xff0c;字符串与 Buffer 之间的转换是常见操作// 1. 从字节数组创建 Buffer 并转换为字符串 // Buffer.from(array) 接收一个字节数值数组&#xff0c;创建对应的 Buffer let buf_4 Buffer.f…

【Java 基础】Java 源代码加密工具有哪些?

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区:个人社区 💞 个人主页:个人主页 🙉 专栏地址: ✅ Java 中级 🙉八股文专题:剑指大厂,手撕 J…

es的histogram直方图聚合和terms分组聚合

你提到的这两个 Elasticsearch aggs 聚合语句&#xff1a;第一种&#xff1a;histogram 直方图聚合 "aggs": {"DayDiagram": {"histogram": {"field": "${FiledName}","interval": ${TimeInterval},"extende…

基于Java的AI/机器学习库(Smile、Weka、DeepLearning4J)的实用

基于Java和AI技术处理动漫视频 以下是一些基于Java和AI技术处理动漫视频(如《亚久斗》)的实用案例和实现方法,涵盖视频分析、风格转换、角色识别等方向。每个案例均提供技术思路和关键代码片段。 视频关键帧提取 使用OpenCV提取动漫视频中的关键帧,保存为图片供后续分析…