PyTorch 深度学习 || 2. 全连接网络 | Ch2.3 PyTorch 全连接自编码网络的无监督学习

news2024/9/22 11:31:54

PyTorch 全连接自编码网络的无监督学习

文章目录

  • PyTorch 全连接自编码网络的无监督学习
  • 1. 数据去噪
    • 1.1 计算库和数据准备工作
    • 1.2 构建自编码网络
    • 1.3 调用主函数
    • 1.4 可视化
  • 2. 数据的重建与降维
    • 2.1 计算模块和数据的准备
    • 2.2 自编码网络数据准备
    • 2.3 自编码网络的构建
    • 2.4 自编码网络的训练
    • 2.5 自编码网络的数据重建
    • 2.6 自编码网络的编码特征可视化

深度学习网络用于无监督学习是通过一种称为 自编码(Auto-Encoder, AE)的网络结构实现的。自编码神经网络是一种以重构输入信号为目标的神经网络,它是无监督学习领域中的一类网络,可以自动从无表注的数据中学习特征。

自编码由3个网络层:输入层、隐藏层和输出层。其中输入层的样本也会充当输出层的角色,即这个神经网络就是一个尽可能复线输入层信号的神经网络,具体结构如下

在这里插入图片描述

1. 数据去噪

1.1 计算库和数据准备工作

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import make_moons
SEED = 2617
N = 500
SIG = 0.1
X, _ = make_moons(n_samples=N, noise=SIG, random_state=SEED)
plt.scatter(X[:,0],X[:,1])
plt.axis('equal');

XT = torch.tensor(X, dtype=torch.float32)

在这里插入图片描述

1.2 构建自编码网络

在这里插入图片描述

class NetworkAE(nn.Module):
    
    def __init__(self, d_in, d_enc, d1, d2):
        super().__init__()
        # YOUR CODE HERE
        self.encoder=nn.Sequential(
            nn.Linear(d_in,d1),
            nn.Tanh(),
            nn.Linear(d1,d2),
            nn.ReLU(), 
            nn.Linear(d2,d1), 
            nn.ReLU(), 
            nn.Linear(d1,d_enc)
        )
        
        self.decoder = nn.Sequential(
            nn.Linear(d_enc, d1),
            nn.ReLU(),
            nn.Linear(d1, d2),
            nn.ReLU(),
            nn.Linear(d2, d1),
            nn.Tanh(), 
            nn.Linear(d1, d_in)
        )
        #raise NotImplementedError()
    
    def forward(self, x):
        # YOUR CODE HERE
        enc = self.encoder(x)
        x = self.decoder(enc)
        return x

训练网络

def train_nn(NN, X, learning_rate, max_iter, print_iter):
    # YOUR CODE HERE
    loss_func = nn.MSELoss(reduction='sum')        # loss function,此函数默认均值对结果影响非常大,暂时不知道为什么
    optimizer = torch.optim.SGD(NN.parameters(), lr=learning_rate)
    
    for epoch in range(max_iter):
        # ===================forward=====================
        output = NN(X)
        loss = loss_func(output, X)
        # ===================backward====================
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # ===================log========================
        
        if epoch % print_iter == 0:
            print('epoch [{}/{}], loss:{:.4f}'.format(epoch + 1, max_iter, loss.item()))

1.3 调用主函数

learning_rate = 5e-4
max_iter = 10000
d1 = 10  
d2 = 25
netenc = NetworkAE(2, 1,d1,d2)
train_nn(netenc, XT, learning_rate, max_iter,1000)

X_NET = netenc(XT).detach().numpy()

1.4 可视化

plt.scatter(X[:,0], X[:,1])
plt.scatter(X_NET[:,0], X_NET[:,1])
plt.axis('equal');

在这里插入图片描述

for i in range(1000):
    X_NET = torch.tensor(X_NET, dtype=torch.float32)
    X_NET = netenc(X_NET).detach().numpy()
plt.scatter(X[:,0], X[:,1])
plt.scatter(X_NET[:,0], X_NET[:,1])
plt.axis('equal');

在这里插入图片描述

2. 数据的重建与降维

2.1 计算模块和数据的准备

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D # 三维数据可视化
import hiddenlayer as hl 

import torch
import torch.nn as nn
import torch.nn.functional as F 
import torch.utils.data as Data 
import torch.optim as optim
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import make_grid
# 模型加载选择GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# device = torch.device('cpu')
print(device)
print(torch.cuda.device_count())
print(torch.cuda.get_device_name(0))
cuda
1
NVIDIA GeForce RTX 2080 SUPER

2.2 自编码网络数据准备

# 使用手写体数据,准备训练数据集
train_data = MNIST(
    root = './data/MNIST',
    train = True, # 只使用训练数据集
    transform = transforms.ToTensor(),
    download = False
)

# 将图像数据转为向量数据
train_data_x = train_data.data.type(torch.FloatTensor) / 255.0
train_data_x = train_data_x.reshape(train_data_x.shape[0], -1)
train_data_y = train_data.targets
# 定义一个数据加载器
train_loader = Data.DataLoader(
    dataset = train_data_x,
    batch_size = 64,
    shuffle = True,
    num_workers = 2 # Windows需要设置为0
)

# 对测试数据集导入
test_data = MNIST(
    root = './data/MNIST',
    train = False, # 不使用训练数据集
    transform = transforms.ToTensor(),
    download = False
)

# 为测试数据添加一个通道维度,获取测试数据的X和Y
test_data_x = test_data.data.type(torch.FloatTensor) / 255.0
test_data_x = test_data_x.reshape(test_data_x.shape[0], -1)
test_data_y = test_data.targets
print('训练数据集:', train_data_x.shape)
print('测试数据集:', test_data_x.shape)

数据的显示

# 可视化训练数据集中一个batch的图像内容,以观察手写体图像的情况,程序如下:
for step, b_x in enumerate(train_loader):
    if step > 0:
        break
# 可视化一个batch
# make_grid将[batch, channel, height, width]形式的batch图像转为图像矩阵,便于对多张图像的可视化
im = make_grid(b_x.reshape((-1, 1, 28, 28)))
im = im.data.numpy().transpose((1, 2, 0))
plt.figure()
plt.imshow(im)
plt.axis('off')
plt.show()

在这里插入图片描述

2.3 自编码网络的构建

在这里插入图片描述

class EnDecoder(nn.Module):
    def __init__(self):
        super(EnDecoder, self).__init__()
        # 定义Encoder
        self.Encoder = nn.Sequential(
            nn.Linear(784, 512),
            nn.Tanh(),
            nn.Linear(512, 256),
            nn.Tanh(),
            nn.Linear(256, 128),
            nn.Tanh(),
            nn.Linear(128, 3),
            nn.Tanh(),
        )
        # 定义Decoder
        self.Decoder = nn.Sequential(
            nn.Linear(3, 128),
            nn.Tanh(),
            nn.Linear(128, 256),
            nn.Tanh(),
            nn.Linear(256, 512),
            nn.Tanh(),
            nn.Linear(512, 784),
        )
    
    def forward(self, x):
        encoder = self.Encoder(x)
        decoder = self.Decoder(encoder)
        return encoder, decoder

# 定义自编码网络edmodel
myedmodel = EnDecoder().to(device)

from torchsummary import summary

summary(myedmodel, input_size=(1, 784))
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Linear-1               [-1, 1, 512]         401,920
              Tanh-2               [-1, 1, 512]               0
            Linear-3               [-1, 1, 256]         131,328
              Tanh-4               [-1, 1, 256]               0
            Linear-5               [-1, 1, 128]          32,896
              Tanh-6               [-1, 1, 128]               0
            Linear-7                 [-1, 1, 3]             387
              Tanh-8                 [-1, 1, 3]               0
            Linear-9               [-1, 1, 128]             512
             Tanh-10               [-1, 1, 128]               0
           Linear-11               [-1, 1, 256]          33,024
             Tanh-12               [-1, 1, 256]               0
           Linear-13               [-1, 1, 512]         131,584
             Tanh-14               [-1, 1, 512]               0
           Linear-15               [-1, 1, 784]         402,192
          Sigmoid-16               [-1, 1, 784]               0
================================================================
Total params: 1,133,843
Trainable params: 1,133,843
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.04
Params size (MB): 4.33
Estimated Total Size (MB): 4.37
----------------------------------------------------------------

2.4 自编码网络的训练

optimizer = optim.Adam(myedmodel.parameters(), lr = 0.003)
loss_func = nn.MSELoss().to(device)
# 记录训练过程的指标
historyl = hl.History()
# 使用Canvas进行可视化
canvasl = hl.Canvas()
train_num = 0
val_num = 0
# 对模型迭代训练
for epoch in range(10):
    train_loss_epoch = 0
    # 对训练数据的加载器进行迭代计算
    for step, b_x in enumerate(train_loader):
        # 使用每个batch进行训练模型
        b_x = b_x.to(device)
        _, output = myedmodel(b_x) # 前向传递输出
        loss = loss_func(output, b_x) # 均方根误差
        optimizer.zero_grad() # 每个迭代步的梯度初始化为0
        loss.backward() # 损失的后向传播,计算梯度
        optimizer.step() # 使用梯度进行优化
        train_loss_epoch += loss.item() * b_x.size(0)
        train_num = train_num + b_x.size(0)
    # 计算一个epoch的损失
    train_loss = train_loss_epoch / train_num
    # 保存每个epoch上的输出loss
    historyl.log(epoch, train_loss = train_loss)
    # 可视网络训练的过程
    with canvasl:
        canvasl.draw_plot(historyl['train_loss'])

在这里插入图片描述

2.5 自编码网络的数据重建

# 预测测试集前100张图像的输出
myedmodel.eval()
_, test_decoder = myedmodel(test_data_x[0: 100, :].to(device))
# 可视化原来的图像
plt.figure(figsize = (6, 6))
for ii in range(test_decoder.shape[0]):
    plt.subplot(10, 10, ii + 1)
    im = test_data_x[ii, :]
    im = im.cpu().data.numpy().reshape(28, 28)
    plt.imshow(im, cmap = plt.cm.gray)
    plt.axis('off')
plt.show()
# 可视化编码后的图像
plt.figure(figsize = (6, 6))
for ii in range(test_decoder.shape[0]):
    plt.subplot(10, 10, ii + 1)
    im  = test_decoder[ii, :]
    im = im.cpu().data.numpy().reshape(28, 28)
    plt.imshow(im, cmap = plt.cm.gray)
    plt.axis('off')
plt.show()

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

2.6 自编码网络的编码特征可视化

# 获取前500个样本的自编码后的特征,并对数据进行可视化
myedmodel.eval()
TEST_num = 500
test_encoder, _ = myedmodel(test_data_x[0: TEST_num, :].to(device))
print('test_encoder.shape:', test_encoder.shape)

%config InlineBackend.print_figure_kwargs = {'bbox_inches': None}
# 将3个维度的特征进行可视化
test_encoder_arr = test_encoder.cpu().data.numpy()
fig = plt.figure(figsize = (12, 8))
ax1 = Axes3D(fig)
X = test_encoder_arr[:, 0]
Y = test_encoder_arr[:, 1]
Z = test_encoder_arr[:, 2]
ax1.set_xlim([min(X), max(X)])
ax1.set_ylim([min(Y), max(Y)])
ax1.set_zlim([min(Z), max(Z)])
for ii in range(test_encoder.shape[0]):
    text = test_data_y.data.numpy()[ii]
    ax1.text(X[ii], Y[ii], Z[ii], str(text), fontsize = 8, bbox = dict(boxstyle = 'round', facecolor = plt.cm.Set1(text), alpha = 0.7))
plt.show()

在这里插入图片描述

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

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

相关文章

深入理解程序的结构

文章目录 前言一、程序的组成二、未初始化和初始化变量保存地址三、栈什么时候被创建四、内存映射段总结 前言 本篇文章我们来深入的理解一下理解程序的结构。 一、程序的组成 通常情况下,一个可执行程序由以下几个不同的段组成: 1.代码段 (Text Seg…

怎么针对微服务架构做单元测试?

Martin Fowler 是国际著名的软件专家,敏捷开发方法的创始人之一,现为 ThoughtWorks 公司的首席科学家。在面向对象分析设计、UML、模式、软件开发方法学、XP、重构等方面,都扮演着举足 什么是微服务? 微服务的由来 微服务的前身…

笑谈之传统行业的软件测试

最近进入一传统企业做O2O社区,在里面,项目管理一团混乱,上层对软件测试的理解更是匮乏。今天没有技术,仅是对这些现象的吐槽。当然我相信传统行业不都是这样,所以大家仅当笑谈。 产品经理写的需求文档永远是拿来作为做…

cas单点登录 前端步骤流程

CAS(Central Authentication Service)是一个开源的单点登录协议和实现,它提供了一种统一的方法来管理和验证用户身份,使用户只需通过一次登录即可访问多个应用程序。CAS 单点登录的工作原理是基于服务提供者 (Service Provider) 和…

MNIST机器学习入门

引入所需库 import osimport cv2 import matplotlib.pyplot as plt import numpy as np import pandas as pd import tensorflow as tf from PIL import ImageMNIST数据集 下载MNIST数据集 mnisttf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) mnist.load_…

【干货】Android系统定制基础篇:第七部分-Android OTA升级(系统、应用)

OTA升级应用 项目地址:https://github.com/aystshen/Android-RomUpgrade. 这是一个负责 Android OTA 升级的后台应用,开机后自动运行后台 Service,支持系统升级和应用升级,支持本地升级(tf卡、u盘)和在线升…

数据库系统概述——第一章 绪论(知识点复习+练习题)

✨博主:命运之光 🦄专栏:离散数学考前复习(知识点题) 🍓专栏:概率论期末速成(一套卷) 🐳专栏:数字电路考前复习 🦚专栏:数…

Qt 每月收支计算

Qt 每月收支计算,针对每月有支出(房贷、车贷、花呗、借呗)的情况,计算收支明细,直观看到未来的个人经济情况,培养良好的消费习惯,进行理性的财富支配,量入为出。 #include "mai…

云安全技术(三)之云计算相关的安全概念

云计算相关的安全概念 Security Concepts Relevant to Cloud Computing 1. 密码学和密钥管理 Cryptography and key management 1、加密技术: 有许多不同类型和等级的加密技术。在云环境中,云安全专家有责任评价应用程序的需求、所使用的技术、需要保护的数据类型&…

【UE 从零开始制作坦克】5-通过旋转摄像机控制炮塔旋转

效果 步骤 打开动画蓝图“ABP_West_Tank_M1A1Abrams” 我们在动画图表中可以发现控制坦克炮塔旋转和炮管旋转的变量分别是“TurretRotation”和“GunRotattion”,因此只需改变这两个旋转体的值即可控制炮塔和炮管的旋转。 切换到事件图表中,首先通过“T…

单向散列函数【密码学】(一)

目录 一、前言:密码学有什么用? 二、单向散列函数 1、单向函数 2、散列函数 3、单向散列函数 三、怎么解决完整性问题 四、如何设置合适的安全强度 一、前言:密码学有什么用? 二、单向散列函数 单向散列函数就是用来解决…

article-6-pss 并联六自由度机构轨迹规划

建模 ** [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djltxj90-1687070335773)(data:image/svgxml;utf8, )] ** 程序如下: % clc % clear all % function []PSS1(XP,YP,ZP) tic %%%%%鍒濆浣嶇疆鐨勪綅濮?%%%%% % XP 0; %鍔ㄥ钩鍙…

存储笔记6 SAN

SAN(Storage Area Networks) SAN 优势 benefitsSAN 组件 componentsSAN连接选项 connective optionsFC协议 FC寻址 protocol addressing\FC拓扑 topologie SAN优缺点 光纤通道 fibre channel SAN组件 FC三种互联 FC端口类型 fabric 企业需要和科技…

RFID期末复习总结

一.概念部分 1.基础概念 射频识别无线电频率识别RFID 应答器:存放识别信息的电子数据载体 阅读器:将识别信息从应答器中读出(还可以写入数据) 应答器是统称,在各种专业场合有专业名字,比如射频卡&#…

pikachu靶场-PHP反序列化

在理解这个漏洞前,你需要先搞清楚php中serialize(),unserialize()这两个函数。 序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象: class S{public $test"pikachu";}$snew S(); //创建一个对象serialize($s); //…

FPGA时序约束--进阶篇(主时钟约束)

在FPGA设计中,时序约束的设置对于电路性能和可靠性都至关重要。在上一篇的文章中,已经详细介绍了FPGA时序约束的基础知识。 本文将重点讲解主时钟约束设置,给出详细的约束命令,并介绍了在Vivado中如何写入主时钟约束。 一、主时…

一文详解!接口测试(http与rpc)总结

目录 前言: 一、了解一下HTTP与RPC 二、HTTP接口测试 三、RPC接口测试 四、接口测试用例设计 五、测试思路总结 前言: 在接口测试方面,常见的接口类型有HTTP接口和RPC接口。这两者的测试方法略有不同,在测试前需要进行技术选…

[INFO] [copilotIgnore] inactive,github copilot没反应怎么解决

在使用github copilot的时候,插件不工作,后台出现了这种输出, 这种情况下就是它的激活出现了问题,如果账号的使用权没有问题的话,就将该插件disable之后再重新enable,重新观察输出,就会看到copi…

LAMP架构搭建实操

目录 一、LAMP架构概述 二、LAMP框架搭建 1.准备工作 2.部署apache 3.部署mysql 4.部署php 三、部署BBS论坛 一、LAMP架构概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用…

win11系统提示msvcp140.dll丢失的三个解决方法,简单实用

Win11系统在运行photoshop或其他软件,游戏的时候,电脑提示“找不到msvcp140.dll”,“msvcp140.dll丢失”,“无法定位输入点msvcp140.dll”等问题,都是由于Windows11系统中的msvcp140.dll文件丢失或者损坏了。 问题场景…