• Theano 学习一 初步使用


    Theano是深度学习较早的库之一,由深度学习三大先驱(Geoffrey Hinton(Google)、Yann LeCun(Facebook))的Yoshua Bengio构建。

    使用Python组织逻辑,C编译执行,CUDA并行加速计算,是非常好的实验平台。

    它的库源码中包含大量注释,并且提供深度学习的几个基本模型的代码实现文档。

    以下转自Physical的博文Theano深度学习结构分析

    Theano的一般结构
    
    Theano基于Python的面向对象,所以它的神经网络也是基于面向对象的思路去写的。
    
    【对象】
    
    它认为,浅层网络的中分类器,深度网络中的每个层,都是一个对象。
    
    在这个对象里,你被指定了输入格式,你只需要做两件事:
    
    根据格式,定义参数、定义输出。
    
     
    
    【数据读入/处理】
    
    从文件读入数据,并且对数据进行全局分享处理(shared)
    
    Theano中搞了一个奇怪的shared类型,Python的普通类型可以由theano.shared()方法转换。
    
    Shared区是供GPU、C代码使用的内存区,与Python的内存区独立,但是由Tensor变量联系着。
    
    这里就不得不提Theano的函数机制。theano.tensor中封装的着大量的惰性函数。
    
    这些惰性函数,在Python里是不会执行的。需要在theano.function()里执行。
    
    theano.function()有四大区:
    
    inputs=[], 如果只是一个普通的列表,就把输入放在这个参数。如果输入有很多,应该放在givens区里。inputs区不支持shared变量,所以也要挪到givens区。
    
    inputs在写function时基本是留空的,inputs=[],这个位置接受的是在线传入的值,如果是离线值,应当放到givens区里。
    
     
    
    outputs=普通函数or惰性函数,就是指定工作函数。
    
    这里有个trick,就是如何print出Tensor表达式的量(因为该量的值只会在执行时确定,不能使用get_value)。以取出Softmax的预测值y_pred为例。
    
    只要写这样一个function就行了,function(inputs=[],outputs=classifier.y_pred,givens={....自己指定范围...})。
    
     
    
    updates=参数更新的列表,格式[(原,新),(原,新)....],Shared区的变量只能在updates里更新,Python的中赋值只会让变量留在Python的内存区。
    
    但是在function的内存区和Python一点关系也每有。如果Python里设置一个Tensor关联一些Shared变量的话,Shared区的updates会波及到Python区的值。
    
    如CNN教程里的,params这个Tensor,明明在Python的全局内存区,但是每次update之后,都会被改变。
    
    也就是说Shared区能影响Python区,但是Python区无法动Shread区一根汗毛。
    
    givens={x:List1[:],y:List2[:],.....},其中x和y是outputs函数里使用的变量的名字,一定要对应,下面会讲为什么。
    
     
    
    theano.function()不是以Python的方式执行,而是迅速编译成C代码执行,相当于每个function都是一个独立的子程序,所以这四大区是必要的。
    
    由于是独立子程序,Python中的普通变量显然不能很好工作。所以一般都设成shared类型。
    
    实际上,tensor的不少惰性函数都需要在Python状态下的shared变量才能定义。原理未知。比如T.dot就不要求shared变量,但是grad的param一定要求是shared。
    
    由于Theano的大部分计算都在function里,而function又是以C执行,所以Theano具有不输于C的速度,同时兼具Python的灵活性。
    
     
    
    【主过程:前向传播构建&反向传播迭代】
    
    创建各个神经网络层、分类器的实例对象,由I/O首尾相连,最后利用分类器构建cost函数,完成前向传播。
    
    利用各个层对象的参数、cost函数,构建梯度表达式,以及updates列表。
    
    为训练集、验证集、测试集创建以theano.function()为壳的模型。
    
    使用mini-batch梯度法分批训练训练集,测试验证集&测试集。

    在之前的随笔(Softmax回归(使用theano)中使用了简单的theano功能,提高了速度使得短时间内只能训练5000个到训练50000个mnist数据。

    使用到的函数包括:

    # T.matrix 分配给矩阵(matrix)”
    x = T.matrix('x')  
    # T.ivector 分配给“int类型(i)的向量(vector)”
    y = T.ivector('y')  
    # T.lscalar 分配给“long类型(l)的标量(scalar)”
    index = T.lscalar()  
    # theano.shared将数据转化为theano.shared类型, T.cast将数据从float转成int32
    label = T.cast(theano.shared(np.asarray(label, dtype=theano.config.floatX)), 'int32')
    # T.mean 获取均值
    cost = -T.mean(T.log(hx)[T.arange(y.shape[0]), y]) + 0.5 * self.landa * T.sum(theta ** 2)  
    # T.argmax 获取最大值的序列
    predict = T.argmax(hx, axis=1)
    hx = T.nnet.softmax(T.dot(x, theta))
    g_theta = T.grad(cost, theta)

    对于T.nnet.softmax,之前不使用theano时的实现如下:

    def h(self, x):
        m = np.exp(np.dot(x, self.theta.T))
         sump = np.sum(m, axis=1)
        return m / sump

    theano中将T.nnet.softmax定义为一个类,除了上述计算,还有用于求导的grad部分以及一些c代码。softmax_grad又用了另一个类来实现。

        def perform(self, node, input_storage, output_storage):
            x, = input_storage
            e_x = numpy.exp(x - x.max(axis=1)[:, None])
            sm = e_x / e_x.sum(axis=1)[:, None]
            output_storage[0][0] = sm
        def grad(self, inp, grads):
            x, = inp
            g_sm, = grads
            sm = softmax_op(x)
            return [softmax_grad(g_sm, sm)]
    
    

    T.grad将在下一篇随笔中进行理解。

  • 相关阅读:
    自定义“浏览文件夹”对话框
    CYABFFW:这是另一个文件夹包装器
    CYABFFW:这是另一个文件夹包装器
    ToDoList样式表:教程
    7.2.23 -一个有效而灵活的方法来掌握你的任务
    使用。net SDK编写位图按钮控件
    在MVC应用程序中使用自动程序进行CRUD操作
    imp
    openpyxl
    fabric
  • 原文地址:https://www.cnblogs.com/qw12/p/6213056.html
Copyright © 2020-2023  润新知