【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用

系列文章目录

【时间序列篇】基于LSTM的序列分类-Pytorch实现 part1 案例复现
【时间序列篇】基于LSTM的序列分类-Pytorch实现 part2 自有数据集构建
【时间序列篇】基于LSTM的序列分类-Pytorch实现 part3 化为己用


在一个人体姿态估计的任务中,需要用深度学习模型来进行序列分类。
化为己用,实现成功。

文章目录

  • 系列文章目录
  • 前言
  • 一、模型训练
    • 1 导入库和自用函数
    • 2 导入数据集
    • 3 设备部署
    • 4 网络模型
    • 5 训练过程
    • 6 运行结果
    • 7 完整代码
    • SequenceClassifier
  • 二、模型预测
    • 1 完整代码
    • 2 运行结果
  • 三、模型评估
    • 1 完整代码
    • 2 运行结果
  • 总结


前言

结合了part1 和 part2的文章,处理现有序列分类任务。

基于LSTM的序列分类-Pytorch实现 这个部分先告一段落。
part3 主要是优化后的代码实现,包括训练,预测,模型评估。


一、模型训练

这一部分就是对part1文章中代码的优化和运行结果。每一节都是一整个代码的一部分,最后放完整代码。

1 导入库和自用函数

import os
import copy
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from tqdm import tqdmdef calculate_accuracy(y_pred, y_true):_, predicted_labels = torch.max(y_pred, 1)correct = (predicted_labels == y_true).float()accuracy = correct.sum() / len(correct)return accuracy

2 导入数据集

'''
/****************************************************/导入数据集
/****************************************************/
'''
# ----------------------------------------------------#
#   路径指定
# ----------------------------------------------------#
ROOT_PATH = "DATA/RT_Position_dataset"dataset_path = os.path.join(ROOT_PATH, "dataset")
target_path = os.path.join(ROOT_PATH, "groups/Movement4_target.csv")
groups_path = os.path.join(ROOT_PATH, "groups/Movement4_DatasetGroup.csv")checkpoint_pth = "best_model.pth"  # 模型参数
seq_len = 16  # 序列长度
# ----------------------------------------------------#
#    sequences列表读取所有的样本
# ----------------------------------------------------#
path = os.path.join(dataset_path, "Movement4_")
sequences = list()
for i in range(1, 3731):  # 3731为样本数file_path = path + str(i) + '.csv'# print(file_path)df = pd.read_csv(file_path, header=0)values = df.valuessequences.append(values)# print(len(sequences))
# len_sequences = []
# for one_seq in sequences:
#     len_sequences.append(len(one_seq))
# ----------------------------------------------------#
#   数据集标签
# ----------------------------------------------------#
targets = pd.read_csv(target_path)
targets = targets.values[:, 1]
# ----------------------------------------------------#
#   数据集划分
# ----------------------------------------------------#
groups = pd.read_csv(groups_path, header=0)
groups = groups.values[:, 1]# ----------------------------------------------------#
#   Padding the sequence with the values in last row to max length
# ----------------------------------------------------#
# 函数用于填充和截断序列
def pad_truncate_sequences(sequences, max_len, dim=4, truncating='post', padding='post'):# 初始化一个空的numpy数组,用于存储填充后的序列padded_sequences = np.zeros((len(sequences), max_len, dim))for i, one_seq in enumerate(sequences):if len(one_seq) > max_len:  # 截断if truncating == 'pre':padded_sequences[i] = one_seq[-max_len:]else:padded_sequences[i] = one_seq[:max_len]else:  # 填充padding_len = max_len - len(one_seq)to_concat = np.repeat(one_seq[-1], padding_len).reshape(dim, padding_len).transpose()if padding == 'pre':padded_sequences[i] = np.concatenate([to_concat, one_seq])else:padded_sequences[i] = np.concatenate([one_seq, to_concat])return padded_sequences# ----------------------------------------------------#
#   设置序列长度
# ----------------------------------------------------#
# 使用自定义函数进行填充和截断
final_seq = pad_truncate_sequences(sequences, max_len=seq_len, dim=4, truncating='post', padding='post')# 设置标签从 1~6 换为 0~5
targets = np.array(targets)
final_targets = targets - 1# ----------------------------------------------------#
#   数据集划分
# ----------------------------------------------------## 将numpy数组转换为PyTorch张量
final_seq = torch.tensor(final_seq, dtype=torch.float)# 划分样本为 训练集,验证集
train = [final_seq[i] for i in range(len(groups)) if groups[i] == 1]
validation = [final_seq[i] for i in range(len(groups)) if groups[i] == 2]
# 标签同理
train_target = [final_targets[i] for i in range(len(groups)) if groups[i] == 1]
validation_target = [final_targets[i] for i in range(len(groups)) if groups[i] == 2]# 转换为PyTorch张量
train = torch.stack(train)
train_target = torch.tensor(train_target).long()validation = torch.stack(validation)
validation_target = torch.tensor(validation_target).long()

3 设备部署

'''
/****************************************************/device
/****************************************************/
'''def device_on():device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(f"Using {device} device")return device# ----------------------------------------------------#
# device
# ----------------------------------------------------#
device = device_on()

4 网络模型

'''
/****************************************************/网络模型
/****************************************************/
'''# ----------------------------------------------------#
#   创建模型
# ----------------------------------------------------#
class TimeSeriesClassifier(nn.Module):def __init__(self, n_features, hidden_dim=256, output_size=1):super().__init__()self.lstm = nn.LSTM(input_size=n_features, hidden_size=hidden_dim, batch_first=True)self.fc = nn.Linear(hidden_dim, output_size)  # output_size classesdef forward(self, x):x, _ = self.lstm(x)  # LSTM层x = x[:, -1, :]  # 只取LSTM输出中的最后一个时间步x = self.fc(x)  # 通过一个全连接层return x# ----------------------------------------------------#
#   模型实例化
# ----------------------------------------------------#
seq_len = 16  # 根据你的序列长度进行调整
n_features = 4  # 根据你的特征数量进行调整
output_size = 6
model = TimeSeriesClassifier(n_features=n_features, output_size=output_size)# # 打印模型结构
print(model)
# ----------------------------------------------------#
#   模型部署
# ----------------------------------------------------#
model.to(device)

5 训练过程

'''
/****************************************************/训练过程
/****************************************************/
'''# 设置训练参数
epochs = 100  # 训练轮数,根据需要进行调整
batch_size = 4  # 批大小,根据你的硬件调整# DataLoader 加载数据集
train_dataset = torch.utils.data.TensorDataset(train, train_target)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)validation_dataset = torch.utils.data.TensorDataset(validation, validation_target)
validation_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=batch_size, shuffle=True)# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
criterion = criterion.to(device)# 学习率和优化策略
learning_rate = 1e-3
optimizer = optim.Adam(params=model.parameters(), lr=learning_rate, weight_decay=5e-4)
lr_scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.5)  # 设置学习率下降策略# ----------------------------------------------------#
#   训练
# ----------------------------------------------------#
best_acc = 0.0
for epoch in range(epochs):model.train()  # 将模型设置为训练模式train_epoch_loss = []train_epoch_accuracy = []pbar = tqdm(train_loader, total=len(train_loader))for index, (inputs, labels) in enumerate(pbar, start=1):# 获取输入数据和目标,并将它们转移到GPU(如果可用)inputs = inputs.to(device)labels = labels.to(device)# 清零梯度optimizer.zero_grad()# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()train_epoch_loss.append(loss.item())accuracy = calculate_accuracy(outputs, labels)train_epoch_accuracy.append(accuracy.item())pbar.set_description(f'Epoch [{epoch + 1}/{epochs}]')pbar.set_postfix(**{'loss': loss.item(),'accuracy': accuracy.item(),})# Validation accuracymodel.eval()valid_epoch_loss = []valid_epoch_accuracy = []pbar = tqdm(validation_loader, total=len(validation_loader))for index, (inputs, labels) in enumerate(pbar, start=1):inputs = inputs.to(device)labels = labels.to(device)outputs = model(inputs)loss = criterion(outputs, labels)valid_epoch_loss.append(loss.item())accuracy = calculate_accuracy(outputs, labels)valid_epoch_accuracy.append(accuracy.item())pbar.set_description('valid')pbar.set_postfix(**{'total_loss': loss.item(),'accuracy': accuracy.item(),})# 计算平均精度print("--------------------------------------------")train_epoch_loss = np.average(train_epoch_loss)train_epoch_accuracy = np.average(train_epoch_accuracy)print(f'Epoch {epoch + 1}, train Accuracy: {train_epoch_accuracy:.4f}')valid_epoch_loss = np.average(valid_epoch_loss)valid_epoch_accuracy = np.average(valid_epoch_accuracy)print(f'Epoch {epoch + 1}, Validation Accuracy: {valid_epoch_accuracy:.4f}')print("--------------------------------------------")if valid_epoch_accuracy > best_acc:best_acc = valid_epoch_accuracybest_model_wts = copy.deepcopy(model.state_dict())state = {'state_dict': model.state_dict(),'best_acc': best_acc,'optimizer': optimizer.state_dict(),}torch.save(state, checkpoint_pth)print('Finished Training')
print('Best val Acc: {:4f}'.format(best_acc))

6 运行结果

在这里插入图片描述在这里插入图片描述
可以看到相比起part1的实验,分类准确率更高。毕竟part1总共314个样本,自有数据集样本有3730个。

7 完整代码

SequenceClassifier

二、模型预测

输入样本,运行模型,输出预测

1 完整代码

这里直接贴完整代码。

"""
@file name:predict.py
@desc: 用于序列分类预测
"""import os
import pandas as pd
import torch
import torch.nn as nn'''
/****************************************************/输入一个数据样本
/****************************************************/
'''
# 读取CSV样本文件
csv_file = "DATA/RT_Position_dataset/dataset/Movement4_7.csv"
data = pd.read_csv(csv_file)# 将Pandas DataFrame转换为NumPy数组
data_array = data.values# 将NumPy数组转换为PyTorch张量
input = torch.tensor(data_array, dtype=torch.float).unsqueeze(0)'''
/****************************************************/device
/****************************************************/
'''def device_on():device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(f"Using {device} device")return device# ----------------------------------------------------#
# device
# ----------------------------------------------------#
device = device_on()'''
/****************************************************/网络模型
/****************************************************/
'''# ----------------------------------------------------#
#   创建模型
# ----------------------------------------------------#
class TimeSeriesClassifier(nn.Module):def __init__(self, n_features, hidden_dim=256, output_size=1):super().__init__()self.lstm = nn.LSTM(input_size=n_features, hidden_size=hidden_dim, batch_first=True)self.fc = nn.Linear(hidden_dim, output_size)  # output_size classesdef forward(self, x):x, _ = self.lstm(x)  # LSTM层x = x[:, -1, :]  # 只取LSTM输出中的最后一个时间步x = self.fc(x)  # 通过一个全连接层return x# ----------------------------------------------------#
#   模型实例化
# ----------------------------------------------------#
seq_len = 16  # 根据你的序列长度进行调整
n_features = 4  # 根据你的特征数量进行调整
output_size = 6
model = TimeSeriesClassifier(n_features=n_features, output_size=output_size)# ----------------------------------------------------#
#   模型部署
# ----------------------------------------------------#
model.to(device)# ----------------------------------------------------#
#   导入模型参数
# ----------------------------------------------------#
save_pth = "best_model.pth"
checkpoint = torch.load(save_pth)
best_acc = checkpoint['best_acc']
model.load_state_dict(checkpoint['state_dict'])
'''
/****************************************************/预测输出
/****************************************************/
'''
model.eval()  # 设置为评估模式# 假设你有一个预处理好的序列数据,shape为(batch_size, seq_len, n_features)
# 例如:一个序列,长度为16,每个时间步有4个特征
# input = torch.randn(1, 16, 4)  # 替换为你的数据with torch.no_grad():output = model(input)# 将输出转换为概率分布prediction = torch.softmax(output, dim=1)# 取得最高概率的类别作为预测结果predicted_class = torch.argmax(prediction, dim=1)
print(f"Predicted class: {predicted_class}")

2 运行结果

在这里插入图片描述


三、模型评估

1 完整代码

"""
@file name:evaluate.py
@desc: 用于模型评估
"""import os
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_scoredef calculate_accuracy(y_pred, y_true):_, predicted_labels = torch.max(y_pred, 1)correct = (predicted_labels == y_true).float()accuracy = correct.sum() / len(correct)return accuracy'''
/****************************************************/导入数据集
/****************************************************/
'''
# ----------------------------------------------------#
#   路径指定
# ----------------------------------------------------#
ROOT_PATH = "DATA/RT_Position_dataset"dataset_path = os.path.join(ROOT_PATH, "dataset")
target_path = os.path.join(ROOT_PATH, "groups/Movement4_target.csv")
groups_path = os.path.join(ROOT_PATH, "groups/Movement4_DatasetGroup.csv")checkpoint_pth = "best_model.pth"  # 模型参数
seq_len = 16  # 序列长度
# ----------------------------------------------------#
#    sequences列表读取所有的样本
# ----------------------------------------------------#
path = os.path.join(dataset_path, "Movement4_")
sequences = list()
for i in range(1, 3731):  # 3731为样本数file_path = path + str(i) + '.csv'# print(file_path)df = pd.read_csv(file_path, header=0)values = df.valuessequences.append(values)# print(len(sequences))
# len_sequences = []
# for one_seq in sequences:
#     len_sequences.append(len(one_seq))
# ----------------------------------------------------#
#   数据集标签
# ----------------------------------------------------#
targets = pd.read_csv(target_path)
targets = targets.values[:, 1]
# ----------------------------------------------------#
#   数据集划分
# ----------------------------------------------------#
groups = pd.read_csv(groups_path, header=0)
groups = groups.values[:, 1]# ----------------------------------------------------#
#   Padding the sequence with the values in last row to max length
# ----------------------------------------------------#
# 函数用于填充和截断序列
def pad_truncate_sequences(sequences, max_len, dim=4, truncating='post', padding='post'):# 初始化一个空的numpy数组,用于存储填充后的序列padded_sequences = np.zeros((len(sequences), max_len, dim))for i, one_seq in enumerate(sequences):if len(one_seq) > max_len:  # 截断if truncating == 'pre':padded_sequences[i] = one_seq[-max_len:]else:padded_sequences[i] = one_seq[:max_len]else:  # 填充padding_len = max_len - len(one_seq)to_concat = np.repeat(one_seq[-1], padding_len).reshape(dim, padding_len).transpose()if padding == 'pre':padded_sequences[i] = np.concatenate([to_concat, one_seq])else:padded_sequences[i] = np.concatenate([one_seq, to_concat])return padded_sequences# ----------------------------------------------------#
#   设置序列长度
# ----------------------------------------------------#
# 使用自定义函数进行填充和截断
final_seq = pad_truncate_sequences(sequences, max_len=seq_len, dim=4, truncating='post', padding='post')# 设置标签从 1~6 换为 0~5
targets = np.array(targets)
final_targets = targets - 1# ----------------------------------------------------#
#   数据集划分
# ----------------------------------------------------## 将numpy数组转换为PyTorch张量
final_seq = torch.tensor(final_seq, dtype=torch.float)# 划分样本为 训练集,验证集
train = [final_seq[i] for i in range(len(groups)) if groups[i] == 1]
validation = [final_seq[i] for i in range(len(groups)) if groups[i] == 2]
# 标签同理
train_target = [final_targets[i] for i in range(len(groups)) if groups[i] == 1]
validation_target = [final_targets[i] for i in range(len(groups)) if groups[i] == 2]# 转换为PyTorch张量
train = torch.stack(train)
train_target = torch.tensor(train_target).long()validation = torch.stack(validation)
validation_target = torch.tensor(validation_target).long()'''
/****************************************************/device
/****************************************************/
'''def device_on():device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(f"Using {device} device")return device# ----------------------------------------------------#
# device
# ----------------------------------------------------#
device = device_on()'''
/****************************************************/网络模型
/****************************************************/
'''# ----------------------------------------------------#
#   创建模型
# ----------------------------------------------------#
class TimeSeriesClassifier(nn.Module):def __init__(self, n_features, hidden_dim=256, output_size=1):super().__init__()self.lstm = nn.LSTM(input_size=n_features, hidden_size=hidden_dim, batch_first=True)self.fc = nn.Linear(hidden_dim, output_size)  # output_size classesdef forward(self, x):x, _ = self.lstm(x)  # LSTM层x = x[:, -1, :]  # 只取LSTM输出中的最后一个时间步x = self.fc(x)  # 通过一个全连接层return x# ----------------------------------------------------#
#   模型实例化
# ----------------------------------------------------#
seq_len = 16  # 根据你的序列长度进行调整
n_features = 4  # 根据你的特征数量进行调整
output_size = 6
model = TimeSeriesClassifier(n_features=n_features, output_size=output_size)# # 打印模型结构
print(model)
# ----------------------------------------------------#
#   模型部署
# ----------------------------------------------------#
model.to(device)# ----------------------------------------------------#
#   导入模型参数
# ----------------------------------------------------#
checkpoint_pth = "best_model.pth"
checkpoint = torch.load(checkpoint_pth)
best_acc = checkpoint['best_acc']
model.load_state_dict(checkpoint['state_dict'])
batch_size = 4# DataLoader 加载数据集
train_dataset = torch.utils.data.TensorDataset(train, train_target)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)validation_dataset = torch.utils.data.TensorDataset(validation, validation_target)
validation_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=batch_size, shuffle=True)'''
/****************************************************/模型评估
/****************************************************/
'''
# ----------------------------------------------------#
#   评估
# ----------------------------------------------------## Validation
model.eval()
# 存储所有预测和真实标签
all_preds = []
all_labels = []
# 不计算梯度,减少计算和内存消耗
with torch.no_grad():for data, labels in validation_loader:# data和labels的预处理(如:转移到GPU、标准化等)...# 生成预测并获取最可能的类别outputs = model(data)_, predicted = torch.max(outputs, 1)# 收集预测和真实标签all_preds.extend(predicted.cpu().numpy())all_labels.extend(labels.cpu().numpy())# 计算性能指标
accuracy = accuracy_score(all_labels, all_preds)
conf_matrix = confusion_matrix(all_labels, all_preds)
precision = precision_score(all_labels, all_preds, average='macro')
recall = recall_score(all_labels, all_preds, average='macro')
f1 = f1_score(all_labels, all_preds, average='macro')print(f"Accuracy: {accuracy}")
print(f"Confusion Matrix:\n{conf_matrix}")
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F1 Score: {f1}")

2 运行结果

在这里插入图片描述


总结

到此,基于LSTM的序列分类任务就结束啦。
完整项目
SequenceClassifier

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

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

相关文章

天天酷跑-C语言搭建童年游戏(easyx)

游戏索引 游戏名称&#xff1a;天天酷跑 游戏介绍&#xff1a; 本游戏是在B站博主<程序员Rock>的视频指导下完成 想学的更详细的小伙伴可以移步到<程序员Rock>视频 【程序员Rock】C语言项目&#xff1a;手写天天酷跑丨大一课程设计首选项目&#xff0c;手把手带你用…

【linux】Debian挂起和休眠

一、挂起和休眠 在Debian桌面系统中&#xff0c;挂起和休眠是两种不同的状态&#xff0c;它们之间有一些区别。 挂起&#xff08;Suspend&#xff09;是将当前系统的状态保存到RAM&#xff08;内存&#xff09;中&#xff0c;然后关闭所有硬件设备&#xff0c;除了RAM之外。在…

如何用H5+CSS+JS写一个简单的招聘网站

大家好&#xff0c;我是猿码叔叔&#xff0c;一个 Java 语言开发者。应网友要求&#xff0c;写一个简单的招聘页面。由于技术原因&#xff0c;页面相对简单&#xff0c;朋友们可以选择性的阅读&#xff0c;如果对您有帮助&#xff0c;也可直接拿去使用&#xff0c;因为接下来除…

数据分析的理念、流程、方法、工具(下)

四、用户分群 1、用户分群 用户分群是精细化运营的基础要求&#xff0c;也是数据分析的最基础方式。对用户进行分群&#xff0c;能帮助我们了解每个细分群体用户的变化情况&#xff0c;进而了解用户的整体现状及发展趋势。同时&#xff0c;由于运营资源本身有限&#xff0c;不…

技术变革下职业危机

方向一&#xff1a;技术变革 1.人工智能&#xff08;AI&#xff09;&#xff1a;AI技术的快速发展正在改变各个行业。AI在医疗诊断、金融分析、客户服务以及物流管理等方面都有广泛应用&#xff0c;提高了效率和准确性。但同时也引发了一些道德和道德问题&#xff0c;比如隐私…

玩法与画面全面升级,艾尔莎H311-PRO和你玩转《如龙8:无尽财富》

作为经典的日系开放式世界游戏系列&#xff0c;《如龙》至今已经推出了有十多部作品&#xff0c;它凭借着经典的日式RPG玩法吸引了不少忠实粉丝。早在2022年9月的时候&#xff0c;世嘉就已经公布了最新的正统续作《如龙8》&#xff0c;而在经历了一年半的等待以后&#xff0c;我…

jvs-rules(规则引擎)1.23功能更新说明,新增SQL变量、数据源等

规则引擎更新功能 新增: 1、新增SQL变量&#xff1a; SQL变量通常指的是在执行SQL查询时使用的动态变量。这些变量允许在查询中注入或更改某些值&#xff0c;以便根据不同的条件或输入执行不同的查询。 1.1 新增自定义SQL语言进行数据查询&#xff1b; 用户可以使用自定义的…

强化学习12——策略梯度算法学习

Q-learning、DQN算法是基于价值的算法&#xff0c;通过学习值函数、根据值函数导出策略&#xff1b;而基于策略的算法&#xff0c;是直接显示地学习目标策略&#xff0c;策略梯度算法就是基于策略的算法。 策略梯度介绍 将策略描述为带有参数 θ \theta θ 的连续函数&#…

Pycharm运行提示(运行‘Python测试(00.py内)‘(u)

为什么有时候我在pycharm中运行代码会出现图片中的问题&#xff1f; 我们该如何改过来&#xff1f; 很简单 点击文件-设置 点击Python集成工具&#xff0c;在默认测试运行程序里修改为Unittest即可 再次运行代码就会显示正常的运行 你的pycharm可能是英文 如何英文变中文&…

鸿蒙APP的应用场景

鸿蒙APP可以用于多种场合和设备类型&#xff0c;这是鸿蒙系统的分布式能力和多终端适配的优势。以下是一些鸿蒙APP的应用场景&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.智能手机和平板电脑&am…

开源:两个免费的年会抽奖项目

前言 年会抽奖项目平常基本不用&#xff0c;只有到年终才会排上用场。开发的时长也不会给太久&#xff0c;而且也只是自家公司内部使用的&#xff0c;所以不需要部署&#xff0c;数据库后端甚至都可以省略&#xff1b;然后我就找了个开源的 符合我要求的年会抽奖项目进行二次开…

CSS 图片遮罩学习小节

概念&#xff1a;-webkit-mask-image是一项用于制作镂空图形和图形遮罩效果的CSS样式属性。 -webkit-mask-image 的值既可以是渐变色也可以是图片地址。 -webkit-mask-image 的起源很早&#xff0c;但兼容性不好&#xff0c;因此用途并不广泛。 效果如下&#xff1a; 底图&…

Spring Security 6 学习-1

什么是 Spring Security Spring Security文档 Spring Security中文文档 Spring Security 是 Spring 家族中的安全型开发框架&#xff0c;主要解决三大方面问题&#xff1a;认证&#xff08;你是谁&#xff09;、授权&#xff08;你能干什么&#xff09;、常见攻击保护&#xff…

深度强化学习Task3:A2C、A3C算法

本篇博客是本人参加Datawhale组队学习第三次任务的笔记 【教程地址】 文章目录 Actor-Critic 算法提出的动机Q Actor-Critic 算法A2C 与 A3C 算法广义优势估计A3C实现建立Actor和Critic网络定义智能体定义环境训练利用JoyRL实现多进程 练习总结 Actor-Critic 算法提出的动机 蒙…

Tableau1 安装基础知识

参考内容&#xff1a; 戴师兄-戴你玩转数据分析菜菜菊花酱数据分析课程 1 安装注意事项 若下次打开发现软件损坏&#xff0c;可以重新安装&#xff1b;后期激活码可以去淘宝上购买&#xff08;选择1key两机&#xff09;&#xff1b;若买了1key1机的密钥&#xff0c;需要在两台…

深度学习记录--mini-batch gradient descent

batch vs mini-batch gradient descent batch&#xff1a;段&#xff0c;块 与传统的batch梯度下降不同&#xff0c;mini-batch gradient descent将数据分成多个子集&#xff0c;分别进行处理&#xff0c;在数据量非常巨大的情况下&#xff0c;这样处理可以及时进行梯度下降&…

力扣精选算法100题——在排序数组中查找元素的第一个和最后一个位置(二分查找专题)

目录 第一步&#xff1a;了解题意 第二步&#xff1a;算法原理 &#x1f6a9;查找区间左端点值 ❗处理细节 循环条件&#xff1a; 求中点 &#x1f6a9;查找区间右端点值 ❗处理细节 循环条件 求中点 &#x1f6a9;总结 第三步&#xff1a;代码实现 第四步:总结模…

OpenHarmony 鸿蒙使用指南——概述

简介 OpenHarmony采用多内核&#xff08;Linux内核或者LiteOS&#xff09;设计&#xff0c;支持系统在不同资源容量的设备部署。当相同的硬件部署不同内核时&#xff0c;如何能够让设备驱动程序在不同内核间平滑迁移&#xff0c;消除驱动代码移植适配和维护的负担&#xff0c;…

技术驱动宠物健康:宠物在线问诊系统的高效搭建手册

在数字化时代&#xff0c;技术正在催生出许多创新的医疗服务&#xff0c;而宠物在线问诊系统便是其中一项引领潮流的创举。本文将为你提供一份高效搭建宠物在线问诊系统的手册&#xff0c;通过技术代码示例&#xff0c;让你轻松打造一套技术驱动的宠物健康管理系统。 1. 架构…

常用芯片学习——HC244芯片

HC573 三态输出八路缓冲器|线路驱动器 使用说明 SNx4HC244 八路缓冲器和线路驱动器专门设计用于提高三态存储器地址驱动器、时钟驱动器以及总线导向接收器和发送器的性能和密度。SNx4HC244 器件配备两个具有独立输出使能 (OE) 输入的 4 位缓冲器和驱动器。当 OE 为低电平时&a…