| 
 | 
 
 本帖最后由 xingpengwei 于 2017-6-24 13:54 编辑  
 
        本帖只针对新生尽快熟悉工作做参考,我会写得啰嗦些,大神绕道{:243:} 。 
 
        生物信息主要处理一维字符序列,如果想转化成矩阵处理,可使用onehot编码,快速理解就是01编码每个字符类别,如果序列只有AUGC四种字符,那么每个字符用0001,0010,0100,1000编码代替。这样序列就变成了Nx4的矩阵。 
        StackAutoEncoder,即Stack自动编码机,一种最简单的无监督学习深度网络,首先我们来理解一下无监督学习: 
        (引自http://blog.csdn.net/zouxy09/article/details/8775524) 
        ![]()  
        如图,输入的样本是有标签的,即(input, target),我们根据当前输出和target(label)之间的差去改变前面各层的参数,直到收敛。 
        那么无标签怎么得到误差呢? 
        ![]()  
        如上图,我们将input输入一个encoder编码器,就会得到一个code,这个code也就是输入的一个表示,那么我们怎么知道这个code表示的就是input呢?我们加一个decoder解码器,这时候decoder就会输出一个信息,那么如果输出的这个信息和一开始的输入信号input是很像的(理想情况下就是一样的),那很明显,我们就有理由相信这个code是靠谱的。所以,我们就通过调整encoder和decoder的参数,使得重构误差最小,这时候我们就得到了输入input信号的第一个表示了,也就是编码code了。因为是无标签数据,所以误差的来源就是直接重构后与原输入相比得到。 
        Stack自动编码机的话,就是堆叠上述层,上一层的输入作为下一层的输入。 
        看到这里,我们知道了StackAutoEncoder就是(encoder->decoder)-(encoder->decoder)-(encoder->decoder)... 
 
        当然还有一些变形和其他知识,这里主要讲应用,有不看原理心忐忑的伙伴有时间后可以参考以下教程。 
        斯坦福的UFLDL教程算是根正苗红的深度学习基础教程,或者是Andrew Ng的视频 
        那么,我们来上代码: 
        matlab自带有StackAutoEncoder的例子,首先我们来实现onehot编码: 
- [tits, seqs]=fastaread('p1_n1_H.txt');
 
 - num=length(tits);
 
 - len=length(char(seqs(1)));
 
  
- Y=zeros(2,num);
 
 - X=cell(1,num);
 
 - %onehot
 
 - for i=1:num
 
 -     
 
 -     str=char(tits(i));
 
 -     temp=strsplit(str,'|');
 
 -     label=char(temp(2));
 
 -     if label=='1'
 
 -         Y(:,i)=[1,0];
 
 -     else
 
 -         Y(:,i)=[0,1];
 
 -     end
 
 -     
 
 -     
 
 -     img=zeros(len,4);
 
 -     for j=1:len
 
 -         seq=char(seqs(1,i));
 
 -         switch seq(j)
 
 -             case 'A'
 
 -                 img(j,:)=[0,0,0,1];
 
 -             case 'C'
 
 -                 img(j,:)=[0,0,1,0];
 
 -             case 'G'
 
 -                 img(j,:)=[0,1,0,0];
 
 -             case 'U'
 
 -                 img(j,:)=[1,0,0,0];
 
 -             case 'T'
 
 -                 img(j,:)=[1,0,0,0];
 
 -         end
 
 -     end
 
 -      X{i}=img;
 
  复制代码 
        以上代码基本就是01编码代替序列字符。 
        主体StackAutoEncoder代码参考https://cn.mathworks.com/help/nn ... classification.html 
        你只需要替换相关输入,改图片长宽等。 
 
        我们主要讲Deep Belief Networks深度信念网络: 
        深度信念网络也是stack层,只是stack的是RBM,Restricted Boltzmann Machine (RBM)限制波尔兹曼机。 
        理论参考http://blog.csdn.net/zouxy09/article/details/8781396 讲得挺好。 
        这里我们使用matlab第三方的工具包:DeeBNet (Deep Belief Networks) toolbox in MATLAB and Octave: 
        工具包里边有很多例子脚本,我们主要使用test_getFeatureMNIST.m其他也行: 
        首先我们要做的依然是把我们的数据结构化成这个脚本接受的形式: 
- [tits, seqs]=fastaread('+SCM6A/p1_n1_H.txt');
 
 - num=length(tits);
 
 - len=length(char(seqs(1)));
 
  
- Y=zeros(num,1);
 
 - X=zeros(num,len*4);
 
 - %onehot
 
 - for i=1:num
 
 -     
 
 -     str=char(tits(i));
 
 -     temp=strsplit(str,'|');
 
 -     label=char(temp(2));
 
 -     if label=='1'
 
 -         Y(i)=1;
 
 -     else
 
 -         Y(i)=2;
 
 -     end
 
 -     
 
 -     
 
 -     img=zeros(len,4);
 
 -     for j=1:len
 
 -         seq=char(seqs(1,i));
 
 -         switch seq(j)
 
 -             case 'A'
 
 -                 img(j,:)=[0,0,0,1];
 
 -             case 'C'
 
 -                 img(j,:)=[0,0,1,0];
 
 -             case 'G'
 
 -                 img(j,:)=[0,1,0,0];
 
 -             case 'U'
 
 -                 img(j,:)=[1,0,0,0];
 
 -             case 'T'
 
 -                 img(j,:)=[1,0,0,0];
 
 -         end
 
 -     end
 
 -      X(i,:)=img(:);
 
 -     
 
 - end
 
  
- inputs = X;
 
 - targets = Y;
 
 - %custom your split_point by multiplier 
 
 - split_point=round(size(inputs,1)*0.7);
 
 - ranindex=randperm(size(inputs,1));
 
  
- data=inputs(ranindex(1:split_point),:);
 
 - labels=targets(ranindex(1:split_point),:);
 
  
- testdata=inputs(ranindex(split_point+1:end),:);
 
 - testlabels=targets(ranindex(split_point+1:end),:);
 
  
- save('SCM6A.mat','data','labels','testdata','testlabels');
 
  复制代码 
        后边的代码是生成一个随机种子然后分割训练测试集。 
 
        下边是主体脚本: 
        如果不包装网格调参的设定的话,代码是这样的:- dbn=DBN();
 
 - dbn.dbnType='autoEncoder';
 
 - % RBM1
 
 - rbmParams=RbmParameters(1000,ValueType.binary);
 
 - rbmParams.maxEpoch=50;
 
 - rbmParams.samplingMethodType=SamplingClasses.SamplingMethodType.CD;
 
 - rbmParams.performanceMethod='reconstruction';
 
 - dbn.addRBM(rbmParams);
 
 - % RBM2
 
 - rbmParams=RbmParameters(500,ValueType.binary);
 
 - rbmParams.maxEpoch=50;
 
 - rbmParams.samplingMethodType=SamplingClasses.SamplingMethodType.CD;
 
 - rbmParams.performanceMethod='reconstruction';
 
 - dbn.addRBM(rbmParams);
 
 - % RBM3
 
 - rbmParams=RbmParameters(250,ValueType.binary);
 
 - rbmParams.maxEpoch=50;
 
 - rbmParams.samplingMethodType=SamplingClasses.SamplingMethodType.CD;
 
 - rbmParams.performanceMethod='reconstruction';
 
 - dbn.addRBM(rbmParams);
 
 - RBM4
 
 - rbmParams=RbmParameters(200,ValueType.gaussian);
 
 - rbmParams.maxEpoch=50;
 
 - rbmParams.samplingMethodType=SamplingClasses.SamplingMethodType.CD;
 
 - rbmParams.performanceMethod='reconstruction';
 
 - dbn.addRBM(rbmParams);
 
  
- dbn.train(data);
 
 - dbn.backpropagation(data,'yes');
 
  复制代码 
        Stack了四层RBM,每一层设置了一些参数,设置好后addRBM,然后训练,然后fine turn。 
         
        为了能网格调参,我们需要把这部分的参数设置成变量的形式,然后包裹在几层for循环中(简单粗暴法),我们先设定一堆参数,如需修改参数范围,修改这部分就可以         
- RbmNode1=[250,100];
 
 - RbmNode2=[500,250,100];
 
 - RbmNode3=[1000,500,250,100];
 
 - GridSearch_nodes={RbmNode1,RbmNode2,RbmNode3};
 
 - GridSearch_maxEpoch=[200];
 
 - GridSearch_learningRate=[0.1,0.01,0.001];
 
 - GridSearch_BPorNot=[1,0];
 
  复制代码 
        然后把单层包裹着for循环中: 
         
- fid = fopen('out.txt','w');
 
 - for k=1:length(GridSearch_maxEpoch);
 
 -     for l=1:4%GridSearch_SamplingMethodType
 
 -         for m=1:length(GridSearch_learningRate)
 
 -             for n=1:length(GridSearch_BPorNot)
 
 -                 
 
 -                 for i=1:length(GridSearch_nodes)
 
 -                     for times=1:3
 
 -                         dbn=DBN();
 
 -                         dbn.dbnType='autoEncoder';
 
 -                         for j=1:length( GridSearch_nodes{i})
 
 -                             
 
 -                             rbmParams=RbmParameters(GridSearch_nodes{i}(j),ValueType.binary);
 
 -                             rbmParams.maxEpoch=GridSearch_maxEpoch(k);
 
 -                             rbmParams.samplingMethodType=l;
 
 -                             rbmParams.performanceMethod='reconstruction';
 
 -                             rbmParams.learningRate=GridSearch_learningRate(m);
 
 -                             dbn.addRBM(rbmParams);
 
 -                         end
 
 -                         dbn.train(data);
 
 -                         if GridSearch_BPorNot(n)==1
 
 -                             dbn.backpropagation(data,'yes');
 
 -                         end
 
 -                         
 
 -                         load('SCM6A_nosh.mat');
 
 -                         feat=dbn.getFeature(inputs);
 
 -                         label=targets-1;
 
 -                         label(label==1)=-1;
 
 -                         label(label==0)=1;
 
 -                         
 
 -                         confu=svmtrain(label,feat,'-v 10');
 
 -                         confu=double(confu);
 
 -                         TP=confu(1);
 
 -                         FN=confu(2);
 
 -                         FP=confu(3);
 
 -                         TN=confu(4);
 
 -                         
 
 -                         Sn=TP/(TP+FN);
 
 -                         Sp=TN/(TN+FP);
 
 -                         Acc=(TP+TN)/(TP+FN+FP+TN);
 
 -                         MCC=(TP*TN-FN*FP)/sqrt((TP+FP)*(TN+FN)*(TP+FN)*(TN+FP));
 
 -                         
 
 -                         fprintf(fid, '%s %s %s %s %s %s %s %s %s %s %s %s %s %s\n','times','GridSearch_nodes','maxEpoch','SamplingMethodType','learningRate','BPorNot','Sn','Sp','Acc','MCC','TP','FN','FP','TN');
 
 -                         fprintf(fid, '%d %s %d %d %d %d %.4f %.4f %.4f %.4f %d %d %d %d\n',times,mat2str(GridSearch_nodes{i}(:)),GridSearch_maxEpoch(k),l,GridSearch_learningRate(m),GridSearch_BPorNot(n),Sn,Sp,Acc,MCC,TP,FN,FP,TN);
 
 -                         
 
 -                         
 
 -                         
 
 -                         feat_label=[feat,targets-1];
 
 -                         csvwrite('feat_temp.csv',feat_label);
 
 -                         
 
 -                         S = fileread('feat_temp.csv');
 
 -                         feat_dim=100;
 
 -                         attribute='';
 
 -                         for index=1:feat_dim
 
 -                             attribute=[attribute,'@attribute Fea',int2str(index),' numeric',char(10)];
 
 -                         end
 
 -                         header=['@relation m6a_dbn',char(10),attribute,'@attribute class {0,1}',char(10),'@data',char(10)];
 
 -                         
 
 -                         S = [header,  S];
 
 -                         name=sprintf('%s-%d-%d-%d-%d-%.4f-%.4f-%.4f-%.4f-%d-%d-%d-%d-%d',mat2str(GridSearch_nodes{i}(:)),GridSearch_maxEpoch(k),l,GridSearch_learningRate(m),GridSearch_BPorNot(n),Sn,Sp,Acc,MCC,TP,FN,FP,TN,times);
 
 -                         FID = fopen([name,'.arff'], 'w');
 
 -                         if FID == -1, error('Cannot open file'); end
 
 -                         fwrite(FID, S, 'char');
 
 -                         fclose(FID);
 
 -                     end
 
 -                 end
 
 -             end
 
 -         end
 
 -     end
 
 - end
 
 - fclose(fid);
 
  复制代码 
        当然,我们也利用这个训练批量地 
        使用修改编译后的libsvm十折交叉验证: 
- confu=svmtrain(label,feat,'-v 10');
 
  复制代码 
        这一行直接可以输出混淆矩阵,默认的libsvm包是十折的话只输出一个准确度,这是蛋疼, 
        具体参考关于libsvm包优化的那一篇 
 
        计算了准确率等论文可以直接使用的指标: 
- confu=double(confu);
 
 -                         TP=confu(1);
 
 -                         FN=confu(2);
 
 -                         FP=confu(3);
 
 -                         TN=confu(4);
 
 -                         
 
 -                         Sn=TP/(TP+FN);
 
 -                         Sp=TN/(TN+FP);
 
 -                         Acc=(TP+TN)/(TP+FN+FP+TN);
 
 -                         MCC=(TP*TN-FN*FP)/sqrt((TP+FP)*(TN+FN)*(TP+FN)*(TN+FP));
 
  复制代码 
        生成保存了arff文件以[/code]便后续使用: 
                - feat_label=[feat,targets-1];
 
 -                         csvwrite('feat_temp.csv',feat_label);
 
 -                         
 
 -                         S = fileread('feat_temp.csv');
 
 -                         feat_dim=100;
 
 -                         attribute='';
 
 -                         for index=1:feat_dim
 
 -                             attribute=[attribute,'@attribute Fea',int2str(index),' numeric',char(10)];
 
 -                         end
 
 -                         header=['@relation m6a_dbn',char(10),attribute,'@attribute class {0,1}',char(10),'@data',char(10)];
 
 -                         
 
 -                         S = [header,  S];
 
 -                         name=sprintf('%s-%d-%d-%d-%d-%.4f-%.4f-%.4f-%.4f-%d-%d-%d-%d-%d',mat2str(GridSearch_nodes{i}(:)),GridSearch_maxEpoch(k),l,GridSearch_learningRate(m),GridSearch_BPorNot(n),Sn,Sp,Acc,MCC,TP,FN,FP,TN,times);
 
 -                         FID = fopen([name,'.arff'], 'w');
 
 -                         if FID == -1, error('Cannot open file'); end
 
 -                         fwrite(FID, S, 'char');
 
 -                         fclose(FID);
 
  复制代码 
        先就酱。 |   
 
 
 
 |