Предсказание белка вторичная структура Используя нейронную сеть

Этот пример показывает вторичный метод прогноза структуры, который использует прямую каналом нейронную сеть и функциональность, доступную с Deep Learning Toolbox™.

Это - упрощенный пример, предназначенный, чтобы проиллюстрировать шаги для подготовки нейронной сети с целью предсказания вторичной структуры белков. Его настройка и учебные методы не предназначены, чтобы быть обязательно лучшим решением для проблемы под рукой.

Введение

Модели нейронной сети пытаются моделировать обработку информации, которая происходит в мозгу и широко используется во множестве приложений, включая автоматизированное распознавание образов.

Набор данных Rost-шлифовального-станка [1] состоит из белков, структуры которых охватывают относительно широкий спектр доменных типов, состава и длины. RostSanderDataset.mat файла содержит подмножество этого набора данных, где о структурном присвоении каждого остатка сообщают для каждой последовательности белка.

load RostSanderDataset.mat

N = numel(allSeq);

id = allSeq(7).Header            % annotation of a given protein sequence
seq = int2aa(allSeq(7).Sequence) % protein sequence
str = allSeq(7).Structure        % structural assignment
id =

    '1CSE-ICOMPLEX(SERINEPROTEINASE-INHIBITOR)03-JU'


seq =

    'KSFPEVVGKTVDQAREYFTLHYPQYNVYFLPEGSPVTLDLRYNRVRVFYNPGTNVVNHVPHVG'


str =

    'CCCHHHCCCCHHHHHHHHHHHCCCCEEEEEECCCCEECCCCCCEEEEEEECCCCEECCCCEEC'

В этом примере вы создадите нейронную сеть, чтобы изучить структурное состояние (спираль, лист или обмотка) каждого остатка в данном белке, на основе структурных шаблонов, наблюдаемых во время учебной фазы. Из-за случайной природы некоторых шагов в следующем подходе, числовые результаты могут немного отличаться каждый раз, когда сеть обучена, или прогноз моделируется. Чтобы гарантировать воспроизводимость результатов, мы сбрасываем глобальный случайный генератор к сохраненному состоянию, включенному в загруженный файл, как показано ниже:

rng(savedState);

Определение сетевой архитектуры

Для текущей проблемы мы задаем нейронную сеть с одним входным слоем, одним скрытым слоем и одним выходным слоем. Входной слой кодирует раздвижное окно в каждой входной последовательности аминокислот, и прогноз сделан на структурном состоянии центрального остатка в окне. Мы выбираем окно размера 17 на основе статистической корреляции, найденной между вторичной структурой данного положения остатка и этими восемью остатками по обе стороны от точки [2] прогноза. Каждое положение окна закодировано с помощью двоичного массива размера 20, имея один элемент для каждого типа аминокислоты. В каждой группе из 20 входных параметров элемент, соответствующий типу аминокислоты в данном положении, установлен в 1, в то время как все другие входные параметры установлены в 0. Таким образом входной слой состоит из R = 17x20 входные модули, т.е. 17 групп из 20 входных параметров каждый.

В следующем коде мы сначала определяем для каждой последовательности белка все возможные подпоследовательности, соответствующие раздвижному окну размера W путем создания матрицы Ганкеля, где ith столбец представляет подпоследовательность, запускающуюся в ith положении в исходной последовательности. Затем для каждого положения в окне, мы создаем массив размера 20, и мы устанавливаем jth элемент на 1, если остаток в данном положении имеет числовое представление, равное j.

W = 17; % sliding window size


% === binarization of the inputs
for i = 1:N
	seq = double(allSeq(i).Sequence);   % current sequence
	win = hankel(seq(1:W),seq(W:end));  % all possible sliding windows
	myP = zeros(20*W,size(win,2));      % input matrix for current sequence
	for k = 1:size(win, 2)
		index = 20*(0:W-1)' + win(:,k); % input array for each position k
		myP(index,k) = 1;
	end
	allSeq(i).P = myP;
end

Выходной слой нашей нейронной сети состоит из трех модулей, один для каждого из продуманных структурных состояний (или классы), которые закодированы с помощью бинарной схемы. Чтобы создать целевую матрицу для нейронной сети, мы сначала получаем, от данных, структурных присвоений всех возможных подпоследовательностей, соответствующих раздвижному окну. Затем мы рассматриваем центральное положение в каждом окне и преобразовываем соответствующее структурное присвоение с помощью следующего бинарного кодирования: 1 0 0 для обмотки, 0 1 0 для листа, 0 0 1 для спирали.

cr = ceil(W/2); % central residue position

% === binarization of the targets
for i = 1:N
	str = double(allSeq(i).Structure); % current structural assignment
    win = hankel(str(1:W),str(W:end)); % all possible sliding windows
	myT = false(3,size(win,2));
	myT(1,:) = win(cr,:) == double('C');
	myT(2,:) = win(cr,:) == double('E');
	myT(3,:) = win(cr,:) == double('H');
	allSeq(i).T = myT;
end

Можно выполнить бинаризацию входа и предназначаться для матрицы, описанной на двух шагах выше более кратким способом путем выполнения следующего эквивалентного кода:

% === concise binarization of the inputs and targets
for i = 1:N
	seq = double(allSeq(i).Sequence);
    win = hankel(seq(1:W),seq(W:end)); % concurrent inputs (sliding windows)

	% === binarization of the input matrix
	allSeq(i).P = kron(win,ones(20,1)) == kron(ones(size(win)),(1:20)');

	% === binarization of the target matrix
	allSeq(i).T = allSeq(i).Structure(repmat((W+1)/2:end-(W-1)/2,3,1)) == ...
		 repmat(('CEH')',1,length(allSeq(i).Structure)-W+1);
end

Если мы задаем вход и предназначаемся для матриц для каждой последовательности, мы создаем входную матрицу, P, и целевую матрицу, T, представляя кодирование для всех последовательностей, поданных в сеть.

% === construct input and target matrices
P = double([allSeq.P]); % input matrix
T = double([allSeq.T]); % target matrix

Создание нейронной сети

Проблема вторичного прогноза структуры может считаться проблемой распознавания образов, где сеть обучена, чтобы распознать структурное состояние центрального остатка, скорее всего, чтобы произойти, когда определенные остатки в данном раздвижном окне наблюдаются. Мы создаем нейронную сеть распознавания образов с помощью входа и предназначаемся для матриц, заданных выше и задавая скрытый слой размера 3.

hsize = 3;
net = patternnet(hsize);
net.layers{1} % hidden layer
net.layers{2} % output layer
ans = 

    Neural Network Layer
 
              name: 'Hidden'
        dimensions: 3
       distanceFcn: (none)
     distanceParam: (none)
         distances: []
           initFcn: 'initnw'
       netInputFcn: 'netsum'
     netInputParam: (none)
         positions: []
             range: [3x2 double]
              size: 3
       topologyFcn: (none)
       transferFcn: 'tansig'
     transferParam: (none)
          userdata: (your custom info)
 

ans = 

    Neural Network Layer
 
              name: 'Output'
        dimensions: 0
       distanceFcn: (none)
     distanceParam: (none)
         distances: []
           initFcn: 'initnw'
       netInputFcn: 'netsum'
     netInputParam: (none)
         positions: []
             range: []
              size: 0
       topologyFcn: (none)
       transferFcn: 'softmax'
     transferParam: (none)
          userdata: (your custom info)
 

Обучение нейронной сети

Сеть распознавания образов использует Масштабированный алгоритм Метода сопряженных градиентов по умолчанию для обучения, но другие алгоритмы доступны (см. документацию Deep Learning Toolbox для списка доступных функций). В каждом учебном цикле обучающие последовательности представлены сети через раздвижное окно, заданное выше, один остаток за один раз. Каждый скрытый модуль преобразовывает сигналы, полученные от входного слоя при помощи передаточной функции logsig, чтобы произвести выходной сигнал, который является между и или близко к 0 или близко к 1, моделируя увольнение нейрона [2]. Веса настроены так, чтобы ошибка между наблюдаемым выходным сигналом от каждого модуля и желаемым выводом, заданным целевой матрицей, была минимизирована.

% === use the log sigmoid as transfer function
net.layers{1}.transferFcn = 'logsig';

% === train the network
[net,tr] = train(net,P,T);

Во время обучения учебное окно инструментов открывает и отображает прогресс. Учебные детали, такие как алгоритм, критерии производительности, тип рассмотренной ошибки, и т.д. показывают.

Используйте функциональный view, чтобы сгенерировать графическое представление нейронной сети.

view(net)

Одной типичной проблемой, которая происходит во время обучения нейронной сети, является сверхподбор кривой данных, где сеть имеет тенденцию запоминать учебные примеры, не учась, как сделать вывод к новым ситуациям. Метод по умолчанию для улучшения обобщения называется, рано останавливаясь и состоит в делении доступного обучающего набора данных в три подмножества: (i) набор обучающих данных, который используется для вычисления градиента и обновления сетевых весов и смещений; (ii) набор валидации, ошибка которого проверена во время учебного процесса, потому что это имеет тенденцию увеличиваться, когда данные сверхадаптированы; и (iii) набор тестов, ошибка которого может использоваться, чтобы оценить качество деления набора данных.

При использовании функционального train, по умолчанию, случайным образом разделены данные так, чтобы 60% выборок были присвоены набору обучающих данных, 20% к набору валидации и 20% к набору тестов, но другие типы разделения могут быть применены путем определения свойства net.divideFnc (dividerand по умолчанию). Структурный состав остатков в этих трех подмножествах сопоставим, как замечено по следующему обзору:

[i,j] = find(T(:,tr.trainInd));
Ctrain = sum(i == 1)/length(i);
Etrain = sum(i == 2)/length(i);
Htrain = sum(i == 3)/length(i);

[i,j] = find(T(:,tr.valInd));
Cval = sum(i == 1)/length(i);
Eval = sum(i == 2)/length(i);
Hval = sum(i == 3)/length(i);

[i,j] = find(T(:,tr.testInd));
Ctest = sum(i == 1)/length(i);
Etest = sum(i == 2)/length(i);
Htest = sum(i == 3)/length(i);

figure()
pie([Ctrain; Etrain; Htrain]);
title('Structural assignments in training data set');
legend('C', 'E', 'H')

figure()
pie([Cval; Eval; Hval]);
title('Structural assignments in validation data set');
legend('C', 'E', 'H')

figure()
pie([Ctest; Etest; Htest]);
title('Structural assignments in testing data set ');
legend('C', 'E', 'H')

Функциональный plotperform отображает тренды обучения, валидации, и тестирует ошибки как учебную передачу итераций.

figure()
plotperform(tr)

Учебный процесс останавливается, когда одно из нескольких условий (см. net.trainParam) соблюдают. Например, в рассмотренном обучении, учебный процесс останавливается, когда ошибочные увеличения валидации для конкретного количества итераций (6) или максимальное количество позволенных итераций достигнуты (1000).

% === display training parameters
net.trainParam

% === plot validation checks and gradient
figure()
plottrainstate(tr)
ans = 

 
    Function Parameters for 'trainscg'
 
    Show Training Window Feedback   showWindow: true
    Show Command Line Feedback showCommandLine: false
    Command Line Frequency                show: 25
    Maximum Epochs                      epochs: 1000
    Maximum Training Time                 time: Inf
    Performance Goal                      goal: 0
    Minimum Gradient                  min_grad: 1e-06
    Maximum Validation Checks         max_fail: 6
    Sigma                                sigma: 5e-05
    Lambda                              lambda: 5e-07
 

Анализ сетевого ответа

Чтобы анализировать сетевой ответ, мы исследуем матрицу беспорядка путем рассмотрения выходных параметров обучившего сеть и сравнения их с ожидаемыми результатами (цели).

O = sim(net,P);
figure()
plotconfusion(T,O);

Диагональные ячейки показывают количество положений остатка, которые были правильно классифицированы для каждого структурного класса. Недиагональные ячейки показывают количество положений остатка, которые были неправильно классифицированы (например, спиральные положения, предсказанные как обмотанные положения). Диагональные ячейки соответствуют наблюдениям, которые правильно классифицируются. И количество наблюдений и процент общего количества наблюдений показывают в каждой ячейке. Столбец на ультраправом из графика показывает проценты всех примеров, предсказанных, чтобы принадлежать каждому классу, которые правильно и неправильно классифицируются. Эти метрики часто называются точностью (или положительное прогнозирующее значение) и ложный уровень открытия, соответственно. Строка в нижней части графика показывает проценты всех примеров, принадлежащих каждому классу, которые правильно и неправильно классифицируются. Эти метрики часто называются отзывом (или истинный положительный уровень) и ложный отрицательный уровень, соответственно. Ячейка в правом нижнем из графика показывает общую точность.

Мы можем также рассмотреть кривую Рабочей характеристики получателя (ROC), график истинного положительного уровня (чувствительность) по сравнению с ложным положительным уровнем (1 - специфика).

figure()
plotroc(T,O);

Совершенствование нейронной сети для более точных результатов

Нейронная сеть, которую мы задали, относительна простой. Чтобы достигнуть некоторых улучшений точности прогноза, мы могли попробовать одно из следующего:

  • Увеличьте число учебных векторов. Увеличение числа последовательностей, выделенных обучению, требует большей курировавшей базы данных структур белка с соответствующим распределением обмотанных, элементов листа и спиральных.

  • Увеличьте число входных значений. Увеличивание размера окна или добавляющий более релевантную информацию, такую как биохимические свойства аминокислот, является допустимыми опциями.

  • Используйте различный учебный алгоритм. Различные алгоритмы отличаются по требованиям к памяти и скорости. Например, Масштабированный алгоритм Метода сопряженных градиентов является относительно медленным, но эффективная память, в то время как Levenberg-Marquardt быстрее, но более требователен с точки зрения памяти.

  • Увеличьте число скрытых нейронов. Путем добавления более скрытых модулей мы обычно получаем более сложную сеть с потенциалом для лучшей производительности, но мы должны бояться сверхсоответствовать данным.

Мы можем задать больше скрытых слоев или увеличенного размера скрытого слоя, когда сеть распознавания образов создается, как показано ниже:

hsize = [3 4 2];
net3 = patternnet(hsize);

hsize = 20;
net20 = patternnet(hsize);

Мы можем также присвоить сетевые начальные веса случайным значениям в области значений-0.1 к 0,1, как предложено исследованием, о котором сообщают в [2] путем установки свойств net20.IW и net20.LW можно следующим образом:

% === assign random values in the range -.1 and .1 to the weights
net20.IW{1} = -.1 + (.1 + .1) .* rand(size(net20.IW{1}));
net20.LW{2} = -.1 + (.1 + .1) .* rand(size(net20.LW{2}));

В целом большие сети (с 20 или больше скрытыми модулями) достигают лучшей точности на наборе обучающих данных белка, но худшей точности в точности прогноза. Поскольку сеть с 20 скрытыми модулями включает почти 7 000 весов и смещений, сеть обычно может соответствовать набору обучающих данных тесно, но теряет способность обобщения. Компромисс между интенсивным обучением и точностью прогноза является одним из основных ограничений нейронных сетей.

net20 = train(net20,P,T);

O20 = sim(net20,P);
numWeightsAndBiases = length(getx(net20))
numWeightsAndBiases =

        6883

Можно отобразить матрицы беспорядка для обучения, валидации и протестировать подмножества путем нажатия на соответствующую кнопку в учебном окне инструментов.

Оценка производительности сети

Можно оценить прогнозы структуры подробно путем вычисления качественных индексов прогноза [3], которые указывают, как хорошо конкретное состояние предсказано и или сверхпрогноз, или underprediction произошел. Мы задаем индекс pcObs (S) для состояния S (S = {C, E, H}) как количество остатков, правильно предсказанных в состоянии S, разделенный на количество остатков, наблюдаемых в состоянии S. Точно так же мы задаем индекс pcPred (S) для состояния S как количество остатков, правильно предсказанных в состоянии S, разделенный на количество остатков, предсказанных в состоянии S.

[i,j] = find(compet(O));
[u,v] = find(T);

% === compute fraction of correct predictions when a given state is observed
pcObs(1) = sum(i == 1 & u == 1)/sum (u == 1); % state C
pcObs(2) = sum(i == 2 & u == 2)/sum (u == 2); % state E
pcObs(3) = sum(i == 3 & u == 3)/sum (u == 3); % state H

% === compute fraction of correct predictions when a given state is predicted
pcPred(1) = sum(i == 1 & u == 1)/sum (i == 1); % state C
pcPred(2) = sum(i == 2 & u == 2)/sum (i == 2); % state E
pcPred(3) = sum(i == 3 & u == 3)/sum (i == 3); % state H

% === compare quality indices of prediction
figure()
bar([pcObs' pcPred'] * 100);
ylabel('Correctly predicted positions (%)');
ax = gca;
ax.XTickLabel = {'C';'E';'H'};
legend({'Observed','Predicted'});

Эти качественные индексы полезны для интерпретации точности прогноза. На самом деле, в случаях, где метод прогноза ухаживает к overpredict/underpredict за данным состоянием, высокая/низкая точность прогноза может только быть артефактом и не обеспечивает меру качества для самого метода.

Заключения

Методика, представленная здесь, предсказывает структурное состояние данного остатка белка на основе структурного состояния его соседей. Однако существуют дальнейшие ограничения при предсказании содержимого структурных элементов в белке, такие как минимальная длина каждого структурного элемента. А именно, спираль присвоена любой группе из четырех или больше непрерывных остатков, и лист присвоен любой группе из двух или больше непрерывных остатков. Чтобы включить этот тип информации, дополнительная сеть может быть создана так, чтобы первая сеть предсказала структурное состояние от последовательности аминокислот, и вторая сеть предсказывает структурный элемент от структурного состояния.

nntraintool('close') % close Neural Network Training Tool

Ссылки

[1] Rost, B. и Шлифовальный станок, C., "Прогноз белка вторичная структура в лучше, чем 70%-я точность", Журнал Молекулярной биологии, 232 (2):584-99, 1993.

[2] Холли, L.H. и Karplus, M., "Белок вторичный прогноз структуры с нейронной сетью", PNAS, 86 (1):152-6, 1989.

[3] Kabsch, W. и Шлифовальный станок, C., "Насколько хороший являются прогнозы белка вторичной структурой?", Буквы FEBS, 155 (2):179-82, 1983.