【基础教程】Tutorial on Pytorch 结合官方基础文档和个人经验

参考与前言

此教程首次书写于2021年12月份 至 2022年4月份间不断补充;阅读本文时可以对着代码运行查看

  1. 官方网址:https://pytorch.org/tutorials/ 【基本从这里翻译而来 更简洁版+碎碎念】
  2. https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py
  3. 简单版分类器:https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html

好像还是很tensorflow有点区别的 毕竟 tensorflow emmm 我看一下 好像懂了,我记得久远之前我看过pytorch的 但是因为没做笔记+好久没用了 所以 忘得也挺快

相关训练细节上加速的tutorial:Tutorial: GPU利用率问题 [V]

1. 数据结构

tensor

tensor 是一种特殊的数据结构,与数组和矩阵非常相似。在 PyTorch 中,我们使用 tensor 对模型的输入和输出以及模型的参数进行编码。

  • !哦 而人家tensorflow 收的可以直接是numpy 不不 也是要做点处理啥的

    好吧 torch.from_numpy 也很快 emm

初始化方法

# Directly from data
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)# From a NumPy array
np_array = np.array(data)
x_np = torch.from_numpy(np_array)# From another tensor:
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")# With random or constant values:
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

可以 from numpy 当然也可以to numpy啦,Changes in the NumPy array reflects in the tensor.

t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")t.add_(1)
print(f"t: {t}")
print(f"n: {n}")t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]

Attribute

就是类似numpy里面的.shape, type(), 以及其特有的存储地点:描述它们的形状、数据类型和存储它们的设备。

tensor = torch.rand(3, 4)print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

操作

换个地方放放:

# We move our tensor to the GPU if available
if torch.cuda.is_available():tensor = tensor.to('cuda')print(f"Device tensor is stored on: {tensor.device}")# 和numpy基本一模一样的操作形式
tensor = torch.ones(4, 4)
tensor[:,1] = 0
print(tensor)tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])# -------------------------------------------------
# 把几个tensor合在一起
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])# -------------------------------------------------# 对应位置的元素相乘
# This computes the element-wise product
print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n")
# Alternative syntax:
print(f"tensor * tensor \n {tensor * tensor}")# 矩阵的形式
# This computes the matrix multiplication between two tensors
print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n")
# Alternative syntax:
print(f"tensor @ tensor.T \n {tensor @ tensor.T}")# -------------------------------------------------
print(tensor, "\n")
tensor.add_(5)
print(tensor)tensor([[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.],[1., 0., 1., 1.]])tensor([[6., 5., 6., 6.],[6., 5., 6., 6.],[6., 5., 6., 6.],[6., 5., 6., 6.]])

In-place operations Operations that have a _ suffix are in-place. For example: x.copy_(y), x.t_(), will change x.

2. 数据与加载

处理数据样本的代码可能会变得混乱且难以维护; 我们希望数据集代码与模型训练代码分离,以获得更好的可读性和模块化。pytorch提供了两个数据的使用库: torch.utils.data.DataLoader and torch.utils.data.Dataset that allow you to use pre-loaded datasets as well as your own data.

  • Dataset stores the samples and their corresponding labels
  • DataLoader wraps an iterable around the Dataset to enable easy access to the samples.

当然pytorch里的Dataset 也有一些开源的数据集成,更多查询: Image Datasets, Text Datasets, and Audio Datasets

FashionMNIST

import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plttraining_data = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor()
)test_data = datasets.FashionMNIST(root="data",train=False,download=True,transform=ToTensor()
)labels_map = {0: "T-Shirt",1: "Trouser",2: "Pullover",3: "Dress",4: "Coat",5: "Sandal",6: "Shirt",7: "Sneaker",8: "Bag",9: "Ankle Boot",
}
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):sample_idx = torch.randint(len(training_data), size=(1,)).item()img, label = training_data[sample_idx]figure.add_subplot(rows, cols, i)plt.title(labels_map[label])plt.axis("off")plt.imshow(img.squeeze(), cmap="gray")
plt.show()

Custom Dataset

自定义的Dataset必须有这三个函数: init, len, and getitem.

对应 FashionMNIST 的数据集,其照片是存在 img_dir文件夹中 and their labels are stored separately in a CSV file annotations_file.

官方示例:

import os
import pandas as pd
from torchvision.io import read_imageclass CustomImageDataset(Dataset):def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):self.img_labels = pd.read_csv(annotations_file)self.img_dir = img_dirself.transform = transformself.target_transform = target_transformdef __len__(self):return len(self.img_labels)def __getitem__(self, idx):img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])image = read_image(img_path)label = self.img_labels.iloc[idx, 1]if self.transform:image = self.transform(image)if self.target_transform:label = self.target_transform(label)return image, label

init

init 函数仅在你实例化这个Dataset object的时候运行一次. 我们在这里给出包含图片,label和是否需要转换

如果一个labels.csv文件长这样的话:

tshirt1.jpg, 0
tshirt2.jpg, 0
......
ankleboot999.jpg, 9

那么__init__函数为:

def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):self.img_labels = pd.read_csv(annotations_file, names=['file_name', 'label'])self.img_dir = img_dirself.transform = transformself.target_transform = target_transform

len

这个函数主要返回我们数据集的大小,比如:

def __len__(self):return len(self.img_labels)

getitem

这个函数主要用来加载输入的 idx 对应的数据,基于给的idx,可以定位到哪张图片,然后使用 read_image 转成tensor,从 self.img_labels找到对应的label,然后返回tensor格式的图片和一个tuple格式的label

def __getitem__(self, idx):img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])image = read_image(img_path)label = self.img_labels.iloc[idx, 1]if self.transform:image = self.transform(image)if self.target_transform:label = self.target_transform(label)return image, label

transforms

数据并不总是以训练机器学习算法所需的最终处理形式出现。 我们使用转换来对数据进行一些操作并使其适合训练。

从上一条我们知道需要返回tensor格式的数据,如image可能直接可以从库里调用ToTensor()

TorchVision 库里的数据集,通常有两个参数

  • transform to modify the features
  • target_transform to modify the labels - that accept callables containing the transformation logic.

torchvision.transforms 这个模块,已经提供了很多通用的transform的功能

例如以下,同样FashionMNIST 这个数据集下 feature图片是PIL图片格式,label是整数;为了训练,我们需要把feature归一化成tensors,把label用one-hot encoded的tensor表示,为了实现这些呢:我们就需要使用 ToTensor and Lambda. 比如这里:比前面的多了一行对label的转换

import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambdads = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor(),target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)

比如最近参加kaggle竞赛练手的,写了关于image的transforms

preprocess = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

ToTensor()

ToTensor 是把PIL图片或者是numpy的ndarray转成 FloatTensor. 然后图片的像素intensity值都归一化到[0., 1.]

Lambda Transforms

Lambda 转换适用于任何用户定义的 lambda 函数。 在这里,我们定义了一个函数来将整数转换为单one-hot tensor。 它首先创建一个大小为 10(我们数据集中的标签数量)的zero tensor,并调用 scatter_,它在标签 y 给定的索引上分配一个值=1

target_transform = Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(dim=0, index=torch.tensor(y), value=1))

3. 网络NetWork

构建网络

神经网络由对数据执行操作的层/模块组成。 torch.nn 命名空间提供了构建自己的神经网络所需的所有构建块。 PyTorch 中的每个模块都是 nn.Module 的子类。 神经网络是一个模块,由其他模块(层)组成。 这种嵌套结构允许轻松构建和管理复杂的架构。

在下面是构建一个神经网络来对 FashionMNIST 数据集中的图像进行分类的一个例子

import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transformsdevice = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f'Using {device} device')class NeuralNetwork(nn.Module):def __init__(self):super(NeuralNetwork, self).__init__()self.flatten = nn.Flatten()self.linear_relu_stack = nn.Sequential(nn.Linear(28*28, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),)def forward(self, x):x = self.flatten(x)logits = self.linear_relu_stack(x)return logitsmodel = NeuralNetwork().to(device)
print(model)

通过继承 nn.Module 来定义我们的神经网络,并在 __init__ 中初始化神经网络层。 每个 nn.Module 子类都在 forward 方法中实现对输入数据的操作。

  • 这里就是和tensorflow不太一样的地方,比如这里tensorflow定义完后 直接是 .fit 然后就是trainde 过程了

    # Creat a neural network now
    model_cnn = Sequential(name = "CNN")# First Convolution Layer
    model_cnn.add(Conv2D(8, input_shape = x_trainr.shape[1:], kernel_size = 3,padding='same',strides=1,activation='relu'))
    model_cnn.add(MaxPooling2D(pool_size=2))# 2nd Convolution Layer
    model_cnn.add(Conv2D(16,kernel_size = 3,padding='same',strides=1,activation='relu'))
    model_cnn.add(MaxPooling2D(pool_size=2))# Fully connected layer
    model_cnn.add(Flatten())
    model_cnn.add(Dense(64))
    model_cnn.add(Activation("relu"))# Last Fully connected layer
    model_cnn.add(Dense(11))model_cnn.add(Activation("softmax"))
    model_cnn.compile(loss = "sparse_categorical_crossentropy",optimizer="adam",metrics=['accuracy'])
    model_cnn.summary()
    model_cnn.fit(x_trainr,y_train,epochs=10)
    print("Test Dataset:")
    test_loss, test_acc = model_cnn.evaluate(x_testr,y_test)
    

使用将data传到模型里就行,它会自动运行 model’s forward, 同时还有 background operations. 不需要自己调用 model.forward() directly!

在输入上调用模型会返回一个 10D tensor,其中包含每个类的原始预测值。 我们通过将其传递给 nn.Softmax 模块的实例来获得预测概率。

X = torch.rand(1, 28, 28, device=device)
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")
  • 奇怪模型的训练是啥?直接输入数据,训练过程是?

    原来是自己写ephoc来训练

block 形式的

参考于:5. 深度学习计算 - 动手学深度学习 2.0.0-beta0 documentation

训练方法

直接快进到这里了,这个是示例里的:

import torch.nn as nn
import torch.nn.functional as F# 1. 导入数据
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
batch_size = 4
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,shuffle=False, num_workers=2)
classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 2. 定义网络层
class Net(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = torch.flatten(x, 1) # flatten all dimensions except batchx = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()# 3. 评判器
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)# 4. 训练过程
for epoch in range(2):  # loop over the dataset multiple timesrunning_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputs; data is a list of [inputs, labels]inputs, labels = data# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# print statisticsrunning_loss += loss.item()if i % 2000 == 1999:    # print every 2000 mini-batchesprint('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0
print('Finished Training')# 5. save model
PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)# 6. 从测试集中弄一些出来
dataiter = iter(testloader)
images, labels = dataiter.next()# print images
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))# 7. 打开原来的model
net = Net()
net.load_state_dict(torch.load(PATH))# 8. 输出output
outputs = net(images)
_, predicted = torch.max(outputs, 1)
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]for j in range(4)))

动态调整 learning rate

参考,此处需要注意文档的版本选择,因为1.10后的torch实现了更多动态调整的方式:torch.optim - PyTorch 1.10.1 documentation

使用方式参考:

import torch.optim as optim
net = MODEL(out_label = len(classes)).to(device)criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=lr)# 动态改变Learning rate
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)# 4. 训练过程
for epoch in tqdm(range(num_epochs)):  # loop over the dataset multiple timesfor i, data in enumerate(train_dataloader,0):# get the inputs; data is a list of [inputs, labels]inputs, labels = datainputs, labels = inputs.to(device), labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()scheduler.step()

4. 数据操作

由杰哥代码发现的一个更好用的:rearrange

rearrange - Einops

Pytorch view() permute() contiguous() transpose()

view

CSDN介绍;官网介绍

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda, Compose
import matplotlib.pyplot as pltx = torch.rand(24,3,256,256)
x.size()a = x.view(x.size(0), -1)
print('after view',a.size())m = nn.Sequential(nn.Flatten())
y = m(x)
print('after flatten',y.size())

有意思的是,CSDN 下有人问了 和flatten有什么区别 这个操作,从数据输出上来看,都是一样的输出 [24,196608] ,而且展开的数据也都是一样的,关于这个我提了一个问 有人回答了 真不错呀,省流版:一般大家在model中都会习惯性nn.Flatten()

YP大哥:好像是某个开的空间是连续的

  • 但是我实践了一下 并没有什么区别?首先是关于contiguous说的是返回和原数据一样的形式的连续空间tensor,但是我一改b/y 还是会对其他造成影响,也就是说明 =和=.contiguous 都是直接指向了原tensor的地址?→ 但这点我实际vscode debug的时候发现地址并不一样

    view

December 14, 2021 10:22 PM (GMT+8) 刚刚又仔细看了一下,是这样的view的操作需要这个tensor在连续的空间呢,所以呢一般都会在view操作前先contiguous,使其放在一个连续的内存空间上

contiguous

将数据放在连续空间内存下,一般在view操作前会用一下,因为tensor经过permute,

permute

torch官方

torch.permute(input, dims) → Tensor
  • input (Tensor) – 输出的tensor数据
  • dims (tuple of python:ints) – 想要的维度的顺序

举个例子,在这里 2,0,1 表示 我希望第二个维度(也就是size 5那里)在第0个,第零个维度在第1个,第一个维度在第2个【以0为开始哈】

x = torch.randn(2, 3, 5)
x.size()
torch.permute(x, (2, 0, 1)).size()

所以permute后,size就变成了(5,2,3)

sqeeze 和 unsqeeze

  • **torch.squeeze():**这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,默认是将a中所有为1的维度删掉。也可以通过dim指定位置,删掉指定位置的维数为1的维度。
  • **torch.unsqueeze():**这个函数主要是对数据维度进行扩充。需要通过dim指定位置给指定位置加上维数为1的维度

这里是关于squeeze和unsqueeze的图示 (图片摘自stackexchange):
请添加图片描述


赠人点赞 手有余香 😆;正向回馈 才能更好开放记录 hhh

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

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

相关文章

vue3+element-plus 实现动态菜单和动态路由的渲染

在 Vue.js 中,使用 Vue Router 管理路由数据,并将其用于渲染 el-menu(Element UI 的菜单组件)通常涉及以下几个步骤: 定义路由元数据: 在你的路由配置中,为每个路由项添加 meta 字段&#xff0c…

无人机10公里WiFi图传摄像模组,飞睿智能超清远距离无线监控,智能安防新潮流

在这个科技日新月异的时代,我们对影像的捕捉和传播有了更高的要求。从传统的有线传输到无线WiFi图传,每一次技术的飞跃都为我们带来了全新的视觉体验。今天,我们要探讨的,正是一款具有划时代意义的科技产品——飞睿智能10公里WiFi…

自学网络安全,从小白到大神的破茧之路!

在当今数字化高速发展的时代,网络安全已经成为了至关重要的领域。无论是个人的隐私保护,还是企业、国家的关键信息资产维护,都离不开网络安全的有力保障。出于对这一领域的浓厚兴趣以及对未来职业发展的清晰规划,我毅然决然地踏上…

0722_驱动1 字符设备驱动框架

一、字符设备驱动框架 字符设备驱动按照字节流进行访问,并且只能顺序访问 设备号一共有32位,主设备号(高12位)次设备号(低20位) 二、注册/注销字符设备驱动API接口 2.1、注册字符设备驱动(入口) #include &…

树莓派智能家居中枢

一个先进的枢纽,使智能家居系统更智能、更可定制、更易于控制 Homey Pro由树莓派 Compute Module 4 供电,Homey Pro 为用户提供了一个单一界面,用于控制和监控来自不同品牌的所有智能家居设备。它完全在本地网络上运行,而不是依赖云端,从而实现了最低的延迟、最高的…

docker发布镜像到自己远程私有仓库

1、登录docker hub创建自己的仓库地址:https://hub.docker.com/repository/create 输入仓库名称 2.构建镜像 略过。。。。请自己查找别的资料,此篇文章只讲述镜像推送到远程 3.推送 假设你已经构建了一个镜像 web/online-editor:latest,现…

推荐系统三十六式学习笔记:工程篇.常见架构25|Netflix个性化推荐架构

目录 架构的重要性经典架构1.数据流2.在线层3.离线层4.近线层 简化架构总结 你是否曾经觉得算法就是推荐系统的全部,即便不是全部,至少也是嫡长子,然而实际上,工程实现才是推荐系统的骨架。如果没有好的软件实现,算法不…

树 ----- 基础学习

树 树:n(n>0)个结点的有限集合。n 0 ,空树。 在任意一个非空树中, 1,有且仅有一个特定的根结点 2,当n>1 时,其余结点可分为m个互不相交的有限集合T1,T2,T3.。。。。Tm,其中每…

如何利用业余时间做副业,在家里赚钱,来增加收入

人一生每个阶段都会有压力和烦恼,中年人更是如此。 上有老下有小,生活的重担都在一个人身上,压得人喘不过气,这些都需要钱,仅靠工资已经很难维持一家人的开支了。 所以很多人打算利用业余时间做副业,来增加…

Pycharm软件Win 64位安装包+详细安装步骤 百度云

如大家所掌握的,Pycharm是一款集成开发环境(IDE),专门用于python语言开发的工具。作为一款功能强大的IDE,Pycharm提供了丰富的功能和工具,使得python开发变得更加高效和便捷。 Pycharm常用场景如下&#x…

Delphi5实现鱼C屏幕保护程序

效果图 鱼C屏幕保护程序 添加背景图片 在additional添加image组件,修改picture属性上传图片。 这个图片可以截屏桌面,方便后面满屏不留白操作。实现无边框 即上面的“- □ ”不显示 将Form1的borderstyle属性改为bsnone实现最大化,满屏 将…

使用API Monitor探测C++程序在调用HtmlHelp接口打开.chm文件时传入了哪些参数

目录 1、API Monitor介绍 2、为何要使用API Monitor工具? 2、HtmlHelp函数在API列表函数中找不到,将所在模块作为外部Extern DLL模块添加到API Monitor中 3、开启对Beyond Compare工具软件的实时监测 4、在Beyond Compare软件中打开chm帮助文档&…

0719_驱动3 printk使用方法

一、printk使用方法 1.应用层打印使用printf,内核层使用printk 2.如何查看内核层中printk如何使用 3.在内核空间执行grep "printk" * -nR 4.在内核空间执行vi -t KERN_INFO 5.printk有8中打印级别(0-7),打印级别用来过滤…

学习大数据DAY22 Linux 基 本 指 令 3与 在 Linux 系 统 中 配 置MySQL 和 Oracle

目录 网络配置类 ps 显示系统执行的进程 kill systemctl 服务管理 配置静态 ip 常见错误---虚拟机重启网卡失败或者网卡丢失 mysql 操作 上机练习 6---安装 mysql---参考《mysql 安装》文档 解锁 scott 重启后的步骤 上机练习 7---安装 oracle---参考《oracle 安装》…

Java数据结构与算法--链表(Linked List)

博客主页:誓则盟约系列专栏:Java SE关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 深入了解链表: 链表是一种常见的数据结构,它由一系列节点…

jdk版本区别

JDK(Java Development Kit)是 Java 开发工具包,它包括了 Java SE(Standard Edition)、编译器、调试器和其他开发工具。Oracle 公司是 JDK 的主要供应商,它提供了多个版本的 JDK,每个版本都有自己…

SQLException:Operation not allowed after ResultSet closed

运行代码时出现的错误: 这是在运行简单的JDBC访问数据库时出现的问题,原因是在ResultSet方法中添加了close()关闭方法,如图: ResultSet 是通过 query 方法获得的,并且在 try-catch 块中没有显式地关闭它。这实际上是 一个常见的…

暴雨宅家?AI拯救你的无聊暑假!高中生必藏神器大公开

嘿,各位高中生朋友们,最近是不是被这没完没了的暴雨困在家里,感觉暑假生活都快发霉了?别急,今天我要揭秘一个宝藏网站—— ai123.cn,它简直就是咱们暑期宅家必备的救星!接下来,我就来…

whaler_通过镜像导出dockerfile

1、Whaler简介 Whaler:从镜像导出Dockerfile,whaler英文释义捕鲸船。 2、下载安装 # wget -cO /usr/local/bin/whaler https://github.com/P3GLEG/Whaler/releases/download/1.0/Whaler_linux_amd64 3、赋予可执行权限 [rootlocalhost ~]# chmod x /usr/local/…

Web漏洞扫描工具(AWVS、Goby)

一、背景 想针对自己项目或者小公司的Web安全做相关扫描,自己做漏洞进行自查工作,能够减少自身系统的安全风险,提高系统的安全性。但是没有找到一些开源性质的、扫描质量比较高的相关工具,使用安全公司的专业产品价格又承受不起。…