稀疏自动编码器MATLAB 实现
稀疏自动编码器 MATLAB 代码,包含:
- 单隐藏层自动编码器(输入→隐藏→输出)
- 稀疏惩罚(KL 散度,目标激活概率 ρ)
- 权重衰减(L2 正则化)
- 批量梯度下降训练
- 可视化隐藏层特征(当输入为图像时)
一、核心函数:sparseAutoencoder.m
function [optTheta, costHistory] = sparseAutoencoder(inputSize, hiddenSize, ...
X, lambda, beta, rho, maxIter)
% 稀疏自动编码器训练
% 输入:
% inputSize - 输入层神经元数
% hiddenSize - 隐藏层神经元数
% X - 训练数据 (inputSize × m)
% lambda - 权重衰减系数
% beta - 稀疏惩罚系数
% rho - 稀疏目标(期望激活概率)
% maxIter - 最大迭代次数
% 输出:
% optTheta - 优化后的参数向量
% costHistory- 每次迭代的损失值
% 初始化参数
epsilon_init = 0.12;
W1 = rand(hiddenSize, inputSize) * 2 * epsilon_init - epsilon_init;
W2 = rand(inputSize, hiddenSize) * 2 * epsilon_init - epsilon_init;
b1 = zeros(hiddenSize, 1);
b2 = zeros(inputSize, 1);
% 展平为向量
theta = [W1(:); W2(:); b1(:); b2(:)];
% 选项(使用 L-BFGS 优化)
options = optimoptions('fminunc', ...
'Algorithm', 'quasi-newton', ...
'MaxIterations', maxIter, ...
'Display', 'iter', ...
'SpecifyObjectiveGradient', true);
% 优化
[optTheta, cost] = fminunc(@(t) saeCost(t, inputSize, hiddenSize, ...
X, lambda, beta, rho), theta, options);
costHistory = cost; % 实际 fminunc 只返回最终值,若需完整曲线可改用梯度下降
end
function [cost, grad] = saeCost(theta, inputSize, hiddenSize, X, lambda, beta, rho)
% 稀疏自动编码器损失函数与梯度
% 参数提取
W1 = reshape(theta(1:hiddenSize*inputSize), hiddenSize, inputSize);
offset = hiddenSize*inputSize;
W2 = reshape(theta(offset+1:offset+hiddenSize*inputSize), inputSize, hiddenSize);
offset = offset + hiddenSize*inputSize;
b1 = theta(offset+1:offset+hiddenSize);
offset = offset + hiddenSize;
b2 = theta(offset+1:offset+inputSize);
m = size(X, 2);
% 前向传播
z2 = W1 * X + b1;
a2 = sigmoid(z2); % 隐藏层激活
z3 = W2 * a2 + b2;
a3 = sigmoid(z3); % 输出层激活
% 重构误差(交叉熵)
cost = -1/m * sum(sum(X .* log(a3) + (1-X) .* log(1-a3)));
% 权重衰减
cost = cost + lambda/2 * (sum(W1(:).^2) + sum(W2(:).^2));
% 稀疏惩罚(KL散度)
rho_hat = mean(a2, 2); % 隐藏层平均激活
kl_div = sum(rho * log(rho ./ rho_hat) + (1-rho) * log((1-rho) ./ (1-rho_hat)));
cost = cost + beta * kl_div;
% ====== 反向传播 ======
% 输出层误差
delta3 = a3 - X;
% 稀疏惩罚项对隐藏层的贡献
sparsity_term = beta * (-rho./rho_hat + (1-rho)./(1-rho_hat));
% 隐藏层误差
delta2 = (W2' * delta3 + sparsity_term) .* sigmoidGradient(z2);
% 梯度
W1grad = 1/m * delta2 * X' + lambda * W1;
W2grad = 1/m * delta3 * a2' + lambda * W2;
b1grad = 1/m * sum(delta2, 2);
b2grad = 1/m * sum(delta3, 2);
% 展平梯度
grad = [W1grad(:); W2grad(:); b1grad(:); b2grad(:)];
end
function g = sigmoid(z)
g = 1 ./ (1 + exp(-z));
end
function g = sigmoidGradient(z)
g = sigmoid(z) .* (1 - sigmoid(z));
end
二、演示脚本:demo_sparseAE.m
该脚本生成模拟数据(或加载 MNIST 子集),训练稀疏自动编码器,并可视化隐藏层权重。
%% 稀疏自动编码器演示
clear; clc; close all;
%% 1. 生成或加载数据
% 使用随机小块图像(8×8 块)
patchSize = 8;
inputSize = patchSize^2; % 64
numPatches = 10000;
% 生成随机自然图像块(模拟)
patches = rand(inputSize, numPatches);
% 归一化到 [0,1]
patches = bsxfun(@rdivide, patches, max(patches, [], 1));
% 若你有 MNIST 数据,可替换为:
% load mnist_uint8.mat;
% train_x = double(train_x') / 255;
% patches = train_x(:, 1:10000); % 取前10000个样本
%% 2. 设置参数
hiddenSize = 36; % 隐藏层神经元数
lambda = 0.003; % 权重衰减系数
beta = 5; % 稀疏惩罚系数
rho = 0.1; % 目标激活概率
maxIter = 400; % 最大迭代次数
%% 3. 训练稀疏自动编码器
fprintf('开始训练稀疏自动编码器...\n');
tic;
[optTheta, costHist] = sparseAutoencoder(inputSize, hiddenSize, ...
patches, lambda, beta, rho, maxIter);
toc;
%% 4. 提取并可视化隐藏层权重
% 从优化后的参数中提取 W1
W1 = reshape(optTheta(1:hiddenSize*inputSize), hiddenSize, inputSize);
% 显示权重(每个隐藏单元对应一个 patchSize×patchSize 的图像)
figure;
displayNetwork(W1', patchSize, patchSize, 6, 6);
title('隐藏层学习到的特征(权重)');
%% 5. 重构测试
% 取几个测试样本
testIdx = 1:10;
testX = patches(:, testIdx);
% 前向传播得到重构
W1 = reshape(optTheta(1:hiddenSize*inputSize), hiddenSize, inputSize);
offset = hiddenSize*inputSize;
W2 = reshape(optTheta(offset+1:offset+hiddenSize*inputSize), inputSize, hiddenSize);
offset = offset + hiddenSize*inputSize;
b1 = optTheta(offset+1:offset+hiddenSize);
offset = offset + hiddenSize;
b2 = optTheta(offset+1:offset+inputSize);
z2 = W1 * testX + b1;
a2 = sigmoid(z2);
z3 = W2 * a2 + b2;
reconstructed = sigmoid(z3);
% 显示原图和重构
figure;
for i = 1:10
subplot(2,10,i);
imshow(reshape(testX(:,i), patchSize, patchSize), []);
title('原图');
subplot(2,10,i+10);
imshow(reshape(reconstructed(:,i), patchSize, patchSize), []);
title('重构');
end
sgtitle('原图 vs 重构');
%% 辅助函数:显示网络权重
function displayNetwork(W, h, w, rows, cols)
% W: hiddenSize × inputSize, 每行是一个隐藏单元的权重
% h, w: 每个小图的高度和宽度
% rows, cols: 显示的行数和列数
figure;
for i = 1:rows*cols
subplot(rows, cols, i);
img = reshape(W(i,:), h, w);
imshow(img, []);
axis off;
end
end
function g = sigmoid(z)
g = 1 ./ (1 + exp(-z));
end
三、运行说明
- 将上述两个函数保存为
.m文件:sparseAutoencoder.mdemo_sparseAE.m
- 在 MATLAB 中运行
demo_sparseAE。 - 若需要更快的训练,可将
maxIter调小(如 200);若希望更精细的特征,可增大。
四、结果示例
- 隐藏层特征:训练完成后会显示 6×6 网格的权重图像(每个小图代表一个隐藏单元学到的“基”)。对于自然图像块,通常会学到边缘检测器(类似 Gabor 滤波器)。
- 重构效果:原图与重构图的对比显示自动编码器能够较好地重建输入。
参考代码 稀疏自动编码器的matlab代码 www.youwenfan.com/contentcnv/81171.html
五、关键参数调优指南
| 参数 | 作用 | 典型范围 |
|---|---|---|
hiddenSize |
隐藏层神经元数 | 小于输入维度(压缩)或大于(过完备) |
lambda |
权重衰减系数 | 0.001 ~ 0.01 |
beta |
稀疏惩罚强度 | 1 ~ 10 |
rho |
目标激活概率 | 0.01 ~ 0.2(越稀疏越小) |
maxIter |
迭代次数 | 200 ~ 800 |
六、扩展建议
- 使用真实数据:将
patches替换为图像块(如从im2col提取的 8×8 块),或直接使用 MNIST 手写数字。 - 栈式自编码器:训练多个稀疏自动编码器堆叠,逐层预训练深度网络。
- 不同激活函数:将 sigmoid 替换为 ReLU 或 tanh,并相应调整梯度。
浙公网安备 33010602011771号