TensorFlow2.x基础与mnist手写数字识别示例

news2024/11/27 8:41:22

文章目录

  • Github
  • 官网
  • 文档
  • Playground
  • 安装
  • 声明张量
    • 常量
    • 变量
  • 张量计算
  • 张量数据类型转换
  • 张量数据维度转换
  • ReLU 函数
  • Softmax 函数
  • 卷积神经网络
  • 训练模型
  • 测试模型
  • 数据集保存目录
  • 显示每层网络的结果

在这里插入图片描述

TensorFlow 是一个开源的深度学习框架,由 Google Brain 团队开发和维护。它被广泛应用于机器学习和深度学习领域,可用于构建各种人工智能模型,包括图像识别、自然语言处理、语音识别、推荐系统等。

  1. 灵活性和可扩展性:TensorFlow 提供了灵活且可扩展的架构,可以在各种硬件平台上运行,包括 CPU、GPU 和 TPU(Tensor Processing Unit)。这使得 TensorFlow 成为构建大规模深度学习模型的理想选择。

  2. 计算图:TensorFlow 使用静态计算图的概念来表示机器学习模型。在构建模型时,首先定义计算图,然后执行计算图以训练模型或进行推理。

  3. 自动求导:TensorFlow 提供了自动求导功能,能够自动计算模型中各个参数的梯度。这简化了模型训练过程中的反向传播步骤。

  4. 高级 API:TensorFlow 提供了多种高级 API,如 tf.keras、tf.estimator 和 tf.data 等,使得构建、训练和部署机器学习模型更加简单和高效。

  5. 跨平台支持:TensorFlow 不仅支持在各种硬件平台上运行,还可以在多种操作系统上运行,包括 Linux、Windows 和 macOS。

  6. 社区支持:TensorFlow 拥有庞大的开发者社区,提供了丰富的文档、教程和示例代码,使得学习和使用 TensorFlow 更加容易。

Github

  • https://github.com/tensorflow/tensorflow

官网

  • https://tensorflow.google.cn/?hl=zh-cn

文档

  • https://tensorflow.google.cn/api_docs/python/tf

Playground

  • https://playground.tensorflow.org/

TensorFlow Playground 是一个交互式可视化工具,旨在帮助用户理解和探索神经网络的基本概念和行为。它提供了一个易于使用的界面,可以在浏览器中运行,不需要编写代码。用户可以通过调整参数和观察结果,直观地理解神经网络的工作原理。

在这里插入图片描述

安装

  • 清理所有安装包
pip freeze | xargs pip uninstall -y
pip install tensorflow==2.13.1
pip install matplotlib==3.7.5
pip install numpy==1.24.3
  • 查看版本
pip list
import tensorflow as tf
print("TensorFlow version:", tf.__version__)

在这里插入图片描述

声明张量

常量

  • https://tensorflow.google.cn/api_docs/python/tf/constant
tf.constant(value, dtype=None, shape=None, name=None)
  • value:常量张量的值。可以是标量、列表、数组等形式的数据。如果传入的是标量,则创建的是一个标量张量;如果传入的是列表或数组,则创建的是一个多维张量。

  • dtype:常量张量的数据类型。可选参数,默认为 None。如果未指定数据类型,则根据传入的 value 推断数据类型。

  • shape:常量张量的形状。可选参数,默认为 None。如果未指定形状,则根据传入的 value 推断形状。

  • name:常量张量的名称。可选参数,默认为 None。如果未指定名称,则 TensorFlow 将自动生成一个唯一的名称。

import tensorflow as tf

tensor_constant = tf.constant([[1, 2], [3, 4]], dtype=tf.int32, shape=(2, 2), name="constant")
print("常量张量:", tensor_constant)
  • 输出
常量张量: tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32)

变量

  • https://tensorflow.google.cn/api_docs/python/tf/Variable
tf.Variable(initial_value, dtype, name=None)
  • initial_value:变量张量的初始值。可以是标量、列表、数组等形式的数据。如果传入的是标量,则创建的是一个标量张量;如果传入的是列表或数组,则创建的是一个多维张量。

  • dtype:变量张量的数据类型。此参数是必须的,不能为 None。你需要明确指定变量张量的数据类型。

  • name:变量张量的名称。可选参数,默认为 None。如果未指定名称,则 TensorFlow 将自动生成一个唯一的名称。

import tensorflow as tf

tensor_variable = tf.Variable(initial_value=[1, 2], dtype=tf.int32, name="variable")
print("变量张量:", tensor_variable)
  • 输出
变量张量: <tf.Variable 'variable:0' shape=(2,) dtype=int32, numpy=array([1, 2], dtype=int32)>

张量计算

import tensorflow as tf

a_constant = tf.constant([[1, 2], [3, 4]], dtype=tf.int32, shape=(2, 2), name="a")
print("常量张量:", a_constant)

b_variable = tf.Variable(initial_value=[1, 2], dtype=tf.int32, name="b")
print("变量张量:", b_variable)

# 定义加法操作节点
c = tf.add(a_constant, b_variable, name="c")
# 执行加法操作并获取结果
print("输出结果: a + b = ", c.numpy())
  • 输出
常量张量: tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32)
变量张量: <tf.Variable 'b:0' shape=(2,) dtype=int32, numpy=array([1, 2], dtype=int32)>
输出结果: a + b =  [[2 4]
 [4 6]]

张量数据类型转换

import tensorflow as tf

int_tensor = tf.constant([[1, 2], [3, 4]], dtype=tf.int32, shape=(2, 2), name="constant")
print("整型张量:", int_tensor)
# 将整数张量转换为浮点数张量
float_tensor = tf.cast(int_tensor, dtype=tf.float32)
print("浮点张量:", float_tensor)
  • 输出
整型张量: tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32)
浮点张量: tf.Tensor(
[[1. 2.]
 [3. 4.]], shape=(2, 2), dtype=float32)

张量数据维度转换

  • 张量转换为指定形状的新张量,而不改变张量中的元素值
import tensorflow as tf

# [2, 3] 形状的张量
tensor = tf.constant([[1, 2, 3], [4, 5, 6]])
# [3, 2] 形状的张量
new_tensor = tf.reshape(tensor, [3, 2])

print("[2, 3] 形状的张量:", tensor)
print("[3, 2] 形状的张量:", new_tensor)
  • 输出
[2, 3] 形状的张量: tf.Tensor(
[[1 2 3]
 [4 5 6]], shape=(2, 3), dtype=int32)
[3, 2] 形状的张量: tf.Tensor(
[[1 2]
 [3 4]
 [5 6]], shape=(3, 2), dtype=int32)

ReLU 函数

ReLU(x)=max(0,x) 即当输入值 x 大于0时,输出 𝑥;否则输出0。

  • 引入非线性:
    ReLU 函数能够引入非线性,使得 CNN 能够学习和表示更复杂的模式和特征。卷积操作本身是线性的,而非线性激活函数使得网络可以逼近任意复杂的函数。

  • 计算效率高:
    计算 ReLU 非常简单,只需要对输入进行比较操作,这使得训练和推理过程更加高效。

  • 缓解梯度消失问题:
    相比 Sigmoid 和 Tanh,ReLU 的梯度在正区间是常数1,这帮助梯度在反向传播时不会消失,使得深层网络的训练更加稳定。

  • 稀疏激活:
    ReLU 的一部分输出为零,这使得神经元在同一时间不必全部激活,导致更为稀疏和高效的计算。

import numpy as np
import matplotlib.pyplot as plt

# 定义ReLU函数
def relu(x):
    return np.maximum(0, x)

# 生成输入数据
x = np.linspace(-10, 10, 400)
y = relu(x)

# 绘制ReLU函数图形
plt.figure(figsize=(8, 6))
plt.plot(x, y, label="ReLU(x) = max(0, x)", color='b')
plt.xlabel('x')
plt.ylabel('ReLU(x)')
plt.title('ReLU Activation Function')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

Softmax 函数

Softmax 函数是一种用于多分类问题的激活函数,通常用在神经网络的输出层。它将一个未归一化的数字向量(称为“logits”)转换为一个归一化的概率分布。

在卷积神经网络(CNN)中,Softmax 函数通常用于多分类问题的输出层。

  • 概率分布:
    Softmax 函数将网络的输出转换为概率分布,使得每个类别的输出值在0到1之间,且所有类别的输出值之和为1。这使得输出值可以直接解释为各个类别的概率。

  • 分类决策:
    在多分类任务中,通常选择 Softmax 函数输出概率最高的类别作为模型的预测结果。

  • 梯度计算:
    Softmax 函数与交叉熵损失函数(Cross-Entropy Loss)结合使用效果很好。交叉熵损失函数能够很好地衡量预测的概率分布与真实标签分布之间的差异,从而指导模型参数的优化。

import numpy as np
import matplotlib.pyplot as plt

# Softmax 函数
def softmax(x):
    exp_x = np.exp(x - np.max(x))  # 稳定计算,防止溢出
    return exp_x / exp_x.sum(axis=0)

# 定义输入值范围
x = np.linspace(-2, 2, 400)
scores = np.vstack([x, np.ones_like(x), 0.2 * np.ones_like(x)])

# 计算 Softmax 输出
softmax_scores = softmax(scores)

# 绘制图形
plt.plot(x, softmax_scores[0], label='x')
plt.plot(x, softmax_scores[1], label='1')
plt.plot(x, softmax_scores[2], label='0.2')
plt.title('Softmax Function')
plt.xlabel('Input Value')
plt.ylabel('Softmax Output')
plt.legend()
plt.show()

在这里插入图片描述

Softmax 函数如何将不同输入转换为概率分布,并且可以清晰地看到随着输入值 x 的变化,Softmax 输出的动态变化。

  • 第一条线(label=‘x’):代表输入值从 -2 到 2 的变化范围。由于 x 的变化较大,Softmax 函数的输出也会随之变化,反映出该行输入在整个向量中的相对影响力。
  • 第二条线(label=‘1’):代表一个常数值 1 的输入。由于这个值是常数,Softmax 的输出会相对稳定,不会随着 x 的变化而变化太大。
  • 第三条线(label=‘0.2’):代表一个常数值 0.2 的输入。与常数值 1 类似,这条线也相对稳定,但因为 0.2 小于 1,在 Softmax 输出中,其影响力会更小。

卷积神经网络

卷积神经网络(Convolutional Neural Network,CNN)是一类深度学习模型,主要用于图像识别、语音识别和自然语言处理等领域。CNN 在计算机视觉任务中取得了巨大成功,是许多图像识别任务的首选模型。

CNN 的核心思想是通过卷积层和池化层来提取输入图像的特征,并将这些特征输入到全连接层中进行分类或回归。

  1. 卷积层(Convolutional Layer): 卷积层通过使用卷积核(也称为过滤器)来提取图像中的特征。卷积操作会在输入图像上滑动卷积核,并将卷积核与输入图像的局部区域进行点积运算,从而得到特征图(也称为卷积特征映射)。

  2. 池化层(Pooling Layer): 池化层用于降低特征图的空间尺寸,同时保留重要的特征信息。最常见的池化操作是最大池化(Max Pooling),它选取输入区域的最大值作为输出;还有平均池化(Average Pooling),它计算输入区域的平均值作为输出。

  3. 激活函数(Activation Function): 激活函数引入非线性性质,使得 CNN 能够学习非线性的特征。常用的激活函数包括ReLU(Rectified Linear Unit)、Sigmoid、Tanh等。

  4. 全连接层(Fully Connected Layer): 全连接层将卷积层和池化层提取的特征进行展开,并连接到一个或多个全连接层中。全连接层通常用于将特征映射到输出类别或进行回归预测。

  5. 损失函数(Loss Function): 损失函数用于衡量模型预测值与真实标签之间的差异。在分类任务中常用的损失函数包括交叉熵损失函数(Cross Entropy Loss)等。

  6. 优化器(Optimizer): 优化器用于更新模型的参数,以最小化损失函数。常用的优化器包括随机梯度下降(SGD)、Adam、RMSProp等。

训练模型

  1. Conv2D 层:用于提取图像特征。每个 Conv2D 层都包括一组卷积核(filters),用于对输入图像进行卷积操作。在这个模型中,我们使用了三个 Conv2D 层,每个 Conv2D 层后面跟着一个 ReLU 激活函数,以引入非线性。

  2. MaxPooling2D 层:用于下采样和减少模型复杂度。MaxPooling2D 层通过在局部区域内取最大值来减小特征图的空间大小,从而降低计算量和参数数量。在这个模型中,我们使用了两个 MaxPooling2D 层,每个层将特征图的大小减半。

  3. Flatten 层:用于将多维的特征图展平成一维向量,以便与全连接层相连。

  4. Dense 层:全连接层,用于最终分类。我们使用了两个 Dense 层,其中最后一个 Dense 层的激活函数为 softmax,用于输出每个类别的概率分布。

import tensorflow as tf
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt

# 加载 MNIST 数据集,这个数据集包含手写数字的图像(0 到 9)
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 归一化处理,将像素值从 0-255 缩放到 0-1 之间
train_images, test_images = train_images / 255.0, test_images / 255.0

# 创建卷积神经网络模型
model = models.Sequential([
    # 第一层卷积层,使用 32 个 3x3 的卷积核,激活函数为 ReLU,输入形状为 28x28x1
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    # 第一层池化层,使用 2x2 的池化窗口
    layers.MaxPooling2D((2, 2)),
    # 第二层卷积层,使用 64 个 3x3 的卷积核,激活函数为 ReLU
    layers.Conv2D(64, (3, 3), activation='relu'),
    # 第二层池化层,使用 2x2 的池化窗口
    layers.MaxPooling2D((2, 2)),
    # 第三层卷积层,使用 64 个 3x3 的卷积核,激活函数为 ReLU
    layers.Conv2D(64, (3, 3), activation='relu'),
    # 将多维的卷积层输出展平成一维向量
    layers.Flatten(),
    # 第一个全连接层,包含 64 个神经元,激活函数为 ReLU
    layers.Dense(64, activation='relu'),
    # 输出层,包含 10 个神经元,对应 10 个类别,使用 Softmax 激活函数输出概率分布
    layers.Dense(10, activation='softmax')
])

# 编译模型,指定优化器、损失函数和评估指标
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 调整数据维度,以匹配卷积层输入的形状要求 (28, 28, 1)
train_images = train_images[..., tf.newaxis]
test_images = test_images[..., tf.newaxis]

# 开始跟踪计算图,记录模型结构和计算过程
tf.summary.trace_on(graph=True)

# 训练模型,使用训练数据,进行 5 个周期(epochs)的训练
model.fit(train_images, train_labels, epochs=5)

# 停止跟踪计算图并将其写入日志文件,以便在 TensorBoard 中进行可视化
with tf.summary.create_file_writer('logs').as_default():
    tf.summary.trace_export(
        name="model_trace",
        step=0,
        profiler_outdir='logs')

# 评估模型使用测试数据集,输出损失值和准确率
test_loss, test_acc = model.evaluate(test_images, test_labels)
print("Test accuracy:", test_acc)

# 保存模型,将模型结构和权重保存到文件 "mnist_model.h5"
model.save("mnist_model.h5")
print("Model saved successfully.")
  • 输出
Epoch 1/5
1875/1875 [==============================] - 33s 17ms/step - loss: 0.1454 - accuracy: 0.9555 
Epoch 2/5
1875/1875 [==============================] - 34s 18ms/step - loss: 0.0465 - accuracy: 0.9856
Epoch 3/5
1875/1875 [==============================] - 30s 16ms/step - loss: 0.0320 - accuracy: 0.9902
Epoch 4/5
1875/1875 [==============================] - 30s 16ms/step - loss: 0.0251 - accuracy: 0.9923
Epoch 5/5
1875/1875 [==============================] - 30s 16ms/step - loss: 0.0196 - accuracy: 0.9935
313/313 [==============================] - 2s 4ms/step - loss: 0.0293 - accuracy: 0.9906 
Test accuracy: 0.9905999898910522
Model saved successfully.
  • Adam优化器(Adam Optimizer)是深度学习中广泛使用的一种优化算法,它结合了动量优化和RMSProp优化的优点。Adam是“Adaptive Moment Estimation”的缩写,即自适应动量估计。它在处理稀疏梯度和非平稳目标函数方面表现良好。

  • sparse_categorical_crossentropy 是一种用于多类别分类问题的损失函数,特别适用于目标标签为整数编码的情形。它在深度学习中广泛应用,尤其是在处理类别数量较多且标签为整数编码(如0, 1, 2, …)的分类问题中。

  • accuracy(准确率)是衡量分类模型性能的一个常用指标。它表示模型预测正确的样本数量占总样本数量的比例。准确率适用于各种分类问题,但在类别不平衡的数据集中需要谨慎使用,因为它可能会误导模型性能的真实情况。

测试模型

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 加载 MNIST 测试集
mnist = tf.keras.datasets.mnist
(_, _), (test_images, test_labels) = mnist.load_data()

# 加载保存的模型
loaded_model = tf.keras.models.load_model("mnist_model.h5")
print("Model loaded successfully.")

# 选择五个测试图片
num_samples = 5
indices = np.random.randint(0, len(test_images), size=num_samples)
test_images_sample = test_images[indices]
test_labels_sample = test_labels[indices]

# 归一化处理并添加批处理维度
test_images_sample = np.expand_dims(test_images_sample / 255.0, axis=(3))

# 进行预测
predictions = loaded_model.predict(test_images_sample)
predicted_labels = np.argmax(predictions, axis=1)

# 输出预测结果和真实标签
for i in range(num_samples):
    print(f"True label: {test_labels_sample[i]}, Predicted label: {predicted_labels[i]}")

# 显示测试图片
plt.figure(figsize=(15, 3))
for i in range(num_samples):
    plt.subplot(1, num_samples, i + 1)
    plt.imshow(test_images_sample[i, :, :, 0], cmap='gray')
    plt.title(f"True: {test_labels_sample[i]}, Predicted: {predicted_labels[i]}")
    plt.axis('off')
    plt.subplots_adjust(wspace=0.5)
plt.show()
  • 输出
Model loaded successfully.
1/1 [==============================] - 0s 125ms/step
True label: 6, Predicted label: 6
True label: 0, Predicted label: 0
True label: 4, Predicted label: 4
True label: 2, Predicted label: 2
True label: 1, Predicted label: 1

在这里插入图片描述

数据集保存目录

cd ~/.keras/datasets

显示每层网络的结果

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras import layers, models

# 加载MNIST数据集
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape(-1, 28, 28, 1).astype('float32') / 255.0

# 创建卷积神经网络模型
model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

# 创建一个新的模型,该模型的输出为每一层的输出
layer_outputs = [layer.output for layer in model.layers]  # 获取所有层的输出
activation_model = models.Model(inputs=model.input, outputs=layer_outputs)

# 选择一张训练集中的图像并进行预测
img = train_images[0][np.newaxis, ...]
activations = activation_model.predict(img)

# 可视化每一层的输出
layer_names = [layer.name for layer in model.layers]  # 获取所有层的名称

for i, (layer_name, layer_activation) in enumerate(zip(layer_names, activations)):
    plt.figure(figsize=(15, 15))
    if len(layer_activation.shape) == 4:  # 处理卷积层输出
        n_features = layer_activation.shape[-1]  # 特征图的数量
        size = layer_activation.shape[1]  # 特征图的大小
        n_cols = n_features // 8  # 显示列数
        display_grid = np.zeros((size * n_cols, 8 * size))

        for col in range(n_cols):  # 遍历所有的特征图
            for row in range(8):
                channel_image = layer_activation[0, :, :, col * 8 + row]
                channel_image -= channel_image.mean()  # 标准化图像
                if channel_image.std() != 0:
                    channel_image /= channel_image.std()
                channel_image *= 64
                channel_image += 128
                channel_image = np.clip(channel_image, 0, 255).astype('uint8')
                display_grid[col * size: (col + 1) * size,
                             row * size: (row + 1) * size] = channel_image

        # 显示每一层的特征图
        plt.title(layer_name)
        plt.grid(False)
        plt.imshow(display_grid, aspect='auto', cmap='viridis')
        plt.axis('off')
    else:  # 处理展平层和全连接层输出
        plt.title(layer_name)
        plt.grid(False)
        plt.plot(layer_activation[0])
        plt.axis('off')

    plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【学术小白成长之路】01三方演化博弈(基于复制动态方程) -基础概念与模型构建

1.演化博弈基础知识 经典博弈论起源于1944年Von Neumann和Morgenstern合著的《博弈论与经济学行为》&#xff0c;是研究理性决策者之间竞争和合作关系的数学方法。 博弈论主要研究完全理性的博弈个体为实现利益最大化而做的策略选择&#xff0c;在过去几十年取得了极大发展&am…

Camtasia Studio怎么自动加字幕呢,Camtasia Studio有什么功能呢

在信息化高度发达的今天&#xff0c;视频作为一种直观、生动的信息表达方式&#xff0c;受到了越来越多人的青睐。无论是教育领域的教学视频&#xff0c;还是企业宣传的推广短片&#xff0c;甚至是个人创作的分享作品&#xff0c;都离不开一款优秀的视频编辑软件。Camtasia Stu…

番外篇 | 利用华为2023最新Gold-YOLO中的Gatherand-Distribute对特征融合模块进行改进

前言:Hello大家好,我是小哥谈。论文提出一种改进的信息融合机制Gather-and-Distribute (GD) ,通过全局融合多层特征并将全局信息注入高层,以提高YOLO系列模型的信息融合能力和检测性能。通过引入MAE-style预训练方法,进一步提高模型的准确性。🌈 目录 🚀1.论文解…

全志D1s软件入门之Tina Linux烧写教程

烧写 Tina Linux 烧写&#xff0c;即将编译打包好的固件下载到设备 烧写方式简介 全志平台为开发者提供了多种多样的烧写方式和烧写工具&#xff1a; &#xff08;1&#xff09; PhoenixSuit&#xff1a;基于Windows的系统的烧写工具&#xff0c;是最常用的烧写工具&#x…

【三十三】springboot+序列化实现返回值脱敏和返回值字符串时间格式化问题

互相交流入口地址 整体目录&#xff1a; 【一】springboot整合swagger 【二】springboot整合自定义swagger 【三】springboot整合token 【四】springboot整合mybatis-plus 【五】springboot整合mybatis-plus 【六】springboot整合redis 【七】springboot整合AOP实现日志操作 【…

解决VIvado编程中遇到的bug 5

解决VIvado编程中遇到的bug 5 语言 &#xff1a;Verilg HDL EDA工具&#xff1a; Vivado、quartus2 、modelsim 解决VIvado编程中遇到的bug 5一、引言二、问题、分析及解决方法1. vivado编译时报错&#xff08;1&#xff09;错误&#xff08;2&#xff09;分析&#xff08;3&am…

【C++课程学习】:C++入门(引用)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f369;1.引用的概念&#xff1a; &#x1f369;2.引用和指针是两个概念&#xff1a; &#x…

C语言之字符函数总结(全部!),一篇记住所有的字符函数

前言 还在担心关于字符的库函数记不住吗&#xff1f;不用担心&#xff0c;这篇文章将为你全面整理所有的字符函数的用法。不用记忆&#xff0c;一次看完&#xff0c;随查随用。用多了自然就记住了 字符分类函数和字符转换函数 C语言中有一系列的函数是专门做字符分类和字符转换…

【AI基础】第三步:纯天然保姆喂饭级-安装并运行chatglm2-6b

chatglm2构建时使用了RUST&#xff0c;所以在安装chatglm2之前&#xff0c;先安装RUST。 此系列文章列表&#xff1a; 【AI基础】第一步&#xff1a;安装python开发环境-windows篇_下载安装ai环境python-CSDN博客 【AI基础】第一步&#xff1a;安装python开发环境-conda篇_mini…

springboot+minio+kkfileview实现文件的在线预览

在原来的文章中已经讲述过springbootminio的开发过程&#xff0c;这里不做讲述。 原文章地址&#xff1a; https://blog.csdn.net/qq_39990869/article/details/131598884?spm1001.2014.3001.5501 如果你的项目只是需要在线预览图片或者视频那么可以使用minio自己的预览地址进…

python 多任务之多进程

多任务 优势 多个任务同时执行可以大大提高程序执行效率&#xff0c;可以充分利用CPU资源&#xff0c;提高程序的执行效率 概念 是指在同一时间内执行多个任务 多进程 概念 进程&#xff08;process&#xff09;是资源分配的最小单位&#xff0c;他是操作系统进行资源分配…

EKF在LiFePO4电池SOC估算中不好用?一问带你破解EKF应用难题

磷酸铁锂电池因为平台区的存在&#xff0c;导致使用戴维南模型EKF的方法时&#xff0c;无法准确进行SOC准确预估。所以最近搜索了大量关于磷酸铁锂电池SOC预估的论文、期刊&#xff0c;但我被海量忽略客观事实、仅为了毕业的硕士论文给震惊到了。很多论文为了掩饰平台区的存在&…

C++ OpenCV 图像分类魔法:探索神奇的模型与代码

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

基于SSM的旅游民宿预定系统【源码】【运行教程】

基于SSM的旅游民宿预定系统 一、项目介绍1. 游客功能2. 管理员功能3. 高级功能 二、项目技术栈三、项目运行四、项目演示总结 大家好&#xff0c;这里是程序猿代码之路&#xff01;随着旅游业的快速发展&#xff0c;民宿作为一种独特的住宿方式越来越受到游客的喜爱。为了提升用…

【Linux操作系统】Linux中进程的五种状态:R、S、D、T、X以及僵尸进程、孤儿进程

操作系统中有许多同时执行的进程&#xff0c;这些进程都可能处于不同的状态代表着不同的含义。 R运行状态(running) 概念&#xff1a;并不意味着进程一定在运行中&#xff0c;它表明进程要么是在运行中要么在运行队列里。 我们运行可执行程序myproc利用指令 ps ajx可以看到进程…

git凭证

默认是manager # 将凭证缓存到内存中&#xff0c;默认缓存15分钟 git config --global credential.helper cache# 将凭证存储到磁盘上的纯文本文件中 git config --global credential.helper store# 使用 Git 凭证管理器 git config --global credential.helper manager-core查…

微服务开发与实战Day03

一、导入黑马商城项目 资料文档&#xff1a;Docs 1. 安装MySQL ①删除root目录下的mysql rm -rf mysql/ ②把课前资料里的mysql目录上传到root目录下 ③创建一个通用网络 docker network create hm-net ④使用下面的命令安装MySQL docker run -d \--name mysql \-p 330…

CMakeLists如何多行注释

在使用Visual Studio编写CMakeLists的时候你可能会遇到需要多行注释的情况&#xff0c;可又不知道快捷键是什么。。。 其实你只需要敲个 #[[ 就行了&#xff0c;另外一般方括号VS会自动帮你补全&#xff0c;之后将需要注释的内容放在第二个方括号与第三个方括号之间就完成注释…

今天是放假带娃的一天

端午节放假第一天 早上5点半宝宝就咔咔乱叫了&#xff0c;几乎每天都这个点醒&#xff0c;准时的很&#xff0c;估计他是个勤奋的娃吧&#xff0c;要早起锻炼婴语&#xff0c;哈哈 醒来后做饭、洗锅、洗宝宝的衣服、给他吃D3&#xff0c;喂200ml奶粉、给他洗澡、哄睡&#xff0…

【上篇】从 YOLOv1 到 YOLOv8 的 YOLO 物体检测模型历史

YOLO 型号之所以闻名遐迩,主要有两个原因:其速度和准确性令人印象深刻,而且能够快速、可靠地检测图像中的物体。 在本文中,我将与大家分享我在阅读一篇长达 30 页的综合性论文时获得的见解,该论文深入探讨了 YOLO 模型的进步。 这篇评论全面概述了 YOLO 框架的演变过程,…