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

Этот пример показывает вторичный метод предсказания структуры, который использует нейронную сеть прямого распространения и функциональность, доступную с 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 входные модули, i.e. 17 групп из 20 входных параметров каждый.

В следующем коде мы сначала определяем для каждой последовательности белка все возможные подпоследовательности, соответствующие раздвижному окну размера W путем создания матрицы Ганкеля, где i-ый столбец представляет подпоследовательность, запускающуюся в i-ом положении в исходной последовательности. Затем для каждого положения в окне, мы создаем массив размера 20, и мы устанавливаем j-ый элемент на 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);

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

Мы можем также рассмотреть кривую Рабочей характеристики приемника (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 за данным состоянием, высокая/низкая точность предсказания может только быть артефактом и не обеспечивает меру качества для самого метода.

Заключения

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

Ссылки

[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.