基于前馈神经网络完成鸢尾花分类

目录

1 小批量梯度下降法

        1.0 展开聊一聊~

        1.1 数据分组

        1.2 用DataLoader进行封装

        1.3 模型构建

        1.4 完善Runner类

        1.5 模型训练

        1.6 模型评价 

        1.7 模型预测        

思考

总结

参考文献


首先基础知识铺垫~       

继续使用第三章中的鸢尾花分类任务,将Softmax分类器替换为前馈神经网络

  • 损失函数:交叉熵损失;
  • 优化器:随机梯度下降法;
  • 评价指标:准确率;

1 小批量梯度下降法

        1.0 展开聊一聊~

        在梯度下降法中,目标函数是整个训练集上的风险函数,这种方式称为批量梯度下降法(Batch Gradient Descent,BGD)。批量梯度下降法在每次迭代时需要计算每个样本上损失函数的梯度并求和。为了减少每次迭代的计算复杂度,我们可以在每次迭代时只采集一小部分样本,计算在这组样本上损失函数的梯度并更新参数,这种优化方式称为小批量梯度下降法(Mini-Batch Gradient Descent,Mini-Batch GD)。

        梯度下降算法一般情况下主要说的是三种,批量梯度下降随机梯度下降小批量梯度下降。

        知道大家跟我一样不爱看一大段一大段的定义,巴拉巴拉一堆的,所以我大概总结了一下,快拿出你们的小本本!!!

首先,要明确梯度下降算法都是优化算法,用于求解目标函数的最优参数:

  • 批量梯度下降(Batch Gradient Descent,BGD)
  • 随机梯度下降(Stochastic Gradient Descent,SGD)
  • 小批量梯度下降(Mini-Batch Gradient Descent,MBGD)

        批量梯度下降(BGD):最早出现的梯度下降方法是批量梯度下降。BGD在每一次迭代中使用所有训练样本来计算梯度,并更新模型参数,步骤如下:

  • 对于每个训练样本,计算梯度。
  • 将所有梯度求平均,得到一个全局梯度。
  • 根据学习率和全局梯度更新模型参数。

优点:

  • 收敛性较好,能够达到全局最优(目标函数是凸函数)。
  • 梯度计算相对准确,参数更新稳定。
  • 收敛速度最快,可以保证每一步都是准确地向着极值点的方向趋近,所需要的迭代次数最少。

缺点:

  • 计算梯度时需要处理大量数据,计算开销较大。
  • 参数更新只能在整个训练集上进行,但大规模数据集通常会有大量冗余数据,所以不适用于大规模数据集。
  • 容易陷入局部最优(目标函数是非凸函数)。

        这里需要提一下~对所有样本的计算,可以利用向量运算进行并行计算来提升运算速度。

        随机梯度下降(SGD):为了解决批量梯度下降在处理大规模数据集时的计算开销问题,随机梯度下降方法被提出。SGD在每一次迭代中仅使用一个训练样本来计算梯度,并更新模型参数。具体步骤如下:

  • 随机选择一个训练样本。
  • 计算该样本的梯度。
  • 根据学习率和该样本的梯度更新模型参数。

优点:

  • 计算开销较小,适用于大规模数据集。
  • 参数更新频繁,可能更容易逃离局部最优。

缺点:

  • 每次迭代只使用一个样本,但是单个样本计算出的梯度不能够很好的体现全体样本的梯度。
  • 参数更新的方向较不稳定,可能会产生参数震荡。
  • 参数更新非常的频繁,在最优点附近晃来晃去,收敛速度大大降低。

小批量梯度下降(MBGD):为了兼顾批量梯度下降和随机梯度下降的优点,小批量梯度下降方法被引入。小批量梯度下降算法又被叫做小批量随机梯度下降算法。MBGD在每一次迭代中使用一小部分训练样本(通常称为mini-batch)来计算梯度,并更新模型参数。具体步骤如下:

  • 随机选择一小部分训练样本(mini-batch)。
  • 计算这些样本的梯度。
  • 根据学习率和这些样本的梯度更新模型参数。

优点:

  • 兼具BGD和SGD的优点,计算开销适中,参数更新相对稳定。
  • 可以利用矩阵运算的高效性,提高计算效率。
  • 较容易并行化处理,适用于大规模数据集。

缺点:

  • 学习率选择较为敏感,需要进行合适的调参。

        总结:三种梯度下降方法各有优劣。批量梯度下降收敛性好,但计算开销大;随机梯度下降计算开销小,但更新不稳定;小批量梯度下降在两者之间取得平衡,并且对于大规模数据集有较好的适应性。在实际应用中,根据具体问题的规模和特点选择合适的梯度下降方法。

        1.1 数据分组

        为了小批量梯度下降法,我们需要对数据进行随机分组。目前,机器学习中通常做法是构建一个数据迭代器,每个迭代过程中从全部数据集中获取一批指定数量的数据。原理图展示一下:

        首先,将数据集封装为Dataset类,传入一组索引值,根据索引从数据集合中获取数据;

        其次,构建DataLoader类,需要指定数据批量的大小和是否需要对数据进行乱序,通过该类即可批量获取数据。

import torch.utils.data as Dataclass IrisDataset(Data.Dataset):def __init__(self, mode='train', num_train=120, num_dev=15):super(IrisDataset, self).__init__()# 调用第三章中的数据读取函数,其中不需要将标签转成one-hot类型X, y = load_data(shuffle=True)if mode == 'train':self.X, self.y = X[:num_train], y[:num_train]elif mode == 'dev':self.X, self.y = X[num_train:num_train + num_dev], y[num_train:num_train + num_dev]else:self.X, self.y = X[num_train + num_dev:], y[num_train + num_dev:]def __getitem__(self, idx):return self.X[idx], self.y[idx]def __len__(self):return len(self.y)

__getitem__:根据给定索引获取数据集中指定样本,并对样本进行数据处理;

__len__:返回数据集样本个数。

train_dataset = IrisDataset(mode='train')
dev_dataset = IrisDataset(mode='dev')
test_dataset = IrisDataset(mode='test')print("length of train set: ", len(train_dataset))

 

        1.2 用DataLoader进行封装

batch_size = 16# 加载数据
train_loader = Data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
dev_loader = Data.DataLoader(dev_dataset, batch_size=batch_size)
test_loader = Data.DataLoader(test_dataset, batch_size=batch_size)

        1.3 模型构建

class Model_MLP_L2_V3(nn.Module):def __init__(self, input_size, output_size, hidden_size):super(Model_MLP_L2_V3, self).__init__()# 构建第一个全连接层self.fc1 = nn.Linear(input_size, hidden_size)# 构建第二全连接层self.fc2 = nn.Linear(hidden_size, output_size)# 定义网络使用的激活函数self.act = nn.Sigmoid()nn.init.normal_(self.fc1.weight, mean=0., std=0.01)nn.init.constant_(self.fc1.bias, 1.0)nn.init.normal_(self.fc2.weight, mean=0., std=0.01)nn.init.constant_(self.fc2.bias, 1.0)def forward(self, inputs):outputs = self.fc1(inputs)outputs = self.act(outputs)outputs = self.fc2(outputs)return outputsfnn_model = Model_MLP_L2_V3(input_size=4, output_size=3, hidden_size=6)

        1.4 完善Runner类

class Accuracy(object):def __init__(self, is_logist=True):"""输入:- is_logist: outputs是logist还是激活后的值"""# 用于统计正确的样本个数self.num_correct = 0# 用于统计样本的总数self.num_count = 0self.is_logist = is_logistdef update(self, outputs, labels):"""输入:- outputs: 预测值, shape=[N,class_num]- labels: 标签值, shape=[N,1]"""# 判断是二分类任务还是多分类任务,shape[1]=1时为二分类任务,shape[1]>1时为多分类任务if outputs.shape[1] == 1:  # 二分类outputs = torch.squeeze(outputs, axis=-1)if self.is_logist:# logist判断是否大于0preds = (outputs >= 0).to(torch.float32)else:# 如果不是logist,判断每个概率值是否大于0.5,当大于0.5时,类别为1,否则类别为0preds = (outputs >= 0.5).to(torch.float32)else:# 多分类时,使用'paddle.argmax'计算最大元素索引作为类别preds = torch.argmax(outputs, dim=1).int()# 获取本批数据中预测正确的样本个数labels = torch.squeeze(labels, dim=-1)batch_correct = float((preds == labels).sum())# batch_correct = torch.sum(torch.tensor(preds == labels, dtype=torch.float32)).numpy()batch_count = len(labels)# 更新num_correct 和 num_countself.num_correct += batch_correctself.num_count += batch_countdef accumulate(self):# 使用累计的数据,计算总的指标if self.num_count == 0:return 0return self.num_correct / self.num_countdef reset(self):# 重置正确的数目和总数self.num_correct = 0self.num_count = 0def name(self):return "Accuracy"

        完善RunnerV3类

import torchclass RunnerV3(object):def __init__(self, model, optimizer, loss_fn, metric, **kwargs):self.model = modelself.optimizer = optimizerself.loss_fn = loss_fnself.metric = metric  # 只用于计算评价指标# 记录训练过程中的评价指标变化情况self.dev_scores = []# 记录训练过程中的损失函数变化情况self.train_epoch_losses = []  # 一个epoch记录一次lossself.train_step_losses = []  # 一个step记录一次lossself.dev_losses = []# 记录全局最优指标self.best_score = 0def train(self, train_loader, dev_loader=None, **kwargs):# 将模型切换为训练模式self.model.train()# 传入训练轮数,如果没有传入值则默认为0num_epochs = kwargs.get("num_epochs", 0)# 传入log打印频率,如果没有传入值则默认为100log_steps = kwargs.get("log_steps", 100)# 评价频率eval_steps = kwargs.get("eval_steps", 0)# 传入模型保存路径,如果没有传入值则默认为"best_model.pdparams"save_path = kwargs.get("save_path", "best_model.pdparams")custom_print_log = kwargs.get("custom_print_log", None)# 训练总的步数num_training_steps = num_epochs * len(train_loader)if eval_steps:if self.metric is None:raise RuntimeError('Error: Metric can not be None!')if dev_loader is None:raise RuntimeError('Error: dev_loader can not be None!')# 运行的step数目global_step = 0# 进行num_epochs轮训练for epoch in range(num_epochs):# 用于统计训练集的损失total_loss = 0for step, data in enumerate(train_loader):X, y = data# 获取模型预测logits = self.model(X)loss = self.loss_fn(logits, y)  # 默认求meantotal_loss += loss# 训练过程中,每个step的loss进行保存self.train_step_losses.append((global_step, loss.item()))if log_steps and global_step % log_steps == 0:print(f"[Train] epoch: {epoch}/{num_epochs}, step: {global_step}/{num_training_steps}, loss: {loss.item():.5f}")# 梯度反向传播,计算每个参数的梯度值loss.backward()if custom_print_log:custom_print_log(self)# 小批量梯度下降进行参数更新self.optimizer.step()# 梯度归零self.optimizer.zero_grad()  #无clear_grad# 判断是否需要评价if eval_steps > 0 and global_step > 0 and \(global_step % eval_steps == 0 or global_step == (num_training_steps - 1)):dev_score, dev_loss = self.evaluate(dev_loader, global_step=global_step)print(f"[Evaluate]  dev score: {dev_score:.5f}, dev loss: {dev_loss:.5f}")# 将模型切换为训练模式self.model.train()# 如果当前指标为最优指标,保存该模型if dev_score > self.best_score:self.save_model(save_path)print(f"[Evaluate] best accuracy performence has been updated: {self.best_score:.5f} --> {dev_score:.5f}")self.best_score = dev_scoreglobal_step += 1# 当前epoch 训练loss累计值trn_loss = (total_loss / len(train_loader)).item()# epoch粒度的训练loss保存self.train_epoch_losses.append(trn_loss)print("[Train] Training done!")# 模型评估阶段,使用'paddle.no_grad()'控制不计算和存储梯度@torch.no_grad()def evaluate(self, dev_loader, **kwargs):assert self.metric is not None# 将模型设置为评估模式self.model.eval()global_step = kwargs.get("global_step", -1)# 用于统计训练集的损失total_loss = 0# 重置评价self.metric.reset()# 遍历验证集每个批次for batch_id, data in enumerate(dev_loader):X, y = data# 计算模型输出logits = self.model(X)# 计算损失函数loss = self.loss_fn(logits, y).item()# 累积损失total_loss += loss# 累积评价self.metric.update(logits, y)dev_loss = (total_loss / len(dev_loader))dev_score = self.metric.accumulate()# 记录验证集lossif global_step != -1:self.dev_losses.append((global_step, dev_loss))self.dev_scores.append(dev_score)return dev_score, dev_loss# 模型评估阶段,使用'paddle.no_grad()'控制不计算和存储梯度@torch.no_grad()def predict(self, x, **kwargs):# 将模型设置为评估模式self.model.eval()# 运行模型前向计算,得到预测值logits = self.model(x)return logitsdef save_model(self, save_path):torch.save(self.model.state_dict(), save_path)def load_model(self, model_path):model_state_dict = torch.load(model_path)self.model.load_state_dict(model_state_dict)

        注意torch环境中没有clear_grad方法,这儿需要调用zero_grad方法。 

        1.5 模型训练

        这里把RunnerV3放入runner.py存储在nndl文件夹中

import torch.optim as opt
from nndl.runner import RunnerV3
import torch.nn.functional as Flr = 0.2
# 定义网络
model = fnn_model
# 定义优化器
optimizer = opt.SGD(model.parameters(), lr=lr)
# 定义损失函数。softmax+交叉熵
loss_fn = F.cross_entropy# 定义评价指标
metric = Accuracy(is_logist=True)runner = RunnerV3(model, optimizer, loss_fn, metric)

        使用训练集和验证集进行模型训练,共训练150个epoch。在实验中,保存准确率最高的模型作为最佳模型。

# 启动训练
log_steps = 100
eval_steps = 50
runner.train(train_loader, dev_loader,num_epochs=150, log_steps=log_steps, eval_steps=eval_steps,save_path="best_model.pdparams")

        可视化观察训练集损失和训练集loss变化情况,代码如下:

import matplotlib.pyplot as plt# 绘制训练集和验证集的损失变化以及验证集上的准确率变化曲线
def plot_training_loss_acc(runner, fig_name,fig_size=(16, 6),sample_step=20,loss_legend_loc="upper right",acc_legend_loc="lower right",train_color="#e4007f",dev_color='#f19ec2',fontsize='large',train_linestyle="-",dev_linestyle='--'):global dev_stepsplt.figure(figsize=fig_size)plt.subplot(1, 2, 1)train_items = runner.train_step_losses[::sample_step]train_steps = [x[0] for x in train_items]train_losses = [x[1] for x in train_items]plt.plot(train_steps, train_losses, color=train_color, linestyle=train_linestyle, label="Train loss")if len(runner.dev_losses) > 0:dev_steps = [x[0] for x in runner.dev_losses]dev_losses = [x[1] for x in runner.dev_losses]plt.plot(dev_steps, dev_losses, color=dev_color, linestyle=dev_linestyle, label="Dev loss")# 绘制坐标轴和图例plt.ylabel("loss", fontsize=fontsize)plt.xlabel("step", fontsize=fontsize)plt.legend(loc=loss_legend_loc, fontsize='x-large')# 绘制评价准确率变化曲线if len(runner.dev_scores) > 0:plt.subplot(1, 2, 2)plt.plot(dev_steps, runner.dev_scores,color=dev_color, linestyle=dev_linestyle, label="Dev accuracy")# 绘制坐标轴和图例plt.ylabel("score", fontsize=fontsize)plt.xlabel("step", fontsize=fontsize)plt.legend(loc=acc_legend_loc, fontsize='x-large')plt.savefig(fig_name)plt.show()plot_training_loss_acc(runner, 'fw-loss.pdf')

 

        1.6 模型评价 

        使用测试数据对在训练过程中保存的最佳模型进行评价,观察模型在测试集上的准确率以及Loss情况,代码如下:

# 加载最优模型
runner.load_model('best_model.pdparams')
# 模型评价
score, loss = runner.evaluate(test_loader)
print("[Test] accuracy/loss: {:.4f}/{:.4f}".format(score, loss))

        1.7 模型预测        

        同样地,也可以使用保存好的模型,对测试集中的某一个数据进行模型预测,观察模型效果。代码如下

# 获取测试集中第一条数据
X, label = train_dataset[0]
logits = runner.predict(X)pred_class = torch.argmax(logits[0]).numpy()
label = label.numpy()# 输出真实类别与预测类别
print("The true category is {} and the predicted category is {}".format(label, pred_class))

思考

softmax、svm、前馈神经网络三种进行比较,svm代码如下:

from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
def SVC_split(x_train, y_train, x_test, y_test):# 定义SVM分类器svm = SVC()# 定义参数空间param_grid = {'C': [0.01, 0.1, 1, 10],'kernel': ['linear', 'rbf', 'poly'],'gamma': ['scale', 'auto']}# 使用GridSearchCV进行交叉验证和参数选择grid_search = GridSearchCV(svm, param_grid=param_grid, cv=5)grid_search.fit(x_train, y_train.ravel())# 在测试集上评估模型性能y_pred = grid_search.predict(x_test)accuracy = accuracy_score(y_test, y_pred)print("Accuracy on test set: {:.2f}%".format(accuracy * 100))SVC_split(train_dataset.X,train_dataset.y ,test_dataset.X, test_dataset.y)

调用实验四的softmax函数的结果如下:

        很明显我们发现softmax回归的准确率远远低于前馈神经网络和svm,简单总结一下都有什么原因吧:

               softmax回归是一个线性模型,其只能学习到线性关系。对于复杂的非线性分类问题,Softmax回归的表达能力可能不足以捕捉到数据中的更复杂模式。相比之下,前馈神经网络具有更强大的非线性建模能力,可以通过多个隐藏层和非线性激活函数来学习到更复杂的特征表示。SVM也可以通过核函数将低维输入映射到高维空间,从而进行非线性分类。

        由此得出结论,但需要注意的是,Softmax回归在所有二分类任务上表现都会远远低于前馈神经网络和SVM。对于一些简单的线性可分问题或数据分布较为简单的情况下,Softmax回归可能表现得很好。然而,对于更复杂的问题和数据集,使用更复杂的模型如前馈神经网络和SVM通常能够获得更好的性能。

        但是有个疑问前馈神经网络和SVM究竟哪个更好一点?

        简而言之,神经网络是个“黑匣子”,优化目标是基于经验风险最小化,易陷入局部最优,训练结果不太稳定,一般需要大样本;

        而支持向量机有严格的理论和数学基础,基于结构风险最小化原则, 泛化能力优于前者,算法具有全局最优性, 是针对小样本统计的理论。

        就目前我的理论知识,好像想搞明白哪个好哪个坏可能有点难,而且模型好像很难说哪个好哪个坏,可能针对不同的数据集表现也会不一样,害,浅浅插个眼,等之后,对深度学习有了一定程度的了解的时候再回来,看看有没有一个答案吧。

总结

        到此为止前馈神经网络结束啦,有了一点搭建神经网络的经验了吧,大概流程如下:

  1. 定义网络结构:首先需要确定网络的结构,包括输入层、隐藏层和输出层的大小和数量。

  2. 初始化参数:对于每个神经元,需要初始化权重和偏置值。权重和偏置值通常是随机初始化的,以避免初始状态过于相似导致模型收敛缓慢。

  3. 定义损失函数:损失函数用来衡量预测值和真实值之间的误差。二分类问题通常使用交叉熵损失函数,回归问题可以使用均方误差损失函数。

  4. 定义优化器:优化器用于更新模型的参数,使损失函数最小化。常见的优化器包括随机梯度下降 (SGD)、Adam等。

  5. 训练模型:通过传递数据进行前向传播和反向传播,更新模型的参数。在训练过程中,需要将数据分为训练集、验证集和测试集。

  6. 模型评价:在训练完成之后,可以通过输入新数据并进行前向传播来得到预测结果。也可以进行可视化等等。

        本次实验对前馈神经网络的应用有更为明确的理解,同时针对softmax,svm,CNN的对比,在实验和搜索资料的过程中,也明白了什么模型更适合应用在什么范围内,softmax和CNN的具体的应用区别还没弄明白算是个小小的遗憾吧,等有更多深度学习经验的时候看看能不能再回来解答这个问题吧~

参考文献

torch.nn.Module所有方法总结及其使用举例_torch.nn.module cuda-CSDN博客
torch.nn — PyTorch master documentation

NNDL 实验五 前馈神经网络(3)鸢尾花分类-CSDN博客
神经网络 VS SVM_svm和神经网络的区别-CSDN博客

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

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

相关文章

uinapp微信小程序隐私政策授权

&#x1f680; 隐私弹窗效果图&#xff1a; 1、启用隐私相关功能在manifest.json文件中配置 usePrivacyCheck: true "mp-weixin" : {"__usePrivacyCheck__" : true, },2、创建组件 <template><view><!-- 隐私政策弹窗 --><uni-popu…

阿里云服务器怎么购买更省钱?优惠入口分享

阿里云服务器怎么购买更省钱&#xff1f;不要直接在云服务器页面购买&#xff0c;不划算&#xff0c;在阿里云特价活动上购买更优惠&#xff0c;阿腾云atengyun.com分享阿里云服务器省钱购买方法&#xff0c;节省90%&#xff0c;可以先在阿里云CLUB中心领券 aliyun.club 专用满…

Java-Hbase介绍

1.1. 概念 base 是分布式、面向列的开源数据库&#xff08;其实准确的说是面向列族&#xff09;。HDFS 为 Hbase 提供可靠的 底层数据存储服务&#xff0c;MapReduce 为 Hbase 提供高性能的计算能力&#xff0c;Zookeeper 为 Hbase 提供 稳定服务和 Failover 机制&#xff0c…

【优选算法系列】【专题五位运算】第一节.常见的位运算(面试题 01.01. 判定字符是否唯一和268. 丢失的数字)

文章目录 前言常见的位运算一、判定字符是否唯一 1.1 题目描述 1.2 题目解析 1.2.1 算法原理 1.2.2 代码编写二、丢失的数字 2.1 题目描述 2.2 题目解析 2.2.1 算法原理 2.2.2 代码编写总结 前言 常见的…

k8s之service五种负载均衡byte的区别

1&#xff0c;什么是Service&#xff1f; 1.1 Service的概念​ 在k8s中&#xff0c;service 是一个固定接入层&#xff0c;客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端pod&#xff0c;这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件&a…

Spring的总结

SpringFramework 认识SpringFramework 最首先&#xff0c;我们先要认识Spring和SpringFramework两者之间有什么联系&#xff1f; 广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。 狭义的 Spring 特指 Spring Framework&#xff0c;通常我们将它称为 Spr…

找不到d3dcompiler_47.dll,无法继续执行代码,解决方法

首先&#xff0c;让我们来了解一下d3dcompiler_47.dll文件。d3dcompiler_47.dll是一个动态链接库文件&#xff0c;它是DirectX SDK中的一个重要组件&#xff0c;用于编译DirectX着色器。当我们在使用一些需要DirectX支持的软件或游戏时&#xff0c;如果缺少了这个文件&#xff…

Mysql数据库的备份和恢复及日志管理

一、数据备份概述 1.1 备份的分类 完全备份&#xff1a;整个数据库完整地进行备份 增量备份&#xff1a;在完全备份的基础之上&#xff0c;对后续新增的内容进行备份 冷备份&#xff1a;关机备份&#xff0c;停止mysql服务&#xff0c;然后进行备份 热备份&#xff1a;开机备…

java 版本企业招标投标管理系统源码+多个行业+tbms+及时准确+全程电子化

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

go 语言介绍

背景 一直有在零散的时间用go写点代码&#xff0c;正好借着最近比较有时间写东西的契机&#xff0c;给这个看着年轻&#xff0c;实际也已经发展10几年&#xff0c;并在当下众多开发领域都有不可忽视作用的语言做个介绍吧 golang 的起点 golang 的诞生可以说是时代造就了它&a…

Python实现Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换

Python实现Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换 前言前提条件相关介绍实验环境Labelme的Json标注文件与YOLO格式的TXT标注文件相互转换convert_labelme_json_to_txtjsons/000000000009.json代码实现输出结果labels/000000000009.txt convert_txt_to_labelme_…

Docker Compose安装milvus向量数据库单机版-milvus基本操作

目录 安装Ubuntu 22.04 LTS在power shell启动milvus容器安装docker desktop下载yaml文件启动milvus容器Milvus管理软件Attu python连接milvus配置下载wget示例导入必要的模块和类与Milvus数据库建立连接创建名为"hello_milvus"的Milvus数据表插入数据创建索引基于向量…

NLP之Bert多分类实现案例(数据获取与处理)

文章目录 1. 代码解读1.1 代码展示1.2 流程介绍1.3 debug的方式逐行介绍 3. 知识点 1. 代码解读 1.1 代码展示 import json import numpy as np from tqdm import tqdmbert_model "bert-base-chinese"from transformers import AutoTokenizertokenizer AutoToken…

数据结构--前缀树(Trie)

1. 简介 前缀树是一种数据结构&#xff0c;常用来字符搜索。 2. 实现 包含的操作主要是: 加入串搜索串 代码实现&#xff0c;直接用leetcode_208的题解咯。 代码 class Trie { public:Trie():isEnd(false){for ( int i 0; i < 26;i)child[i] nullptr;}~Trie() {fo…

Webpack 中 Plugin 的作用是什么?常用 plugin 有哪些?

说说webpack中常见的Plugin&#xff1f;解决了什么问题&#xff1f;- 题目详情 - 前端面试题宝典 1、plugin 的作用 Plugin 是一种计算机应用程序&#xff0c;它和主应用程序互相交互&#xff0c;以提供特定的功能。 是一种遵循一定规范的应用程序接口编写出来的程序&#…

CSDN每日一题学习训练——Java版(两数相加、二叉树的锯齿形层序遍历、解数独)

版本说明 当前版本号[20231106]。 版本修改说明20231106初版 目录 文章目录 版本说明目录两数相加题目解题思路代码思路补充说明参考代码 二叉树的锯齿形层序遍历题目解题思路代码思路参考代码 解数独题目解题思路代码思路补充说明参考代码 两数相加 题目 给你两个 非空 的…

动态IP和静态IP哪个安全,该怎么选择

随着互联网的普及&#xff0c;越来越多的人开始关注网络安全问题。其中&#xff0c;IP地址作为网络通信中的重要组成部分&#xff0c;也成为了人们关注的焦点。 在IP地址中&#xff0c;动态IP和静态IP是两种不同的分配方式&#xff0c;它们各自具有不同的特点&#xff0c;那么…

论文阅读—— CEASC(cvpr2023)

arxiv&#xff1a;https://arxiv.org/abs/2303.14488 github&#xff1a;https://github.com/Cuogeihong/CEASC 为了进一步减轻SC中的信息损失&#xff0c;使训练过程更加稳定&#xff0c;我们在训练过程中除了稀疏卷积之外&#xff0c;还保持了正常的密集卷积&#xff0c;生成…

基于SSM的社区智慧养老监护管理平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Android---彻底掌握 Handler

Handler 现在几乎是 Android 面试的必问知识点&#xff0c;大多数 Adnroid 工程师都在项目中使用过 Handler。主要场景是子线程完成耗时操作的过程中&#xff0c;通过 Handler 向主线程发送消息 Message&#xff0c;用来刷新 UI 界面。 下面我们来了解 Handler 的发送消息和处…