深度学习-线性回归+基础优化算法

目录

  • 线性模型
  • 衡量预估质量
  • 训练数据
  • 参数学习
    • 训练损失
    • 最小化损失来学习参数
    • 显式解
  • 总结
  • 基础优化
    • 梯度下降
      • 选择学习率
    • 小批量随机梯度下降
      • 选择批量大小
  • 总结
  • 线性回归的从零开始实现
    • 实现一个函数读取小批量效果展示
      • 这里可视化看一下
    • 线性回归从零开始实现
    • 线性回归的简洁实现效果展示
    • 线性回归的简洁实现
  • 问题总结

线性模型

在这里插入图片描述
线性模型可以看做是单层神经网络

在这里插入图片描述




衡量预估质量

在这里插入图片描述




训练数据

在这里插入图片描述

参数学习

训练损失

在这里插入图片描述
这里的b应该加粗,原先b是标量然后通过广播机制变为一列,即向量b。

最小化损失来学习参数

在这里插入图片描述

显式解

加入一列全一的特征,加入X中。即:
在这里插入图片描述
将偏差加入权重。即:
在这里插入图片描述


损失函数:

在这里插入图片描述


示范过程:

在这里插入图片描述
在这里插入图片描述

因为是线性模型:所以损失是凸函数,所以最优解满足
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述




总结

1、线性回归是对n维输入的加权,外加偏差。
2、使用平方损失来衡量预测值和真实值的差异。
3、线性回归有显示解。
4、线性回归可以看做是单层神经网络。



基础优化

梯度下降

当一个模型没有显式解的时候

在这里插入图片描述

选择学习率

在这里插入图片描述




小批量随机梯度下降

在这里插入图片描述

选择批量大小

在这里插入图片描述




总结

在这里插入图片描述




线性回归的从零开始实现

我们将从零开始实现整个方法,包括数据流水线、模型、损失函数和小批量随机梯度下降优化器。
在这里插入图片描述
在这里插入图片描述

import torch
def synthetic_data(w, b, num_examples):
    """生成y=Xw+b+噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
print('features:', features[0], '\nlabel:', labels[0])

正态分布函数:normal()
1、normal(0,1,(num_examples,len(w)))表示均值为0,方差为1的随机数,它的大小是说有num_examples个样本,列数是w的长度

2、矩阵乘法:matmul()

3、y.reshape((-1, 1)中的-1表示维度的大小自动计算,第二个维度是1表示新数组将有一个列。
例如:

import torch
y = torch.tensor([1, 2, 3, 4, 5])
print(y.reshape((-1, 1)))

结果:
在这里插入图片描述

在这个例子中,-1被自动替换为5,因为y有5个元素,并且你想要一个只有一列的二维数组。所以,根据另一个维度(这里是1)自动计算这个维度的大小。

4、features是特征,features中的每一行都包含一个二维数据样本,labels中的每一行包含一维标签值(一个标量)

在这里插入图片描述

在这里插入图片描述

import torch
from d2l import torch as d2l
import matplotlib.pyplot as plt


def synthetic_data(w, b, num_examples):
    """生成y=Xw+b+噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))#方差为0,均值为1,num_examples个样本,列数是w的长度
    y = torch.matmul(X, w) + b #这里的y是一个行向量
    y += torch.normal(0, 0.01, y.shape) 
    #意思是给 y 加上一个符合正态分布的随机噪声。torch.normal(0, 0.01, y.shape) 生成一个与 y 形状相同的张量,
    #其中的元素是从均值为 0、标准差为 0.01 的正态分布中随机抽取的。
    #然后,这个随机生成的张量会被加到 y 上。
    return X, y.reshape((-1, 1)) #这里的y目的是转换为列向量


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

d2l.set_figsize() #用于设置Matplotlib图像的大小,可以接受两个参数宽度和高度
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1) #detach()分离出数值,不再含有梯度
plt.show()

d2l.plt.scatter(): 使用 scatter 函数绘制散点图。
第一个参数是x轴的数据(即 features 的第二列)。
第二个参数是y轴的数据(即 labels)。
第三个参数1: 这是散点的大小。在这里,所有散点的大小都被设置为1。

features[:, 1].detach().numpy():
features[:, 1]:从 features 数组中选择所有行的第二列
.detach(): features 是一个PyTorch张量,.detach() 方法用于创建一个新的张量,从当前计算图中分离出来,这样它就不会计算梯度。这对于绘图来说通常是必要的,因为我们不需要对绘图数据进行反向传播。
.numpy(): 将PyTorch张量转换为NumPy数组,因为 matplotlib 通常与NumPy数组一起使用。

结果:
在这里插入图片描述




实现一个函数读取小批量效果展示

import random
import torch


def synthetic_data(w, b, num_examples):
    """生成y=Xw+b+噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)


def data_iter(batch_size, features, labels):
    num_examples = len(features) #多个样本
    indices = list(range(num_examples)) #从0到n-1
    # 这些样本是随机读取的,没有特定的顺序
    random.shuffle(indices)  # 将列表中的元素打乱顺序
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(
            indices[i:min(i + batch_size, num_examples)]
        )
        yield features[batch_indices], labels[batch_indices]
		#yield相当于返回一个可迭代对象

batch_size = 10
for X, y in data_iter(batch_size, features, labels):
    print(X, '\n', y)
    break

indices 是一个从0到 num_examples-1 的整数列表,代表所有样本的索引。

i:min(i + batch_size, num_examples) 是一个切片操作,用于从 indices 中选择一部分索引。从 i 开始,选取到 i + batch_size 或者 num_examples(取两者中较小的一个)结束。是为了确保在最后一个批次中不会超出索引范围。例如,如果总共有1000个样本,批大小为100,当 i 为900时,i + batch_size 会超出索引范围,因此 min(i + batch_size, num_examples) 会确保只选取到最后一个索引。

将上面通过切片操作得到的索引列表转换为一个PyTorch张量

data_iter 函数是一个数据迭代器,它接收批大小 batch_size、特征 features 和标签 labels 作为输入。它首先计算样本数量 num_examples,并创建一个从0到 num_examples-1 的索引列表。然后,它打乱索引列表的顺序,以便在每次迭代时随机选择样本。最后,它使用这些随机索引从特征和标签中抽取小批量数据,并使用 yield 语句返回这些数据。yield 使得这个函数成为一个生成器,每次调用时返回一批数据。设置批大小为10,并使用 data_iter 函数迭代数据和标签。在循环中,每次迭代都会打印出一个小批量的特征 X 和标签 y。由于循环后面有一个 break 语句,所以只会打印出第一批数据。

结果:
在这里插入图片描述

这里可视化看一下

import random
import torch
from d2l import torch as d2l
import matplotlib.pyplot as plt


def synthetic_data(w, b, num_examples):
    """生成y=Xw+b+噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)


def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    # 这些样本是随机读取的,没有特定的顺序
    random.shuffle(indices)  # 将列表中的元素打乱顺序
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(
            indices[i:min(i + batch_size, num_examples)]
        )
        yield features[batch_indices], labels[batch_indices]


batch_size = 10
for X, y in data_iter(batch_size, features, labels):
    print(X, '\n', y)
    break

# 获取一个批次的数据
X_batch, y_batch = next(data_iter(batch_size, features, labels))

# 绘制批次数据的散点图
d2l.plt.scatter(X_batch[:, 0].numpy(), y_batch.numpy())
d2l.plt.show()

在这里插入图片描述
在这里插入图片描述




线性回归从零开始实现

import random
import torch

def synthetic_data(w, b, num_examples):
    """生成y=Xw+b+噪声。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)


def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    # 这些样本是随机读取的,没有特定的顺序
    random.shuffle(indices)  # 将列表中的元素打乱顺序
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(
            indices[i:min(i + batch_size, num_examples)]
        )
        yield features[batch_indices], labels[batch_indices]


batch_size = 10

# 定义初始化模型参数,需要w,b进行更新,所以才将requires_grad设置为True
w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
#size=(2, 1)生成的张量 w 是一个形状为 2x1 的二维张量,即它有 2 行和 1 列。
b = torch.zeros(1, requires_grad=True)
#这里的 1 意味着 b 是一个一维张量,它只有一个元素,并且这个元素的值为 0。
#在 PyTorch 中,一维张量通常可以看作是一个向量。
#因此,b 是一个只包含一个元素(值为 0)的向量。


# 定义模型
def linreg(X, w, b):
    """线性回归模型。"""
    return torch.matmul(X, w) + b


# 定义损失函数,其中y_hat是预测值y是真实值
def squared_loss(y_hat, y):
    """均方损失。均方误差公式"""
    return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2


# 定义优化算法
def sgd(params, lr, batch_size):
    """小批量随机梯度下降。"""
    with torch.no_grad():#不需要计算梯度,使用 torch.no_grad() 可以减少内存消耗,并提高运行速度。
        for param in params:#其中param可能是w也可能是b
            param -= lr * param.grad / batch_size
            param.grad.zero_()


lr = 0.03
num_epochs = 3 #意思是把整个数据扫三遍
net = linreg #定义的模型
loss = squared_loss#均方损失
for epoch in range(num_epochs): #每一次对数据扫一遍
    for X, y in data_iter(batch_size, features, labels):
        l = loss(net(X, w, b), y)  #一个长为批量大小的损失
        # 因为’1‘形状是(’batch_size‘,1),而不是一个标量。'1'中的所有元素被加到
        # 并以此计算关于['w','b']的梯度
        l.sum().backward()
        sgd([w, b], lr, batch_size)  # 使用参数的梯度更新
    with torch.no_grad():
        train_l = loss(net(features, w, b), labels)
        print(f'epoch{epoch + 1},loss{float(train_l.mean()):f}')#:f确保train_l.mean()的结果以浮点数形式被格式化并嵌入到字符串中
print(f'w的估计误差:{true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差:{true_b - b}')

在这里插入图片描述
说明 param -= lr * param.grad / batch_size中param.grad / batch_size的含义。是用来计算平均梯度的。
示例:

import torch
 
X = torch.tensor([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0]])
w = torch.tensor([[1.0], [2.0]], dtype=torch.float32, requires_grad=True)
b = torch.tensor([0.0], requires_grad=True)
y = torch.tensor([[0.0], [1.0], [2.0]])
 
y_hat = torch.matmul(X, w) + b
l = (y_hat - y)**2 / 2
l.sum().backward()
 
print(w.grad)
print(b.grad)

运行结果:

tensor([[46.],
        [67.]])
tensor([21.])

计算过程:
在这里插入图片描述
计算损失函数时,对它调用.backward()会将自动求导计算的梯度累积存在param.grad中。当一个批次包含batch_size个样本时,并且每个样本都贡献一个梯度给模型参数。那么调用backward()后,paramgrad中存储的就是这些梯度的和。这就是为什么在更新参数时,需要将param.grad除以batch_size。这样做可以得到一个平均梯度。
这样,w.grad / batch_size和b.grad / batch_size相当于在batch_size中取平均值。
然后这整句公式的含义:是进行梯度下降
在这里插入图片描述




学习率不能太高也不能太低。
当学习率很低时

#当lr = 0.03改为0.001时
lr = 0.001

跑完三次后损失还是很大
在这里插入图片描述

多跑几遍看看

#num_epochs由3改为10
num_epochs = 10

在这里插入图片描述
跑完十次后损失还是很大
学习率很高时

#lr 从0.03改为10时
lr = 10

在这里插入图片描述
这种情况是求导的时候会除0或者是无限的值,然后超出了浮点类型的计算范围。




线性回归的简洁实现效果展示

import torch
from torch.utils import data
from d2l import torch as d2l

def load_array(data_arrays, batch_size, is_train=True):
    """构造一个PyTorch数据迭代器。"""
    #在PyTorch中,data.TensorDataset是一个用于包装数据张量(tensors)的数据集类。
    #*data_arrays 是一个解包操作,它将data_arrays这个元组(或列表)中的每个元素作为单独的参数传递给TensorDataset。
    #data_arrays是一个包含特征张量features和标签张量labels的元组,那么*data_arrays的效果等同于直接传递这两个张量作为参数
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train) #每一次随机从中挑选batch_size个样本,并随机打乱顺序


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
batch_size = 10
data_iter = load_array((features, labels),batch_size)
print(next(iter(data_iter)))#iter() 函数用于获取一个迭代器对象。next() 函数用于获取迭代器对象的下一个元素。

结果:
在这里插入图片描述




# ’nn‘ 是神经网络的缩写
from torch import nn
#使用框架预定义好的层
net = nn.Sequential(nn.Linear(2, 1))#输入的维度是2,输出的维度是1
#这意味着这个线性层接受一个形状为[batch_size, 2]的张量作为输入,并输出一个形状为[batch_size, 1]的张量。

#初始化模型参数
print(net[0].weight.data.normal_(0, 0.01))#net 是一个 nn.Sequential 的实例,它包含了一个 nn.Linear 层。
#.weight表示该层的权重参数。对于 nn.Linear(2, 1),这个权重参数是一个形状为 [2, 1] 的二维张量。
#.data:这是访问张量底层数据的方式。在这里,我们仅用它来初始化权重。
#normal_(0, 0.01):它会将张量的值替换为从均值为0、标准差为0.01的正态分布中抽取的随机值。这里的下划线 _ 表示这是一个原地操作,它会直接修改调用它的张量,而不是返回一个新的张量。
print(net[0].bias.data.fill_(0))#.bias表示该层的偏置参数。对于nn.Linear(2, 1),这个偏置参数是一个形状为[1]的一维张量。
#fill_(0):它会将张量的所有值设置为给定的标量值,这里是0。


结果:在这里插入图片描述

net = nn.Sequential(nn.Linear(2, 1))的使用示例:

import torch  
import torch.nn as nn  
  
# 定义网络模型  
model = nn.Sequential(nn.Linear(2, 1))  
  
# 创建一个输入张量,形状为 [batch_size, 2]  
input_tensor = torch.randn(3, 2)  # 这里batch_size是3  
  
# 通过网络模型传递输入张量  
output_tensor = model(input_tensor)  
  
# 输出张量的形状将是 [batch_size, 1]  
print(output_tensor.shape)  # 输出: torch.Size([3, 1])



线性回归的简洁实现

# ’nn‘ 是神经网络的缩写
import torch.optim
from torch import nn
from torch.utils import data
from d2l import torch as d2l

def load_array(data_arrays, batch_size, is_train=True):
    """构造一个PyTorch数据迭代器。"""
    #在PyTorch中,data.TensorDataset是一个用于包装数据张量(tensors)的数据集类。
    #*data_arrays 是一个解包操作,它将data_arrays这个元组(或列表)中的每个元素作为单独的参数传递给TensorDataset。
    #data_arrays是一个包含特征张量features和标签张量labels的元组,那么*data_arrays的效果等同于直接传递这两个张量作为参数
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train) #每一次随机从中挑选batch_size个样本,并随机打乱顺序


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
batch_size = 10
data_iter = load_array((features, labels),batch_size)

#使用框架预定义好的层
net = nn.Sequential(nn.Linear(2, 1))#输入的维度是2,输出的维度是1
#这意味着这个线性层接受一个形状为[batch_size, 2]的张量作为输入,并输出一个形状为[batch_size, 1]的张量。

#初始化模型参数
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)

#计算均方误差使用的是MSELoss类,也称为平方范数
loss = nn.MSELoss()
#实例化SGD实例,torch.optim.SGD 是一个用于实现随机梯度下降(Stochastic Gradient Descent, SGD)优化算法的类。
trainer = torch.optim.SGD(net.parameters(), lr=0.03)#net.parameters():拿出所有的参数(即权重w和偏置b)。

#训练过程代码和从零开始实现类似
num_epochs = 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)#这里net自带了模型参数,不需要w和b弄进去了
        trainer.zero_grad()#trainer优化器梯度清零
        l.backward()#这里不需要求和,因为pytorch自动求和了
        trainer.step()#进行模型的更新和从零开始的sgd函数类似
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')

结果:在这里插入图片描述




问题总结

1、为啥使用平方损失而不是绝对差值呢
区别不大,但绝对差值是个不可导的函数

2、损失为什么要求平均?
求不求平均本质上没有关系,不求平均梯度的数值有点大,如果使用梯度下降的话,那么不除以n的话,就把学习率除以n。除以n的好处是说:不管批量和样本多大我的梯度都差不多,调学习率好调。

3、线性回归损失函数是不是通常都是MSE(均方损失误差)
是的

4、不管是gd(梯度下降)还是sgd(随机梯度下降)怎么找到合适的学习率?有什么好的方法吗?
两个办法
找到一个对学习率不那么敏感的算法,比如adam。
通过合理的参数的初始化

5、针对batchsize大小的数据集进行网络训练的时候,网络中每个参数更新时的减去的梯度是batchsize中每个样本对应参数梯度求和后取得平均值吗?
是的

6、detach()是什么作用?
告诉不要算梯度了

7、如果样本大小不是批量数的整数倍,那需要随机剔除多余的样本吗?
假设有100个样本,批量大小为60
第一次60,那么剩下40怎么办?
1、普遍做法是拿到一个小的样本,长为40的批量样本
2、把不完整的批量大小扔掉
3、从下一个里面补20个

8、本质上我们为什么要用SGD(随机梯度下降),是因为大部分的实际loss(损失函数)太复杂,推导不出导数为0的解么?只能逐个batch去逼近?
是的

9、l.backward()这里是调用pytorch自定义的back propogation(梯度反向传播)吗?
是的

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

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

相关文章

selenium在Pycharm中结合python的基本使用、交互、无界面访问

下载 下载与浏览器匹配的浏览器驱动文件,这里一定注意的是,要选择和浏览器版本号相同的驱动程序,否则后面会有很多问题。 (1)浏览器(以google为例)版本号的查询: 我这里的版本号是1…

大规模数据处理和分析

大规模数据处理和分析:随着大数据技术的发展,处理大规模数据集的能力成为了一种竞争优势。热门问题包括数据清洗、特征工程、分布式计算等。 当我们谈到大规模数据处理和分析时,通常涉及到以下几个方面的内容: 数据清洗&#xff1…

C语言 | Leetcode C语言题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; #define max(a, b) (((a) > (b)) ? (a) : (b))bool canJump(int* nums, int numsSize){int cover 0;int i;// 只可能获取cover范围中的步数&#xff0c;所以i<coverfor(i 0; i < cover; i) {// 更新cover为从i出发能到达的最大…

prime1--vulnhub靶场通关教程

一. 信息收集 1. 探测目标主机IP地址 arp-scan -l //查看网段 vm 编辑--查看虚拟网络编辑器&#xff0c;看到靶机的网段 网段是&#xff1a; 192.168.83.0 是c段网络 2. 全面检测目标IP nmap -sP 192.168.83.1/24 靶机ip是&#xff1a; 192.168.83.145 攻击机的ip是&…

浏览器渲染机制:重排(Reflow)与重绘(Repaint)以及Vue优化策略

浏览器渲染机制是一个复杂但有序的过程&#xff0c;其目的是将HTML、CSS和JavaScript代码转化为用户可以看到和交互的视觉界面。重排&#xff08;Reflow&#xff09;与重绘&#xff08;Repaint&#xff09;是浏览器渲染过程中对页面元素进行更新的两个重要步骤&#xff0c;理解…

格瑞威特 | 邀您参加2024全国水科技大会暨技术装备成果展览会

—— 展位号&#xff1a;A13 —— 企业介绍 北京格瑞威特环保设备有限公司成立于2009年&#xff0c;是专业从事设计、研发、销售智能加药计量泵、在线水质分析仪表、便携式水质分析仪表、流量计、液位计、阀门、搅拌机、烟气报警仪、加药装置等各类水处理设备及配件的OEM供服…

C++ | Leetcode C++题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canJump(vector<int>& nums) {int n nums.size();int rightmost 0;for (int i 0; i < n; i) {if (i < rightmost) {rightmost max(rightmost, i nums[i]);if (rightmost > n - 1) {r…

亚马逊云科技AWS将推出数据工程师全新认证(有资料)

AWS认证体系最近更新&#xff0c;在原有12张的基础上&#xff0c;将在2023年11月27日添加第13张&#xff0c;数据工程师助理级认证(Data Engineer Associate)&#xff0c;并且在2024/1/12前半价(省75刀&#xff1d;544人民币。 原有的数据分析专家级认证(Data Analytics Specia…

tfrecord文件介绍、读取、写入介绍

1、tfrecord文件格式介绍 tfrecord文件格式&#xff0c;是深度学习框架tensorflow专用的一种文件格式&#xff0c;其底层使用protobuf&#xff0c;TensorFlow(python)也提供了api用于读取和写入tfrecord&#xff0c;非常方便&#xff0c;而对于golang语言&#xff0c;目前没有成…

开发总结-Controller层

Controller层一定要try catch一下&#xff0c;不然里面报的错可能导致程序报错。 catch中就表示有错误就 Return ResultUtils.err(e.getMessage()) 必填项校验 在实体属性中添加注解 NotNull : 用在基本类 型上 不能为null 但可以为空字符串 NotEmpty : 用在集合类上 不能为…

Java Swing 桌面程序使用 GraalVM 封装为 exe 文件进行Native化

背景 本文主要基于如下两点情况&#xff0c;进行的实际案例&#xff0c;并记录的操作步骤。 使用 Java Swing 开发的小型桌面程序&#xff0c;运行需要依赖当前电脑安装 jre 环境&#xff0c;对使用者很不友好&#xff0c;且相比原生的 exe 程序偏慢。 GraalVM Native 允许开…

SpringMVC整体工作流程

. 用户发起一个请求&#xff0c;请求首先到达前端控制器前端控制器接收到请求后会调用处理器映射器&#xff0c;由此得知&#xff0c;这个请求该由哪一个Controller来进行处理(并未调用Controller)&#xff1b;前端控制器调用处理器适配器&#xff0c;告诉处理器适配器应该要…

甘特图是什么?利用甘特图来优化项目管理流程

在现代项目管理中,图表是一种强大而直观的工具,可以帮助项目经理和团队成员清晰地了解并掌控整个项目进程。其中,甘特图是最常用和最有效的图表之一。 甘特图是一种条形图,可以用来直观地展示项目中各个任务的进度、持续时间和相互关系。它由一个横轴和一个纵轴组成。横轴代表时…

[LitCTF 2023]Ping、[SWPUCTF 2021 新生赛]error、[NSSCTF 2022 Spring Recruit]babyphp

[LitCTF 2023]Ping 尝试ping一下127.0.0.1成功了&#xff0c;但要查看根目录时提示只能输入IP 查看源代码&#xff0c;这段JavaScript代码定义了一个名为check_ip的函数&#xff0c;用于验证输入是否为有效的IPv4地址。并且使用正则表达式re来匹配IPv4地址的格式。 对于这种写…

【计算机组成原理 1】计算机硬件概念

0️⃣ 参考 王道计算机考研408 1️⃣ 冯诺依曼机 核心思想【存储程序】 存储程序就是将指令先放入内存中&#xff0c;再从内存读取指令执行&#xff0c;从而实现自动化。核心 【运算器】 说明&#xff1a;在计算机系统中&#xff0c;软件和硬件在逻辑上是等效的 例如&#xf…

Debian 系统设置SSH 连接时长

问题现象&#xff1a; 通过finalshell工具连接Debian系统远程操作时&#xff0c;总是一下断开一下断开&#xff0c;要反复重新连接 &#xff0c;烦人&#xff01; 解决办法&#xff1a; 找到ssh安装目录下的配置文件&#xff1a;sshd_config vi sshd_config &#xff1a; 找到…

基于Springboot+Vue的Java项目-火车票订票系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

Matlab实现CNN-LSTM模型,对一维时序信号进行分类

1、利用Matlab2021b训练CNN-LSTM模型&#xff0c;对采集的一维时序信号进行分类二分类或多分类 2、CNN-LSTM时序信号多分类执行结果截图 训练进度&#xff1a; 网络分析&#xff1a; 指标变化趋势&#xff1a; 代码下载方式&#xff08;代码含数据集与模型构建&#xff0c;附…

基于Springboot的爱心商城系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的爱心商城系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

Idea异常 | Process 453 is still running

问题现象 Idea启动报错"Cannot connect to already running IDE instance. Exception: Process 453 is still running" 问题原因 通常原因是Idea未正常关闭&#xff0c;导致进程锁文件没有删除。同样Pycharm等其它JeBrains等产品也有可能出现这个问题 解决办法 查…