1TensorFlow实现自编码器-1.3 TensorFlow实现降噪自动编码器--计算图美化

这里写图片描述

import numpy as np
import sklearn.preprocessing as prep
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# Xvaier均匀初始化
# fan_in是输入节点的数量,fan_out是输出节点的数量。
def xavier_init(fan_in, fan_out, constant=1):
    low = -constant * np.sqrt(6.0 / (fan_in + fan_out))
    high = constant * np.sqrt(6.0 / (fan_in + fan_out))
    return tf.random_uniform((fan_in, fan_out), minval=low, maxval=high, dtype=tf.float32)

# 加性高斯噪声的自动编码
class AdditiveGaussianNoiseAutoencoder(object):
    # 在初始的数据中加入高斯噪声。在实现降噪自编码器的时候,
    # 只是在输入加进去的时候,在输入上加上高斯噪声就行
    # 其他的部分和基本自编码器一样
    # n_input:输入变量数;n_hidden:隐含层节点数;transfer_function:隐含层激活函数;optimizer:优化器;scale:高斯噪声系数;
    # Class内的scale声明成一个占位符placeholder,参数初始化则使用了接下来定义的_initialize_weights函数。我们只用了一个隐含层。
    def __init__(self, n_input, n_hidden, transfer_function=tf.nn.softplus, optimizer=tf.train.AdamOptimizer(),scale=0.1):
        self.n_input = n_input
        self.n_hidden = n_hidden
        # n_input,n_hidden都是输入和隐藏层的维度
        self.transfer = transfer_function
        # self.scale = tf.placeholder(tf.float32)
        self.training_scale = scale
        # scale 就是一个标量
        network_weights = self._initialize_weights()
        self.weights = network_weights

        # model
        with tf.name_scope("RawInput"):
            self.x = tf.placeholder(tf.float32, [None, self.n_input])
        # none不给定具体的值,它由输入的数目来决定

        with tf.name_scope("NoiseAdder"):
            self.scale = tf.placeholder(tf.float32)
            self.noise_x = self.x + self.scale * tf.random_normal((n_input,))

        with tf.name_scope("Encoder"):
            self.hidden = self.transfer(tf.add(tf.matmul(self.noise_x,self.weights['w1']), self.weights['b1']))
        # 在输入的时候,在输入的数据上加上一些高斯噪声,
        # tf.random_normal((n_input,)) 默认给的是一个均值为0,标准差是1的正态分布的随机数。

        with tf.name_scope("Reconstruction"):
            self.reconstruction = tf.add(tf.matmul(self.hidden, self.weights['w2']), self.weights['b2'])

        # x:一维的数量为n_input的placeholder;
        # 建立一个能提取特征的隐含层:
        # 先对输入x添加高斯噪声,即self.x + scale * tf.random_normal((n_input,));
        #  再用tf.matmul()让被噪声污染的信号与隐藏层的权重相乘,再用tf.add()添加偏置;
        # 最后使用transfer()对加权汇总结果进行激活函数处理。

        # 经过隐藏层后,在输出层进行数据复原和重建操作,即建立reconstruction层,这时候就不需要激活函数了,
        # 直接将隐含层的输出self.hidden乘以输出层的权重w2再加上输出层的偏置b2。

        # cost
        with tf.name_scope("Loss"):
            self.cost = 0.5 * tf.reduce_sum(tf.pow(tf.subtract(self.reconstruction, self.x), 2.0))

        with tf.name_scope("Train"):
            self.optimizer = optimizer.minimize(self.cost)

        init = tf.global_variables_initializer()
        self.sess = tf.Session()
        self.sess.run(init)
        print("begin ti run session...")


    def _initialize_weights(self):
        all_weights = dict()
        all_weights['w1'] = tf.Variable(xavier_init(self.n_input, self.n_hidden),name='weight1')
        # 在初始化的时候,就只是第一个权重矩阵是赋予一些随机值,其他的都是赋予全0矩阵
        all_weights['b1'] = tf.Variable(tf.zeros([self.n_hidden], dtype=tf.float32),name='bias1')
        all_weights['w2'] = tf.Variable(tf.zeros([self.n_hidden, self.n_input], dtype=tf.float32),name='weight2')
        all_weights['b2'] = tf.Variable(tf.zeros([self.n_input], dtype=tf.float32),name='bias2')
        return all_weights
    #变量初始化函数:创建一个dicts,包含所有Variable类型的变量w1,b1,w2,b2
    #隐藏层:w1用前面写的xavier_init函数初始化,传入输入节点数和隐含节点数,即可得到一个比较适合softplus等激活函数的初始状态,b1初始化为0

#产生一个AdditiveGaussianNoiseAutoencoder类的对象实例,调用tf.summary.FileWriter把计算图写入文件,使用TensorBoard查看
AGN_AC = AdditiveGaussianNoiseAutoencoder(n_input=784,n_hidden=200,transfer_function=tf.nn.softplus,
                                          optimizer=tf.train.AdamOptimizer(learning_rate=0.01),scale=0.01)

print('把计算图写入事件文件,在TensorBoard里面查看')
writer = tf.summary.FileWriter(logdir='logs',graph=AGN_AC.sess.graph)
writer.close()
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
降噪自编码器是一种无监督学习算法,用于学习输入数据的低维表示。它通过在输入数据中引入噪声,并尝试从噪声数据中重构原始输入数据来训练模型。以下是一个简单的降噪自编码器的C语言实现示例: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #define INPUT_SIZE 10 #define HIDDEN_SIZE 5 #define OUTPUT_SIZE 10 #define LEARNING_RATE 0.01 #define EPOCHS 1000 // 定义降噪自编码器的结构体 typedef struct { double input[INPUT_SIZE]; double hidden[HIDDEN_SIZE]; double output[OUTPUT_SIZE]; double weights_ih[INPUT_SIZE][HIDDEN_SIZE]; double weights_ho[HIDDEN_SIZE][OUTPUT_SIZE]; } Autoencoder; // 初始化降噪自编码器的权重 void initialize_weights(Autoencoder *ae) { for (int i = 0; i < INPUT_SIZE; i++) { for (int j = 0; j < HIDDEN_SIZE; j++) { ae->weights_ih[i][j] = ((double)rand() / RAND_MAX) * 2 - 1; } } for (int i = 0; i < HIDDEN_SIZE; i++) { for (int j = 0; j < OUTPUT_SIZE; j++) { ae->weights_ho[i][j] = ((double)rand() / RAND_MAX) * 2 - 1; } } } // 前向传播 void forward(Autoencoder *ae) { // 计算隐藏层输出 for (int i = 0; i < HIDDEN_SIZE; i++) { double sum = 0.0; for (int j = 0; j < INPUT_SIZE; j++) { sum += ae->input[j] * ae->weights_ih[j][i]; } ae->hidden[i] = 1.0 / (1.0 + exp(-sum)); } // 计算输出层输出 for (int i = 0; i < OUTPUT_SIZE; i++) { double sum = 0.0; for (int j = 0; j < HIDDEN_SIZE; j++) { sum += ae->hidden[j] * ae->weights_ho[j][i]; } ae->output[i] = 1.0 / (1.0 + exp(-sum)); } } // 反向传播 void backward(Autoencoder *ae) { // 计算输出层误差 double output_errors[OUTPUT_SIZE]; for (int i = 0; i < OUTPUT_SIZE; i++) { output_errors[i] = ae->input[i] - ae->output[i]; } // 更新隐藏层到输出层的权重 for (int i = 0; i < HIDDEN_SIZE; i++) { for (int j = 0; j < OUTPUT_SIZE; j++) { ae->weights_ho[i][j] += LEARNING_RATE * ae->hidden[i] * output_errors[j] * ae->output[j] * (1.0 - ae->output[j]); } } // 更新输入层到隐藏层的权重 for (int i = 0; i < INPUT_SIZE; i++) { for (int j = 0; j < HIDDEN_SIZE; j++) { double sum = 0.0; for (int k = 0; k < OUTPUT_SIZE; k++) { sum += output_errors[k] * ae->weights_ho[j][k]; } ae->weights_ih[i][j] += LEARNING_RATE * ae->input[i] * ae->hidden[j] * (1.0 - ae->hidden[j]) * sum; } } } // 训练降噪自编码器 void train(Autoencoder *ae, double input_data[][INPUT_SIZE], int num_samples) { for (int epoch = 0; epoch < EPOCHS; epoch++) { for (int sample = 0; sample < num_samples; sample++) { // 添加噪声到输入数据 for (int i = 0; i < INPUT_SIZE; i++) { ae->input[i] = input_data[sample][i] + ((double)rand() / RAND_MAX) * 0.1 - 0.05; } // 执行前向传播和反向传播 forward(ae); backward(ae); } } } int main() { Autoencoder ae; initialize_weights(&ae); // 假设有一些输入数据用于训练 double input_data[][INPUT_SIZE] = { {0, 1, 1, 0, 0, 0, 0, 1, 1, 0}, {1, 1, 1, 1, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 1, 1, 1, 1, 0, 0, 0} }; int num_samples = sizeof(input_data) / sizeof(input_data[0]); // 训练降噪自编码器 train(&ae, input_data, num_samples); // 测试降噪自编码器 double test_input[INPUT_SIZE] = {0, 1, 1, 0, 0, 0, 0, 1, 1, 0}; for (int i = 0; i < INPUT_SIZE; i++) { ae.input[i] = test_input[i]; } forward(&ae); // 打印输出结果 printf("Input: "); for (int i = 0; i < INPUT_SIZE; i++) { printf("%.2f ", ae.input[i]); } printf("\nOutput: "); for (int i = 0; i < OUTPUT_SIZE; i++) { printf("%.2f ", ae.output[i]); } printf("\n"); return 0; } ``` 这是一个简单的降噪自编码器的C语言实现示例,其中包括了初始化权重、前向传播、反向传播和训练过程。你可以根据自己的需求进行修改和扩展。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值