PyTorch 之 神经网络 Mnist 分类任务

文章目录

  • 一、Mnist 分类任务简介
  • 二、Mnist 数据集的读取
  • 三、 Mnist 分类任务实现
    • 1. 标签和简单网络架构
    • 2. 具体代码实现
  • 四、使用 TensorDataset 和 DataLoader 简化

本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052
在这里插入图片描述

一、Mnist 分类任务简介

  • 在上一篇博客当中,我们通过搭建 PyTorch 神经网络实现了气温预测,这本质上是一个回归任务。在本次博文当中,我们使用 PyTorch 做一个分类任务。
  • 其实,分类任务和回归任务在本质上没有任何区别,只是说在结果上是不同的,损失函数是不同的,中间的网络架构却是大体一致的。
  • 在本次的分类任务当中,我们使用的数据集是 Mnist 数据集,这个数据集大家都比较熟悉,可以在 http://yann.lecun.com/exdb/mnist/ 中获取,主要包括四个文件:
文件名称大小内容
train-images-idx3-ubyte.gz9,681 kb55000 张训练集,5000 张验证集
train-labels-idx1-ubyte.gz29 kb训练集图片对应的标签
t10k-images-idx3-ubyte.gz1,611kb10000 张测试集
t10k-labels-idx1-ubyte.gz5 kb测试集图片对应的标签
  • 在上述在上述文件中,训练集 train 一共包含了 60000 张图像和标签,而测试集一共包含了 10000 张图像和标签。
  • idx3 表示 3 维,ubyte 表示是以字节的形式进行存储的,t10k 表示 10000 张测试图片(test10000)。
  • 每张图片是一个 28*28 像素点的 0 ~ 9 的灰质手写数字图片,黑底白字,图像像素值为 0 ~ 255,越大该点越白。
  • 本次分类任务主要包含如下的几个部分:
  • (1) 网络基本构建与训练方法,常用函数解析。
  • (2) torch.nn.functional 模块。
  • (3) nn.Module 模块。

二、Mnist 数据集的读取

  • 对于 Mnist 数据集,我们可以通过代码编写,就可以实现自动下载。
%matplotlib inline
from pathlib import Path
import requests
​
DATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"
​
PATH.mkdir(parents=True, exist_ok=True)
​
URL = "http://deeplearning.net/data/mnist/"
FILENAME = "mnist.pkl.gz"
  • 对于我们上面定义的下载路径等等,会进行自动判断,如果该路径下没有 Minst 数据集的话,就会自动进行下载。
if not (PATH / FILENAME).exists():
        content = requests.get(URL + FILENAME).content
        (PATH / FILENAME).open("wb").write(content)
  • 由于下载出来的数据集是压缩包的状态,因此,我们还需要对其进行解压,具体的代码详见下面。
import pickle
import gzip
​
with gzip.open((PATH / FILENAME).as_posix(), "rb") as f:
        ((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")
  • 在上述工作准备完成后,我们可以先查看一个数据,观察他的特征。
from matplotlib import pyplot
import numpy as np
​
pyplot.imshow(x_train[0].reshape((28, 28)), cmap="gray")
print(x_train.shape)
#(50000, 784)
  • 在此处,我们查看的训练集当中的第一个数据,大小重构为 (28,28,1),表示长是 28,宽是 28,颜色通道是 1(黑白图就只有一个颜色通道),颜色设置为灰色。在查看第一个数据的同时,我们也输出整个训练集的数据大小,其中,(50000, 784) 中的 50000 表示训练集一共有 50000 个数据样本,784 表示训练集中每个样本有 784 个像素点(可以理解成 784 个特征)。

在这里插入图片描述

三、 Mnist 分类任务实现

1. 标签和简单网络架构

  • 在分类任务当中,标签的设计是有所不同的。

在这里插入图片描述

  • 很多人认为预测出来的 9,具体指的是 0,1,2,3,4,5,6,7,8,9 当中的具体哪一个,但实际上并不是这样的,他也是一个 One-Hot 的编码,他预测的出来的不是一个具体的数值,而是十个概率,就是当前这个输入属于 0-9 这十个数字的概率是多少。
  • 以上图为例,该输入属于 0 的概率就是 0,属于 1 的概率就是 12%,属于 9 的概率就是 87%,属于 9 的概率最高,因此,该输入的输出就是 9。

在这里插入图片描述

  • 对于这个网络架构,由于我们的每个数据样本都有 784 个像素点,中间进行特征提取,得到一定数量的特征,最终得到 10 个输出,通过 Softmax 层得到是个概率。

2. 具体代码实现

  • 需要注意的是,我们需要先将数据转换成 tensor 才能参与后续建模训练。
  • 这里的数据包括 x_train, y_train, x_valid, y_valid 四种,对于他们的含义,我们可以这样理解:
  • (1) x_train 包括所有自变量,这些变量将用于训练模型。
  • (2) y_train 是指因变量,需要此模型进行预测,其中包括针对自变量的类别标签,我们需要在训练/拟合模型时指定我们的因变量。
  • (3) x_valid 也就是 x_test,这些自变量将不会在训练阶段使用,并将用于进行预测,以测试模型的准确性。
  • (4) y_valid 也就是 y_test,此数据具有测试数据的类别标签,这些标签将用于测试实际类别和预测类别之间的准确性。
import torch
​
x_train, y_train, x_valid, y_valid = map(
    torch.tensor, (x_train, y_train, x_valid, y_valid)
)
n, c = x_train.shape
x_train, x_train.shape, y_train.min(), y_train.max()
print(x_train, y_train)
print(x_train.shape)
print(y_train.min(), y_train.max())
#tensor([[0., 0., 0.,  ..., 0., 0., 0.],
#        [0., 0., 0.,  ..., 0., 0., 0.],
#        [0., 0., 0.,  ..., 0., 0., 0.],
#        ...,
#        [0., 0., 0.,  ..., 0., 0., 0.],
#        [0., 0., 0.,  ..., 0., 0., 0.],
#        [0., 0., 0.,  ..., 0., 0., 0.]]) tensor([5, 0, 4,  ..., 8, 4, 8])
#torch.Size([50000, 784])
#tensor(0) tensor(9)
  • 在模型训练的过程中,大家经常会看到 nn.Module 和 nn.functional。那什么时候使用 nn.Module,什么时候使用 nn.functional 呢?
  • 一般情况下,如果模型有可学习的参数,最好用 nn.Module,其他情况 nn.functional 相对更简单一些。
  • 我们先导入需要的模块包。
import torch.nn.functional as F
​
loss_func = F.cross_entropy
​
def model(xb):
    return xb.mm(weights) + bias
  • 然后进行参数的设定。
bs = 64
xb = x_train[0:bs]  # a mini-batch from x
yb = y_train[0:bs]
weights = torch.randn([784, 10], dtype = torch.float,  requires_grad = True) 
bs = 64
bias = torch.zeros(10, requires_grad=True)print(loss_func(model(xb), yb))
#tensor(10.7988, grad_fn=<NllLossBackward>)
  • 我们也创建一个 model 来更简化代码。
  • 在这中间必须继承 nn.Module 且在其构造函数中需调用 nn.Module 的构造函数,无需写反向传播函数,nn.Module 能够利用 autograd 自动实现反向传播,Module 中的可学习参数可以通过 named_parameters() 或者 parameters() 返回迭代器。
from torch import nn
​
class Mnist_NN(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden1 = nn.Linear(784, 128) #隐藏层1:784*128
        self.hidden2 = nn.Linear(128, 256) #隐藏层2:128*256
        self.out  = nn.Linear(256, 10) #输出层,256*10def forward(self, x):
        x = F.relu(self.hidden1(x))
        x = F.relu(self.hidden2(x))
        x = self.out(x)
        return x
        
net = Mnist_NN()
print(net)#Mnist_NN(
#  (hidden1): Linear(in_features=784, out_features=128, bias=True)
#  (hidden2): Linear(in_features=128, out_features=256, bias=True)
#  (out): Linear(in_features=256, out_features=10, bias=True)
#)
  • 我们可以打印定义好名字里的权重和偏置项,首先打印名字,然后打印参数,最后打印参数的维度。
for name, parameter in net.named_parameters():
    print(name, parameter,parameter.size())
#hidden1.weight Parameter containing:
#tensor([[ 0.0018,  0.0218,  0.0036,  ..., -0.0286, -0.0166,  0.0089],
#        [-0.0349,  0.0268,  0.0328,  ...,  0.0263,  0.0200, -0.0137],
#        [ 0.0061,  0.0060, -0.0351,  ...,  0.0130, -0.0085,  0.0073],
#        ...,
#        [-0.0231,  0.0195, -0.0205,  ..., -0.0207, -0.0103, -0.0223],
#        [-0.0299,  0.0305,  0.0098,  ...,  0.0184, -0.0247, -0.0207],
#        [-0.0306, -0.0252, -0.0341,  ...,  0.0136, -0.0285,  0.0057]],
#       requires_grad=True) torch.Size([128, 784])
#hidden1.bias Parameter containing:
#tensor([ 0.0072, -0.0269, -0.0320, -0.0162,  0.0102,  0.0189, -0.0118, -0.0063,
#        -0.0277,  0.0349,  0.0267, -0.0035,  0.0127, -0.0152, -0.0070,  0.0228,
#        -0.0029,  0.0049,  0.0072,  0.0002, -0.0356,  0.0097, -0.0003, -0.0223,
#        -0.0028, -0.0120, -0.0060, -0.0063,  0.0237,  0.0142,  0.0044, -0.0005,
#         0.0349, -0.0132,  0.0138, -0.0295, -0.0299,  0.0074,  0.0231,  0.0292,
#        -0.0178,  0.0046,  0.0043, -0.0195,  0.0175, -0.0069,  0.0228,  0.0169,
#         0.0339,  0.0245, -0.0326, -0.0260, -0.0029,  0.0028,  0.0322, -0.0209,
#        -0.0287,  0.0195,  0.0188,  0.0261,  0.0148, -0.0195, -0.0094, -0.0294,
#        -0.0209, -0.0142,  0.0131,  0.0273,  0.0017,  0.0219,  0.0187,  0.0161,
#         0.0203,  0.0332,  0.0225,  0.0154,  0.0169, -0.0346, -0.0114,  0.0277,
#         0.0292, -0.0164,  0.0001, -0.0299, -0.0076, -0.0128, -0.0076, -0.0080,
#        -0.0209, -0.0194, -0.0143,  0.0292, -0.0316, -0.0188, -0.0052,  0.0013,
#        -0.0247,  0.0352, -0.0253, -0.0306,  0.0035, -0.0253,  0.0167, -0.0260,
#        -0.0179, -0.0342,  0.0033, -0.0287, -0.0272,  0.0238,  0.0323,  0.0108,
#         0.0097,  0.0219,  0.0111,  0.0208, -0.0279,  0.0324, -0.0325, -0.0166,
#        -0.0010, -0.0007,  0.0298,  0.0329,  0.0012, -0.0073, -0.0010,  0.0057],
#       requires_grad=True) torch.Size([128])
#hidden2.weight Parameter containing:
#tensor([[-0.0383, -0.0649,  0.0665,  ..., -0.0312,  0.0394, -0.0801],
#        [-0.0189, -0.0342,  0.0431,  ..., -0.0321,  0.0072,  0.0367],
#        [ 0.0289,  0.0780,  0.0496,  ...,  0.0018, -0.0604, -0.0156],
#        ...,
#        [-0.0360,  0.0394, -0.0615,  ...,  0.0233, -0.0536, -0.0266],
#        [ 0.0416,  0.0082, -0.0345,  ...,  0.0808, -0.0308, -0.0403],
#        [-0.0477,  0.0136, -0.0408,  ...,  0.0180, -0.0316, -0.0782]],
#       requires_grad=True) torch.Size([256, 128])
#hidden2.bias Parameter containing:
#tensor([-0.0694, -0.0363, -0.0178,  0.0206, -0.0875, -0.0876, -0.0369, -0.0386,
#         0.0642, -0.0738, -0.0017, -0.0243, -0.0054,  0.0757, -0.0254,  0.0050,
#         0.0519, -0.0695,  0.0318, -0.0042, -0.0189, -0.0263, -0.0627, -0.0691,
#         0.0713, -0.0696, -0.0672,  0.0297,  0.0102,  0.0040,  0.0830,  0.0214,
#         0.0714,  0.0327, -0.0582, -0.0354,  0.0621,  0.0475,  0.0490,  0.0331,
#        -0.0111, -0.0469, -0.0695, -0.0062, -0.0432, -0.0132, -0.0856, -0.0219,
#        -0.0185, -0.0517,  0.0017, -0.0788, -0.0403,  0.0039,  0.0544, -0.0496,
#         0.0588, -0.0068,  0.0496,  0.0588, -0.0100,  0.0731,  0.0071, -0.0155,
#        -0.0872, -0.0504,  0.0499,  0.0628, -0.0057,  0.0530, -0.0518, -0.0049,
#         0.0767,  0.0743,  0.0748, -0.0438,  0.0235, -0.0809,  0.0140, -0.0374,
#         0.0615, -0.0177,  0.0061, -0.0013, -0.0138, -0.0750, -0.0550,  0.0732,
#         0.0050,  0.0778,  0.0415,  0.0487,  0.0522,  0.0867, -0.0255, -0.0264,
#         0.0829,  0.0599,  0.0194,  0.0831, -0.0562,  0.0487, -0.0411,  0.0237,
#         0.0347, -0.0194, -0.0560, -0.0562, -0.0076,  0.0459, -0.0477,  0.0345,
#        -0.0575, -0.0005,  0.0174,  0.0855, -0.0257, -0.0279, -0.0348, -0.0114,
#        -0.0823, -0.0075, -0.0524,  0.0331,  0.0387, -0.0575,  0.0068, -0.0590,
#        -0.0101, -0.0880, -0.0375,  0.0033, -0.0172, -0.0641, -0.0797,  0.0407,
#         0.0741, -0.0041, -0.0608,  0.0672, -0.0464, -0.0716, -0.0191, -0.0645,
#         0.0397,  0.0013,  0.0063,  0.0370,  0.0475, -0.0535,  0.0721, -0.0431,
#         0.0053, -0.0568, -0.0228, -0.0260, -0.0784, -0.0148,  0.0229, -0.0095,
#        -0.0040,  0.0025,  0.0781,  0.0140, -0.0561,  0.0384, -0.0011, -0.0366,
#         0.0345,  0.0015,  0.0294, -0.0734, -0.0852, -0.0015, -0.0747, -0.0100,
#         0.0801, -0.0739,  0.0611,  0.0536,  0.0298, -0.0097,  0.0017, -0.0398,
#         0.0076, -0.0759, -0.0293,  0.0344, -0.0463, -0.0270,  0.0447,  0.0814,
#        -0.0193, -0.0559,  0.0160,  0.0216, -0.0346,  0.0316,  0.0881, -0.0652,
#        -0.0169,  0.0117, -0.0107, -0.0754, -0.0231, -0.0291,  0.0210,  0.0427,
#         0.0418,  0.0040,  0.0762,  0.0645, -0.0368, -0.0229, -0.0569, -0.0881,
#        -0.0660,  0.0297,  0.0433, -0.0777,  0.0212, -0.0601,  0.0795, -0.0511,
#        -0.0634,  0.0720,  0.0016,  0.0693, -0.0547, -0.0652, -0.0480,  0.0759,
#         0.0194, -0.0328, -0.0211, -0.0025, -0.0055, -0.0157,  0.0817,  0.0030,
#         0.0310, -0.0735,  0.0160, -0.0368,  0.0528, -0.0675, -0.0083, -0.0427,
#        -0.0872,  0.0699,  0.0795, -0.0738, -0.0639,  0.0350,  0.0114,  0.0303],
#       requires_grad=True) torch.Size([256])
#out.weight Parameter containing:
#tensor([[ 0.0232, -0.0571,  0.0439,  ..., -0.0417, -0.0237,  0.0183],
#        [ 0.0210,  0.0607,  0.0277,  ..., -0.0015,  0.0571,  0.0502],
#        [ 0.0297, -0.0393,  0.0616,  ...,  0.0131, -0.0163, -0.0239],
#        ...,
#        [ 0.0416,  0.0309, -0.0441,  ..., -0.0493,  0.0284, -0.0230],
#        [ 0.0404, -0.0564,  0.0442,  ..., -0.0271, -0.0526, -0.0554],
#        [-0.0404, -0.0049, -0.0256,  ..., -0.0262, -0.0130,  0.0057]],
#       requires_grad=True) torch.Size([10, 256])
#out.bias Parameter containing:
#tensor([-0.0536,  0.0007,  0.0227, -0.0072, -0.0168, -0.0125, -0.0207, -0.0558,
#         0.0579, -0.0439], requires_grad=True) torch.Size([10])

四、使用 TensorDataset 和 DataLoader 简化

  • 自己构建数据集,使用 batch 取数据会略显麻烦,因此,我们可以使用 TensorDataset 和 DataLoader 这两个模块进行简化。
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
​
train_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True)
​
valid_ds = TensorDataset(x_valid, y_valid)
valid_dl = DataLoader(valid_ds, batch_size=bs * 2)
def get_data(train_ds, valid_ds, bs):
    return (
        DataLoader(train_ds, batch_size=bs, shuffle=True),
        DataLoader(valid_ds, batch_size=bs * 2),
    )
  • 一般在训练模型时加上 model.train(),这样会正常使用 Batch Normalization 和 Dropout。
  • 测试的时候一般选择 model.eval(),这样就不会使用 Batch Normalization 和 Dropout。
import numpy as np
​
def fit(steps, model, loss_func, opt, train_dl, valid_dl):
    for step in range(steps):
        model.train()
        for xb, yb in train_dl:
            loss_batch(model, loss_func, xb, yb, opt)
​
        model.eval()
        with torch.no_grad():
            losses, nums = zip(
                *[loss_batch(model, loss_func, xb, yb) for xb, yb in valid_dl]
            )
        val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)
        print('当前step:'+str(step), '验证集损失:'+str(val_loss))
from torch import optim
def get_model():
    model = Mnist_NN()
    return model, optim.SGD(model.parameters(), lr=0.001)
def loss_batch(model, loss_func, xb, yb, opt=None):
    loss = loss_func(model(xb), yb)if opt is not None:
        loss.backward()
        opt.step()
        opt.zero_grad()return loss.item(), len(xb)
  • 我们也可以像上篇博文一样,使用三行代码进行解决。
train_dl, valid_dl = get_data(train_ds, valid_ds, bs)
model, opt = get_model()
fit(25, model, loss_func, opt, train_dl, valid_dl)
#当前step:0 验证集损失:2.2796445930480957
#当前step:1 验证集损失:2.2440698066711424
#当前step:2 验证集损失:2.1889826164245605
#当前step:3 验证集损失:2.0985311767578123
#当前step:4 验证集损失:1.9517273582458496
#当前step:5 验证集损失:1.7341805934906005
#当前step:6 验证集损失:1.4719875366210937
#当前step:7 验证集损失:1.2273896869659424
#当前step:8 验证集损失:1.0362271406173706
#当前step:9 验证集损失:0.8963696184158325
#当前step:10 验证集损失:0.7927186088562012
#当前step:11 验证集损失:0.7141492074012756
#当前step:12 验证集损失:0.6529350900650024
#当前step:13 验证集损失:0.60417300491333
#当前step:14 验证集损失:0.5643046331882476
#当前step:15 验证集损失:0.5317994566917419
##当前step:16 验证集损失:0.5047958114624024
#当前step:17 验证集损失:0.4813900615692139
#当前step:18 验证集损失:0.4618900228500366
#当前step:19 验证集损失:0.4443243554592133
#当前step:20 验证集损失:0.4297310716629028
#当前step:21 验证集损失:0.416976597738266
#当前step:22 验证集损失:0.406348459148407
#当前step:23 验证集损失:0.3963301926612854
#当前step:24 验证集损失:0.38733808159828187​

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

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

相关文章

Lambda表达式

第一章 Java为什么引入 Lmabda表达式目的尽可能轻量级的将代码封装为数据1.1 什么是Lambda表达式Lambda表达式也被成为箭头函数、匿名函数、闭包 Lambda表达式体现的是轻量级函数式编程思想 ‘->’符号是Lambda表达式的核心符号&#xff0c;符号左侧是操作参数&#xff0c;符…

YOLOv8 多目标跟踪

文章大纲 简介环境搭建代码样例跟踪原理代码分析原始老版实现新版本封装代码实现追踪与计数奇奇怪怪错误汇总lap 安装过程报错推理过程报错参考文献与学习路径简介 使用yolov8 做多目标跟踪 文档地址: https://docs.ultralytics.com/modes/track/https://github.com/ultralyt…

【多线程】多线程案例

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; ✨每日一语&#xff1a;we can not judge the value of a moment until it becomes a memory. 目 录&#x1f35d;一. 单例模式&#x1f364;1. 饿汉模式实现&#x1f9aa;2. 懒汉模…

java如何创建线程

java如何创建线程1. java如何创建线程1.1 通过继承Thread类来创建线程1.2 通过实现Runnable接口来创建线程1.3 通过匿名内部类来创建线程1.4 lambda表达式1.5 通过实现Runnable接口的方式创建线程目标类的优缺点1. java如何创建线程 一个线程在Java中使用一个Thread实例来描述…

android8 rk3399 同时支持多个USB摄像头

文章目录一、前文二、CameraHal_Module.h三、CameraHal_Module.cpp四、编译&烧录Image五、App验证一、前文 Android系统默认支持2个摄像头&#xff0c;一个前置摄像头&#xff0c;一个后置摄像头需要支持数量更多的摄像头&#xff0c;得修改Android Hal层的代码 二、Camer…

VueX快速入门(适合后端,无脑入门!!!)

文章目录前言State和Mutations基础简化gettersMutationsActions&#xff08;异步&#xff09;Module总结前言 作为一个没啥前端基础&#xff08;就是那种跳过js直接学vue的那种。。。&#xff09;的后端选手。按照自己的思路总结了一下对VueX的理解。大佬勿喷qAq。 首先我们需要…

我的 System Verilog 学习记录(11)

引言 本文简单介绍 SystemVerilog 的其他程序结构。 前文链接&#xff1a; 我的 System Verilog 学习记录&#xff08;1&#xff09; 我的 System Verilog 学习记录&#xff08;2&#xff09; 我的 System Verilog 学习记录&#xff08;3&#xff09; 我的 System Verilo…

Linux lvm管理讲解及命令

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…

软件行业的最后十年【ChatGPT】

在这篇文章中&#xff0c;我将说明像 ChatGPT 这样的生成式人工智能 (GAI) 将如何在十年内取代软件工程师。 预测被离散化为 5 个阶段&#xff0c;总体轨迹趋向于完全接管。 但首先&#xff0c;一个简短的前言。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 1、关于AI…

二叉搜索树:AVL平衡

文章目录一、 二叉搜索树1.1 概念1.2 操作1.3 代码实现二、二叉搜索树的应用K模型和KV模型三、二叉搜索树的性能分析四、AVL树4.1 AVL树的概念4.2 AVL树的实现原理4.3 旋转4.4 AVL树最终代码一、 二叉搜索树 1.1 概念 二叉搜索树&#xff08; Binary Search Tree&#xff0c;…

LeetCode刷题记录---数位DP算法

😄 学会数位dp算法,可以连杀好几道力扣困难题,加油~ 🚀题目: 难度题目困难2376. 统计特殊整数困难1012. 至少有 1 位重复的数字困难233. 数字 1 的个数困难面试题 17.06. 2出现的次数🚀学习资料: 数位dp算法,我是跟着灵神学的,感谢灵神!数位 dp 通用模板参考灵神…

Python数据分析案例24——基于深度学习的锂电池寿命预测

本期开始案例较为硬核起来了&#xff0c;适合理工科的硕士&#xff0c;人文社科的同学可以看前面的案例。 案例背景 这篇文章是去年就发了&#xff0c;刊物也印刷了&#xff0c;现在分享一部分代码作为案例给需要的同学。 原文链接&#xff08;知网文章 C核&#xff09;&…

python如何快速采集美~女视频?无反爬

人生苦短 我用python~ 这次康康能给大家整点好看的不~ 环境使用: Python 3.8 Pycharm mou歌浏览器 mou歌驱动 —> 驱动版本要和浏览器版本最相近 <大版本一样, 小版本最相近> 模块使用: requests >>> pip install requests selenium >>> pip …

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…

【selenium学习】数据驱动测试

数据驱动在 unittest 中&#xff0c;使用读取数据文件来实现参数化可以吗&#xff1f;当然可以。这里以读取 CSV文件为例。创建一个 baidu_data.csv 文件&#xff0c;如图所示&#xff1a;文件第一列为测试用例名称&#xff0c;第二例为搜索的关键字。接下来创建 test_baidu_da…

百度生成式AI产品文心一言邀你体验AI创作新奇迹:百度CEO李彦宏详细透露三大产业将会带来机遇(文末附文心一言个人用户体验测试邀请码获取方法,亲测有效)

百度生成式AI产品文心一言邀你体验AI创作新奇迹中国版ChatGPT上线发布强大中文理解能力超强的数理推算能力智能文学创作、商业文案创作图片、视频智能生成中国生成式AI三大产业机会新型云计算公司行业模型精调公司应用服务提供商总结获取文心一言邀请码方法中国版ChatGPT上线发…

贪心算法的原理以及应用

文章目录0、概念0.1.定义0.2.特征0.3.步骤0.4.适用1、与动态规划的联系1.1.区别1.2.联系2、例子3、总结4、引用0、概念 0.1.定义 贪心算法&#xff08;greedy algorithm &#xff0c;又称贪婪算法&#xff09;是指&#xff0c;在对问题求解时&#xff0c;总是做出在当前看来是…

Java怎么实现几十万条数据插入(30万条数据插入MySQL仅需13秒)

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证实体类、mapper和配置文件定义User实体mapper接口mapper.xml文件jdbc.propertiessqlMapConfig.xml不分批次直接梭哈循环逐条插入MyBatis实现插入30万条数据JDBC实现插入30万条数…

第十九天 Maven总结

目录 Maven 1. 前言 2. 概述 2.1 介绍 2.2 安装 3. IDEA集成Maven 3.1 集成Maven环境 3.2 创建Maven项目 3.3 Maven坐标详解 3.4 导入maven项目 4. 依赖管理 4.1 依赖配置 4.2 依赖传递 4.3 依赖范围 4.4 生命周期 4.5 插件 Maven 1. 前言 1). 什么是Maven? …

Linux实操之服务管理

文章目录一、服务(service)管理介绍:service管理指令查看服务名服务的运行级别(runlevel):CentOS7后运行级别说明chkconfig指令介绍一、服务(service)管理介绍: 服务(service)本质就是进程&#xff0c;但是是运行在后台的&#xff0c;通常都会监听某个端口&#xff0c;等待其它…
最新文章