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