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。…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
Linux入门课的思维导图
耗时两周,终于把慕课网上的Linux的基础入门课实操、总结完了! 第一次以Blog的形式做学习记录,过程很有意思,但也很耗时。 课程时长5h,涉及到很多专有名词,要去逐个查找,以前接触过的概念因为时…...
