图像分类项目2:鸟类图像分类

1 数据集处理

1.1数据集下载

数据集来源:kaggle,网址:https://www.kaggle.com/,点击进入网站,左侧选择Datasets。
在这里插入图片描述
进入后搜索栏搜索关键词bird。此时出现很多数据集可以选择,推荐选择第一个或者第三个。这里以第三个为例进行演示。
在这里插入图片描述
点击进入,注册登录账号后,点击Download进行下载。下载后选择第一个压缩包进行解压。
在这里插入图片描述

1.2 数据集划分

先观察数据集。进入数据集文件夹,直接选择images进入。
在这里插入图片描述

此时我们可以观察到有200个文件夹,代表200个鸟的种类。当我们知道文件结构后需要对其进行划分了。按照常用比例8:1:1划分为训练集、验证集和测试集。

import os
import shutil
import random
# 数据集根目录,这里选择自己的目录
data_dir = './bird200/CUB_200_2011/images' 
# 划分后的数据集根目录
output_dir = './bird200_new'# 创建训练集、验证集和测试集的文件夹
train_dir = os.path.join(output_dir, 'train')
val_dir = os.path.join(output_dir, 'val')
test_dir = os.path.join(output_dir, 'test')os.makedirs(train_dir, exist_ok=True)
os.makedirs(val_dir, exist_ok=True)
os.makedirs(test_dir, exist_ok=True)# 遍历每个类别文件夹
for class_name in os.listdir(data_dir):class_dir = os.path.join(data_dir, class_name)if os.path.isdir(class_dir):# 创建训练集、验证集和测试集的类别文件夹train_class_dir = os.path.join(train_dir, class_name)val_class_dir = os.path.join(val_dir, class_name)test_class_dir = os.path.join(test_dir, class_name)os.makedirs(train_class_dir, exist_ok=True)os.makedirs(val_class_dir, exist_ok=True)os.makedirs(test_class_dir, exist_ok=True)# 获取该类别下的所有文件files = os.listdir(class_dir)random.shuffle(files)  # 随机打乱文件顺序# 计算划分的索引num_files = len(files)train_size = int(num_files * 0.8)val_size = int(num_files * 0.1)# 划分文件train_files = files[:train_size]val_files = files[train_size:train_size + val_size]test_files = files[train_size + val_size:]# 复制文件到对应的文件夹for file in train_files:src_path = os.path.join(class_dir, file)dst_path = os.path.join(train_class_dir, file)shutil.copyfile(src_path, dst_path)for file in val_files:src_path = os.path.join(class_dir, file)dst_path = os.path.join(val_class_dir, file)shutil.copyfile(src_path, dst_path)for file in test_files:src_path = os.path.join(class_dir, file)dst_path = os.path.join(test_class_dir, file)shutil.copyfile(src_path, dst_path)print("数据集划分完成!")

2.前期准备工作

2.1 导入需要的库

import warnings
from sklearn.exceptions import ConvergenceWarning
warnings.filterwarnings("ignore", category=ConvergenceWarning)
warnings.simplefilter(action='ignore', category=FutureWarning)
warnings.simplefilter(action='ignore', category=UserWarning)# 导入必要的库
import itertools
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from PIL import Image
from sklearn.metrics import classification_report, f1_score , confusion_matrix# 导入TensorFlow库
import tensorflow as tf
from tensorflow import keras
from keras.layers import Dense, Dropout , BatchNormalization
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import layers,models,Model
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers.experimental import preprocessing
from tensorflow.keras.callbacks import Callback, EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras import mixed_precision
mixed_precision.set_global_policy('float32')# 输出TensorFlow版本
print(tf.__version__)

进行测试运行结果:
在这里插入图片描述

2.2加载数据

这里进行数据集载入,遍历文件夹读取照片和标签信息。并对其转化格式,使其符合TensorFlow运行。

# 定义数据集路径
dataset = {"train_data" : "./lty/input/bird-species/train","valid_data" : "./lty/input/bird-species/valid","test_data" : "./lty/input/bird-species/test"}all_data = []# 遍历数据集文件夹并读取图片和标签信息
for path in dataset.values():data = {"imgpath": [] , "labels": [] }category = os.listdir(path)for folder in category:folderpath = os.path.join(path , folder)filelist = os.listdir(folderpath)for file in filelist:fpath = os.path.join(folderpath, file)data["imgpath"].append(fpath)data["labels"].append(folder)# 将数据加入列表中all_data.append(data.copy())data.clear()# 将列表转化为DataFrame格式
train_df = pd.DataFrame(all_data[0] , index=range(len(all_data[0]['imgpath'])))
valid_df = pd.DataFrame(all_data[1] , index=range(len(all_data[1]['imgpath'])))
test_df = pd.DataFrame(all_data[2] , index=range(len(all_data[2]['imgpath'])))# 将标签转化为数字编码
lb = LabelEncoder()
train_df['encoded_labels'] = lb.fit_transform(train_df['labels'])
valid_df['encoded_labels'] = lb.fit_transform(valid_df['labels'])
test_df['encoded_labels'] = lb.fit_transform(test_df['labels'])
进行一个可视化展示,展示每个类别数量以及标签。
# 获取训练集中每个类别的图像数量和标签
train  = train_df["labels"].value_counts()
label = train.tolist()
index = train.index.tolist()# 设置颜色列表
colors = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd","#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf","#aec7e8", "#ffbb78", "#98df8a", "#ff9896", "#c5b0d5","#c49c94", "#f7b6d2", "#c7c7c7", "#dbdb8d", "#9edae5","#5254a3", "#6b6ecf", "#bdbdbd", "#8ca252", "#bd9e39","#ad494a", "#8c6d31", "#6b6ecf", "#e7ba52", "#ce6dbd","#9c9ede", "#cedb9c", "#de9ed6", "#ad494a", "#d6616b","#f7f7f7", "#7b4173", "#a55194", "#ce6dbd"
]# 绘制水平条形图
plt.figure(figsize=(30,30))
plt.title("Training data images count per class",fontsize=38)
plt.xlabel('Number of images', fontsize=35)
plt.ylabel('Classes', fontsize=35)
plt.barh(index,label, color=colors)
plt.grid(True)
plt.show()

展示如图:
在这里插入图片描述

2.3检查训练集、验证集和测试集的内容

通过打印输出训练集、验证集和测试集的内容,确保分配没有出现问题。

import os# 设置训练集文件夹路径
path = "C:/Users/z/lty/bird-species/train"# 获取train训练集文件夹列表
dirs = os.listdir(path)# 遍历文件夹列表并打印文件名
for file in dirs:print(file)

展示如图:
在这里插入图片描述

# 打印训练集信息
print("----------Train-------------")
print(train_df[["imgpath", "labels"]].head(5))  # 打印前5行的图像路径和标签
print(train_df.shape)  # 打印训练集的形状,即行数和列数# 打印验证集信息
print("--------Validation----------")
print(valid_df[["imgpath", "labels"]].head(5))  # 打印前5行的图像路径和标签
print(valid_df.shape)  # 打印验证集的形状,即行数和列数# 打印测试集信息
print("----------Test--------------")
print(test_df[["imgpath", "labels"]].head(5))  # 打印前5行的图像路径和标签
print(test_df.shape)  # 打印测试集的形状,即行数和列数

展示如图:
在这里插入图片描述

随机展示数据集的照片,用于直观体验:

import matplotlib.pyplot as plt
from PIL import Image# 创建一个大小为15x12的画布
plt.figure(figsize=(15, 12))# 从验证集中随机选择16个样本,重置索引并逐行处理
for i, row in valid_df.sample(n=16).reset_index().iterrows():# 在4x4的子图中的第i+1个位置创建一个子图plt.subplot(4, 4, i+1)# 获取图像路径image_path = row['imgpath']image = Image.open(image_path)plt.imshow(image)# 设置子图的标题为标签值plt.title(row["labels"])plt.axis('off')
plt.show()

如图所示:
在这里插入图片描述

2.4数据预处理

再对数据进行处理,例如进行数据增强等操作。

%%timeBATCH_SIZE = 35
IMAGE_SIZE = (224, 224)# 导入图像数据生成器 ImageDataGenerator
from keras.preprocessing.image import ImageDataGenerator# 定义数据增强生成器
generator = ImageDataGenerator(preprocessing_function=tf.keras.applications.efficientnet.preprocess_input,  # 预处理函数rescale=1./255,  # 将像素值缩放到0-1之间width_shift_range=0.2,  # 水平和垂直方向上的随机平移范围height_shift_range=0.2,zoom_range=0.2  # 随机缩放图像的范围
)# 将训练集数据分批生成并进行数据增强
train_images = generator.flow_from_dataframe(dataframe=train_df,  # 使用train_df作为数据源x_col='imgpath',  # 图像路径的列名y_col='labels',  # 标签的列名target_size=IMAGE_SIZE,  # 图像的目标大小color_mode='rgb',  # 图像的颜色通道模式class_mode='categorical',  # 分类模式,输出是一个one-hot编码的向量batch_size=BATCH_SIZE,  # 批次大小shuffle=True,  # 是否打乱数据顺序seed=42  # 随机种子
)# 将验证集数据分批生成
val_images = generator.flow_from_dataframe(dataframe=valid_df,  # 使用valid_df作为数据源x_col='imgpath',y_col='labels',target_size=IMAGE_SIZE,color_mode='rgb',class_mode='categorical',batch_size=BATCH_SIZE,shuffle=False
)# 将测试集数据分批生成
test_images = generator.flow_from_dataframe(dataframe=test_df,  # 使用test_df作为数据源x_col='imgpath',y_col='labels',target_size=IMAGE_SIZE,color_mode='rgb',class_mode='categorical',batch_size=BATCH_SIZE,shuffle=False
)经过这些处理后,照片的大小就是一致的了。最后一步就是调整子图间的空白部分。
labels = [k for k in train_images.class_indices]
sample_images = train_images.__next__()images = sample_generate[0]
titles = sample_generate[1]
plt.figure(figsize = (15 , 15))for i in range(20):plt.subplot(5 ,  5 , i+1)plt.subplots_adjust(hspace = 0.3 , wspace = 0.3)#调整子图之间的空白区域plt.imshow(images[i])plt.title(f'Class: {labels[np.argmax(titles[i],axis=0)]}')plt.axis("off")

运行结果如下:
在这里插入图片描述

3.进行模型训练

3.1 模型加载

先进行模型加载,我们可以下载一个适合的预训练模型,再其基础上进行训练和微调可以减少训练时间。

# 加载预训练模型
pretrained_model = tf.keras.applications.EfficientNetB5(input_shape=(224, 224, 3),include_top=False, # 不加载或重新初始化顶层(输出层)的参数weights='imagenet',pooling='max'
)# 冻结预训练神经网络的层
for i, layer in enumerate(pretrained_model.layers):pretrained_model.layers[i].trainable = False

3.2 构建模型

这一步构建我们自己的训练模型。

# 获取类别数
num_classes = len(set(train_images.classes))# 对数据进行增强
augment = tf.keras.Sequential([layers.experimental.preprocessing.RandomFlip("horizontal"),layers.experimental.preprocessing.RandomRotation(0.15),layers.experimental.preprocessing.RandomZoom(0.12),layers.experimental.preprocessing.RandomContrast(0.12),
], name='AugmentationLayer')# 输入层
inputs = layers.Input(shape=(224, 224, 3), name='inputLayer')
x = augment(inputs)  # 应用数据增强
pretrain_out = pretrained_model(x, training=False)# 添加全连接层和激活函数
x = layers.Dense(1024)(pretrain_out)
x = layers.Activation(activation="relu")(x)
x = BatchNormalization()(x)
x = layers.Dropout(0.45)(x)
x = layers.Dense(512)(x)
x = layers.Activation(activation="relu")(x)
x = BatchNormalization()(x)
x = layers.Dropout(0.3)(x)
x = layers.Dense(num_classes)(x)
outputs = layers.Activation(activation="softmax", dtype=tf.float32, name='activationLayer')(x)# 创建模型
model = Model(inputs=inputs, outputs=outputs)# 编译模型
model.compile(optimizer=Adam(0.0005),loss='categorical_crossentropy',metrics=['accuracy']
)# 打印模型结构摘要
print(model.summary())

展示如图,可以查看模型具体参数:
在这里插入图片描述

3.3 模型训练

这一步就可以正式训练模型了。在 transfer learning 中,我们可以选择保持预训练模型的一部分或全部参数不变(称为冻结),只对最后几层或某些层进行微调,以适应新任务的特定要求。这样做的原因是预训练模型已经学习到了通用的特征,我们可以认为这些特征对于新任务也是有用的。通过仅微调少量参数,我们可以在较小的数据集上快速训练出具有良好性能的模型。

# 训练模型
history = model.fit(train_images,steps_per_epoch=len(train_images),validation_data=val_images,validation_steps=len(val_images),epochs=10,callbacks=[# 提前停止回调,如果验证集损失在连续3个epoch中没有改善,则提前停止训练EarlyStopping(monitor="val_loss", patience=3, restore_best_weights=True),# 学习率调整,在验证集损失没有改善时降低学习率ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=2, mode='min')]
)# 保存模型权重
model.save_weights('./lty/input/bird-species/my_checkpoint')

训练如图所示:
在这里插入图片描述

4.结果与评估

4.1 结果展示

绘制训练过程图。

# 定义所需的变量
tr_acc = history.history['accuracy']
tr_loss = history.history['loss']
val_acc = history.history['val_accuracy']
val_loss = history.history['val_loss']
index_loss = np.argmin(val_loss)
val_lowest = val_loss[index_loss]
index_acc = np.argmax(val_acc)
acc_highest = val_acc[index_acc]
Epochs = [i+1 for i in range(len(tr_acc))]
loss_label = f'best epoch= {str(index_loss + 1)}'
acc_label = f'best epoch= {str(index_acc + 1)}'# 绘制训练历史
plt.figure(figsize= (20, 8))
plt.style.use('fivethirtyeight')plt.subplot(1, 2, 1)
plt.plot(Epochs, tr_loss, 'r', label= 'Training loss')
plt.plot(Epochs, val_loss, 'g', label= 'Validation loss')
plt.scatter(index_loss + 1, val_lowest, s= 150, c= 'blue', label= loss_label)
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(Epochs, tr_acc, 'r', label= 'Training Accuracy')
plt.plot(Epochs, val_acc, 'g', label= 'Validation Accuracy')
plt.scatter(index_acc + 1 , acc_highest, s= 150, c= 'blue', label= acc_label)
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.tight_layout
plt.show()

展示结果:
在这里插入图片描述

4.2 评估

评估模型在当前数据集上的性能,包括测试损失和测试的准确率,并打印分数报告。

results = model.evaluate(test_images, verbose=0)# 对测试集进行评估,返回测试损失和测试准确率print("    Test Loss: {:.5f}".format(results[0]))# 打印测试损失,保留小数点后5位
print("Test Accuracy: {:.2f}%".format(results[1] * 100))
# 打印测试准确率,乘以100后保留两位小数
y_true = test_images.classes  # 获取测试集样本的真实标签
y_pred = np.argmax(model.predict(test_images), axis=1)
# 获取模型对测试集样本的预测标签# 计算并打印F1 Score和分类报告
f1 = f1_score(y_true, y_pred, average='macro')  # 计算F1 Score
print("F1 Score:", f1)
print(classification_report(y_true, y_pred, target_names=test_images.class_indices.keys()))  # 打印分类报告

展示:
在这里插入图片描述

为了获得结果展示,我能可以打印预测结果。这里展示前8条。

# 创建一个字典,将类别索引和对应的类别名称进行关联
classes = dict(zip(test_images.class_indices.values(), test_images.class_indices.keys()))# 创建一个DataFrame来存储预测结果
Predictions = pd.DataFrame({"Image Index": list(range(len(test_images.labels))),  # 图像索引"Test Labels": test_images.labels,  # 真实标签"Test Classes": [classes[i] for i in test_images.labels],  # 真实类别"Prediction Labels": y_pred,  # 预测标签"Prediction Classes": [classes[i] for i in y_pred],  # 预测类别"Path": test_images.filenames,  # 图像路径"Prediction Probability": [x for x in np.asarray(tf.reduce_max(model.predict(test_images), axis=1))]  # 预测概率
})Predictions.head(8)  # 输出前8行预测结果

展示:
在这里插入图片描述

4.3 优化方向

在这里我们展示了最容易出错的样本,用于后续。

plt.figure(figsize=(20, 20))
# 选择分类错误的预测结果中概率最高的20个样本
subset = Predictions[Predictions["Test Labels"] != Predictions["Prediction Labels"]].sort_values("Prediction Probability").tail(20).reset_index()for i, row in subset.iterrows():plt.subplot(5, 4, i+1)image_path = row['Path']image = Image.open(image_path)# 显示图像plt.imshow(image)# 设置图像标题,包括真实类别和预测类别plt.title(f'TRUE: {row["Test Classes"]} | PRED: {row["Prediction Classes"]}', fontsize=8)plt.axis('off')plt.show()

展示如图:
在这里插入图片描述

混淆矩阵(Confusion Matrix)和分类报告(Classification Report)

import numpy as np
from sklearn.metrics import confusion_matrix
import itertools
import matplotlib.pyplot as plt# 使用模型对测试图片进行预测
preds = model.predict_generator(test_images)
# 找到每个预测结果中概率最高的类别作为预测标签
y_pred = np.argmax(preds, axis=1)# 获取测试图片的真实标签和对应的类别字典
g_dict = test_images.class_indices
# 创建一个包含所有类别名称的列表
classes = list(g_dict.keys())# 计算混淆矩阵
cm = confusion_matrix(test_images.classes, y_pred)plt.figure(figsize=(30, 30))
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.title('Confusion Matrix')
plt.colorbar()tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):plt.text(j, i, cm[i, j], horizontalalignment='center', color='white' if cm[i, j] > thresh else 'black')plt.tight_layout()
plt.ylabel('True Label')
plt.xlabel('Predicted Label')plt.show()

使用matplotlib库绘制了一个大小为30x30的图像窗口,显示了混淆矩阵的热力图。热力图的颜色越深,表示预测结果越准确。图像中的数字表示每个混淆矩阵单元格中的样本数量。图像上方的标题为"Confusion Matrix",颜色条表示每个颜色对应的样本数量范围。x轴标签为预测标签,y轴标签为真实标签。
在这里插入图片描述

5 思考题

5.1 基础概念

图像分类任务中,为什么需要对图像进行预处理?常见的预处理方法有哪些?它们分别有什么作用?

在鸟类图像分类项目中,如何选择合适的卷积神经网络 (CNN) 模型?需要考虑哪些因素?

解释一下什么是数据增强 (Data Augmentation)?在鸟类图像分类项目中,如何使用数据增强来提高模型的泛化能力?

5.2 模型训练与评估

在训练鸟类图像分类模型时,如何选择合适的损失函数和优化器?它们分别对模型的训练过程有什么影响?

如何判断鸟类图像分类模型是否过拟合或欠拟合?有哪些方法可以解决过拟合和欠拟合问题?

除了准确率 (Accuracy) 之外,还有哪些指标可以用来评估鸟类图像分类模型的性能?这些指标分别有什么意义?

5.3 项目实践与拓展

如果鸟类图像数据集存在类别不平衡问题,该如何解决?有哪些方法可以缓解类别不平衡对模型训练的影响?

如何将训练好的鸟类图像分类模型部署到实际应用中?需要考虑哪些因素?

除了鸟类图像分类,图像分类技术还可以应用在哪些领域?请举例说明。

5.4 深入思考

在鸟类图像分类项目中,如何利用迁移学习 (Transfer Learning) 来提高模型的训练效率和性能?

如何解释鸟类图像分类模型的预测结果?有哪些方法可以帮助我们理解模型的决策过程?

随着深度学习技术的不断发展,图像分类领域还有哪些挑战和机遇?

5.5 提示

这些问题没有标准答案,旨在引导你深入思考图像分类项目的各个方面。

在回答问题时,可以结合自己的项目经验和所学知识进行阐述。

可以查阅相关文献和资料,寻找更深入的解答。

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

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

相关文章

01_NLP基础之文本处理的基本方法

自然语言处理入门 自然语言处理(Natural Language Processing, 简称NLP)是计算机科学与语言学中关注于计算机与人类语言间转换的领域,主要目标是让机器能够理解和生成自然语言,这样人们可以通过语言与计算机进行更自然的互动。 …

利用opencv_python(pdf2image、poppler)将pdf每页转为图片

1、安装依赖pdf2image pip install pdf2image 运行.py报错,因为缺少了poppler支持。 2、安装pdf2image的依赖poppler 以上命令直接报错。 改为手工下载: github: Releases oschwartz10612/poppler-windows GitHub 百度网盘: 百度网盘…

IDEA入门及常用快捷键

IDEA是java常用的IDE。当run一个.java文件时,其实是经历了先编译为.class,再运行的过程。 在project文件夹中,out文件夹存储编译的.class文件,src文件夹存储.java代码文件。 设置自动导包 快捷键: 格式化快捷键&…

io学习----->文件io

思维导图: 一.文件io的概念 文件IO:指程序和文件系统之间的数据交互 特点: 1.不存在缓冲区,访问速度慢 2.不可以移植,依赖于操作系统 3.可以访问不同的文件类型(软连接,块设备等) 4.文件IO属于系统调…

深入探索WebGL:解锁网页3D图形的无限可能

深入探索WebGL:解锁网页3D图形的无限可能 引言 。WebGL,作为这一变革中的重要技术,正以其强大的功能和广泛的应用前景,吸引着越来越多的开发者和设计师的关注。本文将深入剖析WebGL的核心原理、关键技术、实践应用,并…

从开发和对抗的角度思考web网页中的接口逆向

如何从开发和对抗的角度去思考web网页中的接口逆向。 文章目录 前言1.从开发和对抗的角度思考接口逆向1.1 什么是接口逆向1.2 开发的角度思考如何开发策略1.3 对抗的角度思考遇到的问题1.4 正常情况下开发者如何防护1.5 正常情况攻击者如何做?1.6 对抗中的胜者 2.某…

C++24--右值引用C++11新特性

目录 1.C11简介 2.统一的列表初始化 2.1{}初始化 2.2std::initializer_list 3.声明 3.1auto 3.2decltype 3.3nullptr 4.范围for循环 5.智能指针 6.右值引用和移动语义 6.1左值引用和右值引用 6.2左值引用与右值引用比较 6.3右值引用使用场景和意义 6.4右值引用引…

Android ChatOn-v1.66.536-598-[构建于ChatGPT和GPT-4o之上]

ChatOn 链接:https://pan.xunlei.com/s/VOKYnq-i3C83CK-HJ1gfLf4gA1?pwdwzwc# 添加了最大无限积分 删除了所有调试信息 语言:全语言支持

Java高频面试之集合-03

hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:说说ArrayList和LinkedList的区别 ArrayList 与 LinkedList 的详细对比 一、底层数据结构 特性ArrayListLinkedList存…

华为hcie证书有什么作用?

新盟教育 专注华为认证培训十余年 为你提供认证一线资讯! 在当今数字化飞速发展的时代,ICT行业对专业人才的需求日益增长。华为HCIE证书作为华为认证体系中的最高级别认证,无疑是众多IT从业者追求的目标。那么,华为HCIE证书到底有…

通过微步API接口对单个IP进行查询

import requests import json# 微步API的URL和你的API密钥 API_URL "https://api.threatbook.cn/v3/ip/query" API_KEY "***" # 替换为你的微步API密钥 def query_threatbook(ip):"""查询微步API接口,判断IP是否为可疑"…

Redis|集群 Cluster

文章目录 是什么能干嘛集群算法-分片-槽位slotredis集群的槽位slotredis集群的分片分片槽位的优势slot槽位映射——业界的3种解决方案小厂:哈希取余分区中厂:一致性哈希算法分区大厂:哈希槽分区 面试题:为什么 Redis 集群的最大槽…

城市地质安全专题连载⑧ | 强化工程地质安全保障力度,为工程项目全栈护航

作者 | 徐海洋、孙美琴 在城市化进程日益加速的今天,城市地质安全问题日益凸显,成为制约城市可持续发展的关键因素之一。从隧道掘进中的突发灾害,到高层建筑地基的稳定性挑战,再到城市地下空间的开发利用风险,地质安全…

工厂模式:简单工厂、工厂方法以及抽象工厂

文章目录 前言简单工厂模式优缺点 工厂方法模式优缺点 抽象工厂优缺点 前言 工厂模式是一种创建型设计模式,其作用是将对象的创建和使用进行解耦,用于提高代码的可维护性和可扩展性。通过提供给外部负责创建对象的工厂类,外部类通过工厂来创…

FFMPEG利用H264+AAC合成TS文件

本次的DEMO是利用FFMPEG框架把H264文件和AAC文件合并成一个TS文件。这个DEMO很重要,因为在后面的推流项目中用到了这方面的技术。所以,大家最好把这个项目好好了解。 下面这个是流程图 从这个图我们能看出来,在main函数中我们主要做了这几步&…

sqli-lab靶场学习(七)——Less23-25(关键字被过滤、二次注入)

前言 之前的每一关,我们都是在末尾加上注释符,屏蔽后面的语句,这样我们只要闭合了区间之后,差不多就是为所欲为的状态。但如果注释符不生效的情况下,又该如何呢? Less23(注释符被过滤&#xff…

Self-Supervised Prompt Optimization

论文:[2502.06855] Self-Supervised Prompt Optimization 仓库:GitHub - Airmomo/SPO: SPO | Self-Supervised Prompt Optimization 自监督提示优化(SPO) 创新点 成对比较评估 输出指导优化 全文介绍 背景 随着大语言模型…

AI-Ollama本地大语言模型运行框架与Ollama javascript接入

1.Ollama Ollama 是一个开源的大型语言模型(LLM)平台,旨在让用户能够轻松地在本地运行、管理和与大型语言模型进行交互。 Ollama 提供了一个简单的方式来加载和使用各种预训练的语言模型,支持文本生成、翻译、代码编写、问答等多种…

分布式多卡训练(DDP)踩坑

多卡训练最近在跑yolov10版本的RT-DETR,用来进行目标检测。 单卡训练语句(正常运行): python main.py多卡训练语句: 需要通过torch.distributed.launch来启动,一般是单节点,其中CUDA_VISIBLE…

LLM大型语言模型(一)

1. 什么是 LLM? LLM(大型语言模型)是一种神经网络,专门用于理解、生成并对人类文本作出响应。这些模型是深度神经网络,通常训练于海量文本数据上,有时甚至覆盖了整个互联网的公开文本。 LLM 中的 “大” …