T6:好莱坞明星识别

news2024/9/23 16:18:56

文章目录

  • **T6周:好莱坞明星识别**
      • **一、前期工作**
        • 1.设置GPU(用CPU可忽略该步骤)
        • 2.导入数据
        • 3.查看数据
      • **二、数据预处理**
        • 1.加载数据
        • 2.可视化数据
        • 3.配置数据集
      • **三、构建CNN网络模型**
      • **四、编译模型**
      • **五、训练模型**
      • **六、模型评估**
      • **七、预测**
      • 八、总结(临时)

T6周:好莱坞明星识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

🍺 要求:

  1. 使用categorical_crossentropy(多分类的对数损失函数)完成本次选题
  2. 探究不同损失函数的使用场景与代码实现

🍻 拔高(可选):

  1. 自己搭建VGG-16网络框架
  2. 调用官方的VGG-16网络框架
  3. 使用VGG-16算法训练该模型

🔎 探索(难度有点大)

  1. 准确率达到60%

⛽ 我的环境

  • 语言环境:Python3.10.12
  • 编译器:Google Colab
  • 深度学习环境:
    • TensorFlow2.17.0

⛽ 参考博客:

  • 深度学习 Day6——T6好莱坞明星识别

一、前期工作

1.设置GPU(用CPU可忽略该步骤)
#os提供了一些与操作系统交互的功能,比如文件和目录操作
import os
#提供图像处理的功能,包括打开和显示、保存、裁剪等
import PIL
#pathlib提供了一个面向对象的接口来处理文件系统路径。路径被表示为Path对象,可以调用方法来进行各种文件和目录操作。
import pathlib

#用于绘制图形和可视化数据
import tensorflow as tf
import matplotlib.pyplot as plt
#用于数值计算的库,提供支持多维数组和矩阵运算
import numpy as np
#keras作为高层神经网络API,已被集成进tensorflow,使得训练更方便简单
from tensorflow import keras
#layers提供了神经网络的基本构建块,比如全连接层、卷积层、池化层等
#提供了构建和训练神经网络模型的功能,包括顺序模型(Sequential)和函数式模型(Functional API)
from tensorflow.keras import layers, models
#导入两个重要的回调函数:前者用于训练期间保存模型最佳版本;后者监测到模型性能不再提升时提前停止训练,避免过拟合
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
# 获取所有可用的GPU设备列表,储存在变量gpus中
gpus = tf.config.list_physical_devices("GPU")

# 如果有GPU,即列表不为空
if gpus:
  # 获取第一个 GPU 设备
  gpu0 = gpus[0]
  # 设置 GPU 内存增长策略。开启这个选项可以让tf按需分配gpu内存,而不是一次性分配所有可用内存。
  tf.config.experimental.set_memory_growth(gpu0, True)
  #设置tf只使用指定的gpu(gpu[0])
  tf.config.set_visible_devices([gpu0],"GPU")

gpus
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
2.导入数据
data_dir = "/content/drive/Othercomputers/My laptop/jupyter notebook/data/T6"
data_dir = pathlib.Path(data_dir)
3.查看数据
# 使用glob方法获取当前目录的子目录里所有以'.jpg'为结尾的文件
# '*/*.jpg' 是一個通配符模式
# 第一个星号表示当前目录
# 第二个星号表示子目录
image_count = len (list(data_dir.glob("*/*.jpg")))

print("图片总数:", image_count)
图片总数: 1800
ex = list(data_dir.glob("Jennifer Lawrence/*.jpg"))
image=PIL.Image.open(str(ex[5]))
#查看图像属性
print(image.format, image.size,image.mode)
plt.axis("off")
plt.imshow(image)
plt.show()
JPEG (474, 577) RGB

在这里插入图片描述

二、数据预处理

1.加载数据
#设置批量大小,即每次训练模型时输入图像数量
#每次训练迭代时,模型需处理32张图像
batch_size = 32
#图像的高度,加载图像数据时,将所有的图像调整为相同的高度
img_height = 224
#图像的宽度,加载图像数据时,将所有的图像调整为相同的宽度
img_width = 224
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
"""
tr_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.1,
    #指定数据集中分割出多少比例数据当作验证集,0.1表示10%数据会被用来当验证集
    subset="training",
    #指定是用于训练还是验证的数据子集,这里设定为training
    label_mode = "categorical",
    #标签编码为分类向量,独热编码数组--使用损失函数应为--categorical_crossentropy loss
    seed=123,
    #用于设置随机数种子,以确保数据集划分的可重复性和一致性
    image_size=(img_height, img_width),
    batch_size=batch_size)
Found 1800 files belonging to 17 classes.
Using 1620 files for training.
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split = 0.1,
    subset = "validation",
    label_mode="categorical",
    seed = 123,
    image_size=(img_height,img_width),
    batch_size=batch_size
)
Found 1800 files belonging to 17 classes.
Using 180 files for validation.
class_names = tr_ds.class_names
# 可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称
class_names
['Angelina Jolie',
 'Brad Pitt',
 'Denzel Washington',
 'Hugh Jackman',
 'Jennifer Lawrence',
 'Johnny Depp',
 'Kate Winslet',
 'Leonardo DiCaprio',
 'Megan Fox',
 'Natalie Portman',
 'Nicole Kidman',
 'Robert Downey Jr',
 'Sandra Bullock',
 'Scarlett Johansson',
 'Tom Cruise',
 'Tom Hanks',
 'Will Smith']

随机数种子相关可参考:https://blog.csdn.net/weixin_51390582/article/details/124246873

2.可视化数据
plt.figure(figsize=(20,10))
for images, labels in tr_ds.take(1):
  for i in range(20):
    ax = plt.subplot(5, 10, i + 1)
    plt.imshow(images[i].numpy().astype("uint8"))
    plt.title(class_names[np.argmax(labels[i])], fontsize=10)
    plt.axis("off")

# 显示图片
plt.show()

请添加图片描述

for image_batch, labels_batch in tr_ds:
  print(image_batch.shape)
  print(labels_batch.shape)
  break

#`(32, 224, 224, 3)`--最后一维指的是彩色通道RGB
#`label_batch`是形状(32,17)的张量,这些标签对应32张图片,分为17类
(32, 224, 224, 3)
(32, 17)
3.配置数据集
#自动调整数据管道性能
AUTOTUNE = tf.data.AUTOTUNE
# 使用 tf.data.AUTOTUNE 具体的好处包括:
#自动调整并行度:自动决定并行处理数据的最佳线程数,以最大化数据吞吐量。
#减少等待时间:通过优化数据加载和预处理,减少模型训练时等待数据的时间。
#提升性能:自动优化数据管道的各个环节,使整个训练过程更高效。
#简化代码:不需要手动调整参数,代码更简洁且易于维护。

#使用cache()方法将训练集缓存到内存中,这样加快数据加载速度
#当多次迭代训练数据时,可以重复使用已经加载到内存的数据而不必重新从磁盘加载
#使用shuffle()对训练数据集进行洗牌操作,打乱数据集中的样本顺序
#参数1000指缓冲区大小,即每次从数据集中随机选择的样本数量
#prefetch()预取数据,节约在训练过程中数据加载时间
tr_ds = tr_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

三、构建CNN网络模型

卷积神经网络(CNN)的输入是张量 (Tensor) 形式的 (image_height, image_width, color_channels),包含了图像高度、宽度及颜色信息。不需要输入batch size。color_channels 为 (R,G,B) 分别对应 RGB 的三个颜色通道(color channel)。在此示例中,我们的 CNN 输入形状是 (224, 224, 3)。我们需要在声明第一层时将形状赋值给参数input_shape。

CNN的输入张量表示图像的结构和颜色信息。每个像素点都被表示为具有color_channels个数值的向量,在训练时,通过一系列卷积层、池化层和全连接层等操作提取和处理图像特征。

num_classes = 17

#创建序列模型,一种线性堆叠模型,各层按照他们被添加到模型中的顺序来堆叠
model = models.Sequential([
    #输入层
    layers.Input(shape=(img_height,img_width,3)),

    # 数据预处理层:将像素值从 [0, 255] 缩放到 [0, 1]即归一化,输入(224, 224 ,3),
    layers.Rescaling(scale=1./255),
    #2.17.0的tensorflow貌似已经移除了experimental.preprocessing,而直接放在layers库中(*最好用Input作为单独输入层)
    #layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height,img_width,3)),

    # 卷积层1:16 个 3x3 的卷积核,使用 ReLU 激活函数,输出 (222, 222, 16),
    layers.Conv2D(16, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)),

    # 池化层1:2x2 的平均池化,输出(111,111,16)
    layers.AveragePooling2D((2, 2)),  #池化层1,2*2采样

    # 卷积层2:32 个 3x3 的卷积核,使用 ReLU 激活函数,(109,109,32)
    layers.Conv2D(32, (3, 3), activation='relu'), #卷积层2,卷积核3*3

    # 池化层2:2x2 的平均池化,(54,54,32)
    layers.AveragePooling2D((2, 2)),  #池化层2,2*2采样

    # Dropout层:随机停止50%的神经元工作,防止过拟合
    layers.Dropout(0.5),

    # 卷积层3:64 个 3x3 的卷积核,使用 ReLU 激活函数 (52,52,64)
    layers.Conv2D(64, (3, 3), activation='relu'),

    # 池化层3:2x2 的平均池化,(26,26,64)
    layers.AveragePooling2D((2, 2)),

    # Dropout层:随机停止30%的神经元工作,防止过拟合
    layers.Dropout(0.5),

    # 卷积层4:128个 3x3的卷积核,使用ReLU 激活函数 (24,24,128)
    layers.Conv2D(128, (3,3), activation ="relu"),

    # Dropout层:随机停止30%的神经元工作,防止过拟合
    layers.Dropout(0.5),

    #flatten层
    layers.Flatten(),
    layers.Dense(128, activation="relu"), #全连接层,特征进一步提取
    layers.Dense(num_classes)


    ])
model.summary()  # 打印网络结构
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.
  super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ rescaling (Rescaling)                │ (None, 224, 224, 3)         │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d (Conv2D)                      │ (None, 222, 222, 16)        │             448 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d (AveragePooling2D) │ (None, 111, 111, 16)        │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_1 (Conv2D)                    │ (None, 109, 109, 32)        │           4,640 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d_1                  │ (None, 54, 54, 32)          │               0 │
│ (AveragePooling2D)                   │                             │                 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout (Dropout)                    │ (None, 54, 54, 32)          │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_2 (Conv2D)                    │ (None, 52, 52, 64)          │          18,496 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ average_pooling2d_2                  │ (None, 26, 26, 64)          │               0 │
│ (AveragePooling2D)                   │                             │                 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_1 (Dropout)                  │ (None, 26, 26, 64)          │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ conv2d_3 (Conv2D)                    │ (None, 24, 24, 128)         │          73,856 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_2 (Dropout)                  │ (None, 24, 24, 128)         │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ flatten (Flatten)                    │ (None, 73728)               │               0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense (Dense)                        │ (None, 128)                 │       9,437,312 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_1 (Dense)                      │ (None, 17)                  │           2,193 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
 Total params: 9,536,945 (36.38 MB)
 Trainable params: 9,536,945 (36.38 MB)
 Non-trainable params: 0 (0.00 B)

四、编译模型

在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:

  • 损失函数(loss):用于衡量模型在训练期间的准确率。
  • 优化器(optimizer):决定模型如何根据其看到的数据和自身的损失函数进行更新。
  • 指标(metrics):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
#本次使用代码
# 设置初始学习率
initial_learning_rate = 1e-4

lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate,
        decay_steps=60, # 敲黑板!!!这里是指 steps,不是指epochs
        decay_rate=0.94, # lr经过一次衰减就会变成 decay_rate*lr
        staircase=True)

# 将指数衰减学习率送入优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)

model.compile(optimizer=optimizer,
       loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
       metrics=['accuracy'])

#Adam优化器是一种常用的梯度下降优化算法,用于更新模型的权重以最小化训练过程中的损失函数
#由于是多分类问题这里使用categorical crossentropy损失函数

五、训练模型

epochs = 100

# 保存最佳模型参数
checkpointer = ModelCheckpoint(
    "/content/drive/Othercomputers/My laptop/jupyter notebook/xunlianying/6best.weights.h5",
    monitor='val_accuracy',
    verbose=1,
    mode = "max",
    save_best_only=True,
    save_weights_only=True)

# 设置早停
earlystopper = EarlyStopping(monitor='val_accuracy',
    min_delta=0.001,
    patience=20,
    mode = "max",
    verbose=1)
history = model.fit(tr_ds,
      validation_data=val_ds,
      epochs=epochs,
      callbacks=[checkpointer, earlystopper])
Epoch 1/100

六、模型评估

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(len(loss))

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

请添加图片描述

七、预测

注释参考:https://blog.csdn.net/qq_45735298/article/details/130056861?spm=1001.2014.3001.5502

model.load_weights('../xunlianying/6best.weights.h5')
#这段代码用于加载之前训练中保存的最佳模型权重。使用之前保存的模型权重文件路径和名称。
#这样可以避免从头开始训练模型,直接使用已经训练好的最佳模型进行预测的工作。

from PIL import Image
import numpy as np

img = Image.open("./5/test/nike/4.jpg") #使用 PIL 库中的 Image.open() 方法打开一张待预测的图片。
image = tf.image.resize(img, [img_height, img_width])
#这个函数调整输入图像的大小以符合模型的要求。
#在这个例子中,使用 TensorFlow 的 tf.image.resize() 函数将图像缩放为指定大小,其中 img_height 和 img_width 是指定的图像高度和宽度。

img_array = tf.expand_dims(image, 0)
'''
这个函数将输入图像转换为形状为 (1, height, width, channels) 的四维数组,
其中 height 和 width 是图像的高度和宽度,channels 是图像的通道数(例如 RGB 图像有 3 个通道)。
这里使用 TensorFlow 的 tf.expand_dims() 函数来扩展图像数组的维度,以匹配模型的输入格式。

具体来说:
image 是一个二维图片张量,它的形状是 (height, width, channels)。其中 height 和 width 分别为图片的高度和宽度,channels 为图片的颜色通道数。

0 是一个整数值,它指定在哪个维度上扩展此张量,这里表示在最前面(第一个)的维度上扩展。
因此,函数的作用是将输入张量 image 在最前面添加一个额外的维度(batch_size),生成一个四维张量。

tf.expand_dims(input, axis)
其中 input 表示要扩展的输入张量,axis 表示要在哪个维度上进行扩展。在这个例子中,input 是变量 image,axis 是 0。
'''

pre = model.predict(img_array)
#这个函数用于对输入图像进行分类预测。它使用已经训练好的模型来对输入数据进行推断,并输出每个类别的概率分布。
print("预测结果为:", class_names[np.argmax(pre)])


#将模型输出的概率分布转换为最终预测结果。
#具体来说,使用 np.argmax() 函数找到概率最大的类别索引,然后使用该索引在 class_names 列表中查找相应的类别名称,并输出预测结果。

八、总结(临时)

  • 训练第一次结果val acc最高0.377,修改了一下decay_rate待再次训练
  • 学习了不同损失函数的特点和适用的场景条件
  • VGG16模型待搭建

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

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

相关文章

Circuitjs 分支电路(子电路, subcircuit)功能简介

在 circuitjs 中, 可以使用 分支电路 来实现自定义的"黑盒"器件. 分支电路 也称为 子电路(subcircuit). 因为菜单上已经叫成了 分支电路, 以下均称为 分支电路. 通过分支电路, 可以实现对电路的封装与抽象, 从而达到模块化并简化电路的目的. 更进一步的, 被抽象的黑盒…

Apache Paimon V0.9最新进展

摘要:本文整理自 Paimon PMC Chair 李劲松老师在 8 月 3 日 Streaming Lakehouse Meetup Online(Paimon x StarRocks,共话实时湖仓架构)上的分享。主要分享 Apache Paimon V0.9 的最新进展以及遇到的一些挑战。 一、Paimon&#x…

无人系统特刊合集(二)丨Springer特刊推荐

期刊推荐 期刊征稿:JOURNAL OF INTELLIGENT & ROBOTIC SYSTEMS Journal of Intelligent & Robotic Systems是一本同行评议的期刊,致力于智能系统和机器人技术的理论和实践。 专注于无人系统、机器人和自动化以及人机交互等领域。 在每期中都包…

天猫 登录滑块 淘系滑块分析

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关 前言 玩了几天现在才有空研究轨迹直接用了之前的…

日志组件导致的内存溢出问题分析

1、 内存溢出日志 普通的http请求,导致堆内存直接溢出,看了下代码实现非常简单的一次DB查询且数据量也比较小,不可能导致内存溢出呢 java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at…

网上花店设计+vue

TOC ssm017网上花店设计vue 绪论 1.1 选题背景 网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。计算机软件可以针对不同行业的营业特点以及管理需求&a…

CSS3页面布局-三栏-中栏流动布局

三栏-中栏流动布局 用负外边距实现 实现三栏布局且中栏内容区不固定的核心问题就是处理右栏的定位&#xff0c; 并在中栏内容区大小改变时控制右栏与布局的关系。 控制两个外包装容器的外边距&#xff0c;一个包围三栏&#xff0c;一个包围左栏和中栏。 <!DOCTYPE html&…

计算机毕业设计 在线问诊系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

海运整箱成本与拼箱成本对比 | 国际贸易服务平台 | 箱讯科技

整箱和拼箱 在集装箱运输业务中&#xff0c;我们把一个集装箱、一个出口人、一个收货人、一个目的港&#xff0c;满足这“四个一”条件的货物叫做整箱货&#xff0c;而把一个集装箱、出口人、收货人和目的港这三项之中只要有一项是在两个或两个以上的出口运输货物&#xff0c;就…

批量将labelme的json文件转为png图片查看

文章目录 前提修改 l a b e l m e labelme labelme然后你就可以在这个环境下用代码批量修改了 前提 安装anaconda或者miniconda安装labelme 修改 l a b e l m e labelme labelme 查看labelme所处环境的路径&#xff1a;conda info --envs 比如我的是在py39_torch里面 修改la…

Anki自动生成语音

文章目录 前言安装插件制作音频一些注意事项语音消失现象不同端出现媒体文件丢失 参考文章 前言 已经实现了通过使用Obsidian实现Anki快速制卡。 对于语言学习&#xff0c;仅仅只有不同语言文字的对照是不够的&#xff0c;我们还需要声音。 所以就需要加入音频。 幸好 Anki…

laravel “Class \“Redis\“ not found“ 如何解决?

laravel “Class “Redis” not found” 如何解决 问题&#xff1a;laravel 安装好后&#xff0c;运行报错提示&#xff1a;“Class “Redis” not found” 分析&#xff1a;程序并没有用到redis&#xff0c;百度了一下&#xff0c;初步锁定可能是php环境的原因&#xff0c;运…

【数字ic自整资料】存储器及不同端口RAM对比

参考资料 【FPGA】zynq 单端口RAM 双端口RAM 读写冲突 写写冲突_双口ram-CSDN博客 华为海思数字芯片设计笔试第五套_10、下列不属于动志数组内建函数的是: a lengtho b. new c. delete() d-CSDN博客 目录 1、计算器典型存储体系结构 2、三种不同端口RAM &#xff08;1&…

钢包智慧管理平台

钢包智慧管理平台基于海康、大华视频监控&#xff0c;实现对钢包的全动态管理&#xff0c;实时检测钢包的温度数据变化&#xff0c;也可以随时查询时间区间内的钢包温度数据变化。 平台基于springboot vue前后台分离技术开发&#xff0c;视频基于zlmedia的转码拉流。实现了视频…

嵌入式学习day33

tcp的特点 面向字节流特点&#xff0c;会造成可能数据与数据发送到一块&#xff0c;成为粘包&#xff0c;数据之间不区分 拆包 因为缓冲区的大小&#xff0c;一次性发送的数据会进行拆分&#xff08;大小不符合的时候&#xff09; 就和水一样一次拆一次沾到一块&#xff0c…

快速入门Spring

目录 为什么要学Spring&#xff1a; Spring框架诞生的背景&#xff1a; Spring是什么&#xff1a; 接下来我们就要解决Spring怎么用这个问题 BeanFactory快速入门 IOC思想的体现 BeanFactory快速入门 DI思想的体现 开始学Spring时我们要了解以下几个问题 为什么要学习Sp…

深入理解滑动窗口算法及其经典应用

文章目录 什么是滑动窗口&#xff1f;经典题型分析与讲解**1. 长度最小的子数组****2. 无重复字符的最长子串****3. 最长重复子数组****4. 将x减到0的最小操作数**5. 水果成篮 (LeetCode 904)6. 滑动窗口最大值 (LeetCode 239)7. 字符串中的所有字母异位词 (LeetCode 剑指 Offe…

SAP S4HANA 2023 FPS01 FAA虚拟机发布了

SAP S4HANA 2023 FPS01 FAA虚拟机发布了。 系统不再需要修改虚拟机日期了&#xff0c;提供最高长达三年的许可&#xff0c;业务财务做账都是真实的时间&#xff01; 该虚拟机版本优点&#xff1a; 新版的一键启动脚本&#xff0c;3分钟就能启动完成。 内存加载 80GB 就可以启动…

二叉树检验:算法详解

问题描述 /** 检查二叉树是否为有效的二叉搜索树有效的二叉搜索树满足左子树的节点值都小于根节点值&#xff0c;右子树的节点值都大于根节点值并且左右子树也必须是有效的二叉搜索树param root 二叉树的根节点return 如果二叉树是有效的二叉搜索树&#xff0c;则返回true&…

当AI成为你的私人医生,与AI“医”路同行的奇妙体验

“ 从挂号到诊疗&#xff0c;再到后续的健康管理&#xff0c;人工智能&#xff08;AI&#xff09;正以一种全新的方式融入我们的生活。上海市第一人民医院的创新实践&#xff0c;便是这一变革的生动注脚。 ” AI就医助理&#xff1a;从“助手”到“伙伴” 当你踏入医院大门…