theano学习笔记

theano

 一、搭建环境   

    安装:pip install theano==0.9.0

    卸载:pip uninstall theano
    查看版本号:import theano
                theano.__version__
    设置gpu\cpu:
        方法1:vim /root/.theanorc
                [global]
                model=FAST_RUN    (该模式运行速度快)
                device=cuda1 (或者gpu或cpu)
                floatX=float32
                [blas]
                ldflags=-L/usr/lib/libblas.so

        方法2:
            THEANO_FLAGS=mode=FAST_RUN,device=cuda,floatX=float32 python test_new.py
        备注:theano0.9以上版本,使用gpu新后端,device=gpu或cpu或cuda(新后端)
            #test_theano_gpu.py测试gpu/cpu,https://www.cnblogs.com/shouhuxianjian/p/4590224.html
            THEANO_FLAGS=mode=FAST_RUN,device=cuda,floatX=float32 python test_theano_gpu.py        
                (float32, (False,))>    使用cpu
            THEANO_FLAGS=mode=FAST_RUN,device=cpu,floatX=float32 python test_theano_gpu.py
                    使用cpu
            THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python test_theano_gpu.py
                    使用gpu
                
    tensorflow和theano同时要使用GPU,如何设置?
        如果.theanorc中device设置为gpu,那么tensorflow将无法使用GPU;
        如果.theanorc中device设置为cuda,那么theano在第二次调用中将无法使用GPU;
        因此,如果tensorflow和theano同时要使用GPU,.theanorc中device必须设置为cuda,而且指明哪一个cuda。如上面的device=cuda1。
        与此同时,tensorflow不需要特别指定GPU。

    pygpu安装:
        git clone https://github.com/Theano/libgpuarray.git
        cd libgpuarray
        mkdir Build
        cd Build
        cmake .. -DCMAKE_BUILD_TYPE=Release
        make
        make install
        cd ..
        python setup.py build
        python setup.py install    
        sudo ldconfig
        备注有测试过pygpu==0.6.5与theano==0.9.0 或者pygpu==0.7.5与theano==1.0.0 OK.
            pygpu版本如果为0.65,那么theano必须为0.9。如果为1.0,不兼容。无法成功import theano。
            pygpu版本如果为0.75,那么theano必须为1.0。如果为0.9,不兼容。无法正常初始化pygpu。
    
    例子:DeepAlgnmentNetwork: theano==0.9.0
        error:immporting theano: AttributeError: 'module' object has no attribute 'find_graphviz'
        解决方案:sudo pip uninstall -y pydot 或者 pip install pydot-ng        
        安装lasagne:https://github.com/Lasagne/Lasagne  (深度框架)
            pip install https://github.com/Lasagne/Lasagne/archive/master.zip
        pip install theano==0.9.0
        安装pygpu

   

二、基本用法:

    theano.tensor常用数据类型:
        有double、int、uchar、float等,float是因为GPU一般是float32类型.
        数值:iscalar(int32)、fscalar(float32)、wscalar(int16)、bscalar(int8)、lscalar(int64)
                a = T.scalar() #print (a.dtype) #float32
        一维向量:ivector(int 类型的向量)、fvector(float类型的向量)、
        二维矩阵:fmatrix(float类型矩阵)、imatrix(int类型的矩阵)
        三维float类型矩阵:ftensor3  
        四维float类型矩阵:ftensor4 #tensor5、tensor6、tensor7

        例子:theano.tensor.tensor3(name=None, dtype=config.floatX) #数据类型最好一致,不然会出错


    theano.tensor常用函数:
        x=theano.tensor.iscalar('x',dtype='int32')    #声明一个int类型的变量x  
        y=theano.tensor.pow(x,3)                          #定义y=x^3  
        y1= 1 / (1 + theano.tensor.exp(-x))
        f=theano.function([x],y)                       #定义函数的自变量为x(输入),因变量为y(输出)
        print (f(2))                       #8    
        dx=theano.grad(y,x)             #偏导数函数 

   共享变量:

        共享变量是多线程编程中的一个名词,故名思议就是各线程,公共拥有的变量,这个是为了多线程高效计算、
        访问而使用的变量。
        w= theano.shared(1)    #定义一个共享变量w,其初始值为1  
        print (x.get_value())     #取值

        x.set_value(2)             #设置数值


    theano.tensor的层及函数:import theano.tensor as T
        T.nnet:conv2d、softmax、
        T: T.mean、log、pow、exp、dot、argmax、tanh、grad、
        T.signal.downsample.max_pool_2d:池化操作

   

保存、加载模型:#import pickle
        #save model
        with open("model.pickle", "wb") as file:
            model = [w.get_value(), b.get_value()] #或写成字典的形式
            pickle.dump( model, file )
            print (model[0][:10]) #打印w的前10个数值
        #load model
        with open("model.pickle", "rb") as file:
            model = pickle.load( file )
            w.set_value( model[0] )
            b.set_value( model[1] )
            print ( w.get_value()[:10] ) #打印w的前10个数值


    lasagne:https://github.com/Lasagne/Lasagne  (theano自己的深度框架)
            http://lasagne.readthedocs.io/en/latest/index.html (手册)
        pip install -r https://raw.githubusercontent.com/Lasagne/Lasagne/master/requirements.txt (卸载)
        pip install https://github.com/Lasagne/Lasagne/archive/master.zip (安装)
        备注:batch_norm()函数存储的参数是beta、gamma、mean、inv_std共四个参数。
            # normalize
            normalized = (input - mean) * (gamma * inv_std) + beta
        
        #层:
        lasagne.layers:
            #DenseLayer、DropoutLayer、InputLayer、Conv2DLayer、MaxPool2DLayer、
            get_all_params、get_output、set_all_param_values、get_all_param_values
        lasagne.updates
        lasagne.init
        lasagne.nonlinearities
        lasagne.objectives
        lasagne.regularization
        lasagne.random
        lasagne.utils

        lasagne.layers.DenseLayer(DropoutLayer、InputLayer、Conv2DLayer、MaxPool2DLayer、
                                get_all_params、get_output、set_all_param_values、get_all_param_values)
        lasagne.nonlinearities.rectify(softmax、tanh、relu)  #激活函数
        W=lasagne.init.GlorotUniform() #权值初始化
        loss = lasagne.objectives.categorical_crossentropy(prediction, target_var)
        
    手写字识别例子:
        可以参考lasagne 源码给的mnist.py例子,主要代码如下:
        import numpy as np
        import theano
        import theano.tensor as T
        import lasagne
        import sys,os
        
        def load_dataset():
            if sys.version_info[0] == 2:    # Python 2
                from urllib import urlretrieve
            else:                            # Python 3
                from urllib.request import urlretrieve

            def download(filename, source='http://yann.lecun.com/exdb/mnist/'):
                print("Downloading %s" % filename)
                urlretrieve(source + filename, filename)

            import gzip
            def load_mnist_images(filename): #下载图片
                if not os.path.exists(filename):
                    download(filename)
            
                with gzip.open(filename, 'rb') as f:
                    data = np.frombuffer(f.read(), np.uint8, offset=16)
                data = data.reshape(-1, 1, 28, 28)  #(None, channels, rows, columns)
            return data / np.float32(256)
            
            def load_mnist_labels(filename):    #下载标签
                if not os.path.exists(filename):
                    download(filename)
                with gzip.open(filename, 'rb') as f:
                    data = np.frombuffer(f.read(), np.uint8, offset=8)
                return data
            
            #下载数据        
            X_train = load_mnist_images('train-images-idx3-ubyte.gz')
            y_train = load_mnist_labels('train-labels-idx1-ubyte.gz')
            X_test = load_mnist_images('t10k-images-idx3-ubyte.gz')
            y_test = load_mnist_labels('t10k-labels-idx1-ubyte.gz')
            
            #最后10000个用于预测
            X_train, X_val = X_train[:-10000], X_train[-10000:]
            y_train, y_val = y_train[:-10000], y_train[-10000:]
            return X_train, y_train, X_val, y_val, X_test, y_test
        
        #构建网络模型
        def build_cnn(input_var=None):
            network = lasagne.layers.InputLayer(shape=(None, 1, 28, 28),input_var=input_var)
            network = lasagne.layers.Conv2DLayer(network, num_filters=32, filter_size=(5, 5),
                    nonlinearity=lasagne.nonlinearities.rectify,W=lasagne.init.GlorotUniform())
            network = lasagne.layers.MaxPool2DLayer(network, pool_size=(2, 2))
            network = lasagne.layers.Conv2DLayer(network, num_filters=32, filter_size=(5, 5),
                    nonlinearity=lasagne.nonlinearities.rectify)
            network = lasagne.layers.MaxPool2DLayer(network, pool_size=(2, 2))
            network = lasagne.layers.DenseLayer(lasagne.layers.dropout(network, p=.5),
                        num_units=256,nonlinearity=lasagne.nonlinearities.rectify)
            network = lasagne.layers.DenseLayer(lasagne.layers.dropout(network, p=.5),
                        num_units=10,nonlinearity=lasagne.nonlinearities.softmax)
            return network
        
        def main(num_epochs=500):
            #加载数据
            X_train, y_train, X_val, y_val, X_test, y_test = load_dataset()
            
            # 定义 Theano variables for inputs and targets
            input_var = T.tensor4('inputs')
            target_var = T.ivector('targets')
            
            network = build_cnn(input_var) #构建网络模型
            
            prediction = lasagne.layers.get_output(network) #网络返回结果
            #定义交叉商

            loss = lasagne.objectives.categorical_crossentropy(prediction, target_var)
            loss = loss.mean() # batch_size个数据的均值
            
            #要学习的网络参数
            params = lasagne.layers.get_all_params(network, trainable=True)
            #网络学习过程中梯度下降的方式
            updates = lasagne.updates.nesterov_momentum(loss, params, learning_rate=0.01, momentum=0.9)
            
            #预测deterministic=True是进行一次前向传播,禁用dropout
            test_prediction = lasagne.layers.get_output(network, deterministic=True)
            test_loss = lasagne.objectives.categorical_crossentropy(test_prediction,target_var)
            test_loss = test_loss.mean()
            test_acc = T.mean(T.eq(T.argmax(test_prediction, axis=1), target_var),dtype=theano.config.floatX)
            
            #主要函数
            train_fn = theano.function([input_var, target_var], loss, updates=updates)
            val_fn = theano.function([input_var, target_var], [test_loss, test_acc])
            
            #开始训练
            for epoch in range(num_epochs):
                train_err = 0
                train_batches = 0    #iterate_minibatches()函数要自己写
                for batch in iterate_minibatches(X_train, y_train, 500, shuffle=True):
                    inputs, targets = batch
                    train_err += train_fn(inputs, targets)
                    train_batches += 1
            
            #测试
            test_err = 0
            test_acc = 0
            test_batches = 0
            for batch in iterate_minibatches(X_test, y_test, 500, shuffle=False):
                inputs, targets = batch
                err, acc = val_fn(inputs, targets)
                test_err += err
                test_acc += acc
                test_batches += 1
                
            #保存模型参数
            np.savez('model.npz', *lasagne.layers.get_all_param_values(network))
            #加载模型参数
            with np.load('model.npz') as f:
                param_values = [f['arr_%d' % i] for i in range(len(f.files))]
            lasagne.layers.set_all_param_values(network, param_values)
            
            备注:
                参数存储:

                    net = {}
                    net['input'] = lasagne.layers.InputLayer(shape=(None,nChannels=1,h=112,w=112), input_var=self.data)        
                    print("Input shape: {0}".format(net['input'].output_shape)) #(None, 1, 112, 112)
                    net['s1_conv1_1'] = batch_norm(Conv2DLayer(net['input'], 64, 3, pad='same', W=GlorotUniform('relu')))                         
                        #(None, 64, 112, 112)
                            0 (64, 1, 3, 3) #'s1_conv1_1',1是上一层的卷积核个数
                            1 (64,) #以下4个是存储batch_norm中的beta、gamma、mean、std
                            2 (64,)    
                            3 (64,)
                            4 (64,)
                    # batch_norm  normalize
                    normalized = (input - mean) * (gamma * inv_std) + beta
                numpy(save、load):    
                    如果你想将多个数组保存到一个文件中的话,可以使用numpy.savez函数。
                    savez函数的第一个参数是文件名,其后的参数都是需要保存的数组,
                    也可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为arr_0,
                    arr_1, …。savez函数输出的是一个压缩文件(扩展名为npz),其中每个文件都是一个
                    save函数保存的npy文件,文件名对应于数组名。load函数自动识别npz文件,并且返回一个
                    类似于字典的对象,可以通过数组名作为关键字获取数组的内容:
                    C=np.array([1,0,1,0])
                    np.savez("files.npz",A,B,C_array=C)
                    D=np.load("files.npz")
                    >>D['arr_0']
                    >>D['arr_1']

                    >>D['C_array']



你可能感兴趣的:(theano)