【深度学习】 零基础介绍卷积神经网络(CNN)

news2024/12/21 4:32:47

CNN学习

  • 零基础介绍
  • 写个CNN最简单的代码
  • 一. 概述
  • 二. 搭建CNN
    • 1. 输入层
    • 2. 卷积层
    • 3. 激活层
    • 4. 池化层
    • 5. 全连接层
    • 6. 网络搭建小结
    • 7. 损失函数
    • 8. 梯度下降
    • 9. 反向传播
    • 10. 模型评估与正则化
    • 11. 尝试搭建自己的第一个CNN
  • 三. 经典CNN结构
  • 四. 猫狗识别项目实践
    • 1. Paddle实现版本:
    • 2. Keras 和 TensorFlow实现版本
  • 提问检测环节

零基础介绍

卷积神经网络(CNN,Convolutional Neural Network)是深度学习中的一种神经网络,特别擅长处理图像和视频等有空间结构的数据。

假设我们在做一个“照片分类”的任务,比如判断一张照片中是猫还是狗。下面用一个通俗的例子来解释CNN的工作原理。

  1. 看图的方式:模拟人眼
    当我们看一张图片时,并不是从头到尾一口气看完的,而是我们的眼睛会专注于某个小区域,然后逐渐移到其他地方。CNN就是模仿这种“局部视野”的方式来处理图像。它通过滑动一个小窗口(称为“卷积核”)来查看图片的不同部分。

  2. 卷积层(Convolutional Layer)
    卷积层的作用就是使用多个卷积核对图像进行扫描。这些卷积核可以看作是一个小的滤镜,它们能提取图像中的特征。假设我们有一张猫的照片,卷积核可能会学习到猫的耳朵形状、眼睛的位置、毛发的纹理等特征。每次卷积操作之后,图像会变成一个包含这些特征的“特征图”(feature map)。

    例如,如果我们有一张3×3的卷积核(就是一个3×3的小矩阵),它会遍历图像的每个部分,计算卷积核和图片的局部区域的点积,产生一个新的值。这就像你用滤镜滤镜了一小块区域。

  3. 激活函数(ReLU)
    卷积层提取到特征之后,接下来会通过一个叫做ReLU(Rectified Linear Unit)的激活函数。ReLU会把负数变为零,保留正数。简单来说,就是“过滤”掉一些不重要的信息,保留对分类有帮助的特征。

  4. 池化层(Pooling Layer)
    池化层的作用是将卷积层生成的特征图进行下采样,减少图像的大小和计算量。通常有两种常用的池化方式:

    最大池化(Max Pooling):从每个小区域中选出最大的值。
    平均池化(Average Pooling):从每个小区域中计算平均值。

    池化的作用就是保留图像中最重要的信息,同时减少不必要的细节,就像是在提炼出最精华的部分。

  5. 全连接层(Fully Connected Layer)
    在经过多个卷积层和池化层之后,CNN会将图像的特征汇聚起来,传递到全连接层。这个层的作用类似于神经网络的最终决策阶段,负责根据之前提取到的特征做出最终的分类决策。比如根据猫耳朵、眼睛、毛发的纹理等信息,最终判断出这是猫还是狗。

  6. 输出层(Output Layer)
    最后,输出层会根据神经网络的结果给出分类结果。如果是猫,输出1;如果是狗,输出0。这个结果就是CNN根据图像学习到的特征做出的决策。

总结:
CNN通过逐层提取图像的特征,模拟人类如何观察图像,最终做出分类决策。它的优势在于能够自动学习图像中的有用特征,而不需要人工提取这些特征,这使得CNN特别适合图像处理任务。

比喻:
你可以把CNN想象成一个侦探,它通过从图片的各个细节(耳朵、眼睛、毛发等)收集线索,最终推理出这是一只猫还是狗。每一个卷积核就像是侦探手中的放大镜,帮助他专注于图片中的不同部分,池化层则是帮助侦探筛选出最重要的线索。最终,侦探通过这些线索得出了结论。

写个CNN最简单的代码

假设我们的输入图像是一个 3x3 的矩阵,卷积核(滤波器)是一个 2x2 的矩阵。

  1. 输入:
    1 2 3
    4 5 6
    7 8 9

  2. 卷积核(滤波器)
    1 0
    0 1

  3. 在卷积操作中,卷积核会在输入图像上滑动,并计算卷积核和当前区域的点积

    步骤:
    我们从输入图像的左上角开始,把卷积核放在图像的最左上角,然后计算卷积核与图像覆盖区域的点积。卷积核的每个元素与对应区域的每个元素相乘,然后求和。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  4. 结果
    通过这些卷积操作,我们得到了一个 2x2 的特征图(Feature Map):
    在这里插入图片描述

代码如下:

import numpy as np

# 输入图像
image = np.array([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9]])

# 卷积核(滤波器)
kernel = np.array([[1, 0],
                   [0, 1]])

# 输出特征图的尺寸
output_height = image.shape[0] - kernel.shape[0] + 1
output_width = image.shape[1] - kernel.shape[1] + 1

# 创建一个空的输出特征图
output = np.zeros((output_height, output_width))

# 执行卷积操作
for i in range(output_height):
    for j in range(output_width):
        # 计算当前区域的点积
        region = image[i:i+kernel.shape[0], j:j+kernel.shape[1]]
        output[i, j] = np.sum(region * kernel)

print("卷积结果(特征图):")
print(output)

输出结果:

卷积结果(特征图):
[[ 6. 8.]
[12. 14.]]


接下来正式介绍CNN!
在这里插入图片描述

一. 概述

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

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

在这里插入图片描述

二. 搭建CNN

在这里插入图片描述

1. 输入层

在这里插入图片描述

2. 卷积层

在这里插入图片描述

对于灰度图:
在这里插入图片描述
对于彩色图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 激活层

在这里插入图片描述

4. 池化层

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

5. 全连接层

在这里插入图片描述

6. 网络搭建小结

在这里插入图片描述

7. 损失函数

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

8. 梯度下降

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

9. 反向传播

在这里插入图片描述

在这里插入图片描述

10. 模型评估与正则化

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

11. 尝试搭建自己的第一个CNN

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

在这里插入图片描述

在这里插入图片描述

三. 经典CNN结构

在这里插入图片描述

在这里插入图片描述

四. 猫狗识别项目实践

1. Paddle实现版本:

import paddle
import paddle.fluid as fluid
import numpy as np
from PIL import Image
import sys
from multiprocessing import cpu_count
import matplotlib.pyplot as plt
import os
BATCH_SIZE = 128
# 用于训练的数据提供器
train_reader = paddle.batch(
    paddle.reader.shuffle(paddle.dataset.cifar.train10(),
                            buf_size = BATCH_SIZE * 100),
    batch_size = BATCH_SIZE)

#用于测试的数据提供器
test_reader = paddle.batch(
    paddle.dataset.cifar.test10(),
     batch_size = BATCH_SIZE
)
def  convolutional_neural_network(img):
    # 第一个卷积 - 池化层
    conv1 = fluid.layers.conv2d(input= img, # 输入图像
                        num_filters =20,      #卷积核的大小
                        filter_size = 5,    #卷积核数量,它与输出的通道相同
                        act = 'relu')     #激活函数
    pool1 = fluid.layers.pool2d(
        input = conv1,  # 输入
        pool_size = 2, #池化核大小
        pool_type = 'max', # 池化类型
        pool_stride = 2)  # 池化步长
    conv_pool_1 = fluid.layers.batch_norm(pool1)

    # 第二个卷积 - 池化层
    conv2 = fluid.layers.conv2d(input= conv_pool_1, # 输入图像
                        num_filters =50,      #卷积核的大小
                        filter_size = 5,    #卷积核数量,它与输出的通道相同
                        act = 'relu')     #激活函数
    pool2 = fluid.layers.pool2d(
        input = conv2,  # 输入
        pool_size = 2, #池化核大小
        pool_type = 'max', # 池化类型
        pool_stride = 2)  # 池化步长
    conv_pool_2 = fluid.layers.batch_norm(pool2)

    # 第三个卷积 - 池化层
    conv3 = fluid.layers.conv2d(input= conv_pool_2, # 输入图像
                        num_filters =50,      #卷积核的大小
                        filter_size = 5,    #卷积核数量,它与输出的通道相同
                        act = 'relu')     #激活函数
    pool3 = fluid.layers.pool2d(
        input = conv3,  # 输入
        pool_size = 2, #池化核大小
        pool_type = 'max', # 池化类型
        pool_stride = 2)  # 池化步长
    # 以softmax 为激活函数的全连接输出层,10类数据输出10个数字
    prediction = fluid.layers.fc(input = pool3,size = 10,act = 'softmax')
    return prediction
    
paddle.enable_static()
# 3 代表图像RGB三通道,32✖32的彩色图片
data_shape = [3,32,32]
# 定义全局变量 image 和 label 
images = fluid.layers.data(name = 'images',shape = data_shape,dtype = 'float32')
label = fluid.layers.data(name = 'label',shape=[1],dtype = 'int64')
# 获取分类器,用cnn分类
predict = convolutional_neural_network(images)
cost = fluid.layers.cross_entropy(input=predict,label = label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=predict,label = label)
optimizer = fluid.optimizer.Adam(learning_rate =0.001)
optimizer.minimize(avg_cost)
place =  fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
feeder = fluid.DataFeeder(feed_list=[images,label],place = place)
EPOCH_NUM = 15
for pass_id in range(EPOCH_NUM):
    train_cost = 0
    for batch_id,data in enumerate(train_reader()):
        train_cost,train_acc = exe.run(program = fluid.default_main_program(),
                                        feed = feeder.feed(data),
                                        fetch_list =[avg_cost,acc])
        if batch_id % 100 ==0:
            print('Pass: %d, Batch: %d, Cost: %0.5f, Accuarcy: %0.5f'%(pass_id,batch_id,train_cost[0],train_acc[0]))
    
   
    test_costs = []
    test_accs = []
    for batch_id,data in enumerate(test_reader()):
        test_cost,test_acc = exe.run(program = fluid.default_main_program(),
                                            feed = feeder.feed(data),
                                            fetch_list = [avg_cost,acc])
        test_costs.append(test_cost[0])
        test_accs.append(test_acc[0])

    # 求测试结果的平均值
    test_cost = (sum(test_costs) / len(test_costs))                         #计算误差平均值(误差和/误差的个数)
    test_acc = (sum(test_accs) / len(test_accs))                            #计算准确率平均值( 准确率的和/准确率的个数)
    print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))
    model_save_dir = "/home/aistudio/data/catdog.inference.model"
    if not os.path.exists(model_save_dir):
        os.makedirs(model_save_dir)
    fluid.io.save_inference_model(model_save_dir,
                              ['images'],
                              [predict],
                              exe)

        
infer_exe = fluid.Executor(place)
inference_scope = fluid.core.Scope() 
def load_image(file):
        #打开图片
        im = Image.open(file)
        #将图片调整为跟训练数据一样的大小  32*32
        im = im.resize((32, 32), Image.ANTIALIAS)
        #建立图片矩阵 类型为float32
        im = np.array(im).astype(np.float32)
        #矩阵转置 
        im = im.transpose((2, 0, 1))                               
        #将像素值从【0-255】转换为【0-1】
        im = im / 255.0    
        im = np.expand_dims(im, axis=0)
        return im
with fluid.scope_guard(inference_scope):
    #从指定目录中加载 推理model(inference model)
    [inference_program, # 预测用的program
     feed_target_names,  
     fetch_targets] = fluid.io.load_inference_model(model_save_dir,
                                                    infer_exe)  
    
    infer_path='/home/aistudio/data/cat.png'
    img = Image.open(infer_path)
    plt.imshow(img)   
    plt.show()    
    
    img = load_image(infer_path)

    results = infer_exe.run(inference_program,               
                            feed={feed_target_names[0]: img}, 
                            fetch_list=fetch_targets)        
    
    label_list = [
        "airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse",
        "ship", "truck"
        ]
    print("infer results: %s" % label_list[np.argmax(results[0])])

在这里插入图片描述

2. Keras 和 TensorFlow实现版本

完整CNN代码:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.optimizers import Adam

# 构建一个简单的CNN模型
model = Sequential()

# 第一个卷积层:使用32个3x3的卷积核,激活函数为ReLU,输入图像尺寸为64x64x3(RGB图像)
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))

# 第一个池化层:使用2x2的池化窗口,减少空间尺寸
model.add(MaxPooling2D(pool_size=(2, 2)))

# 第二个卷积层:使用64个3x3的卷积核,激活函数为ReLU
model.add(Conv2D(64, (3, 3), activation='relu'))

# 第二个池化层:同样使用2x2的池化窗口
model.add(MaxPooling2D(pool_size=(2, 2)))

# 第三个卷积层:使用128个3x3的卷积核,激活函数为ReLU
model.add(Conv2D(128, (3, 3), activation='relu'))

# 第三个池化层:同样使用2x2的池化窗口
model.add(MaxPooling2D(pool_size=(2, 2)))

# 将3D的卷积输出展平为1D的向量
model.add(Flatten())

# 添加一个全连接层:512个神经元,激活函数为ReLU
model.add(Dense(512, activation='relu'))

# 添加一个Dropout层:随机丢弃30%的神经元,防止过拟合
model.add(Dropout(0.3))

# 添加输出层:2个神经元(分类为猫或狗),使用Softmax激活函数
model.add(Dense(2, activation='softmax'))

# 编译模型:使用Adam优化器,损失函数为交叉熵,评估指标为准确率
model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 打印模型总结,查看模型结构
model.summary()

代码逐行解释:
tensorflow 是深度学习的框架,keras 是其中的高级API,用于构建神经网络。
Sequential 是模型的线性堆叠结构,表示网络各层按顺序堆叠。
Conv2D 是卷积层,用于图像特征提取。
MaxPooling2D 是池化层,用于降维,减少计算量。
Flatten 是将多维数据转换为一维向量,方便进入全连接层。
Dense 是全连接层,用于决策输出。
Dropout 是一种正则化技术,随机丢弃神经元,防止模型过拟合。
Adam 是一种常用的优化算法,用于调整网络中的权重。

model = Sequential()

这行代码创建了一个空的 Sequential 模型,表示我们将按顺序添加各个网络层。

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)))

Conv2D(32, (3, 3)):这是一个卷积层,使用 32 个 3x3 的卷积核。
activation=‘relu’:激活函数使用 ReLU(Rectified Linear Unit),它可以帮助模型引入非线性。
input_shape=(64, 64, 3):输入图像的大小为 64x64 像素,3 个颜色通道(RGB)。
卷积层的作用是通过卷积核对图像进行扫描,提取局部特征,如边缘、纹理等。

model.add(MaxPooling2D(pool_size=(2, 2)))

MaxPooling2D(pool_size=(2, 2)):这是一个池化层,使用 2x2 的窗口来对图像进行降维。池化层通常将图像的空间尺寸缩小一半,减少计算量,并保留最重要的特征。

model.add(Flatten())

Flatten():将卷积层和池化层输出的 3D 张量(如 64x64x128)展平成 1D 向量(如 512),准备输入到全连接层。

model.add(Dense(512, activation='relu'))

Dense(512):全连接层,包含 512 个神经元,每个神经元与前一层的每个神经元都有连接。
activation=‘relu’:使用 ReLU 激活函数。
全连接层的作用是结合从卷积层提取到的所有特征,进行更高层次的抽象和决策。

model.add(Dropout(0.3))

Dropout(0.3):这是一个 Dropout 层,随机丢弃 30% 的神经元,防止模型过拟合。过拟合是指模型过于依赖训练数据,导致对新数据的预测效果差。

model.add(Dense(2, activation='softmax'))

Dense(2):输出层,包含 2 个神经元,因为我们要分类的是 2 类(比如猫和狗)。
activation=‘softmax’:使用 Softmax 激活函数,它将输出转化为概率值,表示属于每个类别的概率。

model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

optimizer=Adam():使用 Adam 优化器,自动调整学习率以最小化损失。
loss=‘sparse_categorical_crossentropy’:使用交叉熵作为损失函数,适用于多分类任务。
sparse 表示目标标签是整数。
metrics=[‘accuracy’]:我们会评估模型的准确率。

model.summary()

model.summary():输出模型的结构,显示各层的类型、输出形状和参数数量

提问检测环节

  1. CNN 的基本组成部分有哪些?
  2. 卷积层(Convolutional Layer):作用是什么?如何提取特征?
  3. 池化层(Pooling Layer):种类、作用及原理(如 MaxPooling 和 AveragePooling)。
  4. 为什么池化层没有参数?
  5. 激活函数(Activation Function):常见的 ReLU、Sigmoid、Softmax 等作用和区别。
  6. 全连接层(Fully Connected Layer):为什么需要展平(Flatten)?
  7. Dropout:在什么场景使用?如何防止过拟合?
  8. 简述 CNN 的基本组成部分及其功能。
  9. 什么是池化?它对特征图有何作用?
  10. SGD、Adam、RMSprop 的特点与适用场景。
  11. 准确率(Accuracy)、损失(Loss)、混淆矩阵(Confusion Matrix)的解读。
  12. 过拟合模型的表现特点。
  13. 为什么 Adam 优化器适合深层网络?

你都答对了吗?

感谢点赞关注👍

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

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

相关文章

flutter 使用dio 请求go语言后台数据接口展示瀑布流图片

添加依赖 dependencies:flutter:sdk: flutterdio: ^5.0.0 # 请检查最新版本flutter_staggered_grid_view: ^0.4.0 添加网络权限 <uses-permission android:name"android.permission.INTERNET" /> go后端代码 图片存放目录 // main.go package mainimport (&q…

ZYNQ初识2(zynq_7010)基于vivado,从PL端调用PS端的时钟

由于需要进行一些FPGA的简单开发&#xff0c;但板载PL端没有焊接晶振&#xff0c;所以需要从PS端借用时钟到PL端使用。 首先新建项目&#xff0c;根据自己的板载选择芯片&#xff0c;我的板载芯片是zynq_7010。 一路next&#xff0c;在自己的vivado的工作文档新建文件夹并给自…

Go语言启动独立进程

文章目录 问题解决方案1. **将 npc.exe 启动为独立的进程**2. **修改 exec.Command 函数**示例代码解释为什么这样有效注意 问题 在你当前的代码中&#xff0c;调用 exec.Command("XXX.exe") 启动 XXX.exe 程序时&#xff0c;这个程序是由 Go 程序直接启动的。如果 …

oracle client linux服务器安装教程

p13390677_112040_Linux-x86-64_4of7.zip 安装前&#xff0c;确认/etc/hosts文件已配置正确 cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.2…

strongswan构建测试环境

make-testing脚本文件负责构建strongswan的虚拟化测试系统。位于目录strongswan-5.9.14/testing/&#xff0c;需要以管理员身份运行make-testing。生成测试用到的虚拟客户机镜像&#xff0c;KVM虚拟机和虚拟网络的配置文件位于目录:config/kvm。 ~/strongswan-5.9.14/testing$…

页面无滚动条,里面div各自有滚动条

一、双滚动条左右布局 实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Doc…

踩准智能汽车+机器人两大风口,速腾聚创AI+机器人应用双线爆发

日前&#xff0c;RoboSense速腾聚创交出了一份亮眼的Q3财报。受到多重利好消息影响&#xff0c;其股价也应势连续大涨。截止12月9日发稿前&#xff0c;速腾聚创股价近一个月内累计涨幅已超88%。 财务数据方面&#xff0c;速腾聚创在今年前三季度实现总收入约11.3亿元&#xff0…

省略内容在句子中间

一、使用二分查找法 每次查找时&#xff0c;将查找范围分成两半&#xff0c;并判断目标值位于哪一半&#xff0c;从而逐步缩小查找范围。 循环查找 计算中间位置 mid Math.floor((low high) / 2)。比较目标值 target 和中间位置的元素 arr[mid]&#xff1a; 如果 target ar…

CTF — 压缩包密码爆破

CTF — 压缩包密码爆破 ​ 在CTF比赛中&#xff0c;密码爆破压缩包&#xff08;如ZIP或RAR文件&#xff09;是一个常见的任务。针对ZIP压缩包的密码爆破主要是使用工具ARCHPR完成的。这个工具的功能非常强大&#xff0c;假设你已经在Win系统里安装完这个软件了&#xff0c;打开…

Spring之我见 - 从IOC谈到AOP实现原理

前言 以前写过一篇文章&#xff0c; 专门讲了 Spring 的动态代理实现原理 从代理模式再出发&#xff01;Proxy.newProxyInstance的秘密&#xff0c; 这一次我们探究下动态代理模式比较重量级的应用 – Spring AOP 的源码实现。 本文重在讲主流程&#xff0c; 但为了让流程更清…

基于 SSM 框架 Vue 电脑测评系统:赋能电脑品质鉴定

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;作为一个一般的用户都开始注重与自己的信息展示平台&#xff0c;实现基于SSM框架的电脑测评系统在技术上已成熟。本文介绍了基于SSM框架的电脑测评系统的开发全过程。通过分析用户对于基于SSM框架的电脑测评系统的…

[react] 优雅解决typescript动态获取redux仓库的类型问题

store.getState()是可以获取总仓库的 先拿到函数的类型 再用ReturnType<T> 它是 TypeScript 中的一个内置条件类型&#xff0c;用于获取某个函数类型 T 的返回值类型 代码 // 先拿总仓库的函数类型type StatefuncType typeof store.getState;//再拿函数类型T的返回值类…

mysql中与并发相关的问题?

今天我们来聊聊 MySQL 中与并发相关的一些问题。作为一名资深 Python 开发工程师&#xff0c;我觉得这些问题不仅关乎数据库的稳定性和数据的一致性&#xff0c;更与我们的代码实现和业务逻辑密切相关。 尤其是在高并发环境下&#xff0c;如何保证数据的一致性&#xff0c;如何…

(补)算法刷题Day19:BM55 没有重复项数字的全排列

题目链接 给出一组数字&#xff0c;返回该组数字的所有排列 例如&#xff1a; [1,2,3]的所有排列如下 [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1]. &#xff08;以数字在数组中的位置靠前为优先级&#xff0c;按字典序排列输出。&#xff09; 思路&#xff1a; 使用回…

ARM嵌入式学习--第八天(PWM)

PWM -PWM介绍 PWM&#xff08;pulse Width Modulation&#xff09;简称脉宽调制&#xff0c;是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术&#xff0c;广泛应用在测量&#xff0c;通信&#xff0c;工控等方面 PWM的频率 是指在1秒钟内&#xff0c;信号从…

neo4j 图表数据导入到 TuGraph

neo4j 图表数据导入到 TuGraph 代码文件说明后文 前言:近期在引入阿里的 TuGraph 图数据库&#xff0c;需要将 原 neo4j 数据导入到新的 tugraph 数据库中。预期走csv文件导入导出&#xff0c;但因为格式和数据库设计问题&#xff0c;操作起来比较麻烦&#xff08;可能是个人没…

Docker介绍、安装、namespace、cgroup、镜像-Dya 01

0. 容器简介 从生活上来说&#xff0c;容器是一种工具&#xff0c;可以装东西的工具&#xff0c;如衣柜、背包、行李箱等等。 从IT技术方面来说&#xff0c;容器是一种全新的虚拟化技术&#xff0c;它提高了硬件资源利用率&#xff0c;结合k8s还可以让企业业务快速横向扩容、业…

鱼跃医疗获评2024年国家级“绿色工厂”,以绿色制造树立行业标杆

近日&#xff0c;工业和信息化部公布了2024年度绿色制造名单&#xff0c;鱼跃医疗凭借在绿色制造和可持续发展方面的卓越表现&#xff0c;成功入选并获评国家级“绿色工厂”。 “绿色工厂”是工信部为贯彻落实国家《工业绿色发展规划》&#xff0c;加快推动绿色制造体系建设&a…

建投数据与腾讯云数据库TDSQL完成产品兼容性互认证

近日&#xff0c;经与腾讯云联合测试&#xff0c;建投数据自主研发的人力资源信息管理系统V3.0、招聘管理系统V3.0、绩效管理系统V2.0、培训管理系统V3.0通过腾讯云数据库TDSQL的技术认证&#xff0c;符合腾讯企业标准的要求&#xff0c;产品兼容性良好&#xff0c;性能卓越。 …

Java-30 深入浅出 Spring - IoC 基础 启动IoC 纯XML启动 Bean、DI注入

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…