【deep learning】Theano文档学习

1. thenao中的共享共享变量总结:
import theano
import theano.tensor as T
from theano import function
from theano import shared
state = shared(200)  # 使用shared定义共享变量,初始化为200
inc = T.iscalar('inc')
# 定义累加器
accumulator = function([inc], state, updates=[(state, state+inc)])  # function(局部变量列表,共享变量,update参数), 其中update的形式为'(共享变量,新表达式)'
accumulator(2)    # 返回200, 即返回共享变量更新前的值'state=200'
state.get_value()    # 返回202, 即更新后的共享变量,'state+inc = 202'
# 定义'累减器'
decrementor = function([inc], state, updates=[(state, state-inc)])
decrementor(2)        # 返回202
state.get_value()      # 返回200
# theano.shared(value, name=None, strict=False, allow_downcast=None, **kwargs)

# 注意:有时候需要使用共享变量和做一些表达式,但是不想改变共享变来那个的值,此时可以在函数中使用‘givens’参数
fn_of_state = state * 2 + inc
foo = T.scalar(dtype=state.dtype)    # foo的数据类型必须与state一样,用于取代state
skip_shared  = function([inc, foo], fn_of_state, givens = [(state, foo)])
skip_shared(1,3)   # 返回7, inc + 2 * foo

2. AutoEncoder-Theano实现与测试

只需要更改参数,既可以使用最基本的autoencoder算法了,看考deeplearning.net网站

未优化版本如下:

import time

import numpy
import numpy.random as RandomState
from numpy import *

import theano
import theano.tensor as T
from theano.tensor.shared_randomstreams import RandomStreams  # theano中的随机数生成器工具

from operateFile import writeDataToFile
"""
其中参数input, W, bhid, bvis都是张量类型: theano.tensor.TensorType
设定随机数:numpy.random.RandomState; theano.tensor.shared_randomstreams.RandomStreams
如果最初没给权重W,则初始化为[-a, a]之间的均匀分布,numpy.random.RandomState.uniform(low, high, size)
"""
class AutoEncoder(object):
    def __init__(self, numpy_rng, input=None, n_visible=784, n_hidden=500, W=None, bhid=None, bvis=None):
        
        self.n_visible = n_visible
        self.n_hidden = n_hidden
        
        if not W:
            initial_W = numpy.asarray(numpy_rng.uniform(
                            low = -4 * numpy.sqrt(6. / (n_hidden + n_visible)),
                            high = 4 * numpy.sqrt(6. / (n_hidden + n_visible)), 
                            size = (n_visible, n_hidden)),
                            dtype = 'float64' )
            W = theano.shared(value = initial_W, name = 'W')     # 设置为共享变量
  
        if not bvis:
            bvis = theano.shared(value = numpy.zeros(n_visible, dtype = 'float64'), name='bvis')
        if not bhid:
            bhid = theano.shared(value = numpy.zeros(n_hidden, dtype = 'float64'), name='bhid')

        self.W = W
        self.b = bhid                           # b corresponds to the bias of the hidden (最后希望获得W和bhid)
        self.b_prime = bvis                     # b_prime 对应‘输入’层的偏置向量
        self.W_prime = self.W.T                 # tied weights, therefore W_prime is W transpose

        if input == None:
            self.x = T.dmatrix(name = 'input')  # TensorType variable: 2-dim matrix type
        else:
            self.x = input

        self.params = [self.W, self.b, self.b_prime]

    def get_hidden_values(self, input):
        return T.nnet.sigmoid(T.dot(input, self.W) + self.b)    # 返回隐层值

    def get_reconstructed_input(self, hidden):
        return T.nnet.sigmoid(T.dot(hidden, self.W_prime) + self.b_prime)
    
    # 将所有数据点(data point,样本),得到的损失函数是一个向量, axis=1 表示按照列计算
    # 上式得到的所有样本的重构误差之和,下面计算平均重构误差,实际的损失函数
    # 计算目标函数的梯度
    def get_cost_updates(self, learning_rate):
        
        y = self.get_hidden_values(self.x)
        z = self.get_reconstructed_input(y)

        L = - T.sum(self.x * T.log(z) + (1- self.x) * T.log(1-z), axis = 1)
        cost = T.mean(L)

        gparams = T.grad(cost, self.params)         # 张量数据类型,可以很方便的求梯度T.grad()
        '''
                        生成参数的更新列表, 实际中,可能没必要保存所有更新参数,只要最后一组即可,可改写
        return_param
        for param, gparam in zip(self.param, gparams):
            return_param = param - learning_rate * gparam
            del param, gparam
            gc.collect()
        '''
        # generate the list of updates
        updates = []                
        for param, gparam in zip(self.params, gparams):
            updates.append((param, param - learning_rate * gparam))

        return (cost, updates)      # 返回的是(损失代价,参数更新)

# 构造类AutoEncoder的实例
x = T.dmatrix('x')          
M = 10000
N = 2000
K = 1200
train_x = numpy.random.randn(M, N)
# 构建模型
autoencoder = AutoEncoder(numpy_rng = numpy.random.RandomState(1234), input = x, n_visible=N, n_hidden=K)
cost, updates = autoencoder.get_cost_updates(learning_rate = 0.1)
hidden = autoencoder.get_hidden_values(x)                           # 输出隐层值
construction = autoencoder.get_reconstructed_input(hidden) 

# 训练模型
startTime = time.time()
train_autoencoder = theano.function(inputs = [x], outputs = [cost, hidden, construction], updates = updates)
cost_value, hidden_value, construction_value = train_autoencoder(train_x)
endTime = time.time()

print 'shape(autoencoder.W):%s,\ttype(autoencoder.W):%s' % (shape(autoencoder.W.get_value()), type(autoencoder.W.get_value()))
print 'autoencoder.W.get_value():\n', autoencoder.W.get_value()[range(5), range(5)]

print 'type(train_autoencoder):', type(train_autoencoder)
print 'cost_value:', cost_value
print 'type(cost_value):', type(cost_value)

print 'shape(autoencoder.get_hidden_value(train_x)):', shape(hidden_value)
print 'shape(autoencoder.get_hidden_value(train_x)):', shape(construction_value)

writeDataToFile('E:/test_ctr/hidden.value.txt', hidden_value)
writeDataToFile('E:/test_ctr/construction_value.txt', construction_value)
print '程序运行时间:', (endTime - startTime)


你可能感兴趣的:(Deep,Learning,Python,数据挖掘/机器学习)