《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第五章

news2024/11/15 9:50:02

全连接神经网络

隐藏层的节点数决定了模型拟合能力,如果在单隐藏层设置足够多的节点,理论上可以拟合世界上各种维度的数据进行任意规则的分类,但会过拟合。
隐藏层的数量决定了其泛化能力,层数越多,推理的能力越强,(个人观点为:层数越多学习到的特征越多,考虑的因素越多,因此增强了泛化能力)
全连接网络常常放在最后,还具有维度调节的作用,一般前后层维度变换在5倍以内。一般用维度先扩大再缩小的思路。

激活函数

激活函数用来加入非线性因素,弥补线性模型缺陷,常用的有Sigmoid、tanh、ReLU。

有多种形式
类形式和函数形式。


input=torch.autograd.Variable(torch.tensor([0.3,3]))
print(nn.Sigmoid()(input))
print(nn.functional.sigmoid(input))
#tensor([0.5744, 0.9526])
#tensor([0.5744, 0.9526])

更好的激活函数,Swish与Mish,后者没有参数更方便,一般都可以在Relu上直接更换取得更好的效果。

GELU,高斯误差线性单元,与随机正则化有关,可以起到自适应Dropout的效果。

Swish是GELU的特例,Mish是GELU的特例。
训练时特征之间的差距不断变大,输入数据本身差距大时用tanh会好一些,反之用Sigmoid比较好。

损失函数

L1损失函数,计算y’和y的绝对值然后进行平均值计算
MSE损失函数,计算y’和y的相减平方取平均值
预测值要与真实值控制在同样的数据分布内,如进入Sigmoid激活函数后取值为0到1,真实值也应该归一化为0到1。

pre=torch.tensor([1.0,1.5,3.0,3.0])
label=torch.tensor([2.2,3.1,2.0,3.0])
L1Loss=nn.L1Loss()(pre,label)
#(1.2+1.6+1.0+0.0)/4=0.95
MSELoss=nn.MSELoss()(pre,label)
#(1.44+2.56+1.0+0.0)/4=1.25

交叉熵损失函数,一般用在分类问题上,可以加类别权重。

pre=torch.tensor([0.,1.])
label=torch.tensor([0.,1.])
CrossEntropyLoss=nn.CrossEntropyLoss(torch.tensor([1,0.1]))(pre,label)
print(CrossEntropyLoss)
#tensor(0.0313)

其他激活函数…数不胜数

关于损失函数的选取,用输入标签的类型来选取损失函数,如果输入是无界的实数值,用平均方差。如果输入标签是位矢量(分类标识),使用交叉熵函数比较合适。

Softmax算法本质也是一种激活函数,在分类任务中很重要。Sigmoid之类的一般的激活函数只能分两类,而Softmax可以理解成其扩展。如果多分类任务中,每个类彼此不是互斥关系,可以使用多个二分类来组成。分几类最后放几个输出。

利用两边ln,将乘法变加法,然后转换成e的x次方。

实例3:Softmax与交叉熵的应用

logits有两个数据,一个数据有3个元素,代表3个类别。(0类、1类、2类)
labels对应类别标签。
使用LogSoftmax和NLLLoss,与直接用CrossEntropyLoss计算出的损失是一样的。

import torch
logits = torch.autograd.Variable(torch.tensor([[1.5,0.5,6], [0.1,3,0]]))
labels = torch.autograd.Variable(torch.LongTensor([2,1]))
print(logits)
print(labels)
print('Softmax:',torch.nn.Softmax(dim=1)(logits))
logsoftmax = torch.nn.LogSoftmax(dim=1)(logits)
print('logsoftmax:',logsoftmax)
output = torch.nn.NLLLoss()(logsoftmax, labels)
print('NLLLoss:',output)
print ( 'CrossEntropyLoss:', torch.nn.CrossEntropyLoss()(logits, labels) )

优化器模块

有了正向结构和损失函数后,就可以优化参数了。这个过程在反向传播中完成,优化函数为优化器。为了让损失函数最小,对其求导,找到最小值时的函数切线斜率(梯度),让权重沿着梯队来调整。

优化器与梯度下降
梯度下降法也叫最速下降法,用梯度下降(负梯度)的方向求解极小值。

优化器的类别
批量梯度下降、随机梯度下降,小批量梯度下降为上述两种方法的折中。
主流的优化器有,RMSProp、AdaGrad、Adam、SGD等,有各自的特点和适应的场景。

构建一个常用的Adam优化器
lr为学习率,默认为0.001,
weight_decay为权重参数的衰减率
amsgrad为是否使用二阶冲量


learning_rate=0.01
optimizer=torch.optim.Adam(model.parameters(),lr=learning_rate)
print(optimizer)
print(list(optimizer.param_groups[0].keys()))
#Adam (
#Parameter Group 0
#    amsgrad: False
#    betas: (0.9, 0.999)
#    capturable: False
#    differentiable: False
#    eps: 1e-08
#    foreach: None
#    fused: None
#    lr: 0.01
#    maximize: False
#    weight_decay: 0
#)
#['params', 'lr', 'betas', 'eps', 'weight_decay', 'amsgrad', 'maximize', 'foreach', 'capturable', 'differentiable', 'fused']

更好的优化器Ranger…

如何选择优化器
RMSProp、AdaGrad、Adam、SGD,前3个适合自动收敛,最后一个常用于手动精条模型,自动一般用Adam。
一般先用Adam然后用SGD精调。
进一步提升使用AMSGrad、Adamax、Ranger优化器。

退化学习率,在训练速度与精度之间找到平衡。
修改第三章实例,实现每50步将学习率乘0.99,实现将学习率变小的功能。
lr_scheduler退化学习率接口,简化等价写法。

epochs = 1000 #定义迭代次数
losses = [] #定义列表,用于接收每一步的损失值
lres = [] #定义列表,用于接收每一步的学习率
#scheduler=torch.optim.lr_scheduler.StepLR(optimizer,step_size=50,gamma=0.99)
for i in range(epochs):
    loss = model.getloss(xt,yt)
    losses.append(loss.item())
    optimizer.zero_grad()#清空之前的梯度
    loss.backward()#反向传播损失值
    optimizer.step()#更新参数
#   scheduler.step()

    if i%50 ==0:
        for p in optimizer.param_groups:
            p['lr']*=0.99
    lres.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(epochs),lres,color='r')
plt.show()

在这里插入图片描述
lr_scheduler存在多种退化方式
StepLR等间隔、MultiStepLR多间隔、指数衰减、余弦退火、根据指标调整等。

使用lr_scheduler实现MultiStepLR多间隔为200,700,800时。

scheduler=torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[200,700,800],gamma=0.9)

在这里插入图片描述
使用lr_scheduler实现ReduceLROnPlateau时,注意要在scheduler.step(loss.item())传入损失,作为被监控的值。

scheduler=torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,mode='min',factor=0.5,patience=5,verbose=True,threshold=0.0001,threshold_mode='abs',cooldown=0,min_lr=0,eps=1e-08)

在这里插入图片描述

实例4:预测泰坦尼克号船上的生存乘客
大体流程:
载入titanic3.csv,
Index([‘pclass’, ‘survived’, ‘name’, ‘sex’, ‘age’, ‘sibsp’, ‘parch’, ‘ticket’,
‘fare’, ‘cabin’, ‘embarked’, ‘boat’, ‘body’, ‘home.dest’],
舱位等级、是否获救、姓名年龄等等。

1.离散数据特征:如该任务中的男人和女人,数据没有连续性,做特征变换转化为one-hot编码,或者词向量。
具有固定类别的样本处理容易,如性别,按总的类别数变换
没有固定类别的样本,如名字,用hash算法或类似的散列算法处理
2.连续数据特征:如该任务中的年龄,做特征变换做对数运算或归一化处理。
3.连续数据与离散数据相互转化
(1)按最大最小值归一化处理
(2)对其进行对数运算
(3)按照其分布情况分为几类,做离散化处理。如90%的样本在0.1到1之间,10%的在1000到10000之间

前期数据处理:

将离散数据转成One-hot编码,如性别中有男女,男女成为新的特征分别一列,(1,0)为男(0,1)为女。
get_dummies()出来为布尔值可以用下面的代码做转换。

data = titanic_data.replace({True:1, False:0}).to_numpy()
#用哑变量将指定字段转成one-hot
titanic_data = pd.concat([titanic_data,
                          pd.get_dummies(titanic_data['sex']),
                          pd.get_dummies(titanic_data['embarked'],prefix="embark"),
                          pd.get_dummies(titanic_data['pclass'],prefix="class")], axis=1)

print(titanic_data.columns )
print(titanic_data['sex'])
print(titanic_data['female'])
print(titanic_data['embark_C'])

对Nan过滤填充,剔除无用数据列。本例只对连续数据年龄和乘客票价用平均值进行填充。

# print(titanic_data['age'])
# #处理None值
titanic_data["age"] = titanic_data["age"].fillna(titanic_data["age"].mean())
titanic_data["fare"] = titanic_data["fare"].fillna(titanic_data["fare"].mean())#乘客票价
# print(titanic_data['age'])

剔除无关的数据,不能用来做特征。如姓名,票号等等。

# #删去无用的列
titanic_data = titanic_data.drop(['name','ticket','cabin','boat','body','home.dest','sex','embarked','pclass'], axis=1)
print(titanic_data.columns)

分离样本和标签并制作数据集

将survived列拿出当做label,并将训练特征one-hot编码中的bool值转化成数值0和1。
取70%作为训练集,30%作为测试集。
np.random.choice(n,m,replace=False) n个里选m个不重复

list(set(range(len(labels))) - set(train_indices)) 用样本数量的下标减去选取训练集的下标得到剩下测试集的下标元组,然后转化成列表
set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等

# #分离样本和标签
labels = titanic_data["survived"].to_numpy()
print(labels)
titanic_data = titanic_data.drop(['survived'], axis=1)
data = titanic_data.replace({True:1, False:0}).to_numpy()
print(data)

# #样本的属性名称
feature_names = list(titanic_data.columns)
print(feature_names)

# #将样本分为训练和测试两部分
np.random.seed(10)#设置种子,保证每次运行所分的样本一致
train_indices = np.random.choice(len(labels), int(0.7*len(labels)), replace=False)
test_indices = list(set(range(len(labels))) - set(train_indices))

train_features = data[train_indices]
train_labels = labels[train_indices]
test_features = data[test_indices]
test_labels = labels[test_indices]
print(len(test_labels))#393

定义Mish激活函数与多层全连接网络:

输入为12个特征,[‘age’, ‘sibsp’, ‘parch’, ‘fare’, ‘female’, ‘male’, ‘embark_C’, ‘embark_Q’, ‘embark_S’, ‘class_1’, ‘class_2’, ‘class_3’] 再到隐藏层12和8和神经元,最后输出2个预测结果。

# ###########################################
class Mish(nn.Module):#Mish激活函数
    def __init__(self):
        super().__init__()
        print("Mish activation loaded...")
    def forward(self,x):
        x = x * (torch.tanh(F.softplus(x)))
        return x
        
torch.manual_seed(0)  #设置随机种子

class ThreelinearModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = nn.Linear(12, 12)
        self.mish1 = Mish()
        self.linear2 = nn.Linear(12, 8)
        self.mish2 = Mish()
        self.linear3 = nn.Linear(8, 2)
        self.softmax = nn.Softmax(dim=1)
        self.criterion = nn.CrossEntropyLoss() #定义交叉熵函数

    def forward(self, x): #定义一个全连接网络
        lin1_out = self.linear1(x)
        out1 = self.mish1(lin1_out)
        out2 = self.mish2(self.linear2(out1))

        return self.softmax(self.linear3(out2))
    

    def getloss(self,x,y): #实现LogicNet类的损失值计算接口
        y_pred = self.forward(x)
        loss = self.criterion(y_pred,y)#计算损失值得交叉熵
        return loss

##############################

训练模型并输出结果

我这里训练了500轮。

net = ThreelinearModel()

num_epochs = 600

optimizer = torch.optim.Adam(net.parameters(), lr=0.04)


print(train_features.dtype)
print(train_labels.dtype)
input_tensor = torch.from_numpy(train_features).type(torch.FloatTensor)
label_tensor = torch.from_numpy(train_labels)

losses = []#定义列表,用于接收每一步的损失值
for epoch in range(num_epochs): 
    loss = net.getloss(input_tensor,label_tensor)
    losses.append(loss.item())
    optimizer.zero_grad()#清空之前的梯度
    loss.backward()#反向传播损失值
    optimizer.step()#更新参数
    if epoch % 20 == 0:
        print ('Epoch {}/{} => Loss: {:.2f}'.format(epoch+1, num_epochs, loss.item()))


os.makedirs('models', exist_ok=True)
torch.save(net.state_dict(), 'models/titanic_model.pt')    


def moving_average(a, w=10):#定义函数计算移动平均损失值
    if len(a) < w:
        return a[:]
    return [val if idx < w else sum(a[(idx-w):idx])/w for idx, val in enumerate(a)]

def plot_losses(losses):
    avgloss= moving_average(losses) #获得损失值的移动平均值
    plt.figure(1)
    plt.subplot(211)
    plt.plot(range(len(avgloss)), avgloss, 'b--')
    plt.xlabel('step number')
    plt.ylabel('Training loss')
    plt.title('step number vs. Training loss')
    plt.show()

plot_losses(losses)

#输出训练结果
out_probs = net(input_tensor).detach().numpy()
out_classes = np.argmax(out_probs, axis=1)
print("Train Accuracy:", sum(out_classes == train_labels) / len(train_labels))

#测试模型
test_input_tensor = torch.from_numpy(test_features).type(torch.FloatTensor)
out_probs = net(test_input_tensor).detach().numpy()
out_classes = np.argmax(out_probs, axis=1)
print("Test Accuracy:", sum(out_classes == test_labels) / len(test_labels))

#####################################

在这里插入图片描述
如果不加平滑的话效果如下。
在这里插入图片描述
Train Accuracy: 0.8417030567685589
Test Accuracy: 0.7938931297709924

完整代码:

import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
import os
from scipy import stats
import pandas as pd

titanic_data = pd.read_csv(r"E:\desktop\Home_Code\pytorch\chapter5\titanic3.csv")
print(titanic_data.columns)

#用哑变量将指定字段转成one-hot
titanic_data = pd.concat([titanic_data,
                          pd.get_dummies(titanic_data['sex']),
                          pd.get_dummies(titanic_data['embarked'],prefix="embark"),
                          pd.get_dummies(titanic_data['pclass'],prefix="class")], axis=1)

print(titanic_data.columns )
print(titanic_data['sex'])
print(titanic_data['female'])
print(titanic_data['embark_C'])

# print(titanic_data['age'])
# #处理None值
titanic_data["age"] = titanic_data["age"].fillna(titanic_data["age"].mean())
titanic_data["fare"] = titanic_data["fare"].fillna(titanic_data["fare"].mean())#乘客票价
# print(titanic_data['age'])

# #删去无用的列
titanic_data = titanic_data.drop(['name','ticket','cabin','boat','body','home.dest','sex','embarked','pclass'], axis=1)
print(titanic_data.columns)
# #
# ####################################


# #分离样本和标签
labels = titanic_data["survived"].to_numpy()
print(labels)
titanic_data = titanic_data.drop(['survived'], axis=1)
data = titanic_data.replace({True:1, False:0}).to_numpy()
print(data)

# #样本的属性名称
feature_names = list(titanic_data.columns)
print(feature_names)


# #将样本分为训练和测试两部分
np.random.seed(10)#设置种子,保证每次运行所分的样本一致
train_indices = np.random.choice(len(labels), int(0.7*len(labels)), replace=False)
test_indices = list(set(range(len(labels))) - set(train_indices))

train_features = data[train_indices]
train_labels = labels[train_indices]
test_features = data[test_indices]
test_labels = labels[test_indices]
print(len(test_labels))#393
# ###########################################
class Mish(nn.Module):#Mish激活函数
    def __init__(self):
        super().__init__()
        print("Mish activation loaded...")
    def forward(self,x):
        x = x * (torch.tanh(F.softplus(x)))
        return x
        
torch.manual_seed(0)  #设置随机种子

class ThreelinearModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = nn.Linear(12, 12)
        self.mish1 = Mish()
        self.linear2 = nn.Linear(12, 8)
        self.mish2 = Mish()
        self.linear3 = nn.Linear(8, 2)
        self.softmax = nn.Softmax(dim=1)
        self.criterion = nn.CrossEntropyLoss() #定义交叉熵函数

    def forward(self, x): #定义一个全连接网络
        lin1_out = self.linear1(x)
        out1 = self.mish1(lin1_out)
        out2 = self.mish2(self.linear2(out1))

        return self.softmax(self.linear3(out2))
    

    def getloss(self,x,y): #实现LogicNet类的损失值计算接口
        y_pred = self.forward(x)
        loss = self.criterion(y_pred,y)#计算损失值得交叉熵
        return loss

##############################
        
net = ThreelinearModel()

num_epochs = 600

optimizer = torch.optim.Adam(net.parameters(), lr=0.04)


print(train_features.dtype)
print(train_labels.dtype)
input_tensor = torch.from_numpy(train_features).type(torch.FloatTensor)
label_tensor = torch.from_numpy(train_labels)

losses = []#定义列表,用于接收每一步的损失值
for epoch in range(num_epochs): 
    loss = net.getloss(input_tensor,label_tensor)
    losses.append(loss.item())
    optimizer.zero_grad()#清空之前的梯度
    loss.backward()#反向传播损失值
    optimizer.step()#更新参数
    if epoch % 20 == 0:
        print ('Epoch {}/{} => Loss: {:.2f}'.format(epoch+1, num_epochs, loss.item()))


os.makedirs('models', exist_ok=True)
torch.save(net.state_dict(), 'models/titanic_model.pt')    


def moving_average(a, w=10):#定义函数计算移动平均损失值
    if len(a) < w:
        return a[:]
    return [val if idx < w else sum(a[(idx-w):idx])/w for idx, val in enumerate(a)]

def plot_losses(losses):
    avgloss= moving_average(losses) #获得损失值的移动平均值
    plt.figure(1)
    plt.subplot(211)
    plt.plot(range(len(avgloss)), avgloss, 'b--')
    plt.xlabel('step number')
    plt.ylabel('Training loss')
    plt.title('step number vs. Training loss')
    plt.show()

plot_losses(losses)

#输出训练结果
out_probs = net(input_tensor).detach().numpy()
out_classes = np.argmax(out_probs, axis=1)
print("Train Accuracy:", sum(out_classes == train_labels) / len(train_labels))

#测试模型
test_input_tensor = torch.from_numpy(test_features).type(torch.FloatTensor)
out_probs = net(test_input_tensor).detach().numpy()
out_classes = np.argmax(out_probs, axis=1)
print("Test Accuracy:", sum(out_classes == test_labels) / len(test_labels))

#####################################

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

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

相关文章

【前端工具】使用Echats生成关系图谱,可展开折叠

目录 一、需求背景与效果 二、echarts源码 一、需求背景与效果 根据服务关系制作关系图谱&#xff0c;echarts官方关系图没有想要的案例&#xff0c;网上也没有好的效果&#xff0c;故参考网上已有的部分案例&#xff0c;自行写了一个&#xff0c;效果还不错。 当前echarts…

Centos7单机安装Redis

安装Redis依赖 Redis是基于C语言&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl ​ 上传安装包并解压 上传安装包redis-6.2.12至/home目录下 ​ # 解压 tar -xzf redis-6.2.12.tar.gz # 安装 cd redis-6.2.12 make && mak…

react ant table设置动态scroll,且某些列的长度固定

设置scroll x的值为列的个数*100 1.代码 const columns [ {title: 料号描述,dataIndex: itemDesc,align:left,width: 200,ellipsis: true,} ]<EditableProTableclassName"details-table"columns{columns}loading{loading}rowKey"id"value{dataSource}…

C++笔记之自引用结构体

C笔记之自引用结构体 code review! 文章目录 C笔记之自引用结构体1.在结构体中引用相同类型的结构体&#xff0c;并且可以使用指针或引用来实现。2.自引用结构体构建链表3.自引用结构体构建二叉树附:代码随想录——链表定义附:代码随想录——二叉树定义 1.在结构体中引用相同…

分布式幂等问题解决方案

目录 一 背景 二 什么是幂等 三 解决方案三部曲 第一部曲&#xff1a;识别相同请求 第二部曲&#xff1a;列出并减少副作用的分析维度 第三部曲&#xff1a;识别细粒度副作用&#xff0c;针对性设计解决方案 四 总结 一 背景 分布式系统由众多微服务组成&#xff0c;微…

从0到1搭建Springboot整合Quartz定时任务框架(保姆级教学+Gitee源码)

前言&#xff1a;最近学习了目前主流的若依框架&#xff0c;这是一个非常优秀的开源项目&#xff0c;故此我这边把它的源码全部剖析了一遍&#xff0c;简化了它的框架&#xff0c;我会通过这篇博客详细讲解我是如何进行推敲和从0到1搭建这个项目的流程。 目录 一、Quartz简介 …

Java并发(十二)----线程应用之多线程解决烧水泡茶问题

1、背景 统筹方法&#xff0c;是一种安排工作进程的数学方法。它的实用范围极广泛&#xff0c;在企业管理和基本建设中&#xff0c;以及关系复杂的科研项目的组织与管理中&#xff0c;都可以应用。 怎样应用呢&#xff1f;主要是把工序安排好。 比如&#xff0c;想泡壶茶喝。…

【前后端分离开发及项目部署流程】

文章目录 前后端分离开发技术1 前后端分离开发1.1 介绍1.2 开发流程1.3 前端技术栈&#xff08;了解&#xff09; 2 Yapi&#xff08;定义API接口&#xff09;2.1 介绍2.2 使用 3 Swagger3.1 介绍3.2 使用方式3.3 常用注解 4 项目部署4.1 部署架构4.2 部署环境说明4.3 部署前端…

chatgpt赋能python:如何使用Python访问共享目录——让共享变得简单易行

如何使用Python访问共享目录 —— 让共享变得简单易行 作为一种高效而强大的编程语言&#xff0c;Python拥有各种各样的应用。其中一个非常重要的应用场景就是对共享目录的访问和操作。无论是在家庭网络&#xff0c;企业内网或者云存储平台&#xff0c;共享目录的重要性毋庸置…

两个链表的入环节点(java)

两个链表的入环节点 两个链表的入环节点解题思路代码演示 链表相关的题 两个链表的入环节点 给定两个可能有环也可能无环的单链表&#xff0c;头节点head1和head2 请实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的第一个节点。如果不相交返回null 要求如果…

ATTCK(一)之为什么要学习ATTCK

ATT&CK 简介 本系列旨在介绍网络红蓝对抗领域最好的ATT&CK矩阵模型&#xff0c;以期帮助有意愿深耕在红蓝对抗领域的人员能系统性的掌握红蓝对抗领域的知识和经验。本系列将详细ATT&CK的起源、发展历史&#xff0c;ATT&CK矩阵相对其他High-Level红蓝对抗模型…

Redis7【② Key通用命令 十大数据类型】

1 Key的通用命令 redis命令不区分大小写&#xff0c;但是key是区分大小写的。没有返回值的命令执行成功会返回1&#xff0c;失败返回0。 1. KEYS 查看所有的key&#xff0c;返回值是一个数组 2. EXISTS EXISTS key [key ...]&#xff1a;返回给定的key中已存在的个数&#xf…

前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版

前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模版&#xff0c; 请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13221 效果图如下&#xff1a; 实现代码如下&#xff1a; # cc-selectBox #### 使用方法 使…

【计算机网络】可靠传输的实现机制

1、停止-等待协议SW 信道利用率 题目 小结 2.回退N帧协议GBN Go-Back-N 题目 小结

设计模式3:单例模式:JMM与volatile和synchronized的关系

本文目录 JMM简介Java 内部内存模型(The Internal Java Memory Model)硬件内存架构(Hardware Memory Architecture)弥合 Java 内存模型和硬件内存架构之间的差距(Bridging The Gap Between The Java Memory Model And The Hardware Memory Architecture)1.共享对象的可见性2.竞…

OpenStack(T版)——计算(Nova)服务介绍与安装

文章目录 OpenStack(T版)——计算(Nova)服务介绍与安装安装与配置(controller)准备(1)创建数据库(2)加载环境变量(3)创建认证服务凭据(4)创建Nova计算服务组件的API endpoint 安装和配置Nova计算服务组件(1)安装软件包(2)编辑/etc/nova/nova.conf 完成以下操作(3)同步数据库验证…

云服务器Linux防火墙云锁安装部署及使用 技术支持服务器安全运维

服务器必备安全防护及运维管理SAAS解决方案&#xff0c;支持windows/linux服务器跨平台实时、批量、远程安全管理&#xff0c;有效对抗服务器入侵和网络攻击。 服务器&#xff1a;Redhat/CentOS/Ubuntu/SUSE/中标麒麟 64位 Web中间件&#xff1a;Apache/Nginx/kangle/Tomcat/W…

【软考网络管理员】2023年软考网管初级常见知识考点(26)- HTML常见属性标签、表格、表单详解

涉及知识点 Html的概念&#xff0c;html常见标签&#xff0c;html常见属性&#xff0c;html表格&#xff0c;html表单&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码…

5-2图像处理经典案例:正弦噪声图像去噪

学习目标&#xff1a; 图像处理经典案例 去除噪声 1.简述 图像降噪的英文名称是Image Denoising&#xff0c; 图像处理中的专业术语。是指减少数字图像中噪声的过程&#xff0c;有时候又称为图像去噪。图像的噪声来源相对复杂&#xff0c;搞清楚图像噪声的成因对我们进行…

B+树

B树 B树是对B树的一种变形树&#xff0c;它与B树的差异在于: 非叶结点仅具有索引作用&#xff0c;也就是说&#xff0c;非叶子结点只存储key&#xff0c;不存储value 树的所有叶结点构成一个有序链表&#xff0c;可以按照key排序的次序遍历全部数据 B树存储数据 若参数M选…