PyTorch 深度学习 || 专题九:PyTorch 全连接自编码网络的无监督学习

news2024/12/23 13:19:17

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/648955.html

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

相关文章

1.5 掌握Scala内建控制结构(一)

一、条件表达式 (一)语法格式 if (条件) 值1 else 值2 (二)执行情况 条件为真,结果是值1;条件为假,结果是值2。如果if和else的返回结果同为某种类型,那么条件表达式结果也是那种…

微信小程序开发20__第三方UI组件 ColorUI 的应用

ColorUI 有鲜艳的高饱和色彩, 是专注视觉的微信小程序组件库。 gitee 网址 :ColorUI: 鲜亮的高饱和色彩,专注视觉的小程序组件库 一 使用方法 在微信小程序中使用 ColorUI 需要两个步骤: 第一步: 下载源码解压…

【Linux】详解环境变量与命名行参数

目录 环境变量了解PATH什么是环境变量?使用环境变量系统自带环境变量示例 命名行参数argc与argvenvenviron 环境变量 了解PATH 提出问题: 我写的可执行程序,与系统的可执行程序都是可执行程序,那么为什么执行系统的可执行程序…

Dokcer安装---Mqtt

1、拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/synbop/emqttd:2.3.6 老版本 2、运行 docker run -it --name emq -p 18083:18083 -p 1883:1883 -p 8084:8084 -p 8883:8883 -p 8083:8083 -d registry.cn-hangzhou.aliyuncs.com/synbop/emqttd:2.3.6 –name 容器…

佩戴舒适度极好的蓝牙耳机推荐,久戴不累的蓝牙耳机分享

​听歌、刷剧、游戏,运动、吃饭、睡觉等,要说现在年轻人除了离不开手机之外,还有就是蓝牙耳机了!当然,随着蓝牙耳机的快速发展,各种各样的蓝牙耳机都有,导致很多人不知道耳机怎么选了&#xff0…

管理类联考——逻辑——知识篇——第五章 假言命题(必考)(最重要的基础)

第五章 假言命题(必考)(最重要的基础) 假言命题:陈述某一事物情况是另一件事物情况的条件的命题。假言命题中的充分条件假言命题和必要条件假言命题是联考逻辑最重要的必考考点。1 *本质为:充分必要&#…

Vue中如何进行分布式鉴权与认证

Vue中如何进行分布式鉴权与认证 随着前后端分离的趋势不断加强,前端应用的安全性问题也日益受到关注。在Vue应用中,我们通常需要实现分布式鉴权和认证,以确保用户的安全性和数据的保密性。本文将介绍在Vue中如何进行分布式鉴权与认证。 什么…

闲聊下最近哦

随便聊聊 聊聊最近工作或日常上一家公司一直比较忙,人也比较懒,一直没有写博客,最近换了下工作,争取坚持写博客吧 聊聊最近工作或日常 上一家公司一直比较忙,人也比较懒,一直没有写博客,最近换了下工作,争取坚持写博客吧 上家公司做了几年多了,上半年离职换了个工作,现阶段这…

《六》TypeScript 中的泛型

泛型:宽泛的类型,其实就是类型的参数化,让类型像参数一样,不预先指定,而是在使用的时候再让别人传入进来。 在定义函数、类或者接口时,如果遇到类型不明确的时候,就可以使用泛型。 平常开发中可…

Qt5.15.10+msvc2019_x86+qwebengine(含mp4)源码编译

系统要求: win10 64bit 英文版(或者把“区域”->“管理”->“非Unicode程序中所使用的当前语言”->改为"英语(美国)") 内存16g够用,cpu性能越高越好,硬盘在安装环境、下载源码后,至少还有100g可用空间 下载源码: https://download.qt.io/archiv…

Hive SQL:DDL建库 建表

Hive SQL:DDL建库 / 建表 🐘Hive SQL数据库 建库 数据库 在Hive中,默认的数据库叫做default,存储数据位置位于HDFS:/user/hive/warehouse 用户自己创建的数据库存储位 :/user/hive/warehouse/database_name.db 创…

linux文件的增量备份 Shell命令脚本

简单的增量备份脚本,自己用到了之后把部分择出来记录一下,方便日后查阅 # 昨天对应的月份 n_mon$(date -d -1day %Y%m) # 组合文件夹路径 path/home/admin/"$n_mon" # 昨天的0点作为增量备份起始时间,今日0点作为截止时间 s_date$…

web3带大家简单建立区块链概念

上文 Web3.0概念我们简单说了说 web3的概念 可能很多人还是会感觉 太概念了 然后 这一篇 我们再了解一下区块链 因为 web3.0的一个构建基础 就是 区块链 有了区块链 才衍生出了后面的很多东西 去中心化的身份 去中心化的应用 dapp 其实最终的目的 也是带着大家去构建起自己的 …

RK3588 MPP解码句柄泄露问题记录

1. 问题背景 最近在用瑞芯微3588开发板做一个视频处理的项目,前两天拷机发生了闪退,弹出的问题是“打开文件过多”,经过初步排查定位到是MPP硬解码部分出的问题。 我的MPP解码部分主要用来读取网络相机rtsp流,主要参考了一个git…

智能应急照明及疏散指示系统在实际项目中的应用和其实际意义 安科瑞 许敏

摘要:近年来,随着照明技术的迅速发展,高大而复杂的智能建筑日益增多,消防应急照明法规和标准不断健全和完善,消防应急灯具产品品种不断增多,性能不断改进,技术水平有很大提高,得到了…

这就是艺术,优雅的二维码生成器「GitHub 热点速览」

作者:HelloGitHub-小鱼干 平时如果没有需要一般那团黑乎乎的二维码,估计路过的人看见第一眼就不会再看第二眼。但是假若,它是个帅哥靓妹,估计就不同了,更别提像是艺术画一样,将编码图案融入到画里的二维码生…

CEETRON如何赋能航空航天领域打造WEB CAE后处理系统?

CAE(计算机辅助工程)在航空航天领域具有广泛的应用,它在航空航天器的设计、性能评估和安全分析等方面开发坚持重要的作用。 本文主要探讨Ceetron集合CAE在航空航天领域中的应用价值,以及对CAE在航空航天领域应用的更详细描述&…

【粉笔刷题】第二回

在JavaScript中下面选项,关于this描述正确的是() A在使用new实例化对象时, this指向这个实例对象 B当对象调用函数或者方法时,this指向这个对象。 C在函数定义时,this指向全局变量 D在浏览器下的全局范围内,this指向全局对象this表…

Django高级扩展之中间件

中间件是Django请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变Django的输入或输出。每个中间件组件负责实现一些特定的功能。例如,Django包含一个中间件组件AuthenticationMiddleware,它使用会话将…

光伏电池局部遮阴下三种不同的工况对比MATLAB仿真模型

光伏电池局部遮阴下三种不同的工况对比MATLAB仿真模型及程序资源-CSDN文库https://download.csdn.net/download/weixin_56691527/87910311 模型简介: 建议使用MATLAB21b及以上版本打开! 光伏阵列表面被局部遮挡时会产生热斑效应。为了防止太阳电池因热…