我对fMRI分析很新。我试图通过查看他们的脑图像来确定一个人正在考虑哪个对象(9个对象)。我在https://openfmri.org/dataset/ds000105/上使用数据集。因此,我通过输入大脑图像的2D切片来使用神经网络,以将输出作为9个对象中的1个。有关每个步骤的详细信息以及下面代码中的图像。
import os, mvpa2, pyBrain
import numpy as np
from os.path import join as opj
from mvpa2.datasets.sources import OpenFMRIDataset
from pybrain.datasets import SupervisedDataSet,classification
path = opj(os.getcwd() , 'datasets','ds105')
of = OpenFMRIDataset(path)
#12th run of the 1st subject
ds = of.get_model_bold_dataset(model_id=1, subj_id=1,run_ids=[12])
#Get the unique list of 8 objects (sicissors, ...) and 'None'.
target_list = np.unique(ds.sa.targets).tolist()
#Returns Nibabel Image instance
img = of.get_bold_run_image(subj=1,task=1,run=12)
# Getting the actual image from the proxy image
img_data = img.get_data()
#Get the middle voxelds of the brain samples
mid_brain_slices = [x/2 for x in img_data.shape]
# Each image in the img_data is a 3D image of 40 x 64 x 64 voxels,
# and there are 121 such samples taken periodically every 2.5 seconds.
# Thus, a single person's brain is scanned for about 300 seconds (121 x 2.5).
# This is a 4D array of 3 dimensions of space and 1 dimension of time,
# which forms a matrix of (40 x 64 x 64 x 121)
# I only want to extract the slice of the 2D images brain in it's top view
# i.e. a series of 2D images 40 x 64
# So, i take the middle slice of the brain, hence compute the middle_brain_slices
DS = classification.ClassificationDataSet(40*64, class_labels=target_list)
# Loop over every brain image
for i in range(0,121):
#Image of brain at i th time interval
brain_instance = img_data[:,:,:,i]
# We will slice the brain to create 2D plots and use those 'pixels'
# as the features
slice_0 = img_data[mid_brain_slices[0],:,:,i] #64 x 64
slice_1 = img_data[:,mid_brain_slices[1],:,i] #40 x 64
slice_2 = img_data[:,:,mid_brain_slices[2],i] #40 x 64
#Note : we may actually only need one of these slices (the one with top view)
X = slice_2 #Possibly top view
# Reshape X from 40 x 64 to 1D vector 2560 x 1
X = np.reshape(X,40*64)
#Get the target at this intance (y)
y = ds.sa.targets[i]
y = target_list.index(y)
DS.appendLinked(X,y)
print DS.calculateStatistics()
print DS.classHist
print DS.nClasses
print DS.getClass(1)
# Generate y as a 9 x 1 matrix with eight 0's and only one 1 (in this training set)
DS._convertToOneOfMany(bounds=[0, 1])
#Split into Train and Test sets
test_data, train_data = DS.splitWithProportion( 0.25 )
#Note : I think splitWithProportion will also internally shuffle the data
#Build neural network
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure.modules import SoftmaxLayer
nn = buildNetwork(train_data.indim, 64, train_data.outdim, outclass=SoftmaxLayer)
from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(nn, dataset=train_data, momentum=0.1, learningrate=0.01 , verbose=True, weightdecay=0.01)
trainer.trainUntilConvergence(maxEpochs = 20)
行nn.activate(X_test[i])
应该采用2560输入并生成概率输出,对吗?在预测的y向量中(形状9×1)
因此,我假设应该为9个值中的最高值分配答案。但是当我用y_test [i]验证它时,情况并非如此。此外,我为每个测试样本获得了类似的X_test值。为什么会这样?
#Just splitting the test and trainset
X_train = train_data.getField('input')
y_train = train_data.getField('target')
X_test = test_data.getField('input')
y_test = test_data.getField('target')
#Testing the network
for i in range(0,len(X_test)):
print nn.activate(X_test[i])
print y_test[i]
当我包含上面的代码时,这里有一些X_test的值:
.
.
.
nn.activated = [ 0.44403205 0.06144328 0.04070154 0.09399672 0.08741378 0.05695479 0.08178353 0.0623408 0.07133351]
y_test [0 1 0 0 0 0 0 0 0]
nn.activated = [ 0.44403205 0.06144328 0.04070154 0.09399672 0.08741378 0.05695479 0.08178353 0.0623408 0.07133351]
y_test [1 0 0 0 0 0 0 0 0]
nn.activated = [ 0.44403205 0.06144328 0.04070154 0.09399672 0.08741378 0.05695479 0.08178353 0.0623408 0.07133351]
y_test [0 0 0 0 0 0 1 0 0]
.
.
.
因此,无论样本值如何,测试样本在每种情况下的索引0的概率为44.4%。实际值虽然不断变化。
print 'print predictions: ' , trainer.testOnClassData (dataset=test_data)
x = []
for item in y_test:
x.extend(np.where(item == 1)[0])
print 'print actual: ' , x
这里,输出比较是:
print predictions: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
print actual: [7, 0, 4, 8, 2, 0, 2, 1, 0, 6, 1, 4]
所有预测都是第一项。我不知道问题是什么。总错误似乎在减少,这是一个好兆头:
Total error: 0.0598287764931
Total error: 0.0512272330797
Total error: 0.0503835076374
Total error: 0.0486402801867
Total error: 0.0498354140541
Total error: 0.0495447833038
Total error: 0.0494208449895
Total error: 0.0491162599037
Total error: 0.0486775862084
Total error: 0.0486638648161
Total error: 0.0491337891419
Total error: 0.0486965691406
Total error: 0.0490016912735
Total error: 0.0489939195858
Total error: 0.0483910986235
Total error: 0.0487459940103
Total error: 0.0485516142106
Total error: 0.0477407360102
Total error: 0.0490661144891
Total error: 0.0483103097669
Total error: 0.0487965594586
答案 0 :(得分:1)
我无法确定 - 因为我以前没有使用过所有这些工具,或者专门在这类项目中工作过 - 但我会查看文档并确保你的{{1}正如你所期望的那样创建。
具体来说,它在这里提到:
http://pybrain.org/docs/api/tools.html?highlight=buildnetwork#pybrain.tools.shortcuts.buildNetwork
“如果设置了重复标记,将创建RecurrentNetwork,否则为FeedForwardNetwork。”,您可以在此处阅读:
http://pybrain.org/docs/api/structure/networks.html?highlight=feedforwardnetwork
“FeedForwardNetworks是不适用于顺序数据的网络。每个输入都被视为独立于任何先前或后续输入。”。
您的意思是创建“FeedForward”网络对象吗?
您正在测试循环索引并激活基于nn
对象实例化的每个"input"
字段,文档建议将其视为独立于其他输入。这可能就是为什么每当你期望更好的收敛时,你会得到如此类似的结果。
使用参数FeedForwardNetwork
初始化数据集ds
对象,建议您只查看单个主题和模型,但在该模型下从该主题进行12次“运行”,对吧?
很可能你的代码没有任何语义或语法错误,但是PyBrain库假定和假设的模型,参数和算法存在一般性的混淆。所以不要撕掉你的头发寻找代码“错误”;对于文档不足的库来说,这绝对是一个常见的困难。
同样,我可能不在基础上,但根据我对类似工具和库的经验,最常见的是采用极其复杂的过程并将其简化为几十行代码的好处,附带一个TON完全不透明和固定的假设。
我的猜测是,您实际上是在“新”或独立的训练数据上重新运行“新”测试,而没有您认为在之前的代码行中设置的所有实际信息和参数。你是完全正确的,最高值(读:最大概率)是“最有可能”(这正是每个值,一个“可能性”)的答案,特别是如果你的概率数组代表unimodal distribution。
因为没有明显的代码语法错误 - 比如意外地在范围迭代器上循环等效于列表model_id=1, subj_id=1,run_ids=[12]
;您可以验证,因为您在打印[0,0,0,0,0,0]
中重复使用i
索引整数并且y_test
的结果不变 - 那么最有可能发生的是你是基本上每次都重新启动测试,这就是为什么你得到一个相同的结果,而不仅仅是相似但是对于nn.activate(X_test[i])
方法的结果的每次打印都是相同的。
这是一个复杂但写得很好且说得很好的问题,但不幸的是,我认为不会有一个简单或明显的解决方案。
同样,您可以获得PyBrain简化神经网络,数据训练,启发式,数据读取,采样,统计建模,分类等等的好处,所有这些都可以简化为单行或双行命令。 是的假设,是他们的TONS。这就是需要所需的文档,并且当我们使用这些工具时我们必须非常小心,这不仅仅是一个正确的语法问题,而是一个实际上正确的(读取:预期的)算法,假设和所有。
祝你好运!(PS - 尽管缺乏文档,开源库也可以帮助您检查源代码以查看[假设和所有]他们实际正在做的事情:https://github.com/pybrain/pybrain)