【theano-windows】学习笔记十二——卷积神经网络

前言

按照进度, 学习theano中的卷积操作

国际惯例, 来一波参考网址

Convolutional Neural Networks (LeNet)

卷积神经网络如何应用在彩色图像上?

卷积小知识

三大特性:局部感知(稀疏连接), 权值共享, 池化

这里写图片描述

上图很重要, 描述的是前一个隐层m-1具有四个特征图, 第m个隐层具有两个特征图, 四个权重框代表的是第m-1层的所有特征图与第m层的第一个特征图的连接,注意前一层的所有特征图与后一层第二个特征图的权重并没有画出来, 所以说, 由第m-1层映射到第m层, 总共需要4*2=8个不同的权重矩阵, 而不是四个.

代码实现

前面折腾过各种函数,其中就有conv2d, 然后我们就用它来尝试一下2D卷积,需要注意的是定义的输入、输出、卷积核矩阵它们每个维度都代表什么,详细可以戳我前面的【theano-windows】学习笔记十一——theano中与神经网络相关函数, 这里也写一下:

对于输入:是一个4D张量,分别代表 [批大小,输入特征数(即通道数),图像高度,图像宽度]

对于卷积核: 是一个4D张量,分别代表(第m层的特征图数目,第m1层的特征图数目,卷积核高,卷积核宽)

无反向传播的卷积网络

其实这个代码与第一篇关于theano的博客一样,戳这里

写一遍便于理解, 顺序就是

  • 定义输入张量

    import theano
    import theano.tensor as T
    import numpy as np#随机数种子初始化rng=np.random.RandomState(23455)
    input=T.tensor4(name='input')#定义输入张量
  • 初始化权重张量

    
    #初始化权重张量w_shp=(2,3,9,9)#下一层两个特征图,上一层三个特征图,卷积核大小9*9
    w_bound=np.sqrt(3*9*9)
    W=theano.shared(np.asarray(rng.uniform(low=-1.0/w_bound,high=1.0/w_bound,size=w_shp),dtype=input.dtype),name='W')
  • 初始化偏置张量

    
    #初始化偏置,如果需要训练,一般设置为0,此处模仿训练好的偏置b_shp=(2,)
    b=theano.shared(np.asarray(rng.uniform(low=-.5,high=.5,size=b_shp),dtype=input.dtype),name='b')
  • 卷积并用sigmoid激活

    
    #卷积操作conv_out=T.nnet.conv2d(input,W)#用sigmoid激活output=T.nnet.sigmoid(conv_out+b.dimshuffle('x',0,'x','x'))
  • 丢入到function中供后续使用

    
    #整个操作的函数f=theano.function([input],output)
  • 读取并处理图片:需要注意的是图片必须改成(批大小,通道,高,宽)

    
    ############################注意事项#################################### 图片的原始数据是一个3D数据【高,宽,通道数量】,      # 经过数据置换(transpose(2,0,1))之后,变成了【通道数量,高,宽】,      # 因为f中传入参数需要4D,因此需要将图片数据reshape成为一个【1, 通道数量, 高, 宽】这样的4D张量,      # reshape的参数一定要注意,1就是最外的那一维度,3就是通道数量,然后是【高】和【宽】,      # 这样结果的 img_.shape =【1, 3, 宽, 高】     #    # 为什么reshape为这样的size呢?因为调用f时需要传入一个input,而这个input就是4D,最终的这个input是传入到      # conv2d中的第一个参数,而那个参数的格式是什么呢?[mini-batch size,特征图的数量,图像高度,图像宽度]    # 这样就串起来了吧,第一个参数是batch size,据我所知应该是指卷积核的数量吧,但是不知道为什么这里是1?    # 第二个参数代表输入层的特征图数量,这个地方是3,其实就是把一张彩色图片按照3个通道作为3个特征图进行输入;    # 最后两个是图像的高度和宽度,正好一一对应。     
    
    
    #使用此函数对一张图片进行操作import pylab
    from PIL import Imageimg = Image.open('F:\\Photo\\2.jpg')#读取图片
    img_w,img_h=img.size#图像的宽和高
    img=np.asarray(img,dtype=input.dtype)/256.
    img_=img.transpose(2,0,1).reshape(1,3,img_h,img_w)
    filtered_img=f(img_)

    可视化结果

    pylab.subplot(1,3,1);pylab.axis('off');pylab.imshow(img)
    pylab.gray();
    pylab.subplot(1,3,2);pylab.axis('off');pylab.imshow(filtered_img[0,0,:,:])
    pylab.subplot(1,3,3);pylab.axis('off');pylab.imshow(filtered_img[0,1,:,:])
    pylab.show()

这里写图片描述

最大值池化

是卷积中非常重要的非线性下采样方法,它将图像分成不重叠的块,对每一块选择最大值输出

两个理由告诉你为什么最大值池化重要:

  • 通过消除非极大值,可以降低高层的计算
  • 提供了平移不变性, 图像中的每个像素就有8个平移自由度, 如果将最大值池化级联到卷积层,假设是2*2的池化区域, 8种平移可能有3个相同结果, 但是如果用3×3的池化区域,就可能有5种相同结果(这个原因还在探索中)

函数调用格式是:

theano.tensor.signal.pool.pool_2d(input, ws=None, ignore_border=None, stride=None, pad=(0, 0), mode='max', ds=None, st=None, padding=None)

参数说明:

  • input: N维的图片输入张量
  • ws:长度为2的元组, 缩减因子,在每个维度上将图像减半
  • ignore_border: 若为true, 则(5,5)的输入经过ws=(2,2)得到(2,2)的输出, 否则是(3,3)的输出
  • stride:步长, 池化操作在行/列上移动的长度,如果是None,那么与ws相同
  • pad:两个int型元组,或者两个int型的theano向量,大小为2, 用于填充图像的四个边界,第一个是上下填充大小, 第二个是左右填充大小
  • mode是每个池化窗口的操作方法,包括max,’sum’,’average_inc_pad’,’average_exc_pad’
  • ds,st,padding丢弃使用了,分别用ws,stride,pad代替

此处我们就不用官方的例子了,直接把上面的图片进行池化操作:

import theano
import theano.tensor as T
import numpy as np
import pylab
from PIL import Image
#随机数种子初始化
rng=np.random.RandomState(23455)
input=T.dtensor4(name='input')#定义输入张量
img = Image.open('F:\\Photo\\2.jpg')#读取图片
img_w,img_h=img.size#图像的宽和高
img=np.asarray(img,dtype=input.dtype)/256.
img_=img.transpose(2,0,1).reshape(1,3,img_h,img_w)
maxpool_shape=(2,2)
pool_out=T.signal.pool.pool_2d(input,maxpool_shape,ignore_border=False)
f_pool=theano.function([input],pool_out)
pool_img=f_pool(img_)
img_pool=pool_img[0,:,:,:].transpose(1,2,0)print img.shape
print img_pool.shapepylab.subplot(1,2,1);pylab.axis('off');pylab.imshow(img)
pylab.subplot(1,2,2);pylab.axis('off');pylab.imshow(img_pool)
pylab.show()

输出

这里写图片描述

上述程序一定要注意定义的容器input的数据类型,我刚开始写的程序如下:

#错误写法
import theano
import theano.tensor as T
import numpy as np
import pylab
from PIL import Image
#随机数种子初始化
rng=np.random.RandomState(23455)
input=T.tensor4(name='input')#定义输入张量
img = Image.open('F:\\Photo\\2.jpg')#读取图片
img_w,img_h=img.size#图像的宽和高
img=np.asarray(img,dtype=input.dtype)/256.
img_=img.transpose(2,0,1).reshape(1,3,img_h,img_w)
maxpool_shape=(2,2)
pool_out=T.signal.pool.pool_2d(input,maxpool_shape,ignore_border=False)
f_pool=theano.function([input],pool_out)
print input.dtype#float32
print img_.dtype#float32
pool_img=f_pool(img_)
img_pool=pool_img[0,:,:,:].transpose(1,2,0)print img.shape
print img_pool.shapepylab.subplot(1,2,1);pylab.axis('off');pylab.imshow(img)
pylab.subplot(1,2,2);pylab.axis('off');pylab.imshow(img_pool)
pylab.show()

虽然我们的input容器和img输入都是float32,但是不知道为什么一直出现下列错误:

ValueError: GpuDownsampleFactorMax: last dimention size of 600 is bigger then 512. This case is not implemented.
Apply node that caused the error: GpuDownsampleFactorMax{(2, 2),False}(GpuFromHost.0)
Toposort index: 1
Inputs types: [CudaNdarrayType(float32, 4D)]
Inputs shapes: [(1, 3, 800, 1200)]
Inputs strides: [(0, 960000, 1200, 1)]
Inputs values: ['not shown']
Outputs clients: [[HostFromGpu(GpuDownsampleFactorMax{(2, 2),False}.0)]]HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizations can be disabled with 'optimizer=None'.
HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node.

网上的解释戳这里,它的意思是池化以后的矩阵的最后一个维度(第四个维度)不支持大于512的维度,建议翻转一下后两个维度. 但是如果我们的图片长宽都大于1024,那么翻转就没用了,这时候只要把input容器变成dtensor,而非tensor就可以运行了,很神奇,卡了我好几个小时, 原理在于dtensor是在CPU上运行, 而CPU的内存交换没有GPU那么小,tensor是运行在GPU上的.

另一种可以处理任意维度的数据的方法是使用theano.sandbox.cuda.dnn.dnn_pool,详细介绍戳这里, 代码如下

#错误写法
import theano
import theano.tensor as T
import numpy as np
import pylab
from PIL import Image
#random seeds
rng=np.random.RandomState(23455)
input=T.tensor4(name='input',dtype=theano.config.floatX)#input tensor# img = Image.open('F:\\Photo\\2.jpg')#read image
# img_w,img_h=img.size# with and height of the image
# img=np.asarray(img,dtype=theano.config.floatX)/256. #normalize
# img_=img.transpose(2,0,1).reshape(1,3,img_h,img_w) #reshape for inputimg=np.random.RandomState(1).rand(5000, 5000,3)
img_=np.asarray(img,dtype=theano.config.floatX)
img_=img.transpose(2,0,1).reshape(1,3,img_.shape[0],img_.shape[1])
img_=np.asarray(img_,dtype=theano.config.floatX)print img_.shape
maxpool_shape=(2,2)
# pool_out=T.signal.pool.pool_2d(input,maxpool_shape,ignore_border=False)#limited by 512
pool_out=theano.sandbox.cuda.dnn.dnn_pool(input,maxpool_shape)# non-limitedf_pool=theano.function([input],pool_out)
print input.dtype#float32
print img_.dtype#float32
pool_img=f_pool(img_)pool_img=np.asarray(pool_img,dtype=theano.config.floatX)
img_pool=pool_img[0,:,:,:].transpose(1,2,0)print img.shape
print img_pool.shapepylab.subplot(1,2,1);pylab.axis('off');pylab.imshow(img)
pylab.subplot(1,2,2);pylab.axis('off');pylab.imshow(img_pool)
pylab.show()

Lenet分类模型

模型结构如下:

这里写图片描述

如此就可以按照顺序依次搭建: 卷积+池化, 全连接+中间隐层, softmax

读数据

这个没什么好说的,跟前面博客一样, 重点是记得把数据放入到共享区域

#引入相关库
import theano
import theano.tensor as T
import numpy as np
import os 
import cPickle,gzip
import timeit#定义读数据的函数,把数据丢入到共享区域
def load_data(dataset):data_dir,data_file=os.path.split(dataset)if os.path.isfile(dataset):with gzip.open(dataset,'rb') as f:train_set,valid_set,test_set=cPickle.load(f)#共享数据集def shared_dataset(data_xy,borrow=True):data_x,data_y=data_xyshared_x=theano.shared(np.asarray(data_x,dtype=theano.config.floatX),borrow=borrow)shared_y=theano.shared(np.asarray(data_y,dtype=theano.config.floatX),borrow=borrow)return shared_x,T.cast(shared_y,'int32')#定义三个元组分别存储训练集,验证集,测试集train_set_x,train_set_y=shared_dataset(train_set)valid_set_x,valid_set_y=shared_dataset(valid_set)test_set_x,test_set_y=shared_dataset(test_set)rval=[(train_set_x,train_set_y),(valid_set_x,valid_set_y),(test_set_x,test_set_y)]return rval

定义卷积池化层

使用的fan_in,fan_out权重初始化准则, 具体公式戳这里, 前提是需要知道对于每个隐单元有fan_in=(××)个连接,对于低层的每个单元接受的梯度来自fan_out=(××)/.

实现此层过程就是, 先定义并初始化权重和偏置, 随后进行卷积操作, 池化, 激活, (貌似正常情况下是卷积->激活->池化).

#定义卷积和最大池化
class ConvPool(object):def __init__(self,rng,input,filter_shape,img_shape,pool_shape):#input是容器,img_shape是(批大小,输入特征图数,高,宽)self.input=input#初始化参数按照fan_in,fan_out准则#对于每个隐单元,有(输入特征图*高*宽)个输入神经元fan_in=np.prod(filter_shape[1:])#对于低层隐单元接收(输出特征图*滤波器高*滤波器宽)/池化大小的梯度fan_out=(filter_shape[0]*np.prod(filter_shape[2:])//np.prod(pool_shape))#随机初始化权重W_bound=np.sqrt(6./(fan_in+fan_out))self.W=theano.shared(np.asarray(rng.uniform(low=-W_bound,high=W_bound,size=filter_shape),dtype=theano.config.floatX),borrow=True)#初始化偏置全零b_values=np.zeros((filter_shape[0],),dtype=theano.config.floatX)self.b=theano.shared(value=b_values,borrow=True)#定义卷积操作conv_out=T.nnet.conv2d(input=input,filters=self.W,filter_shape=filter_shape,input_shape=img_shape)#定义池化操作pool_out=T.signal.pool.pool_2d(input=conv_out,ws=pool_shape,ignore_border=True)#激活函数self.output=T.tanh(pool_out+self.b.dimshuffle('x',0,'x','x'))#存储参数self.params=[self.W,self.b]#更新输出self.input=input

定义隐层

这一个可以戳前面的博客, 大概过程也是: 定义并初始化权重和偏置, 乘积激活

#定义隐层
class HiddenLayer(object):def __init__(self,rng,input,n_in,n_out,W=None,b=None,activitation=T.tanh):self.input=input #输入#根据fan_in,fan_out初始化权重if W is None:W_values=np.asarray(rng.uniform(low=- np.sqrt(6./(n_in+n_out)),high=np.sqrt(6./(n_in+n_out)),size=(n_in,n_out)),dtype=theano.config.floatX)if activitation==T.nnet.sigmoid:W_values*=4if b is None:b_values=np.zeros((n_out,),dtype=theano.config.floatX)#将权重和偏置放入到共享变量中W=theano.shared(value=W_values,name='W',borrow=True)b=theano.shared(value=b_values,name='b',borrow=True)self.W=Wself.b=bself.params=[self.W,self.b]#激活lin_ouput=T.dot(input,self.W)+self.bself.output=(lin_ouput if activitation is None else activitation(lin_ouput))

定义softmax层

过程是: 定义并初始化权重, 定义损失函数, 定义测试误差函数

#定义输出层,softmax
class SoftMax(object):def __init__(self,rng,input,n_in,n_out):#定义权重W_values=np.asarray(rng.uniform(low=-np.sqrt(6./(n_in+n_out)),high=np.sqrt(6./(n_in+n_out)),size=(n_in,n_out)),dtype=theano.config.floatX)#定义偏置b_values=np.zeros((n_out,),dtype=theano.config.floatX)#共享变量self.W=theano.shared(value=W_values,borrow=True,name='W')self.b=theano.shared(value=b_values,borrow=True,name='b')#softmax函数值self.p_y_given_x=T.nnet.softmax(T.dot(input,self.W)+self.b)#预测值self.y_pred=T.argmax(self.p_y_given_x,axis=1)self.params=[self.W,self.b]self.input=inputdef negative_log_likelihood(self,y):#定义对数似然return - T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]),y])def errors(self,y):#定义误差if y.ndim!=self.y_pred.ndim:raise TypeError('y should have the same shape as self.y_pred',('y',y.type,'y_pred',self.y_pred.type))if y.dtype.startswith('int'):return T.mean(T.neq(self.y_pred,y))else:raise NotImplementedError()

搭建网络

所需要的层已经定义完毕, 然后按照上面的图中所示的网络结构搭建.

需要注意的问题有:

  • 原始图片存储方法为每一行代表一张图片,所以在丢入到卷积层之前需要重新组织成(批大小, 通道数, 图片高, 图片宽), 因为是灰度图,所以通道为1,图片大小是标准的mnist手写数字大小(28\times28)
  • 最好事先推导一下每层卷积的特征图大小, 全连接层单元数, 因为定义的网络需要输入特征图大小, 我刚开始想的是取出第一层卷积过后得到的ouput, 然后用shape自动得到第二层所需要的分别得到下一个卷积所需要的特征图大小, 但是死活取不出来这个值, 尴了个尬.
  • 存储模型的方法还是沿用上一篇博客介绍的方法,存储为pkl格式
#定义整个训练和测试过程
def test_ConvPool(learning_rate=0.1,n_epoches=200,dataset='mnist.pkl.gz',nkerns=[20,50],n_hidden=100,batch_size=500):datasets=load_data(dataset=dataset)train_set_x,train_set_y=datasets[0]valide_set_x,valide_set_y=datasets[1]test_set_x,test_set_y=datasets[2]#计算小批数据的批数n_train_batches=train_set_x.get_value(borrow=True).shape[0]//batch_sizen_valid_batches=valide_set_x.get_value(borrow=True).shape[0]//batch_sizen_test_batches=test_set_x.get_value(borrow=True).shape[0]//batch_size#小批数据的索引print '建立模型...'index=T.iscalar()#批索引x=T.matrix('x')y=T.ivector('y')rng=np.random.RandomState(123455)layer0_input=x.reshape((batch_size,1,28,28))Classifier=Lenet(rng,batch_size=batch_size,input=layer0_input,n_hidden=n_hidden,nkerns=nkerns,n_out=10)#损失函数cost=Classifier.negative_log_likelihood(y)#梯度计算grads=T.grad(cost,Classifier.params)#梯度更新updates=[(params_i,params_i-learning_rate*grad_i)for params_i,grad_i in zip(Classifier.params,grads)]#训练模型train_model=theano.function([index],cost,updates=updates,givens={x:train_set_x[index*batch_size:(index+1)*batch_size],y:train_set_y[index*batch_size:(index+1)*batch_size]})#验证模型valid_model=theano.function([index],Classifier.layer3.errors(y),givens={x:valide_set_x[index*batch_size:(index+1)*batch_size],y:valide_set_y[index*batch_size:(index+1)*batch_size]})#测试模型test_model=theano.function([index],Classifier.layer3.errors(y),givens={x:test_set_x[index*batch_size:(index+1)*batch_size],y:test_set_y[index*batch_size:(index+1)*batch_size]})#使用提前停止方法训练模型print('训练模型...')patiences=10000patiences_increase=2improvement_threshold=0.995validation_frequency=min(n_train_batches,patiences//2)best_validation_loss=np.infbest_iter=0test_score=0start_time=timeit.default_timer()epoch=0done_loop=Falsewhile(epoch<n_epoches) and (not done_loop):epoch=epoch+1for minibatch_index in range(n_train_batches):minibatch_avg_cost=train_model(minibatch_index)iter=(epoch-1)*n_train_batches+minibatch_indexif (iter+1)%validation_frequency==0:validation_loss=[valid_model(i) for i in range(n_valid_batches)]this_validateion_loss=np.mean(validation_loss)print ('epoch %i,minibatch %i/%i,validation error %f %%'%(epoch,minibatch_index+1,n_train_batches,this_validateion_loss*100.))if this_validateion_loss<best_validation_loss:if this_validateion_loss<best_validation_loss*improvement_threshold:patiences=max(patiences,iter*patiences_increase)best_validation_loss=this_validateion_lossbest_iter=itertest_losses=[test_model(i) for i in range(n_test_batches)]test_score=np.mean(test_losses)print(('epoch %i, minibatch %i/%i, test error of best model %f %%') %(epoch, minibatch_index + 1,n_train_batches,test_score * 100.))#保存最优模型save_file=open('best_model_Conv.pkl','wb')model=[Classifier.layer0,Classifier.layer1,Classifier.layer2,Classifier.layer3]cPickle.dump( model,save_file)if patiences<=iter:done_loop=Truebreakendtime=timeit.default_timer()print('优化结束')print('Best validation score of %f %% obtained at iteration %i, ''with test performance %f %%' %(best_validation_loss * 100., best_iter + 1, test_score * 100.))

其实如果你用pycharm之类的工具调试以后,可以发现这个best_model_Conv.pkl存储的就是四个层的模型参数

这里写图片描述

测试网络

首先是载入模型

mnist_class=cPickle.load(open('best_model_Conv.pkl'))

然后构建一个前向网络

x=T.matrix('x')
single_input=x.reshape((1,1,28,28))
hidden_num=mnist_class[2].b.container.data.shape[0];
kerns_num=[mnist_class[1].W.container.data.shape[0],mnist_class[1].W.container.data.shape[1]]
classifier_test=Lenet(rng=np.random.RandomState(1234),batch_size=1,input=single_input,n_hidden=hidden_num,nkerns=kerns_num,n_out=10)

给网络参数赋值

#逐层赋值
#第一层卷积
classifier_test.layer0.W.set_value(mnist_class[0].W.get_value())
classifier_test.layer0.b.set_value(mnist_class[0].b.get_value())
#第二层卷积
classifier_test.layer1.W.set_value(mnist_class[1].W.get_value())
classifier_test.layer1.b.set_value(mnist_class[1].b.get_value())
#第三层全连接->隐层
classifier_test.layer2.W.set_value(mnist_class[2].W.get_value())
classifier_test.layer2.b.set_value(mnist_class[2].b.get_value())
#第四层softmax
classifier_test.layer3.W.set_value(mnist_class[3].W.get_value())
classifier_test.layer3.b.set_value(mnist_class[3].b.get_value())

定义前向计算的操作

#前向计算
forward_compute=theano.function([single_input],classifier_test.layer3.y_pred)

测试网络,这里我们使用前面学习caffe时候手工制作的mnist数据集,戳这里下载, 密码是bead.当然也可以按照MLP中的方法采用mnist原始数据集.

from PIL import Image
import pylab
img=Image.open('E:\\code_test\\theano\\binarybmp\\9.bmp')
img_w,img_h=img.size#图像的宽和高
img=np.asarray(img,dtype='float32')
pylab.imshow(img)
pylab.show()
#原始图片是28*28,要增加两个维度
img=img.reshape((1,1,28,28))

这里写图片描述

识别结果输出

label_pre=forward_compute(img)
print label_pre
#9

目前就是0识别成6, 6识别成5,剩下的几个全对

博客code打包:链接: https://pan.baidu.com/s/1i5xipiH 密码: rvit

后记

通过池化那部分的研究我们发现关于卷积的实现在theano.tensor.nnet戳这里以及theano.sandbox.cuda.dnn戳这里中也有对应实现。这里要注意, 我们以后使用卷积是否要研究后者的使用而非前者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246632.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【theano-windows】学习笔记十三——去噪自编码器

前言 上一章节学习了卷积的写法,主要注意的是其实现在theano.tensor.nnet和theano.sandbox.cuda.dnn中都有对应函数实现, 这一节就进入到无监督或者称为半监督的网络构建中. 首先是自编码器(Autoencoders)和降噪自编码器(denoising Autoencoders) 国际惯例, 参考网址: Denoi…

【theano-windows】学习笔记十四——堆叠去噪自编码器

前言 前面已经学习了softmax,多层感知器,CNN&#xff0c;AE&#xff0c;dAE&#xff0c;接下来可以仿照多层感知器的方法去堆叠自编码器 国际惯例&#xff0c;参考文献&#xff1a; Stacked Denoising Autoencoders (SdA) Greedy Layer-Wise Training of Deep Networks 理…

【theano-windows】学习笔记十五——受限玻尔兹曼机

前言 终于到了最喜欢的模型: 受限玻尔兹曼机(RBM)了, 发现关于RBM是如何从能量模型发展过来的介绍非常不错, 而关于详细理论证明, 可以去看我前面的受限玻尔兹曼机的一系列博客. 国际惯例, 参考博客,超级强推第二个博客, 证明过程很给力: Restricted Boltzmann Machines (R…

【Ogre-windows】环境配置

前言 由于工程原因, 学习一下Ogre面向对象图形渲染开源引擎, 慢慢爬坑吧。首先还是环境的配置问题哎. 其实最重要的是要预先编译三方库, 虽然官方说可以自动编译, 但是在自己电脑上还是出现了无法解析外部符号之类的问题, 正常情况下我就认为是三方库的lib出现了问题, 最后额外…

【theano-windows】学习笔记十六——深度信念网络DBN

前言 前面学习了受限玻尔兹曼机(RBM)的理论和搭建方法, 如果稍微了解过的人, 肯定知道利用RBM可以堆叠构成深度信念网络(deep belief network, DBN)和深度玻尔兹曼机(deep Boltzmann machine), 这里就先学习一下DBN. 国际惯例, 参考博文: Deep Belief Networks A fast lear…

【Ogre-windows】实例配置

前言 折腾了好久才搞定教程实例, 主要是因为上一篇博客安装的具体版本是Ogre1.10.9, 而官方的Ogre Wiki Tutorial Framework没有指定具体版本, 如果单纯下载Ogre Wiki Tutorial Framework 1.10 - (Windows line endings, updated 2015-10-15) 运行, 基本会血崩. 所以, 在经过仔…

【Ogre-windows】旋转矩阵及位置解析

前言 这篇博客主要针对三种问题 如何创建动画帧如何获取全局位置如何计算全局旋转矩阵 仿真环境为VS2013Ogre1.10.9与matlab验证 创建动画帧 这里只做一个简单的实验: 将自带的人物模型Jaiqua的run运动给新创建的运动myrun中并播放&#xff0c;直接贴代码了 void JaiQua:…

BP推导——续

前言 之前有证明过一次人工神经网络——【BP】反向传播算法证明 &#xff0c;但是回头看的时候&#xff0c;有很多地方非常不严谨&#xff0c;特此拿出来再单独证明一次BP&#xff0c;并严格保证其严谨性。如果想看看粗略的证明&#xff0c;可以去看我之前的博客&#xff0c;毕…

matlab学习——强连通分量

前言 最近motion graph相关实验&#xff0c;发现实现运动过渡需要构建运动图&#xff0c;而为了避免运动过渡陷入死胡同&#xff0c;需要对图结构进行裁剪&#xff0c;方法就是计算图模型的极大强联通分量&#xff0c;但是自己懒得去实现&#xff0c;所以就去搜了一下matlab中…

【音频处理】离散傅里叶变换

前言 最近复现音乐驱动舞蹈的文章《Dancing-to-Music Character Animation》&#xff0c;用到了与傅里叶变换很相似的称为常Q变换的方法去分割音乐&#xff0c;所以对傅里叶变换做了一个小了解&#xff0c;本文不深入各种乱糟糟的理论&#xff0c;比如什么蝶形算法啥的&#x…

【音频处理】短时傅里叶变换

前言 上一篇博客讲了离散傅里叶变换&#xff0c;里面的实例是对整个信号进行计算&#xff0c;虽然理论上有N点傅里叶变换(本博客就不区分FFT和DFT了&#xff0c;因为它俩就是一个东东&#xff0c;只不过复杂度不同)&#xff0c;但是我个人理解是这个N点是信号前面连续的N个数值…

【theano-windows】学习笔记十九——循环神经网络

前言 前面已经介绍了RBM和CNN了&#xff0c;就剩最后一个RNN了&#xff0c;抽了一天时间简单看了一下原理&#xff0c;但是没细推RNN的参数更新算法BPTT&#xff0c;全名是Backpropagation Through Time。 【注】严谨来说RNN有两个称呼&#xff1a;①结构上递归的recursive n…

【theano-windows】学习笔记二十——LSTM理论及实现

前言 上一篇学习了RNN&#xff0c;也知道了在沿着时间线对上下文权重求梯度的时候&#xff0c;可能会导致梯度消失或者梯度爆炸&#xff0c;然后我们就得学习一波比较常见的优化方法之LSTM 国际惯例&#xff0c;参考网址&#xff1a; LSTM Networks for Sentiment Analysis …

刚体运动学——欧拉角、四元数、旋转矩阵

前言 刚体运动旋转一般用&#xff1a;欧拉角、四元数、轴角对等表示&#xff0c;在对某个坐标旋转的时候&#xff0c;只需将欧拉角或四元数转换为旋转矩阵&#xff0c;并与原始坐标相乘&#xff0c;便可得到旋转以后的坐标。这里主要看看欧拉角、四元数和旋转矩阵。 国际惯例…

刚体运动学-四元数插值

前言 之前对写了一篇关于刚体运动学相关知识博客&#xff1a;刚体运动学——欧拉角、四元数、旋转矩阵&#xff0c;本篇博客就举例来说明&#xff0c;如何在运动捕捉数据中进行四元数插值。 国际惯例&#xff0c;参考博客&#xff1a; 探讨&#xff1a;向量&#xff08;方向…

【TensorFlow-windows】学习笔记一——基础理解

前言 因为Theano已经停止更新了&#xff0c;所以在前面学完Theano搭建RBM,CNN,RNN相关结构以后&#xff0c;还是得选择一个主流框架的&#xff0c;由于我自身的学习最终是向强化学习靠近&#xff0c;可能用到的仿真环境是openai gym&#xff0c;所以选择了继续学习TensorFlow&…

【TensorFlow-windows】学习笔记二——低级API

前言 上一篇博客初步了解了tensorflow中建立机器学习模型的方法&#xff1a;可以使用eager execution和graph execution两种模式&#xff0c;可以使用高级API estimator中已经封装好的模型&#xff0c;也可以自己创建estimator&#xff0c;更重要的是我们也可以使用低级API自行…

【TensorFlow-windows】学习笔记五——自编码器

前言 上一篇博客介绍的是构建简单的CNN去识别手写数字&#xff0c;这一篇博客折腾一下自编码&#xff0c;理论很简单&#xff0c;就是实现对输入数据的重构&#xff0c;具体理论可以看我前面的【theano-windows】学习笔记十三——去噪自编码器 国际惯例&#xff0c;参考博客&…

【TensorFlow-windows】学习笔记六——变分自编码器

#前言 对理论没兴趣的直接看代码吧&#xff0c;理论一堆&#xff0c;而且还有点复杂&#xff0c;我自己的描述也不一定准确&#xff0c;但是代码就两三句话搞定了。 国际惯例&#xff0c;参考博文 论文&#xff1a;Tutorial on Variational Autoencoders 【干货】一文读懂…

【TensorFlow-windows】学习笔记七——生成对抗网络

前言 既然学习了变分自编码(VAE)&#xff0c;那也必须来一波生成对抗网络(GAN)。 国际惯例&#xff0c;参考网址&#xff1a; 论文: Generative Adversarial Nets PPT:Generative Adversarial Networks (GANs) Generative Adversarial Nets in TensorFlow GAN原理学习笔记…