T7:咖啡豆识别
T7:咖啡豆识别
- **一、前期工作**
- 1.设置GPU,导入库
- 2.导入数据
- 3.查看数据
- **二、数据预处理**
- 1.加载数据
- 2.可视化数据
- 3.配置数据集
- **三、构建CNN网络模型**
- 1、手动搭建
- 2、直接调用官方模型
- **四、编译模型**
- **五、训练模型**
- **六、模型评估**
- **七、预测**
- 八、暂时总结
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
- 时间:9月4日-9月x日
🍺 要求:
- 自己搭建VGG-16网络框架 ✅
- 调用官方的VGG-16网络框架 ✅
🍻 拔高(可选):
- 验证集准确率达到100% ❌
- 使用PPT画出VGG-16算法框架图(发论文需要这项技能)❌
🔎 探索(难度有点大)
- 在不影响准确率的前提下轻量化模型❌
- VGG16总参数量是134,276,942
由于本人没GPU算力了,所以代码跑贼慢,结果后补
⛽ 我的环境
- 语言环境:Python3.10.12
- 编译器:Google Colab
- 深度学习环境:
- TensorFlow2.17.0
⛽ 参考学习博客汇总(暂时):
- ResNet、VGGNet和AlexNet创新点及优缺点
一、前期工作
1.设置GPU,导入库
#os提供了一些与操作系统交互的功能,比如文件和目录操作
import os
#提供图像处理的功能,包括打开和显示、保存、裁剪等
import PIL
from PIL import Image
#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
tf.__version__
'2.17.0'
由于本人没有GPU了,该部分跳过↓
# 获取所有可用的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
2.导入数据
from google.colab import drive
drive.mount("/content/drive/")
%cd "/content/drive/MyDrive/Colab Notebooks/jupyter notebook/data"
Mounted at /content/drive/
/content/drive/MyDrive/Colab Notebooks/jupyter notebook/data
data_dir = "./7"
data_dir = pathlib.Path(data_dir)
3.查看数据
# 使用glob方法获取当前目录的子目录里所有以'.png'为结尾的文件
# '*/*.jpg' 是一個通配符模式
# 第一个星号表示当前目录
# 第二个星号表示子目录
image_count = len (list(data_dir.glob("*/*.png")))print("图片总数:", image_count)
图片总数: 1200
ex = list(data_dir.glob("Green/*.png"))
image=PIL.Image.open(str(ex[8]))
#查看图像属性
print(image.format, image.size,image.mode)
plt.axis("off")
plt.imshow(image)
plt.show()
PNG (224, 224) 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.2,#指定数据集中分割出多少比例数据当作验证集,0.1表示10%数据会被用来当验证集subset="training",#指定是用于训练还是验证的数据子集,这里设定为trainingseed=123,#用于设置随机数种子,以确保数据集划分的可重复性和一致性image_size=(img_height, img_width),batch_size=batch_size)
Found 1200 files belonging to 4 classes.
Using 960 files for training.
val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split = 0.2,subset = "validation",seed = 123,image_size=(img_height,img_width),batch_size=batch_size
)
Found 1200 files belonging to 4 classes.
Using 240 files for validation.
class_names = tr_ds.class_names
# 可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称
class_names
['Dark', 'Green', 'Light', 'Medium']
# #数据增强---参考博客:https://blog.csdn.net/afive54/article/details/135004174# def augment_images(image, label):
# image = tf.image.random_flip_up_down(image) # 随机水平翻转
# image = tf.image.random_flip_left_right(image)
# image = tf.image.random_contrast(image, lower=0.1, upper=1.2) # 随机对比度
# image = tf.image.random_brightness(image, max_delta=0.2) # 随机亮度
# image = tf.image.random_saturation(image, lower=0.1, upper=1.2) # 随机饱和度
# #noise = tf.random.normal(tf.shape(image), mean=0.0, stddev=0.1)
# #image = tf.clip_by_value(image, 0.0, 0.5) # 添加高斯噪声并将像素值限制在0到1之间
# return image, label
# # 对训练集数据进行增强
# augmented_tr_ds = tr_ds.map(augment_images)
2.可视化数据
plt.figure(figsize=(10, 4)) # 图形的宽为10高为5for images, labels in tr_ds.take(1):for i in range(10):ax = plt.subplot(2, 5, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
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,)的张量
(32, 224, 224, 3)
(32,)
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)
normalization_layer = layers.Rescaling(1./255)tr_ds = tr_ds.map(lambda x, y: (normalization_layer(x), y))
val_ds = val_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(val_ds))
first_image = image_batch[0]# 查看归一化后的数据,将每张图片的像素归一至0-1间的数值
print(np.min(first_image), np.max(first_image))
0.0 1.0
三、构建CNN网络模型
[引1]- VGGNet (Visual Geometry Group Network):
创新:VGGNet的创新在于采用了相对简单的卷积层堆叠的结构,其中使用了多个小卷积核(3*3)来替代较大的卷积核。这种结构使网络更深,同时参数共享更多,有助于提取丰富的特征。
- 优点:
- 相对简单而易于理解的网络结构。
- 良好的性能在图像分类任务中得到了验证。
- 网络结构可提取更丰富的特征信息
- 缺点:
- 参数量较大,网络结构比较深,需要消耗大量计算资源和时间来训练。
- 网络结构比较复杂,容易出现梯度消失或爆炸等问题
- 相对于一些后续的模型,不够高效。
网络结构如下图:
1、手动搭建
from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout
#functional model的搭建模式,之前是sequential
def VGG16(nb_classes, input_shape):input_tensor = Input(shape=input_shape)# 1st blockx = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv1')(input_tensor)x = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv2')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block1_pool')(x)# 2nd blockx = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv1')(x)x = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv2')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block2_pool')(x)# 3rd blockx = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv1')(x)x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv2')(x)x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block3_pool')(x)# 4th blockx = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv1')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv2')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block4_pool')(x)# 5th blockx = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv1')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv2')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block5_pool')(x)# full connectionx = Flatten()(x)x = Dense(4096, activation='relu', name='fc1')(x)x = Dense(4096, activation='relu', name='fc2')(x)predictions = Dense(nb_classes, activation='softmax', name='predictions')(x)model = Model(inputs=input_tensor, outputs=predictions)return modelmodel = VGG16(len(class_names), (img_width, img_height, 3))
model.summary()
Model: "functional"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ input_layer (InputLayer) │ (None, 224, 224, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block1_conv1 (Conv2D) │ (None, 224, 224, 64) │ 1,792 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block1_conv2 (Conv2D) │ (None, 224, 224, 64) │ 36,928 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block1_pool (MaxPooling2D) │ (None, 112, 112, 64) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block2_conv1 (Conv2D) │ (None, 112, 112, 128) │ 73,856 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block2_conv2 (Conv2D) │ (None, 112, 112, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block2_pool (MaxPooling2D) │ (None, 56, 56, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block3_conv1 (Conv2D) │ (None, 56, 56, 256) │ 295,168 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block3_conv2 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block3_conv3 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block3_pool (MaxPooling2D) │ (None, 28, 28, 256) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block4_conv1 (Conv2D) │ (None, 28, 28, 512) │ 1,180,160 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block4_conv2 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block4_conv3 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block4_pool (MaxPooling2D) │ (None, 14, 14, 512) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block5_conv1 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block5_conv2 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block5_conv3 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ block5_pool (MaxPooling2D) │ (None, 7, 7, 512) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ flatten (Flatten) │ (None, 25088) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ fc1 (Dense) │ (None, 4096) │ 102,764,544 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ fc2 (Dense) │ (None, 4096) │ 16,781,312 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ predictions (Dense) │ (None, 4) │ 16,388 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 134,276,932 (512.23 MB)
Trainable params: 134,276,932 (512.23 MB)
Non-trainable params: 0 (0.00 B)
2、直接调用官方模型
#调用-去除顶层自定义全连接层,加imagenet权重参数,冻结conv,加BN和dropout
from tensorflow.keras.applications import VGG16# 加载VGG16模型,不包括全连接层,使用ImageNet的权重
base_model = VGG16(weights="imagenet",include_top=False,input_shape=(img_height, img_width, 3),pooling = "max")# 冻结VGG16的卷积层,不进行训练
# base_model.trainable = False#部分解冻?
# 冻结直到某一层的所有层
#仅微调卷积基的最后的两三层
base_model.trainable = Trueset_trainable = False
for layer in base_model.layers[:-2]:if layer.name == 'block5_conv1':set_trainable = Trueif set_trainable:layer.trainable = Trueprint(layer)else:set_trainable = Falselayer.trainable = False
print(base_model.summary(),end="\n")# 在VGG16基础上添加自定义的全连接层
model = models.Sequential([base_model,#layers.GlobalAveragePooling2D(),#layers.GlobalMaxPooling2D(),layers.Flatten(),layers.Dense(1024, activation="relu"),layers.BatchNormalization(),layers.Dropout(0.4),layers.Dense(128, activation= "relu"),layers.BatchNormalization(),layers.Dropout(0.4),layers.Dense(len(class_names), activation="softmax")
])# 打印网络结构
model.summary()# model.load_weights("/content/drive/Othercomputers/My laptop/jupyter notebook/xunlianying/vgg16_1_final.weights.h5")
四、编译模型
在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:
- 损失函数(loss):用于衡量模型在训练期间的准确率。
- 优化器(optimizer):决定模型如何根据其看到的数据和自身的损失函数进行更新。
- 指标(metrics):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
#本次使用代码
# 设置初始学习率
initial_learning_rate = 1e-4lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(initial_learning_rate,decay_steps=30,decay_rate=0.92,staircase=True)# 将指数衰减学习率送入优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)model.compile(optimizer=optimizer,loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['accuracy'])#Adam优化器是一种常用的梯度下降优化算法,用于更新模型的权重以最小化训练过程中的损失函数
#由于是多分类问题这里使用categorical crossentropy损失函数
五、训练模型
epochs = 20# 保存最佳模型参数
checkpointer = ModelCheckpoint("/content/drive/My Drive/Colab Notebooks/jupyter notebook/xunlianying/T7_shou1.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.0001,patience=5,mode = "max",verbose=1)
history = model.fit(tr_ds,validation_data=val_ds,epochs=epochs,callbacks=[checkpointer, earlystopper])
训练过程。。。。漫长。。。。
六、模型评估
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']loss = history.history['loss']
val_loss = history.history['val_loss']epochs_range = range(epochs)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()
七、预测
'''指定图片进行预测'''
# 加载效果最好的模型权重
model.load_weights("/content/drive/My Drive/Colab Notebooks/jupyter notebook/xunlianying/T7_shou1.weights.h5")
from PIL import Imageimport numpy as npimg = Image.open("/content/drive/MyDrive/Colab Notebooks/jupyter notebook/data/7/Dark/dark (133).png") #这里选择你需要预测的图片
image = tf.image.resize(img, [img_height, img_width])img_array = tf.expand_dims(image, 0)predictions = model.predict(img_array) # 这里选用你已经训练好的模型
print("预测结果为:",class_names[np.argmax(predictions)])
八、暂时总结
- 由于没有GPU算力嘞,cpu跑得一天。。。慢慢来吧,最近也好忙,慢慢学,抽空去补点基础知识了。。。
- 后续模型调整再跑什么的感觉得好久了。。。(每次调整优化其实也很耗时)
相关文章:

T7:咖啡豆识别
T7:咖啡豆识别 **一、前期工作**1.设置GPU,导入库2.导入数据3.查看数据 **二、数据预处理**1.加载数据2.可视化数据3.配置数据集 **三、构建CNN网络模型**1、手动搭建2、直接调用官方模型 **四、编译模型****五、训练模型****六、模型评估****七、预测**八、暂时总结…...

【MATLAB】FIR滤波器的MATLAB实现
FIR滤波器的MATLAB实现 FIR滤波器的设计fir1函数fir2函数 与IIR滤波器相比,FIR滤波器既有其优势也有其局限性。FIR滤波器的主要优点包括: 精确的线性相位响应;永远保持稳定性;设计方法通常是线性的;在硬件实现中具有更…...

【RabbitMQ之一:windows环境下安装RabbitMQ】
目录 一、下载并安装Erlang1、下载Erlang2、安装Erlang3、配置环境变量4、验证erlang是否安装成功 二、下载并安装RabbitMQ1、下载RabbitMQ2、安装RabbitMQ3、配置环境变量4、验证RabbitMQ是否安装成功5、启动RabbitMQ服务(安装后服务默认自启动) 三、安…...

ISO26262和Aspice之间的关联
ASPICE 介绍: ASPICE(Automotive Software Process Improvement and Capability dEtermination)是汽车软件过程改进及能力评定的模型,它侧重于汽车软件的开发过程。ASPICE 定义了一系列的过程和活动,包括需求管理、软…...

对极约束及其性质 —— 公式详细推导
Title: 对极约束及其性质 —— 公式详细推导 文章目录 前言1. 对极约束 (Epipolar Constraint)2. 坐标转换 (Coordinate Transformations)3. 像素坐标 (Pixel Coordinates)4. 像素坐标转换 (Transformations of Pixel Coordinates)5. 本质矩阵 (Essential Matrix)6. 线坐标 (Co…...
【论文精读】SCINet-基于降采样和交互学习的时序卷积模型
《SCINet: Time Series Modeling and Forecasting with Sample Convolution and Interaction》的作者团队来自香港中文大学,发表在NeurIPS 2022会议上。 动机 该论文的出发点是观察到时间序列数据具有独特的属性:即使在将时间序列下采样成两个子序列后,时间关系(例如数据…...

深度学习与大模型第1课环境搭建
文章目录 深度学习与大模型第1课环境搭建1. 安装 Anaconda2. 修改环境变量2.1 修改 .condarc 文件2.2 使用 Anaconda Prompt 修改环境变量 3. 新建 .ipynb 文件 机器学习基础编程:常见问题: 深度学习与大模型第1课 环境搭建 1. 安装 Anaconda 首先&am…...

JDK新特性
LTS Record jdk16 不是方法 是一个定 # Sealed Class/Interface jdk17 限制只能由某些类继承 CompletableFuture jkd8 PatternMatching of instanceOf jdk16 switch expressions jdk14 Stream.collect() Collector Collector API Collector.groupBy Collector实战 1. …...
数据处理与数据填充在Pandas中的应用
在数据分析和机器学习项目中,数据处理是至关重要的一步。Pandas作为Python中用于数据分析和操作的一个强大库,提供了丰富的功能来处理和清洗数据。本文将深入探讨Pandas在数据处理,特别是数据填充方面的应用。 在实际的数据集中,…...
【百日算法计划】:每日一题,见证成长(010)
题目 合并两个排序的链表 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 思路 引入一个带虚拟头结点和tail指针的…...

【WPF】WPF学习之【二】布局学习
WPF布局学习 常用布局Grid网格布局StackPanel 布局CanvasDockPanel布局WrapPanel布局 常用布局 1、StackPanel: 学习如何使用StackPanel进行垂直和水平布局。 2、Grid: 掌握Grid的网格布局技术。 3、Canvas: 了解Canvas的绝对定位布局。 4、DockPanel: 学习DockPanel的停靠…...

KEIL中编译51程序 算法计算异常的疑问
KEIL开发 51 单片机程序 算法处理过程中遇到的问题 ...... by 矜辰所致前言 因为产品的更新换代, 把所有温湿度传感器都换成 SHT40 ,替换以前的 SHT21。在 STM32 系列产品上的替换都正常,但是在一块 51 内核的无线产品上面,数据…...

pikachu文件包含漏洞靶场
本地文件包含 1、先随意进行提交 可以得出是GET传参 可以在filename参数进行文件包含 2、准备一个2.jpg文件 内容为<?php phpinfo();?> 3、上传2.jpg文件 4、访问文件保存的路径uploads/2.jpg 5、将我们上传的文件包含进来 使用../返回上级目录 来进行包含木马文件 …...

基于DPU与SmartNIC的K8s Service解决方案
1. 方案背景 1.1. Kubernetes Service介绍 Kubernetes Service是Kubernetes中的一个核心概念,它定义了一种抽象,用于表示一组提供相同功能的Pods(容器组)的逻辑集合,并提供了一种方式让这些Pods能够被系统内的其他组…...

SLM561A系列 60V 10mA到50mA线性恒流LED驱动芯片 为智能家居照明注入新活力
SLM561A系列选型参考: SLM561A10ae-7G SOD123 SLM561A15ae-7G SOD123 SLM561A20ae-7G SOD123 SLM561A25ae-7G SOD123 SLM561A30ae-7G SOD123 SLM561A35ae-7G SOD123 SLM561A40ae-7G SOD123 SLM561A45ae-7G SOD123 SLM561A50ae-7G SOD123 …...
Requests库对session的支持
场景:如何获取登录时响应消息中的sessionid,以及如何在后续请求中把sessionid添到cookie中 Requests库提供了一个Session类,通过requests库中的session对象,requests库会自动帮我们保存服务端返回的cookie数据(set-cookie里的内容…...

利用深度学习实现验证码识别-2-使用Python导出ONNX模型并在Java中调用实现验证码识别
1. Python部分:导出ONNX模型 首先,我们需要在Python中定义并导出一个已经训练好的验证码识别模型。以下是完整的Python代码: import string import torch import torch.nn as nn import torch.nn.functional as FCHAR_SET string.digits# …...
如何通过Spring Cloud Consul增强微服务安全性和可靠性
为了增强微服务的安全性和可靠性,Spring Cloud Consul 是一个非常强大的工具。它不仅提供了服务发现和配置管理功能,还能够有效地管理微服务的安全和健康状态。本文将深入探讨如何通过 Spring Cloud Consul 来增强微服务的安全性和可靠性,主要…...
无代码搭建小程序zion
无代码搭建小程序zion 一、无代码搭建小程序zion的降低技术门槛,提升开发效率 1. 无需编程经验:Zion无代码平台通过提供直观的可视化界面和拖拽式操作,让开发者无需具备复杂的编程技能也能进行小程序的开发。这种方式大大降低了技术门槛&a…...

【南方科技大学】CS315 Computer Security 【Lab1 Packet Sniffing and Wireshark】
目录 IntroductionBackgroundTCP/IP Network StackApplication LayerTransport LayerInternet LayerLink LayerPacket Sniffer Getting WiresharkStarting WiresharkCapturing PacketsTest Run Questions for the Lab Introduction 实验的第一部分介绍数据包嗅探器 Wireshark。…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...

华硕电脑,全新的超频方式,无需进入BIOS
想要追求更佳性能释放 或探索更多可玩性的小伙伴, 可能会需要为你的电脑超频。 但我们常用的不论是BIOS里的超频, 还是Armoury Crate奥创智控中心超频, 每次调节都要重启,有点麻烦。 TurboV Core 全新的超频方案来了 4不规…...