PyTorch深度学习实战(15)——迁移学习

news2025/1/11 6:52:25

PyTorch深度学习实战(15)——迁移学习

    • 0. 前言
    • 1. 迁移学习
      • 1.1 迁移学习基本概念
      • 1.2 迁移学习的重要性
      • 1.3 ImageNet
      • 1.4 迁移学习流程
    • 2. VGG16 架构
    • 3. 使用预训练 VGG16 模型实现猫狗分类
    • 小结
    • 系列链接

0. 前言

迁移学习( Transfer Learning )是一种利用从一项任务中获得的知识来解决另一项类似任务的技术。一个使用数百万张图像训练的模型,训练数据涵盖数千种对象类别,模型的卷积核将能够学习图像中的各种形状、颜色和纹理,通过重用这些卷积核可以学习到新图像的特征,并最终用于执行计算机视觉任务。随着训练数据集中可用图像数量的增加,模型的分类准确率会不断提高,然而,在实际训练模型过程中,获取大量具有标签的数据样本通常比较困难,需要耗费大量时间和人力成本,而迁移学习能够在训练数据不足的情况下实现更好的泛化性能。

1. 迁移学习

1.1 迁移学习基本概念

迁移学习指利用已经学习好的模型在新任务上具有良好的表现和推广能力的机器学习技术,能够将通用数据集上的模型学习迁移到特定数据集中。通常,用于执行迁移学习的预训练模型在数百万张图像(通用大型数据集)上进行训练,然后使用特定感兴趣数据集微调预训练模型。

迁移学习

1.2 迁移学习的重要性

假设我们需要处理道路图像,并根据图像包含的对象进行分类,而从零开始构建、训练模型可能会因为图像的数量不足,而难以学习到数据集中的各种变化,正如在猫狗分类模型中所看到的,对 8,000 张图像进行训练比在 2000 张图像上进行训练的模型准确率更高。在 ImageNet 上训练的预训练模型能够很好的解决该问题,在对 ImageNet 数据集进行训练期间,模型已经学习了很多与交通相关的特征,例如汽车、道路、树木和人等。因为模型已经学习了大量通用特征,因此,利用已经训练好的模型能够更快和更准确的训练新模型,只需要将预训练模型提取到的特征用于新模型的训练,就可以得到适用于目标任务的性能优异的新模型。

1.3 ImageNet

ImageNet 是一个大规模图像数据集,该数据集包含了超过 1400 万张标注图像,覆盖了 1 万多个分类标签。ImageNet 数据集被广泛用于计算机视觉领域中,包括自动驾驶、智能监控、医学影像分析等。ImageNet 挑战赛由 ImageNet 项目组于 2010 年开始举办,是计算机视觉领域的顶尖比赛之一。在本节中,将使用在 ImageNet 数据集上预训练的深度神经网络构建迁移学习模型。

1.4 迁移学习流程

迁移学习的一般流程如下:

  • 归一化输入图像,使用与预训练模型训练期间相同的均值和标准差进行归一化
  • 获取在大型数据集上进行预训练模型的架构与模型权重
  • 丢弃预训练模型的最后几层
  • 将截断的预训练模型连接到一个或多个新初始化的神经网络层,并确保最后一层的神经元与需要预测的类别数(输出)相同
  • 确保预训练模型的权重不可更新(即在反向传播期间冻结预训练模型参数),但新初始化的神经网络层权重是可训练的。因为预训练模型权重已经使用大型数据集进行了很好的训练,因此可以利用从大型模型中学习到的特征而无需对预训练模型进行训练,而只需要利用小数据集训练新初始化的神经网络层
  • 更新可训练参数,拟合模型

我们已经了解了如何实现迁移学习,接下来,我们介绍预训练卷积神经网络架构 VGG,并使用迁移学习将预训练模型应用于猫狗分类任务。

2. VGG16 架构

Visual Geometry Group (VGG) 是由牛津大学的研究人员在 2014 年提出的卷积神经网络架构,其中 16 代表模型中的层数,包含 13 层的卷积层,3 层的全连接层。 VGG16 分类模型在 2014 年的 ImageNet 比赛中获得了亚军,是一种广泛应用于计算机视觉任务的模型架构。VGG16 中的卷积层使用小尺寸的卷积核,以增加网络深度,提高模型的非线性能力,并且能够提取更丰富的特征。接下来,我们介绍 VGG16 架构以及如何在 PyTorch 中使用 VGG16 预训练模型。

(1) 导入所需要的库:

import torch
from torchvision import transforms,models,datasets
from torchsummary import summary
device = 'cuda' if torch.cuda.is_available() else 'cpu'

torchvision 包中的 models 模块提供了 PyTorch 中可用的预训练模型。

(2) 加载 VGG16 模型并在设备内注册模型:

model = models.vgg16(pretrained=True).to(device)

在以上代码中,models 类中调用了 vgg16 方法,通过使用 pretrained = True 指定加载用于在 ImageNet 竞赛中对图像进行分类的权重,然后将模型注册到设备中。

(3) 打印模型摘要:

print(summary(model, (3, 224, 224)))

模型摘要输出如下:

----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 224, 224]           1,792
              ReLU-2         [-1, 64, 224, 224]               0
            Conv2d-3         [-1, 64, 224, 224]          36,928
              ReLU-4         [-1, 64, 224, 224]               0
         MaxPool2d-5         [-1, 64, 112, 112]               0
            Conv2d-6        [-1, 128, 112, 112]          73,856
              ReLU-7        [-1, 128, 112, 112]               0
            Conv2d-8        [-1, 128, 112, 112]         147,584
              ReLU-9        [-1, 128, 112, 112]               0
        MaxPool2d-10          [-1, 128, 56, 56]               0
           Conv2d-11          [-1, 256, 56, 56]         295,168
             ReLU-12          [-1, 256, 56, 56]               0
           Conv2d-13          [-1, 256, 56, 56]         590,080
             ReLU-14          [-1, 256, 56, 56]               0
           Conv2d-15          [-1, 256, 56, 56]         590,080
             ReLU-16          [-1, 256, 56, 56]               0
        MaxPool2d-17          [-1, 256, 28, 28]               0
           Conv2d-18          [-1, 512, 28, 28]       1,180,160
             ReLU-19          [-1, 512, 28, 28]               0
           Conv2d-20          [-1, 512, 28, 28]       2,359,808
             ReLU-21          [-1, 512, 28, 28]               0
           Conv2d-22          [-1, 512, 28, 28]       2,359,808
             ReLU-23          [-1, 512, 28, 28]               0
        MaxPool2d-24          [-1, 512, 14, 14]               0
           Conv2d-25          [-1, 512, 14, 14]       2,359,808
             ReLU-26          [-1, 512, 14, 14]               0
           Conv2d-27          [-1, 512, 14, 14]       2,359,808
             ReLU-28          [-1, 512, 14, 14]               0
           Conv2d-29          [-1, 512, 14, 14]       2,359,808
             ReLU-30          [-1, 512, 14, 14]               0
        MaxPool2d-31            [-1, 512, 7, 7]               0
AdaptiveAvgPool2d-32            [-1, 512, 7, 7]               0
           Linear-33                 [-1, 4096]     102,764,544
             ReLU-34                 [-1, 4096]               0
          Dropout-35                 [-1, 4096]               0
           Linear-36                 [-1, 4096]      16,781,312
             ReLU-37                 [-1, 4096]               0
          Dropout-38                 [-1, 4096]               0
           Linear-39                 [-1, 1000]       4,097,000
================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 218.78
Params size (MB): 527.79
Estimated Total Size (MB): 747.15
----------------------------------------------------------------

神经网络各层可视化结果如下:

VGG

该网络中约有 1.38 亿个参数(网络末端的线性层包括约 102 万 + 16 万 + 400 万 = 1.22 亿个参数),其中包括 13 个卷积层和 3 个线性层,可以使用 models 打印 VGG16 模型组件:

print(model)

输出结果如下所示:

VGG16模型架构
模型中包括三个主要的子模块——featuresavgpoolclassifier,通常,需要冻结 featuresavgpool 模块,删除分类器 (classifier) 模块并在其位置创建一个新的 classifier 模块,用于预测新任务所需的图像类别。

3. 使用预训练 VGG16 模型实现猫狗分类

接下来,我们介绍如何在实践中使用 VGG16 模型,仅使用 1000 张图像(猫、狗图像各 500 张)构建猫狗分类模型。

(1) 导入所需的库:

import torch.nn as nn
import torch
from torchvision import transforms,models
import matplotlib.pyplot as plt
import numpy as np
device = 'cuda' if torch.cuda.is_available() else 'cpu'
import cv2, glob, numpy as np
import matplotlib.pyplot as plt
from glob import glob
import torchvision.transforms as transforms
from torch.utils.data import DataLoader, Dataset

(2) 下载猫狗分类数据集、解压并指定训练和测试目录:

train_data_dir = 'archive/training_set/training_set'
test_data_dir = 'archive/test_set/test_set'

(2) 定义 Dataset 类,用于返回猫狗数据集的输入-输出对,使用 transforms 模块中的 Normalize 调用 normalize 函数执行数据归一化,并获取每个文件夹中的前 500 张图像:

class CatsDogs(Dataset):
    def __init__(self, folder):
        cats = glob(folder+'/cats/*.jpg')
        dogs = glob(folder+'/dogs/*.jpg')
        self.fpaths = cats[:500] + dogs[:500]
        self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])
        from random import shuffle, seed; seed(10); shuffle(self.fpaths)
        self.targets = [fpath.split('/')[-1].startswith('dog') for fpath in self.fpaths] 
    def __len__(self):
        return len(self.fpaths)
    def __getitem__(self, ix):
        f = self.fpaths[ix]
        target = self.targets[ix]
        im = (cv2.imread(f)[:,:,::-1])
        im = cv2.resize(im, (224,224))
        im = torch.tensor(im/255)
        im = im.permute(2,0,1)
        im = self.normalize(im) 
        return im.float().to(device), torch.tensor([target]).float().to(device)

在利用预训练模型时,必须对图像调整大小、交换通道顺序和归一化(根据所用预训练模型),图像将 3 个通道上的像素值缩放至 01 之间,然后使用指定平均值( [0.485, 0.456, 0.406] )和标准差( [0.229, 0.224, 0.225] )归一化 RGB 通道。

(3) 获取图像及其标签,抽样检查示例图像及其对应的类别标签:

data = CatsDogs(train_data_dir)

im, label = data[100]
plt.imshow(im.permute(1,2,0).cpu())
plt.show()
print(label)
# tensor([0.], device='cuda:0')

数据图像
(4) 定义模型,下载预训练的 VGG16 权重,冻结特征提取模块,并训练新的分类器。

首先,利用 models 类下载预训练的 VGG16 模型:

def get_model():
    model = models.vgg16(pretrained=True)

通过指定 param.requires_grad = False 在反向传播期间冻结模型参数:

    for param in model.parameters():
        param.requires_grad = False

替换 avgpool 模块以返回大小为 1 x 1 的特征图替换原模型中 7 x 7 的特征图,即输出尺寸变为 batch_size x 512 x 1 x 1

    model.avgpool = nn.AdaptiveAvgPool2d(output_size=(1,1))

PyTorch 中,nn.MaxPool2d 用于从特征图的每个部分中选择最大值,而 nn.AvgPool2d 会返回特征图每个部分的平均值,在这两个网络层中使用了固定大小的核。nn.AdaptiveAvgPool2d 是另一类池化层,可以指定输出特征图的尺寸,该层自动计算核大小,以便返回指定尺寸的特征图。例如,如果输入特征图尺寸为 batch_size x 512 x k x k,想要得到尺寸为的特征图 batch_size x 512 x 21 x 1,则池化核大小为 k x k,而使用 nn.AdaptiveAvgPool2d 层无论输入尺寸如何,其输出尺寸始终是固定的,因此,神经网络可以接受任何尺寸的输入图像。

定义模型的分类器模块,首先展平 avgpool 模块的输出,然后连接到具有 128 个单元的隐藏层,并在执行激活函数后连接到输出层:

    model.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(512, 128),
            nn.ReLU(),
            nn.Dropout(0.2),
            nn.Linear(128, 1),
            nn.Sigmoid()
    )

定义损失函数 (loss_fn)、优化器:

    loss_fn = nn.BCELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr= 1e-3)
    return model.to(device), loss_fn, optimizer

在以上代码中,我们首先冻结了预训练模型的所有参数,然后定义了新的 avgpool 和分类器模块,打印模型摘要:

from torchsummary import summary
model, criterion, optimizer = get_model()
print(summary(model, (3,224,224)))

输出结果如下所示:

----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 224, 224]           1,792
              ......         ..................               .
        MaxPool2d-31            [-1, 512, 7, 7]               0
AdaptiveAvgPool2d-32            [-1, 512, 1, 1]               0
          Flatten-33                  [-1, 512]               0
           Linear-34                  [-1, 128]          65,664
             ReLU-35                  [-1, 128]               0
          Dropout-36                  [-1, 128]               0
           Linear-37                    [-1, 1]             129
          Sigmoid-38                    [-1, 1]               0
================================================================
Total params: 14,780,481
Trainable params: 65,793
Non-trainable params: 14,714,688
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 218.41
Params size (MB): 56.38
Estimated Total Size (MB): 275.36
----------------------------------------------------------------

输出中省去了与预训练模型中相同的网络层,模型共有 1470 万个参数,其中可训练参数的数量只有 65,793 个,因为模型中只有分类器模块具有要学习的权重。

(5) 定义函数获取数据、训练模型、计算准确度:

def train_batch(x, y, model, optimizer, loss_fn):
    prediction = model(x)
    batch_loss = loss_fn(prediction, y)
    batch_loss.backward()
    optimizer.step()
    optimizer.zero_grad()
    return batch_loss.item()

def accuracy(x, y, model):
    with torch.no_grad():
        prediction = model(x)
    is_correct = (prediction > 0.5) == y
    return is_correct.cpu().numpy().tolist()

def get_data():
    train = CatsDogs(train_data_dir)
    trn_dl = DataLoader(train, batch_size=32, shuffle=True, drop_last = True)
    val = CatsDogs(test_data_dir)
    val_dl = DataLoader(val, batch_size=32, shuffle=True, drop_last = True)
    return trn_dl, val_dl

@torch.no_grad()
def val_loss(x, y, model, loss_fn):
    prediction = model(x)
    val_loss = loss_fn(prediction, y)
    return val_loss.item()

(6) 初始化 get_data()get_model() 函数:

trn_dl, val_dl = get_data()
model, loss_fn, optimizer = get_model()

(7) 训练模型,并绘制模型训练过程中训练和测试准确率:

train_losses, train_accuracies = [], []
val_accuracies = []
for epoch in range(10):
    print(f" epoch {epoch + 1}/10")
    train_epoch_losses, train_epoch_accuracies = [], []
    val_epoch_accuracies = []

    for ix, batch in enumerate(iter(trn_dl)):
        x, y = batch
        batch_loss = train_batch(x, y, model, optimizer, loss_fn)
        train_epoch_losses.append(batch_loss) 
    train_epoch_loss = np.array(train_epoch_losses).mean()

    for ix, batch in enumerate(iter(trn_dl)):
        x, y = batch
        is_correct = accuracy(x, y, model)
        train_epoch_accuracies.extend(is_correct)
    train_epoch_accuracy = np.mean(train_epoch_accuracies)

    for ix, batch in enumerate(iter(val_dl)):
        x, y = batch
        val_is_correct = accuracy(x, y, model)
        val_epoch_accuracies.extend(val_is_correct)
    val_epoch_accuracy = np.mean(val_epoch_accuracies)

    train_losses.append(train_epoch_loss)
    train_accuracies.append(train_epoch_accuracy)
    val_accuracies.append(val_epoch_accuracy)

epochs = np.arange(10)+1
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
plt.plot(epochs, train_accuracies, 'bo', label='Training accuracy')
plt.plot(epochs, val_accuracies, 'r', label='Validation accuracy')
plt.gca().xaxis.set_major_locator(mticker.MultipleLocator(1))
plt.title('Training and validation accuracy with VGG16 \nand 1K training data points')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.ylim(0.95,1)
plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()]) 
plt.legend()
plt.grid('off')
plt.show()

模型性能
可以看到,在第一个 epoch 结束时模型准确率就可以达到 98%,即使训练数据集中仅包含 1,000 张图像(每个类别 500 张图像)。
除了 VGG16,也可以使用 VGG11VGG19 预训练神经网络架构,它们的工作方式与 VGG16 类似,仅层数不同。 VGG19VGG16 有更多的参数,因为它有更多的网络层。
使用 VGG11VGG19 代替 VGG16 预训练模型时的训练和验证准确率如下:

模型性能

可以看到,基于 VGG19 模型的准确率略高于基于 VGG16 的模型,在验证数据上的准确率为 98%,基于 VGG11 模型的准确率略低,为 97%

小结

迁移学习通过利用相关任务或领域的知识,帮助解决新任务或领域中的学习挑战,可以提高模型的泛化能力、加速模型训练,并在实际应用中取得良好的效果。在图像分类、目标检测、机器翻译等任务中,迁移学习已经展现出巨大的应用价值。在本节中,介绍了迁移学习的基本概念,并使用 PyTorch 构建了迁移学习模型,利用预训练模型 VGG 加速学习过程并提高性能。

系列链接

PyTorch深度学习实战(1)——神经网络与模型训练过程详解
PyTorch深度学习实战(2)——PyTorch基础
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch深度学习实战(4)——常用激活函数和损失函数详解
PyTorch深度学习实战(5)——计算机视觉基础
PyTorch深度学习实战(6)——神经网络性能优化技术
PyTorch深度学习实战(7)——批大小对神经网络训练的影响
PyTorch深度学习实战(8)——批归一化
PyTorch深度学习实战(9)——学习率优化
PyTorch深度学习实战(10)——过拟合及其解决方法
PyTorch深度学习实战(11)——卷积神经网络
PyTorch深度学习实战(12)——数据增强
PyTorch深度学习实战(13)——可视化神经网络中间层输出
PyTorch深度学习实战(14)——类激活图

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

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

相关文章

利用evo将kitti数据集真值轨迹由kitti格式转为tum格式

(1)首先是序列对应问题: 00: 2011_10_03_drive_0027 01: 2011_10_03_drive_0042 02: 2011_10_03_drive_0034 03: 2011_09_26_drive_0067 04: 2011_09_30_drive_0016 05: 2011_09_30_drive_0018 06: 2011_09_30_drive_0020 07: 2011_09_30_dr…

精品基于NET实现的期刊订购管理系统

《[含文档PPT源码等]精品基于NET实现的期刊订购管理系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具: 开发软件:VS 2017 (版本2017以上即可,不能低于2017) 数…

12.示例程序(定时器定时中断定时器外部时钟)

目录 定时中断和时钟源选择相关库函数使用 1.定时器初始化配置 2.参数(PSC、ARR等)更改函数(在程序运行过程中修改) 3.使用定时器库函数的一些细节 定时器定时中断实例 定时器外部时钟选择 知识点get: 滤波器工作…

印尼市场TikTok攻略:如何利用海外网红引领品牌营销?

随着社交媒体的迅速崛起,营销策略也在不断演变,其中TikTok作为一个全球热门的短视频平台,为企业在国际市场上推广产品和服务提供了新的机会。印尼作为东南亚最大的国家之一,拥有庞大的互联网用户群体,为品牌在TikTok上…

如何写出一篇爆款产品文案,从目标受众到市场分析!

一篇爆款产品文案意味着什么?意味着更强的种草能力,更高的销售转化和更强的品牌传播力。今天来分享下如何写出一篇爆款产品文案,从目标受众到市场分析! 一、产品文案策略 一篇爆款产品文案,并不是一时兴起造就的。在撰写之前&…

Date日期工具类(数据库日期区间问题)

文章目录 前言DateUtils日期工具类总结 前言 在我们日常开发过程中,当涉及到处理日期和时间的操作时,字符串与Date日期类往往要经过相互转换,且在SQL语句的动态查询中,往往月份的格式不正确,SQL语句执行的效果是不同的…

提升测试效果:深入解析《Effective软件测试》的关键方法与实践

目录 1、写在前面2、独特的观点3、内容介绍4、作者介绍5、赠书 or 购买 1、写在前面 近年来出现了一 些新的出版方式,MEAP(Manning Early Access Program)就是其中的一种,把开源运动扩展到出版行业。在MEAP中,读者可在图书出版前逐章阅读早期…

2023开学值得买电容笔有哪些?ipad第三方电容笔推荐

很多学生都已经在为新学期的到来做准备了,而电容笔,也是他们最喜欢的一种。苹果的Pencil,虽然功能很强,但也很贵,不是每个人都能买得起的。目前市场上有很多价格低廉,使用方便的平替电容笔,因此…

Numpy和Pandas简介

推荐:使用NSDT场景编辑器快速搭建3D应用场景 如果您正在从事数据科学项目,Python 包将简化您的生活,因为您只需要几行代码即可执行复杂的操作,例如操作数据和应用机器学习/深度学习模型。 在开始你的数据科学之旅时,…

[Linux]进程间通信--共享内存

[Linux]system V共享内存 文章目录 [Linux]system V共享内存共享内存通信的原理系统接口创建共享内存接口关联共享内存接口去关联共享内存接口删除共享内存接口 使用指令操作共享内存查看共享内存删除共享内存 共享内存的特性编码测试共享内存 共享内存是Linux系统下的一种进程…

spring boot项目运行及打包

目录 一、项目示例 二、项目运行 三、项目打包 3.1 配置打包项 3.2 运用maven工具打包 3.3 运行打包好的jar文件 一、项目示例 创建项目逻辑实现文件(控制URL路径访问及内容逻辑实现) 如上图点击创建新的java class文件,编辑文件内容&…

开发工程师VS测试工程师VS测试开发工程师

每年正式上班之后就会非常忙,今年也不例外。我们公司现在也忙了起来,都没有时间写我的自动化测试教程了。不过大家放心,我会继续写下去的,不过可能更新的不那么快了。最近被同事问到了一个问题,开发,测试和…

nvidia-smi指令报错:Failed to initialize NVML: Driver 解决

文章目录 如何解决题外话,ubuntu22如何安装NVIDIA驱动 我的系统是ubuntu22。 如何解决 我是之前有能用的驱动,但突然服务器nvidia-smi命令不能用了。 看网上说重启就好了,我重启后还是没用,我建议是重启后运行下面2个指令。 运…

python开发之个人微信机器人的开发

简要描述: 发送链接 请求URL: http://域名地址/sendUrl 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wId是st…

运维学习之采集器Node-Exporter 1.3.1安装并使用

参考《监控系统部署prometheus基本功能》先完成prometheus部署。 wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz下载压缩包。 tar -zxf node_exporter-1.3.1.linux-amd64.tar.gz进行解压。 cp node_e…

【图神经网络 02】图卷积

1 图卷积概念 图卷积获取特征需要:各节点输入特征、网络结构图。 图卷积是半监督任务,不需要全部标签,少量标签也能训练,计算损失时只考虑有标签。 2 图卷积计算方式 针对橙色节点,计算特征:平均其邻居特…

测试----计算机网络

文章目录 计算机网络的历史OSI/RM 协议TCP/IP协议IP地址 计算机网络的历史 50-60年代 内部通讯功能(连接的是同一台主机,只能主机和终端之间通信,终端和终端之间的通讯只能依靠主机来传输)60-70年代 主机和主机之间能通讯70年代-…

MDO4104B-6泰克Tektronix混合域示波器

181/2461/8938泰克MDO4104B-6混合域示波器,1 GHz,4通道。,5 GS/s,6 GHz射频通道。 介绍世界上第一台示波器,它包括一个逻辑分析仪、频谱分析仪和协议分析仪-所有同步的集成视图。虽然您可以将Tektronix MDO4000B系列简…

李沐《动手学深度学习》torch.cat() 和 torch.stack()的区别及思考

一、问题引出 好久没更新啦!最近在学习沐神《动手学深度学习》6.5节池化层的时候,发现沐神在两处相似的地方使用了两种Python拼接函数torch.cat()和torch.stack(): 百思不得其解,于是查阅相关文档之后终于弄清楚了两者之间的区别…

安全文件传输如何进行管控,从而促进业务的有序发展?

随着信息化技术的不断发展,安全文件传输对于企业来说变得越来越重要,企业数据安全在近几年频繁发生,有不少企业都因数据泄漏而造成不同程度的损失,很多企业花费人力和财力采取各种措施,来确保自身数据安全和文件安全。…