利用keras搭建自编码器网络——脑机接口

本文通过使用Keras实现自编码器对MNIST手写数字数据集进行特征学习与重构,探讨了不同网络结构(如单层与多层自编码器)对模型表现的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为我的本科毕设就是做自编码器的,所以,自编码器部分还是很好理解的,在这里不多赘述。

我现在主要是看一下mnist的自编码器部分,然后利用这个来搭建自己数据的自编器网络。

贴几个参考代码的链接

https://kiseliu.github.io/2016/08/16/building-autoencoders-in-keras/

http://ff120.github.io/2017/04/20/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E4%B8%93%E9%A2%98/%E4%BD%BF%E7%94%A8keras%E5%AE%9E%E7%8E%B0autoencoder/

https://keras-cn.readthedocs.io/en/latest/blog/autoencoder/

https://morvanzhou.github.io/tutorials/machine-learning/keras/3-1-save/

#!/usr/bin/python
# -*- coding:utf8 -*-

import keras
import numpy as np
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Dense, Input
from keras import regularizers
import matplotlib.pyplot as plt

batch_size = 256

epochs = 100

#数据预处理
(x_train, _), (x_test, _) = mnist.load_data() #去掉标签加载数据
x_train = x_train.astype('float32') #数据归一化
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:]))) #把28×28的数据平展成784大小的向量
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print x_train.shape
print x_test.shape

#建立自编码器模型
encoding_dim = 32  #将784维的数据压缩到32维,压缩率为24.5
input_img = Input(shape=(784,))
# 增加稀疏性
encoded = Dense(encoding_dim, activation='relu', activity_regularizer=regularizers.l1(10e-5))(input_img) #对输入的编码表示(压缩)
decoded = Dense(784, activation='sigmoid')(encoded) #输入的有损失重构
autoencoder = Model(inputs=input_img, outputs=decoded) #把输入映射到它的重构上

#建立单独的编码器模型
encoder = Model(inputs=input_img, outputs=encoded)

#建立单独的解码器模型
encoded_input = Input(shape=(encoding_dim,)) #编码维度是解码器的输入
decoded_layer = autoencoder.layers[-1]
decoder = Model(inputs=encoded_input, outputs=decoded_layer(encoded_input)) #把编码后的数据映射到最后的输出

#激活模型(compile)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy') #配置模型参数,基于元素的二元交叉熵损失,和Adadelta优化算子

#训练模型
autoencoder.fit(x_train, x_train,
          batch_size=batch_size,
          epochs=epochs,
          shuffle=True,
          validation_data=(x_test, x_test))

# 可视化
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
    ax = plt.subplot(2, n, i+1) #display original
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

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

注意:我看参考链接的正则化都是:
activity_regularizer=regularizers.activity_l1(10e-5))(input_img)
因为运行后报错,我查阅了keras中文文档里正则化的API,发现应该改为
activity_regularizer=regularizers.l1(10e-5))(input_img)

因为模型加入正则化更不容易过拟合,所以训练的epochs从原来的50,加到了100

实验结果:
这里写图片描述

loss有点大,再找下原因

多层自编码器

为了使loss减小,可以尝试多层训练,设计栈式自编码器
代码如下:

#!/usr/bin/python
# -*- coding:utf8 -*-

import keras
import numpy as np
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Dense, Input
from keras import regularizers
import matplotlib.pyplot as plt

batch_size = 256

epochs = 100

#数据预处理
(x_train, _), (x_test, _) = mnist.load_data() #去掉标签加载数据
x_train = x_train.astype('float32') #数据归一化
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:]))) #把28×28的数据平展成784大小的向量
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print x_train.shape
print x_test.shape

#建立自编码器模型
encoding_dim = 32  #将784维的数据压缩到32维,压缩率为24.5
input_img = Input(shape=(784,))
# 增加稀疏性
encoded = Dense(128, activation='relu')(input_img) #对输入的编码表示(压缩)
encoded = Dense(64, activation='relu')(encoded)
encoded = Dense(encoding_dim, activation='relu')(encoded)

decoded = Dense(64, activation='relu')(encoded)
decoded = Dense(128, activation='relu')(decoded)
decoded = Dense(784, activation='sigmoid')(decoded) #输入的有损失重构
autoencoder = Model(inputs=input_img, outputs=decoded) #把输入映射到它的重构上

#建立单独的编码器模型
encoder = Model(inputs=input_img, outputs=encoded)

#建立单独的解码器模型
encoded_input = Input(shape=(encoding_dim,)) #编码维度是解码器的输入
num_decoder_layers = 3
decoder_layer = encoded_input
for i in range(-num_decoder_layers, 0):
    decoder_layer = autoencoder.layers[i](decoder_layer)
decoder = Model(encoded_input, decoder_layer) #这里我参考了stack Overflow上的一个回答https://stackoverflow.com/questions/37758496/python-keras-theano-wrong-dimensions-for-deep-autoencoder


#激活模型(compile)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy') #配置模型参数,基于元素的二元交叉熵损失,和Adadelta优化算子

#训练模型
autoencoder.fit(x_train, x_train,
          batch_size=batch_size,
          epochs=epochs,
          shuffle=True,
          validation_data=(x_test, x_test))

# 可视化
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
    ax = plt.subplot(2, n, i+1) #display original
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

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

注意,由于构建了深度解码器,在单独构建解码器的时候,不能再取最后一层作为解码器了,因为此时最后一层的输入是128维,而此时encoding dim是32维,所以程序会报错https://stackoverflow.com/questions/37758496/python-keras-theano-wrong-dimensions-for-deep-autoencoder

运行结果
这里写图片描述

### 构建和训练自动编码器(AE)深度学习模型 #### 1. 自动编码器的基本结构 自动编码器由两部分组成:编码器(Encoder)和解码器(Decoder)。编码器负责将高维输入数据映射到低维空间,而解码器则尝试从这个低维表示重建原始输入。这种设计使得自动编码器能够捕捉数据的主要特征并忽略噪声。 为了实现这一目标,通常会设置瓶颈层(Bottleneck Layer),即隐藏层的维度小于输入层的维度。这样可以迫使网络学习一种更紧凑的数据表示方式[^1]。 #### 2. 数据预处理 在构建自动编码器之前,需要对数据进行标准化处理。对于数值型数据,可以通过减去均值并除以标准差来完成归一化操作。以下是基于R语言的一个简单例子: ```r normalize <- function(x){ (x - mean(x)) / sd(x) } data_normalized <- apply(data, 2, normalize) ``` 此代码片段展示了如何创建一个用于标准化列向量的函数 `normalize` 并将其应用于整个数据集 `data` 中的所有列[^2]。 #### 3. 使用 Keras 实现自动编码器 Keras 是一个高级神经网络 API,支持快速实验。下面是一个简单的 Python 脚本,展示如何利用 Keras搭建一个基础版本的自动编码器: ```python from keras.layers import Input, Dense from keras.models import Model input_dim = data.shape[1] encoding_dim = 32 # 定义输入占位符 input_layer = Input(shape=(input_dim,)) # 编码层 encoded = Dense(encoding_dim, activation='relu')(input_layer) # 解码层 decoded = Dense(input_dim, activation='sigmoid')(encoded) # 创建自编码器模型 autoencoder = Model(inputs=input_layer, outputs=decoded) # 单独定义编码器模型以便后续提取特征 encoder_model = Model(inputs=input_layer, outputs=encoded) # 配置损失函数与优化器 autoencoder.compile(optimizer='adam', loss='binary_crossentropy') # 开始训练过程 history = autoencoder.fit( x_train, x_train, epochs=50, batch_size=256, shuffle=True, validation_data=(x_test, x_test)) ``` 上述脚本首先定义了一个具有单隐含层的基础架构,接着分别配置了完整的自编码器以及仅包含编码阶段的部分模型。最后一步指定了适合二分类交叉熵误差评估指标下的 Adam 优化算法来进行参数调整[^4]。 #### 4. 特定类型的自动编码器——卷积自编码器(CAE) 当面对图像类别的大数据集合时,传统的全连接层可能无法有效捕获局部模式信息。此时可考虑采用卷积自编码器(Convolutional Autoencoders),它们使用卷积运算替代普通的矩阵乘法,在保持空间关系的同时减少参数数量。例如: ```python from keras.layers import Conv2D, MaxPooling2D, UpSampling2D input_img = Input(shape=(img_rows, img_cols, 1)) x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img) x = MaxPooling2D((2, 2), padding='same')(x) x = Conv2D(8, (3, 3), activation='relu', padding='same')(x) x = MaxPooling2D((2, 2), padding='same')(x) ... encoded = ... ... decoded = ... ``` 这里我们引入了二维卷积层(`Conv2D`) 和最大池化层 (`MaxPooling2D`) 进行下采样;而在上采样的过程中,则采用了反卷积或者插值方法恢复尺寸大小[^5]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值