Я новичок в анализе МРМР. Я пытаюсь определить, какой объект (из 9 объектов) человек думает только, глядя на свои изображения мозга. Я использую набор данных на https://openfmri.org/dataset/ds000105/. Итак, я использую нейронную сеть, вводя 2D-фрагменты изображений мозга, чтобы получить результат как 1 из 9 объектов. На каждом шаге и изображениях приведено подробное описание.Прогнозы нейронной сети всегда одинаковы при тестировании набора данных fMRI с помощью pyBrain. Зачем?
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 x 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
Эй TommyP, Спасибо за быстрый ответ. Мое намерение состояло в том, чтобы создать FeedForwardNetwork, как вы упомянули. В модели я использую 40 x 64 = 2560 функций. Но я тренировал его только около 100 образцов и использовал остальные для тестирования. Я думал, что мне нужно увеличить количество образцов, поэтому я сделал около 1400-иш. Я все еще получаю ту же проблему. Каждый раз, когда я использую функцию в pybrain, я ссылаюсь на код документов. Нет проблем. Поскольку нет глупых ошибок (я думаю), мне просто нужно искать хорошее решение. Еще раз спасибо за ваш вклад. :) –
Да, извините, я не мог видеть ничего очевидного, но я был в подобных ситуациях и искажен по предположениям библиотеки. Трудно отследить. Раньше я имел успех, фактически перейдя к исходному коду и заменяя вызов функции в своем коде исходным кодом из библиотеки, таким образом вы можете добавлять отладочные заявления печати и изменять предполагаемые параметры и т. Д. Удачи! –