<jupyter_start><jupyter_text>This is code for 1. running our fmri scans through an autoencoder2. encoding our fmri data from 4d scans to 1d arrays with a length of 10003. predicting schizophrenia with the encoded scansright now the predictions are still no better than random chance. But this is a template for how to autoencoder could work. We still need to work on preprocessing the fmri data before it even gets to the autoencoder. The data is either too noisy or too big for the autoencoder to accuratly condense the information into something that can accuratly predict schizophrenia. One solution would also be to make the autoencoder way larger, but since the input layer has a vector length of over 3 million, even small increases make the autoencoder way larger quickly. This one has 6 billion total weight and bias parameters. Our best option at the moment would be to work on preprocessing before the autoencoder.<jupyter_code>import os
import numpy as np
from nibabel.testing import data_path
import nibabel as nib
import nilearn

import keras
from keras import backend as K
from keras.layers import Input, Dense
from keras.models import Model
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
%matplotlib inline
from IPython.display import display
# To load these data files, look at other files in repository,
XData = np.load('/Users/KJP/Desktop/neural nets/Codes/XData.npy')
YData = np.load('/Users/KJP/Desktop/neural nets/Codes/YData.npy')
# fetch dataset
dataset = nilearn.datasets.fetch_cobre(n_subjects=146, data_dir="/Users/KJP/Desktop/neural nets/Cobre Dataset2", url=None, verbose=1)
file_paths = dataset["func"]
confounds = dataset["confounds"]
file_paths.sort() #sort file names by alphabetical order, which will result in sorting by patient number
confounds.sort()
del file_paths[74]                           # number 74 is misisng samples so it needs to be removed
del confounds[74]
# #fmri scans, l, h, w, time stamps for each scan
XData.shape
# standardize XData into X_scaled
X_scaled = XData.astype('float32').reshape(XData.shape[0],XData.shape[1]*XData.shape[2]*XData.shape[3]*XData.shape[4])
X_scaled  = X_scaled - X_scaled.mean()
X_scaled = X_scaled / X_scaled.max()

#Split X_scaled and YData into testing and training
x_train = X_scaled[:115]
x_test = X_scaled[115:]
y_train = YData[:115]
y_test = YData[115:]
display(x_train.shape)
display(x_test.shape)
display(y_train.shape)
display(y_test.shape)
#Make autoencoder network
input_dim = x_train.shape[1]
encoding_dim = 200

autoencoder = keras.Sequential()

# Encoder Layers
autoencoder.add(Dense(1000, input_shape=(input_dim,), activation='relu'))
autoencoder.add(Dense(500, activation='relu'))
autoencoder.add(Dense(200, activation='relu'))

autoencoder.add(Dense(encoding_dim, activation='relu'))

# Decoder Layers
autoencoder.add(Dense(200, activation='relu'))
autoencoder.add(Dense(500, activation='relu'))
autoencoder.add(Dense(1000, activation='relu'))
autoencoder.add(Dense(input_dim, activation='sigmoid'))

autoencoder.summary()
# Make seperate encoder network from the autoencoder
input_img = Input(shape=(input_dim,))
encoder_layer1 = autoencoder.layers[0]
encoder_layer2 = autoencoder.layers[1]
encoder_layer3 = autoencoder.layers[2]
encoder_layer4 = autoencoder.layers[3]

encoder = Model(input_img, encoder_layer4(encoder_layer3(encoder_layer2(encoder_layer1(input_img)))))

encoder.summary()
from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', min_delta=.0003, patience=10)

autoencoder.compile(optimizer=keras.optimizers.Adam(lr=.0005), loss='mean_squared_error')
history = autoencoder.fit(x_train[10:20, :], x_train[10:20, :],
                epochs=100,
                batch_size=10,
                validation_data=(x_test[:15,:], x_test[:15,:]),
                verbose = 1,
                callbacks=[early_stopping])
plt.figure()
# summarize history for accuracy
plt.subplot(211)
#plt.plot(history.history['acc'])
#plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
# summarize history for loss
plt.subplot(212)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.tight_layout()
plt.show()
score = autoencoder.evaluate(x_test, x_test, verbose=0)
print('Test loss:', score)
# encode all of our x data from a 4d fmri to 1000 length 1d array
X_encoded = encoder.predict(X_scaled)
# standardize X
X_encoded  = X_encoded - X_encoded.mean()
X_encoded = X_encoded / X_encoded.max()
x_train_encoded = X_encoded[:115, :]
x_test_encoded = X_encoded[115:, :]
display(x_train_encoded.shape)
display(x_test_encoded.shape)
#train with X_encoded on a neural net

# Multi-layer net with ReLU hidden layer
model = keras.models.Sequential()
# Here we make the hidden layer (size 2) with a ReL
# activation function, but also initialize the bias
# weights in the network to a constant 0.1
model.add(keras.layers.Dense(10000,input_dim=len(X_encoded[0]),activation='relu',bias_initializer=keras.initializers.Constant(0.1)))
model.add(keras.layers.Dense(1000,activation='relu',bias_initializer=keras.initializers.Constant(0.1)))
model.add(keras.layers.Dense(100,activation='relu',bias_initializer=keras.initializers.Constant(0.1)))
# Output layer (size 1), sigmoid activation function
model.add(keras.layers.Dense(len(YData[0]),activation='softmax'))
# Compile as above (default learning rate and other
# hyperparameters for the Adam optimizer).
model.compile(loss='categorical_crossentropy',
             optimizer=keras.optimizers.Adam(lr=.0001),
             metrics=['accuracy'])
# Display the model
print(model.summary())
# Train it!
history = model.fit(x_train_encoded, y_train,
batch_size=100,
epochs=200,
verbose=1,
validation_split = 0.2)
plt.figure()
# summarize history for accuracy
plt.subplot(211)
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
# summarize history for loss
plt.subplot(212)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.tight_layout()
plt.show()
score = model.evaluate(x_test_encoded, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
#Overall we still have not achieved better than random chance. The problem at the moment 
#is that we still need more preprocessing before the autoencoder
#Either the data is too noisy or too big for the autoencoder to accurately encode useful
#data for predicting schizophrenia<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11681159420289855, 'fraction_numerical': 0.024927536231884057, 'mean_word_length': 5.928714859437751, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '508035', 'license': 'MIT', 'n_tokens_mistral': 2385, 'n_tokens_neox': 2182, 'n_words': 620, 'path': 'FMRI Preprocessing/AutoEncoder.ipynb', 'repo_name': 'CSCI4850/S19-team4-project', 'size': '6900'}