人工智能入门(一):基于Pytorch的手写数字识别模型

前言:

因为还在上学,时间不太够用,很多内容写到后面心有余力不足,未来有时间我会慢慢补充。人工智能的知识涉猎范围广又杂乱无章,啃书或上课学到的知识往往很早就过时了或者离实际的项目无关。所以,我很希望通过这种一个一个“小实验”的方式让大家拎出一个属于自己的“主干知识”,尝到训练模型的“甜头”。

一、Python基础知识:

1 类与对象的关系:

比如定义一个“鸟类”。鹦鹉就是“鸟类”的一个对象,海鸥也是“鸟类”的一个对象。

“类”是静态的,是在程序执行前就已经被定义好的;

“对象”是动态的,它们在程序执行时可以被创建和删除。

2 类的属性:

class Bird:
    Flight_mode = '滑翔'
    Reproduction_mode = '蛋生'  #类的属性
    def introduce(self):   #类的方法
        print('爷是只高贵的鸟')

类的属性是全类共有的,比如上例中定义的“鸟类“里的”飞行方式“和”繁衍方式“;

类的方法可以简单理解成在类中写了一个函数,不过要注意的是:在Python中,self是一个表示“对象“自身的参数,通常作为方法的第一个参数。当我们创建一个对象时,Python会自动将该对象作为self参数传递给类的方法。

接下来,请读者思考一个问题,假如我有一只小鸟名叫”Lucky“,基于上面的例子,如果我想打印:

(1)“Lucky的飞行方式是滑翔,繁衍方式是蛋生”应该怎么做?

(2)“Lucky的年龄是一岁大,颜色是黄色的”上例中类的方法应该怎么修改?

解答:

(1)的问题比较简单,因为飞行方式和繁衍方式都是整个“鸟类”共同的属性,直接使用类名调用即可。

print("Lucky的飞行方式是"+Bird.Flight_mode+",繁衍方式是"+Bird.Reproduction_mode)

(2)最大的问题在于,年龄和颜色都是Lucky这个“对象”的属性,这时我们就需要使用类的方法来定义对象的属性。说白了就是在类中写一个函数,让函数中的属性只属于定义的对象。

class Bird:
    Flight_mode = '滑翔'
    Reproduction_mode = '蛋生'  # 类的属性

    def __init__(self, name, age, colour):
        self.name = name
        self.age = age
        self.colour = colour

    def introduce(self):
        print(self.name,"的年龄是", self.age, ",颜色是", self.colour)

p = Bird("Lucky", "一岁大", "黄色的")
p.introduce()

其中,__init__是一个特殊的方法,用于在创建对象时进行初始化。它是Python中的构造函数,用于将属性值赋给对象。

类的基础介绍言尽于此,不多赘述。

参考文章:http://t.csdnimg.cn/Eg9kr

3 类的继承:

继承的主要作用是实现代码的重用。继承使得子类拥有父类的方法和属性。在使用深度学习框架,比如Pytorch时,只有将我们的类继承官方的类,我们才能在官方的类实现的基础上继续做下去

class animal:
	def eat(self):
		print("吃")
		
	def drink(self):
		print("喝")
	
class dog(animal):
	def dark(self):
		print("汪汪叫")
	

goudan = dog()
goudan.eat()
goudan.drink()

从上面的代码可以看出,在编写dog类的时候,我们并没有重写eat和drink两个方法。我们只需要在dog后面的括号中加上父类的名字即可。当子类继承了父类,子类就可以直接使用父类中的方法了。在本例中,goudan可以直接使用animal类中的eat和drink两个方法。

参考文章:http://t.csdnimg.cn/sw0VK

二、简单科普:

1 深度学习框架的概念:

如何让计算机识别手写数字0~9?如今的我们只需要一个简单的卷积神经网络(CNN)就可以搞定。

本次我们使用pytorch深度学习框架,使用pytorch中的nn函数来调用深度学习中的基本单元,用pytorch中的nn.squential模块来构建神经网络模型。

深度学习框架的基本属性:

1.将繁琐的计算、操作封装成黑箱,让我们只需要关注输入与输出;

2.把解决问题的流程模块化、模板化;

3.常用的工具封装成库,方便使用。

所以,框架的概念就是模板的概念,就像英语作文模板往往会给你提供好开头、结尾等,让我们只需要根据不同的作文主题更换不同的英语单词一样。

2 张量的概念:

张量,英文为“tensor”,是神经网络的主要数据容器,它包含的数据几乎都是数值。但显然,我们传入神经网络的数据并不只有数字,还有图片、声音、文本等等。如何建立起他们之间的联系?这个我们稍后解释,现在我们先来看看什么是张量。

2.1 什么是张量:

学习过线性代数的话,你可能对矩阵比较熟悉,张量其实就是矩阵向任意维度的推广

(1)如果一个矩阵只有一个元素,那么它被称为0阶张量;

(2)如果一个矩阵只有一行或者一列(我们称其为只有一个“”),则被称为一阶张量;

(3)显然,大部分的矩阵都有m行n列(有两个轴),则就被称为二阶张量;

(4)如果将一个二阶张量看作一个整体,由多个二阶张量组成一个新的数组,则二阶张量就被推广为三阶张量;

bdd298739a984edbb862b385d2071dc7.png

当然,我本人有个小技巧帮助你推导三阶之后的张量。来,跟我念:一个张量、往下拉、往右拉、往后拉;看成一个整体、往下拉(四阶)、往右拉(五阶)、往后拉(六阶);看作一个整体.......以此类推。

当然,在实践中,我们很少遇到三阶之后的张量,所以也没必要对想象出高阶张量那么执着。

参考文章:http://t.csdnimg.cn/OjOqS

2.2 图片与张量的相互转换:

首先,我们来思考一种最简单的情况。假如有一张灰度图像,显然它是一个二维的平面,它由密密麻麻的像素组成。对于每一个像素点如果我们用由低到高的数字来代表像素点灰色的深度,那么显然,这张图片可以被一个二阶张量所表示;

对于一张彩色图像,实际上每一个像素点的颜色是由“红、绿、蓝”(RGB)三种颜色组合而成。所以,在我们的肉眼看来,一张彩色图像是一个二维平面。但实际上,它是由一张红色图片、一张绿色图片、一张蓝色图片叠加而成的。仿照前面对一张灰度图像用二阶张量来表示,一张彩色就可以用一个三阶张量来表示。

以上只是这个转换过程在我们大脑中的想象,实际通过代码来实现这个过程我们需要借助Pytorch中的torchvision库来实现。

三、实战环节:

1 数据预处理:

当我们进行数据预处理时,归一化是一种常见的操作。它的目的是将数据调整到一个特定的范围或分布,通常是为了让模型更容易学习并且提高训练的稳定性和效率。

归一化的过程就好像把数据放进一个标准的框架中,使得它们的分布更加均匀、方便处理。最常见的归一化方法之一是将数据缩放到 0 到 1 的范围内。举个例子,如果你有一组身高数据,其中最小值是 150 厘米,最大值是 190 厘米,那么归一化之后,150 厘米的数据会变成 0,190 厘米的数据会变成 1,其他的数据会按比例变化到 0 和 1 之间。

而对于图像数据,我们归一化处理的其实是每一个像素点。例如,如果你有一组图像数据,像素值范围在 0 到 255 之间,那么归一化可以将像素值除以 255,将其缩放到 0 到 1 的范围内。

除了将数据缩放到 0 到 1 的范围外,还有其他一些归一化方法,如将数据缩放到均值为 0、标准差为 1 的正态分布中。不同的归一化方法适用于不同的情况,但它们的共同目标都是使数据更易于处理和学习。

小结:

1 归一化的方法:

(1)将数据按比例缩放到0~1之间;

(2)将数据缩放为均值为0,标准差为1的正态分布中。

2 图片数据的归一化是对其每一个像素点做归一化。

代码实现:

import torchvision.transforms as transforms
transform = transforms.Compose([
    transforms.ToTensor(),  # 将图像转换为张量
    transforms.Normalize((0,), (1,))  # 归一化,均值为0,标准差为1
])

2 数据加载

2.1 Dataset:

“torchvision.datasets”是 PyTorch 中用于加载常见视觉数据集的模块。

通常情况下,我们需要自定义一个Dataset类来加载我们自己的数据,该类需要实现__len__和__getitem__方法,分别用于返回数据集的长度和访问数据集中的元素。

但Pytorch中提供了torchvision.datasets.MNIST 类,它已经实现了 Dataset 接口,可以直接用于加载 MNIST 数据集。常用的数据集包括 MNIST、CIFAR-10、CIFAR-100、ImageNet 等。

接下来,我们以Minist数据集为例,对其数据进行加载与预处理:

MINIST

Size: 28×28 灰度手写数字图像
Num: 训练集 60000 和 测试集 10000,一共70000张图片
Classes: 0,1,2,3,4,5,6,7,8,9

代码实现:

import torch
from torch.utils.data import Dataset, DataLoader
# 加载训练集和测试集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
  1. root='./data': 这是指定存储数据集的根目录。在这个例子中,MNIST 数据集将被下载并存储在名为 data 的文件夹中。

  2. train=False: 这是一个布尔值参数,用于指示加载的是否是训练集。在这里,由于我们加载的是测试集,因此将其设为 False

  3. download=True: 这也是一个布尔值参数,用于指示是否下载数据集。如果数据集不存在,则将其设置为 True 将自动下载数据集。一旦下载完成,就会被保存在指定的 root 目录中。

  4. transform=transform: 这是数据转换的参数,用于将加载的图像数据转换为模型可接受的张量格式,并进行归一化处理。在这里,你将之前定义的 transform 应用于加载的测试集数据。

Dataset类负责从数据源中加载数据,并对数据进行预处理(如归一化、数据增强等),但它并不负责将数据组织成批次或进行随机化

2.2 Dataloader:

Dataset负责表示数据集和进行数据预处理,而DataLoader负责将数据组织成批次并加载到模型中进行训练。它接收一个“Dataset”对象作为参数,并根据指定的批量大小、是否打乱数据等参数,在实际使用中,通常会将自定义的Dataset对象传递给DataLoader进行数据加载和批处理(用上文提到的类的继承操作)。

代码实现:

import torch
from torch.utils.data import Dataset, DataLoader
# 创建数据加载器
batch_size = 4
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True,num_workers=0)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=0)
  1. batch_size: 这是指定每个批次(batch)包含的样本数量。在这个例子中,将每个批次设置为包含 4 个样本。

  2. shuffle=False: 这是一个布尔值参数,用于指示是否对数据进行洗牌操作。在测试集中,通常不需要对数据进行洗牌,因此将其设置为 False

  3. num_workers=0: 这是用于数据加载的子进程数量。设置为 0 表示所有数据加载操作都在主进程中进行,没有额外的子进程。在一般情况下,将其设置为大于 0 的值可以加速数据加载,但在某些环境中可能会出现问题,因此这里将其设置为 0,表示只使用主进程进行数据加载操作。

3 构建神经网络模型:

# 构建神经网络模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.flatten = nn.Flatten()
        self.feature_extraction = nn.Sequential(
            nn.Linear(28*28, 16*16),
            nn.ReLU(),
            nn.Linear(16*16, 8*8),
            nn.ReLU(),
            nn.Linear(8*8, 10),
            nn.ReLU()
        )

    # 下面定义x的传播路线
    def forward(self, x):
        x = self.flatten(x)
        output = self.feature_extraction(x)
        return output

在神经网络的构建代码中,注意到输入是28×28 的灰度手写数字图像,输出是0~9的十个数字,经过了三层全连接层来一步步提取特征。

在前行传播代码中,( x ) 是一个形参,表示输入数据。当模型进行训练或推理时,需要将实际的数据传递给模型,这个数据就会被赋值给 ( x )。

4 损失函数与优化器:

# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

上例中使用交叉熵损失函数和 SGD 优化器,都是一些固定的格式。不过要注意一 点就是这个学习率,lr=1e-3 是学习率的设置,控制着每次参数更新的步长大小。 学习率是优化算法中一个重要的超参数,它决定了模型在参数空间中搜索的速度 和精度。 例如,lr=1e-3 表示学习率为 0.001,即每次参数更新时,参数值会按照梯度 的方向移动一个较小的步长。

5 定义训练函数与测试函数:

# 定义训练函数
def train(train_dataloader1, model1, loss_fn1, optimizer1):
    for batch, (X, y) in enumerate(train_dataloader1):
        X, y = X.to(device), y.to(device)

        pred = model1(X)
        loss = loss_fn1(pred, y)

        optimizer1.zero_grad()
        loss.backward()
        optimizer1.step()

        if batch % 100 == 0:
            size = len(train_dataloader1)
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:.7f} [{current:>5d}/{size:>5d}]")


# 定义测试函数
def test(test_dataloader2, model2):
    size = len(test_dataloader2.dataset)
    model2.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in test_dataloader2:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= size
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

6 主程序:

# 主程序
epochs = 5
for t in range(epochs):
    print(f"Epoch {t+1}\n")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model)

6 模型的保存与评估:

# 保存模型
torch.save(model.state_dict(), "./model")
print("模型保存在model文件夹内")

# 加载模型
model = CNN()
model.load_state_dict(torch.load("./model"))
model.eval()  # 将模型设置为评估模式

当调用model.eval()时,就像正在告诉模型:“现在我们要用你来做测试或者预测了,所以请你把自己整理好,别再做什么让结果不确定的事情了。”就好像是在考试前整理心情一样,你希望自己在考试时保持冷静和准确,不要因为紧张或者分心而出错。

四、完整代码:

# 导入库
import torch
import torchvision
# 名称简化
import torch.nn as nn
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

# 下载手写数字数据库
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_dataloader = DataLoader(train_dataset, batch_size=4, shuffle=True, num_workers=0)

test_dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
test_dataloader = DataLoader(test_dataset, batch_size=4, shuffle=False, num_workers=0)


# 构建神经网络模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.flatten = nn.Flatten()
        self.feature_extraction = nn.Sequential(
            nn.Linear(28*28, 16*16),
            nn.ReLU(),
            nn.Linear(16*16, 8*8),
            nn.ReLU(),
            nn.Linear(8*8, 10),
            nn.ReLU()
        )

    # 下面定义x的传播路线
    def forward(self, x):
        x = self.flatten(x)
        output = self.feature_extraction(x)
        return output


device = torch.device('cuda')  # 将device指定为GPU
model = CNN().to(device)  # 将模型移动到GPU上
print(model)

# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)


# 定义训练函数
def train(train_dataloader1, model1, loss_fn1, optimizer1):
    for batch, (X, y) in enumerate(train_dataloader1):
        X, y = X.to(device), y.to(device)

        pred = model1(X)
        loss = loss_fn1(pred, y)

        optimizer1.zero_grad()
        loss.backward()
        optimizer1.step()

        if batch % 100 == 0:
            size = len(train_dataloader1)
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:.7f} [{current:>5d}/{size:>5d}]")


# 定义测试函数
def test(test_dataloader2, model2):
    size = len(test_dataloader2.dataset)
    model2.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in test_dataloader2:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= size
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")


# 主程序
epochs = 5
for t in range(epochs):
    print(f"Epoch {t+1}\n")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model)

# 保存和恢复网络权值
torch.save(model.state_dict(), "./model")
print("模型保存在model文件夹内")

# 加载模型
model = CNN()
model.load_state_dict(torch.load("./model"))
model.eval()  # 将模型设置为评估模式

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装mmsegmentation默认主分支main

安装时间2024.4.21 mmsegmentation新版本main分支(v1.2.2) 安装过程 conda create --name openmmlab python3.8 -y conda activate openmmlab// 很关键,可以避免mmcv版本问题 pip install torch1.10.1cu113 torchvision0.11.2cu113 torcha…

【力扣 Hot100 | 第七天】4.22(移动零)

文章目录 1.移动零1.1题目1.2解法:双指针1.2.1双指针思路1.2.2代码实现 1.移动零 1.1题目 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数…

[docker] volume 补充 环境变量 参数

[docker] volume 补充 & 环境变量 & 参数 这里补充一下 volume 剩下的内容,以及添加参数(ARG) 和 环境变量 ENV 的内容 read only volumes ❯ docker run-p 3000:80--rm--name feedback-app-v feedback:/app/feedback-v "$(pwd):/app"-v /app/…

第 394 场 LeetCode 周赛题解

A 统计特殊字母的数量 I 哈希&#xff1a;遍历然后枚举 class Solution {public:int numberOfSpecialChars(string word) {unordered_map<char, int> m;for (auto ch : word)m[ch] 1;int res 0;for (char ch a; ch < z; ch)if (m.count(ch) && m.count(A …

爬虫采集:数据提取

目录 1. 数据分类 2. JSON 2.1 json数据转换​编辑 3. 正则表达式 3.1 re模块 3.1.1 常见方法 3.1.2 单字符匹配 3.1.4 匹配开头和结尾 3.1.5 分组匹配 3.1.6 贪婪非贪婪匹配 4. Xpath 4.1 语法 4.2 查找特定节点 4.3 lxml 模块 4.3.1 安装 4.3.2 导入 4.3.3 使…

【行为型模式】命令模式

一、命令模式概述 命令模式的定义&#xff1a;将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(对象行为型) 命令模式优缺点&#xff1a; 优点&#xff1a; 1.类间解耦&#xff1a;调用者角色与接收者角色之间没有任何依…

TPG原理以及verilog实现

文章目录 一、前言二、verilog代码实现三、仿真以及结果分析 一、前言 TPG(video_test_pattern generator) 视频测试模式发生器用于产生测试数据&#xff0c;对视频数据通路测试。根据视频输出时序产生相应的图像数据 二、verilog代码实现 timescale 1ns / 1nsmodule tpg ( i…

鸿蒙入门10-CheckBoxGroup组件

复选框群组 用于控制多个复选框全选或者不全选状态 参数 参数形式 &#xff1a; CheckboxGroup( options?: { group?: string } ) 创建复选框群组&#xff0c;可以用于控制群组内的 CheckBox 成员 全选 或者 不全选 相同 group 的 CheckBox 和 CheckBoxGroup 为同一群组 参…

Python turtle海龟绘制美国队长盾牌

使用Python中的turtle模块绘制美队盾牌 具体思路如下&#xff1a; 导入海龟库第1个圆&#xff1a;半径 200&#xff0c;红色填充第2个圆&#xff1a;半径 150&#xff0c;白色填充第3个圆&#xff1a;半径 100&#xff0c;红色填充第4个圆&#xff1a;半径 50&#xff0c;蓝色…

摩科智能协办“提高不动产登记质量,促进优化营商环境培训会”

为深入落实国家和自治区自然资源工作会议精神&#xff0c;加强不动产登记队伍作风常态化建设&#xff0c;提高不动产登记质量&#xff0c;促进优化营商环境&#xff0c;学习先进地区工作经验。2024年4月19日&#xff0c;“提高不动产登记质量 促进优化营商环境培训会”在浙江省…

在PostgreSQL中如何实现分区表以提高查询效率和管理大型表?

文章目录 解决方案1. 确定分区键2. 创建分区表3. 数据插入与查询4. 维护与管理 示例代码1. 创建父表和子表2. 插入数据3. 查询数据 总结 随着数据量的增长&#xff0c;单一的大型表可能会遇到性能瓶颈和管理难题。PostgreSQL的分区表功能允许我们将一个大型表分割成多个较小的、…

windows驱动开发-内存概述

“90%的程序问题都是由内存引起的&#xff0c;剩下的10%是使用内存引起的&#xff01;”这是一句非常经典的论证&#xff0c;实际上&#xff0c;在程序开发中&#xff0c;内存问题就是最大的问题&#xff0c;没有之一。 现代的计算机体系中&#xff0c;内存承载了太多的功能&a…

HttpServlet,ServletContext,Listener它仨的故事

1.HttpServlet。 听起来是不是感觉像是个上古词汇&#xff0c;是不是没有阅读下去的兴趣了&#xff1f;Tomcat知道吧&#xff0c;它就是一个servlet容器&#xff0c;当用户向服务器发送一个HTTP请求时&#xff0c;Servlet容器&#xff08;如Tomcat&#xff09;会根据其配置找到…

Vue项目实现懒加载——自用笔记

熟悉指令语法&#xff1a; <template><HomePanel title"人气推荐" sub-title"人气爆款 不容错过"><ul class"goods-list"><li v-for"item in hotList" :key"item.id"><RouterLink to"/&qu…

嵌入式Linux开发

(17 封私信 / 1 条消息) 嵌入式Linux应用 - 搜索结果 - 知乎 (zhihu.com)

【面试】输出设备-①-Tableau入门

感谢大佬 举个栗子&#xff01;Tableau 技巧&#xff08;266&#xff09;&#xff1a;学做双向圆角条形图-CSDN博客 感谢W3Cschool Tableau 概述_w3cschool 感谢Tableau 官方社区 Discover | Tableau Public 1.目标和计划 近期公司需要进行数据大屏的制作&#xff0c;调研了一下…

【大语言模型LLM】-大语言模型乐园,高效办公不迷路!

&#x1f525;博客主页&#xff1a;西瓜WiFi &#x1f3a5;系列专栏&#xff1a;《大语言模型》 ❤️感谢大家点赞&#x1f44d; 收藏⭐ 评论⭐ &#x1f3a5;大语言模型LLM基础-系列文章&#xff1a; 【大语言模型LLM】-大语言模型如何编写Prompt? 【大语言模型LLM】-如何…

Pytorch第一部分数据模块

数据划分&#xff1a; 从数据集中将数据划分为训练集&#xff0c;测试集&#xff0c;验证集 # -*- coding: utf-8 -*- """ # file name : 1_split_dataset.py # author : tingsongyu # date : 2019-09-07 10:08:00 # brief : 将数据集划分为训…

Gamba:将高斯溅射与Mamba结合用于单视图3D重建

Gamba: Marry Gaussian Splatting with Mamba for Single-View 3D Reconstruction Gamba&#xff1a;将高斯溅射与Mamba结合用于单视图3D重建 Qiuhong Shen11  Xuanyu Yi31 Zike Wu31  Pan Zhou2,42 Hanwang Zhang3,5 沈秋红 1 易轩宇 3 吴子可 3 潘周 2,4 2 张汉旺 3,5Shu…

验证线缆(汽车线束、网线、多芯线)破损或断开与正常线缆的区别在哪里?依AEM CV-100 k50测试仪

工厂产线生产的线缆&#xff08;汽车线束、网线、多芯线&#xff09;做成成品&#xff0c;即2端都安装好了模块。在这种情况下如何快速的判定此条线缆是合格的呢&#xff0c;此处的合格为物理层面上的合格&#xff08;不会出现开路、短路&#xff09;&#xff0c;也就是最基本保…