如何利用深度学习中的AutoEncoder进行特征降维和特征可视化,pytorch代码

news2025/3/12 14:36:34

我们将使用 Pytorch 中的 AutoEncoder(自动编码器架构)来减少特征维度和可视化。
北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理

人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典
首先,要安装 PyTorch,您可以使用以下 pip 命令,

$ pip install torch torchvision

torchvision 包含可在 PyTorch 中使用的图像数据集。

安装

导入相关依赖

import matplotlib.pyplot as plt
import numpy as np

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision

设置随机种子和其他配置以实现可重复性。

seed = 21
torch.manual_seed(seed)
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True

设置batch大小、训练epoch数和学习率。

batch_size = 512
epochs = 50
learning_rate = 1e-3

获取数据

使用 torchvision 包加载 MNIST 数据集作为方便的示例。

transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])

train_dataset = torchvision.datasets.MNIST(
    root="~/torch_datasets", train=True, transform=transform, download=True
)

train_loader = torch.utils.data.DataLoader(
    train_dataset, batch_size=batch_size, shuffle=True
)

检查其中一个数据点

examples = enumerate(train_loader)
batch_idx, (example_data, example_targets) = next(examples)
example_data[0][0].max()
tensor(1.)

Autoencoder

自动编码器是一种神经网络,它找到将特征 x 映射到自身的函数。 这个目标被称为重建,自动编码器通过以下过程实现这一目标:
(1) 编码器学习低维空间中的数据表示,
(2) 解码器根据编码器学习到的表征学习重建原始数据。

在下文中,我们为其编码器和解码器组件定义了具有完全连接层和激活函数的自动编码器类。

from torch import Tensor

class AE(nn.Module):
    def __init__(self, **kwargs):
        super().__init__()
        self.encoder_hidden_layer = nn.Linear(
            in_features=kwargs["input_shape"], out_features=1000
        )
        self.encoder_output_layer = nn.Linear(
            in_features=1000, out_features=128
        )
        self.encoder_output_layer2 = nn.Linear(
            in_features=128, out_features=32
        )
        self.encoder_output_layer3 = nn.Linear(
            in_features=32, out_features=2
        )
        
        
            
        self.decoder_hidden_layer = nn.Linear(
            in_features=2, out_features=32
        )
        self.decoder_hidden_layer2 = nn.Linear(
            in_features=32, out_features=128
        )
        self.decoder_hidden_layer3 = nn.Linear(
            in_features=128, out_features=1000
        )
        
        
        self.decoder_output_layer = nn.Linear(
            in_features=1000, out_features=kwargs["input_shape"]
        )


    
    def encode(self, features: Tensor) -> Tensor:
        code = self.encoder_hidden_layer(features)
        code = torch.relu(code)
        code = self.encoder_output_layer(code)
        code = torch.relu(code)
        code = self.encoder_output_layer2(code)
        code = torch.relu(code)
        code = self.encoder_output_layer3(code)
        
        return code

    def decode(self, encoded: Tensor) -> Tensor:
        
        encode = self.decoder_hidden_layer(encoded)
        encode = torch.relu(encode)
        encode = self.decoder_hidden_layer2(encode)
        encode = torch.relu(encode)
        encode = self.decoder_hidden_layer3(encode)
        encode = torch.relu(encode)
        encode = self.decoder_output_layer(encode)
        reconstructed = torch.sigmoid(encode)
        
        return reconstructed   
    
    def forward(self, features: Tensor) -> Tensor:
        encoded = self.encode(features)
        return self.decode(encoded)

在使用我们定义的自动编码器类之前,我们需要做以下事情:
1. 我们配置要在哪个设备上运行。
2. 我们实例化一个 AE 对象。
3. 我们定义我们的优化器。
4. 我们定义重建损失。

#  use gpu if available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# create a model from `AE` autoencoder class
# load it to the specified device, either gpu or cpu
model = AE(input_shape=784).to(device)

# create an optimizer object
# Adam optimizer with learning rate 1e-3
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# mean-squared error loss
criterion = nn.MSELoss()

训练AutoEncoder模型

for epoch in range(epochs):
    loss = 0
    for batch_features, _ in train_loader:
        # reshape mini-batch data to [N, 784] matrix
        # load it to the active device
        batch_features = batch_features.view(-1, 784).to(device)
        
        # reset the gradients back to zero
        # PyTorch accumulates gradients on subsequent backward passes
        optimizer.zero_grad()
        
        # compute reconstructions
        outputs = model(batch_features)
        
        # compute training reconstruction loss
        train_loss = criterion(outputs, batch_features)
        
        # compute accumulated gradients
        train_loss.backward()
        
        # perform parameter update based on current gradients
        optimizer.step()
        
        # add the mini-batch training loss to epoch loss
        loss += train_loss.item()
    
    # compute the epoch training loss
    loss = loss / len(train_loader)
    
    # display the epoch training loss
    print("epoch : {}/{}, recon loss = {:.8f}".format(epoch + 1, epochs, loss))
epoch : 1/50, recon loss = 0.07389576
epoch : 2/50, recon loss = 0.05296296
epoch : 3/50, recon loss = 0.04810659
epoch : 4/50, recon loss = 0.04541392
epoch : 5/50, recon loss = 0.04336656
epoch : 6/50, recon loss = 0.04195889
epoch : 7/50, recon loss = 0.04092639
epoch : 8/50, recon loss = 0.04033839
epoch : 9/50, recon loss = 0.03984492
epoch : 10/50, recon loss = 0.03948938
epoch : 11/50, recon loss = 0.03939159
epoch : 12/50, recon loss = 0.03877884
epoch : 13/50, recon loss = 0.03859487
epoch : 14/50, recon loss = 0.03825530
epoch : 15/50, recon loss = 0.03797148
epoch : 16/50, recon loss = 0.03789599
epoch : 17/50, recon loss = 0.03754379
epoch : 18/50, recon loss = 0.03740290
epoch : 19/50, recon loss = 0.03735819
epoch : 20/50, recon loss = 0.03729593
epoch : 21/50, recon loss = 0.03699356
epoch : 22/50, recon loss = 0.03768872
epoch : 23/50, recon loss = 0.03694447
epoch : 24/50, recon loss = 0.03680794
epoch : 25/50, recon loss = 0.03654349
epoch : 26/50, recon loss = 0.03630730
epoch : 27/50, recon loss = 0.03620429
epoch : 28/50, recon loss = 0.03615394
epoch : 29/50, recon loss = 0.03615029
epoch : 30/50, recon loss = 0.03593704
epoch : 31/50, recon loss = 0.03589566
epoch : 32/50, recon loss = 0.03570651
epoch : 33/50, recon loss = 0.03599412
epoch : 34/50, recon loss = 0.03587519
epoch : 35/50, recon loss = 0.03641265
epoch : 36/50, recon loss = 0.03615064
epoch : 37/50, recon loss = 0.03541873
epoch : 38/50, recon loss = 0.03545310
epoch : 39/50, recon loss = 0.03534035
epoch : 40/50, recon loss = 0.03541123
epoch : 41/50, recon loss = 0.03511182
epoch : 42/50, recon loss = 0.03499481
epoch : 43/50, recon loss = 0.03487989
epoch : 44/50, recon loss = 0.03506399
epoch : 45/50, recon loss = 0.03487079
epoch : 46/50, recon loss = 0.03481269
epoch : 47/50, recon loss = 0.03454635
epoch : 48/50, recon loss = 0.03444027
epoch : 49/50, recon loss = 0.03448961
epoch : 50/50, recon loss = 0.03482613

让我们提取一些测试示例以使用我们训练有素的自动编码器进行重构。

test_dataset = torchvision.datasets.MNIST(
    root="~/torch_datasets", train=False, transform=transform, download=True
)

test_loader = torch.utils.data.DataLoader(
    test_dataset, batch_size=10, shuffle=False
)

test_examples = None

# loop the test data once to get the first batch of 10 datapoints for reconstruction quality check
with torch.no_grad():
    for batch_features in test_loader:
        batch_features = batch_features[0]
        test_examples = batch_features.view(-1, 784)
        reconstruction = model(test_examples)
        reconstruction_hidden = model.encode(test_examples)
        break

检查数据重建质量

让我们尝试使用我们训练有素的自动编码器重建一些测试图像。

with torch.no_grad():
    number = 10
    plt.figure(figsize=(20, 4))
    for index in range(number):
        # display original
        ax = plt.subplot(2, number, index + 1)
        plt.imshow(test_examples[index].numpy().reshape(28, 28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

        # display reconstruction
        ax = plt.subplot(2, number, index + 1 + number)
        plt.imshow(reconstruction[index].numpy().reshape(28, 28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
    plt.show()

在这里插入图片描述

结果分析

正如我们所看到的,重建是好的,但不是特别好; 这主要是因为我们只使用 2 个节点中间隐藏层。 仅使用 2 个节点很容易让我们看到减少的维度,但可能不够好捕捉所有重要特征。 为了纯粹的特征减少目的,我们可以选择更多的节点
对于中间隐藏层。

可视化具有 2 个节点的中间隐藏层以降低维度

# reduce dimension example

results =[]
with torch.no_grad():
    for batch_features in test_loader:
        batch_features = batch_features[0]
        test_examples = batch_features.view(-1, 784)
        reconstruction_hidden = model.encode(test_examples)
        results.append(reconstruction_hidden.numpy())
        
import numpy as np
all_hidden = np.concatenate(results)
all_hidden
array([[-0.43485078,  0.31671965],
       [ 1.5935664 ,  4.4088674 ],
       [ 9.075943  ,  4.4781566 ],
       ...,
       [-0.90027434,  0.3994102 ],
       [-2.9567816 ,  2.2586362 ],
       [-4.884531  ,  1.9589175 ]], dtype=float32)
labels = test_dataset.targets.numpy()
import pandas as pd
rdf = pd.DataFrame(all_hidden)
rdf['lable'] = labels
rdf.columns = ['x','y','label']

from matplotlib import pyplot as plt
import seaborn as sns

plt.figure(figsize=(15,8))  
sns.scatterplot(data=rdf,x='x',y='y',hue='label')
<AxesSubplot:xlabel='x', ylabel='y'>

在这里插入图片描述

代码链接

文末有代码下载链接

下一步

您是否有兴趣了解人工智能的原理和实践? 不要再观望! 我们关于 AI 原则和实践的书是任何想要深入了解 AI 世界的人的完美资源。 由该领域的领先专家撰写,这本综合指南涵盖了从机器学习的基础知识到构建智能系统的高级技术的所有内容。 无论您是初学者还是经验丰富的 AI 从业者,本书都能满足您的需求。 那为什么还要等? 立即下单,开始以一种易于访问、引人入胜且实用的方式学习 AI。

北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理

人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典

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

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

相关文章

力扣(142.1002)补9.17

142.环形链表Ⅱ 不会&#xff0c;不过答案用了数学的想法&#xff0c;我以为计算机里只有暴力呢。 public class Solution { public ListNode detectCycle(ListNode head) { if(headnull||head.nextnull) return null; ListNode phead; ListNode p2head; while(true){ if(p2.ne…

Excel教程之学生成功所需的 5 个电子表格

作为一名学生,跟踪你盘子里的所有任务和责任可能会让人不知所措。 这就是为什么拥有一套组织良好的电子表格可以成为救命稻草的原因。出于多种原因,维护自己的电子表格可能是一项宝贵的技能。首先,它可以帮助您养成良好的习惯,例如组织和关注细节。通过创建和维护您自己的…

RabbitMQ之Exchange(交换机)

目录 一、Exchange简介 二、Exchange(交换机)的类型 1.直连交换机&#xff1a;Direct Exchange 2.主题交换机&#xff1a;Topic Exchange 3.扇形交换机&#xff1a;Fanout Exchange 4、默认交换机 5、Dead Letter Exchange&#xff08;死信交换机&#xff09; 三、交换机…

Conan 上传预编译的包

目录 1. 组织文件 2. 编写conanfile.py 3. 然后执行export 命令 4. 上传到自己的center 疫情肆虐&#xff0c;阳了一周&#xff0c;今天可以正常工作了&#xff0c;刚接触conan, 确实一脸懵逼&#xff0c;今天的任务是把项目转成Conan 管理&#xff0c;因为项目用到了第三方…

R语言学习笔记——扩展篇:第十九章-使用ggplot2进行高级绘图

R语言 R语言学习笔记——扩展篇&#xff1a;第十九章-使用ggplot2进行高级绘图 文章目录R语言一、R中的四种图形系统二、ggplot2包介绍三、用几何函数指定图的类型四、分组&#xff08;重叠图形&#xff09;五、刻面&#xff08;并排图形&#xff09;六、添加光滑曲线七、修改…

SpringMVC的AOP总结

SpringMVC的AOP总结 1、Filter 过滤器 Filter是Servlet规范中规定的&#xff0c;只能用于WEB中, 在Servlet前后起作用 它可以对几乎所有请求进行过滤&#xff0c;但是缺点是一个过滤器实例只能在容器初始化时调用一次 使用场景: 修改字符编码; 对入参进行校验, 校验不通过返回…

java实验报告之Employee类的设计

一个不知名大学生&#xff0c;江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2022.12.20 Last edited: 2022.12.20 目录 一、实验目的 二、实验内容 三、总体设计&#xff08;设计原理、设计方案及流程等&#xff09; 四…

Python数据结构+算法全面讲解:定义函数、定义类

之前的过程抽象例子调用了 Python数学模块中的 sqrt 函数来计算平方根。通常来说,可以 通过定义函数来隐藏任何计算的细节。函数的定义需要一个函数名、一系列参数以及一个函数体。 函数也可以显式地返回一个值。例如,下面定义的简单函数会返回传入值的平方。 >>> …

使用 Appium 报错“... Could not find ‘adb‘ in ...”

使用 Appium 报错 “... Could not find adb in ...”1. 现象2. 问题定位3. 解决方案4. 验证1. 现象 在 Robot Framework 中使用 Open Application 关键字以通过 Appium 来打开模拟器上的应用报错&#xff1a; WebDriverException: Message: An unknown server-side error occ…

Transformer17

还是transformer 这次还是谷歌哈 又在机器人领域发力 谷歌机器人团队等在机器人领域构建了一个多任务 transformer 模型&#xff0c;显著改进了对新任务、环境和对象的零样本泛化。轻松完成700多条指令、成功率达97%&#xff01;谷歌开源机器人领域 我们知道&#xff0c;机器…

Docker搭建MySQL主从集群

使用Docker搭建一主一从的MySQL集群&#xff0c;使用的是8版本的MySQL镜像不是8的版本部分命令会无效&#xff0c;宿主机任意 规划 端口角色3307master3308slave 思路 事先准备 要确保linux宿主机已经安装上Docker。然后将MySQL镜像下载到本地 &#xff0c;可以先去Docker Hu…

ssm java mysql_医院门诊管理系统_

息化不断建设发展的今天&#xff0c;医院看病预约&#xff0c;医生的挂号等&#xff0c;已经十分方便&#xff0c;通过在线挂号&#xff0c;医生的查看&#xff0c;就能够了解到医院的门诊基本信息&#xff0c;并且可以在线进行门诊的医生查看&#xff0c;医院最新的资讯等&…

Golang 【basic_leaming】切片

阅读目录1、为什么要使用切片2、切片的定义3、关于nil 的认识4、切片的循环遍历5、基于数组定义切片6、切片再切片7、关于切片的长度和容量8、切片的本质9、使用 make() 函数构造切片10、切片不能直接比较11、切片是引用数据类型 -- 注意切片的赋值拷贝12、append() 方法为切片…

Mycat(10):分片详解之固定分片hash算法

1 找到conf/schema.xml并备份 2 固定分片hash算法 本条规则类似于十进制的求模运算&#xff0c;区别在于是二进制的操作,是取id的二进制低10位&#xff0c;即id二进制 。 此算法的优点在于如果按照 10进制取模运算&#xff0c;在连续插入1-10 时候1-10会被分到1-10个分片&…

手机号格式检查系统(Java)

本系统支持的手机号检查如下所示&#xff1a; /** * 中国移动&#xff0c;中国联通&#xff0c;中国电信都为11位的手机号 * 中国"移动"前三位: * 135、136、137、138、139、147、150、151、152、157、 * 158、159、172、178、182、183、184、187、188、195、197、19…

铝网初效过滤器及金属网过滤器的区别

广州特耐苏净化设备有限公司详细介绍&#xff1a;粗效过滤器主要技术参数 什么叫铝网初效过滤器及金属网过滤器?铝网初效过滤器也叫金属网过滤器也可叫GH金属孔网过滤器只是人们的叫法不同。 铝网初效过滤器均具安全&#xff0c;坚固&#xff0c;耐高温,耐酸碱,之特性.一般应…

WebDAV之葫芦儿•派盘+Obsidian笔记

Obsidian 支持WebDAV方式连接葫芦儿派盘。 还在为大量的日记、笔记管理而烦恼?推荐一款可以作为第二大脑、支持双向链接、基于Markdown文件的本地知识管理软件。 Obsidian是一款全设备端的笔记软件,让用户能够非常方便的进行笔记上面的记录,纸张无限边界,想到哪,写到哪,不…

点成分享 | 蛋白质浓度测定之BCA法

蛋白质浓度的测定是常见的生物实验之一。本文介绍的是使用BCA法&#xff08;二辛可酸法或二喹啉甲酸法&#xff09;进行蛋白质浓度的测定。 BCA分子式 1 实验原理 BCA是一种稳定的碱性水溶性复合物。在碱性条件下&#xff0c;蛋白质可以将BCA试剂中的二价铜离子Cu2还原成一价…

C++类和对象(上)

学习“类”不“类”&#xff0c;有“对象”了吗&#xff1f; 目录 面向过程和面向对象 类的引入 类的定义 访问限定符 封装 类的作用域 类的实例化 类对象的存储方式 计算类对象的大小 this指针 this指针的特性 this指针两问 面向过程和面向对象 ●C语言是面向过程的…

【Javassist】快速入门系列03 使用Javassist实现方法异常处理

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 03 使用Javassist实现方法异常处理 文章目录系列文章目录前言引入Javassist jar包使用Javassist实现方法异常处理总结说明前言 上一章我们介绍了使用使用Javassist实现了对方法执行时间的…