Tensorflow 自编码器:Fashion MNIST图片重建实战

一. 自编码器

如果把算法x作为监督信号来学习,这类算法成为自监督学习(Self-supervised learning)。自编码器算法属于自监督学习的范畴。

自编码器算法原理:利用数据x本身作为监督信号来知道网络的训练,即希望神经网络能够学习到映射𝑓𝜃: 𝒙 → 𝒙。我们把网络𝑓𝜃分为两部分,前面的子网络学习映射关系:𝑔𝜃1 : 𝒙 → 𝒛,后面的子网络尝试学习映射关系ℎ𝜃2 : 𝒛 → 𝒙。于是把𝑔𝜃1看成一个数据编码(Encode)的过程,把高维度的输入𝒙编码成低维度的隐变量𝒛(Latent variable,或隐藏变量),称为Encoder 网络(编码器);ℎ𝜃2看成数据解码(Decode)的过程,把编码过后的输入𝒛解码为高维度的𝒙,称为Decoder 网络(解码器)。

二. Fashion MNIST图片重建

import tensorflow as tf 
from tensorflow import keras
import numpy as np
from    matplotlib import pyplot as plt
from    PIL import Image


(x_train, y_train), (x_test, y_test) = keras.datasets.fashion_mnist.load_data()
x_train = tf.convert_to_tensor(x_train/255., tf.float32)
x_test = tf.convert_to_tensor(x_test/255., tf.float32)

batchsz = 100
train_db = tf.data.Dataset.from_tensor_slices(x_train)
test_db = tf.data.Dataset.from_tensor_slices(x_test)

train_db = train_db.shuffle(batchsz*5).batch(batchsz).repeat(10)
test_db = test_db.batch(batchsz)

# model = keras.Sequential([
#     keras.layers.Dense(256, activation=tf.nn.relu), # 参数量784*256+256
#     keras.layers.Dense(128, activation=tf.nn.relu), # 参数量256*128+128
#     keras.layers.Dense(20),
#     keras.layers.Dense(128, activation=tf.nn.relu), # 参数量20*128+128
#     keras.layers.Dense(256, activation=tf.nn.relu), # 参数量128*256+256
#     keras.layers.Dense(784)   
# ])
class AE(keras.Model):
    def __init__(self):
        super(AE, self).__init__()

        # 创建Encoders网络
        self.encoder = keras.Sequential([
            keras.layers.Dense(256, activation=tf.nn.relu), # 参数量784*256+256
            keras.layers.Dense(128, activation=tf.nn.relu), # 参数量256*128+128
            keras.layers.Dense(20)                          # 参数量128*20+20
        ])

        # 创建Decoders网络
        self.decoder = keras.Sequential([
            keras.layers.Dense(128, activation=tf.nn.relu), # 参数量20*128+128
            keras.layers.Dense(256, activation=tf.nn.relu), # 参数量128*256+256
            keras.layers.Dense(784)                         # 参数量256*784+784
        ])

    def call(self, inputs, training=None):
        # 前向传播
        # 编码获取隐藏向量h
        h = self.encoder(inputs)
        # 解码获取重建图片
        out = self.decoder(h)
        return out

model = AE()
model.build(input_shape=(4,784))
model.summary()

optimizer = keras.optimizers.Adam(learning_rate=1e-3)

for step, x in enumerate(train_db):
    x = tf.reshape(x,[-1,784])
    with tf.GradientTape() as tape:
        xx = model(x)
        loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=x, logits=xx)
        loss = tf.reduce_mean(loss)

    grads = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))

    if step%100 == 0:
        print(step, 'loss: ', float(loss))

def save_images(imgs, name):
    new_im = Image.new('L', (280, 280))
    index = 0
    for i in range(0, 280, 28): # 10 行图片阵列
        for j in range(0, 280, 28): # 10 列图片阵列
            im = imgs[index]
            im = Image.fromarray(im, mode='L')
            new_im.paste(im, (i, j)) # 写入对应位置
            index += 1
    # 保存图片阵列
    new_im.save(name)


x = next(iter(test_db))
logits = model(tf.reshape(x, [-1,784]))
x_hat = tf.sigmoid(logits)
x_hat = tf.reshape(x_hat, [-1,28,28])

x_concat = tf.concat([x[:50], x_hat[:50]], axis=0)
x_concat = x_concat.numpy() * 255. 
x_concat = x_concat.astype(np.uint8)
save_images(x_concat,'10.png')

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用感知器进行手写数字识别的 MATLAB 代码: 1. 导入数据集 首先,需要导入 MINIST 数据集。这个数据集包含了很多手写数字的图像和对应的标签。可以通过以下代码导入: ```matlab load('mnist.mat'); % 导入 MINIST 数据集 ``` 2. 数据预处理 由于感知器只能接受一维向量作为输入,因此需要将每个手写数字图像转换为一维向量。同时,还需要将图像的像素值从 0-255 转换为 -1 到 1 之间的实数。可以通过以下代码实现: ```matlab % 将图像转换为一维向量 train_data = reshape(train_images, [], 784); test_data = reshape(test_images, [], 784); % 将像素值归一化到 -1 到 1 之间 train_data = double(train_data) / 127.5 - 1; test_data = double(test_data) / 127.5 - 1; ``` 另外,需要将标签转换为独热编码,以便在训练过程中使用。可以通过以下代码实现: ```matlab train_labels = zeros(60000, 10); test_labels = zeros(10000, 10); for i = 1:60000 train_labels(i, train_labels_raw(i) + 1) = 1; end for i = 1:10000 test_labels(i, test_labels_raw(i) + 1) = 1; end ``` 3. 定义感知器模型 感知器模型包括输入层、隐藏层和输出层。在这个例子中,输入层有 784 个神经元,隐藏层有 32 个神经元,输出层有 10 个神经元(分别对应 0-9 十个数字)。可以通过以下代码定义模型: ```matlab input_size = 784; % 输入层大小 hidden_size = 32; % 隐藏层大小 output_size = 10; % 输出层大小 % 初始化权重和偏置 W1 = randn(input_size, hidden_size) / sqrt(input_size); b1 = zeros(1, hidden_size); W2 = randn(hidden_size, output_size) / sqrt(hidden_size); b2 = zeros(1, output_size); % 定义前向传播函数 forward = @(x) softmax(x * W2 + b2); ``` 其中,softmax 函数用于将输出层的输出转换为概率分布。 4. 训练模型 可以使用随机梯度下降算法训练感知器模型。每次迭代时,从训练集中随机选择一个样本,计算前向传播和反向传播,然后更新权重和偏置。可以通过以下代码实现: ```matlab learning_rate = 0.1; % 学习率 batch_size = 32; % 批量大小 num_epochs = 10; % 迭代次数 num_batches = ceil(size(train_data, 1) / batch_size); for epoch = 1:num_epochs for batch = 1:num_batches % 选择一个随机批量 idx = randperm(size(train_data, 1), batch_size); x = train_data(idx, :); y = train_labels(idx, :); % 前向传播 hidden = tanh(x * W1 + b1); output = forward(hidden); % 反向传播 error = output - y; dW2 = hidden' * error; db2 = sum(error, 1); dhidden = (1 - hidden.^2) .* (error * W2'); dW1 = x' * dhidden; db1 = sum(dhidden, 1); % 更新权重和偏置 W2 = W2 - learning_rate * dW2; b2 = b2 - learning_rate * db2; W1 = W1 - learning_rate * dW1; b1 = b1 - learning_rate * db1; end % 在测试集上评估模型表现 hidden = tanh(test_data * W1 + b1); output = forward(hidden); [~, pred] = max(output, [], 2); accuracy = mean(pred == test_labels_raw); fprintf('Epoch %d, Accuracy: %f\n', epoch, accuracy); end ``` 5. 使用模型进行预测 训练完成后,可以使用模型进行预测。可以通过以下代码实现: ```matlab hidden = tanh(test_data * W1 + b1); output = forward(hidden); [~, pred] = max(output, [], 2); ``` 其中,`pred` 变量包含了模型在测试集上的预测结果。可以将其与真实标签进行比较,计算模型的准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪易

给我来点鼓励吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值