Реферат: Notebook "нейронные сети" Глава 2
Notebook "Нейронные сети"
NOTEBOOK
"НЕЙРОННЫЕ СЕТИ"
Глава 2 С34. Единичная функция активации с жестким ограничением hardlim.
Эта функция описывается соотношением
a = hardlim(n) = 1(n)
и равна 0, если n < 0,
и равна 1, если n 0.
Построим график этой функции в диапазоне значений входа от -5 до + 5:
n = -5:0.1:5;
plot(n,hardlim(n),'b+:');
^ C34. Линейная функция активации purelin.
Эта функция описывается соотношением
a = purelin(n) = n.
Построим график этой функции в диапазоне значений входа от -5 до + 5:
n=-5:0.1:5;
plot(n,purelin(n),'b+:');
^ C34. Логистическая функция активации logsig.
Эта функция описывается соотношением
a = logsig(n) = 1/(1 + exp(-n)).
Она принадлежит к классу сигмоидальных функций, и ее аргумент может принимать любое значение в диапазоне от - до +, а выход изменяется в диапазоне от 0 до 1. Благодаря свойству дифференцируемости, эта функция часто используется в сетях с обучением на основе метода обратного распространения ошибки.
Построим график этой функции в диапазоне значений входа от -5 до + 5:
n=-5:0.1:5;
plot(n,logsig(n),'b+:');
^ C42. Формирование архитектуры нейронной сети.
Следующий оператор создает сеть с прямой передачей сигнала
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingd');
gensim(net)
Эта сеть использует один вектор входа с двумя элементами, имеющими допустимые границы значений [-1 2] и [0 5];
- имеет 2 слоя с 3 нейронами в первом слое и 1 нейроном во втором слое;
- используемые функции активации: tansig - в первом слое, purelin – во втором слое;
используемая функция обучения traingd.
^ C42. Инициализация нейронной сети.
После того как сформирована архитектура сети, должны быть заданы начальные значения весов и смещений, или иными словами, сеть должна быть инициализирована. Такая процедура выполняется с помощью метода init для объектов класса network. Оператор вызова этого метода имеет вид
net = init(net);
Если мы хотим заново инициализировать веса и смещения в первом слое, используя функцию rands, то следует ввести следующую последовательность операторов:
net.layers{1}.initFcn = 'initwb';
net.inputWeights{1,1}.initFcn = 'rands';
net.biases{1,1}.initFcn = 'rands';
net.biases{2,1}.initFcn = 'rands';
net = init(net);
^ C43. Моделирование сети.
Статическая нейронная сеть характеризуется тем, что в ее состав не входят линии задержки и обратные связи.
Рассмотрим однослойную сеть с двухэлементным вектором входа и линейной функцией активации. Для задания такой сети предназначена М-функция newlin, которая требует указать минимальное и максимальное значения для каждого из элементов входа; в данном случае они равны –1 и 1, соответственно, а также количество слоев, в данном случае 1.
Формирование однослойной линейной сети net с двухэлементным входным сигналом со значениями от -1 до 1:
net = newlin([-1 1;-1 1],1);
Определим весовую матрицу и смещение, равными ^ W = [1 2], b = 0, и зададим эти значения, используя описание структуры сети
net.IW{1,1} = [1 2];
net.b{1} = 0;
Предположим, что на сеть подается следующая последовательность из четырех векторов входа
Поскольку сеть статическая, можно перегруппировать эту последовательность в следующий числовой массив
P = [-1 0 0 1; 0 -1 1 -1];
Теперь можно моделировать сеть
A = sim(net,P)
A =
-1 -2 2 -1
Результат следует интерпретировать следующим образом. На вход сети подается последовательность из 4 входных сигналов, и сеть генерирует вектор выхода из 4 элементов.
^ Динамическая нейронная сеть характеризуется тем, что в ее состав входят линии задержки и/или обратные связи. Когда сеть содержит линии задержки, вход сети следует рассматривать как последовательность векторов, подаваемых на сеть в определенные моменты времени.
Создание однослойной линейной сети с линией задержки [0 1]:
net = newlin([-1 1],1,[0 1]);
Зададим следующую матрицу весов W=[1 2] и нулевое смещение:
net.IW{1,1} = [1 2];
net.biasConnect = 0;
Предположим, что входная последовательность имеет вид {-1, -1/2, 1/2, 1} и зададим ее в виде массива ячеек
P = {-1 -1/2 1/2 1};
Теперь можно моделировать сеть, используя метод sim:
A = sim(net,P)
A =
[-1] [-2.5000] [-0.5000] [2]
Если те же самые входы подать на сеть одновременно, то получим совершенно иную реакцию. Для этого сформируем следующий вектор входа
P = [-1 -1/2 1/2 1];
После моделирования получаем
A = sim(net,P)
A =
-1.0000 -0.5000 0.5000 1.0000
Результат такой же как, если применить каждый вход к отдельной сети и вычислить ее выход. Поскольку начальные условия для элементов запаздывания не указаны, то по умолчанию они приняты нулевыми. В этом случае выход сети равен
.
Если требуется моделировать реакцию сети для нескольких последовательностей сигналов на входе, то следует сформировать массив ячеек, размер каждой из которых совпадает с числом таких последовательностей. Пусть, например, требуется приложить к сети две последовательности
Вход P в этом случае должен быть массивом ячеек, каждая из которых содержит два элемента по числу последовательностей
P = {[-1,1],[-1/2,1/2],[1/2,-1/2],[1,-1]};
Теперь можно моделировать сеть:
A = sim(net,P); cat(1, A{:})
ans =
-1.0000 1.0000
-2.5000 2.5000
-0.5000 0.5000
2.0000 -2.0000
Глава 3 ^ C52. Адаптация нейронных сетей. Статические сети.
Воспользуемся следующей моделью однослойной линейной сети с двухэлементным вектором входа, значения которого находятся в интервале [–1 1] и нулевым параметром скорости настройки
clear
net = newlin([-1 1;-1 1],1, 0, 0);
Требуется адаптировать параметры сети так, чтобы она формировала линейную зависимость вида
^ Последовательный способ.
Рассмотрим случай последовательного представления обучающей последовательности. В этом случае входы и целевой вектор формируются в виде массива формата cell
P = {[-1; 1] [-1/3; 1/4] [1/2; 0] [1/6; 2/3]};
T = {-1 -5/12 1 1};
P1 = [P{:}], T1=[T{:}]
P1 =
-1.0000 -0.3333 0.5000 0.1667
1.0000 0.2500 0 0.6667
T1 =
-1.0000 -0.4167 1.0000 1.0000
Сначала зададим сеть с нулевыми значениями начальных весов и смещений
net.IW{1} = [0 0];
net.b{1} = 0;
Выполним один цикл адаптации сети с нулевым параметром скорости настройки:
[net1,a,e] = adapt(net,P,T);
В этом случае веса не модифицируются, выходы сети остаются нулевыми, поскольку параметр скорости настройки равен нулю, адаптации сети не происходит. Погрешности совпадают со значениями целевой последовательности
net1.IW{1, 1}, a, e
ans =
0 0
a =
[0] [0] [0] [0]
e =
[-1] [-0.4167] [1] [1]
Зададим значения параметров скорости настройки и весов входа и смещения
net.IW{1} = [0 0];
net.b{1} = 0;
net.inputWeights{1,1}.learnParam.lr = 0.2;
net.biases{1,1}.learnParam.lr = 0;
Выполним один цикл настройки:
[net1,a,e] = adapt(net,P,T);
net1.IW{1, 1}, a, e
ans =
0.3454 -0.0694
a =
[0] [-0.1167] [0.1100] [-0.0918]
e =
[-1] [-0.3000] [0.8900] [1.0918]
Теперь выполним последовательную адаптацию сети в течение 30 циклов:
net = newlin([-1 1;-1 1],1, 0, 0);
net.IW{1} = [0 0];
net.b{1} = 0;
Зададим значения параметров скорости настройки для весов входа и смещения
net.inputWeights{1,1}.learnParam.lr = 0.2;
net.biases{1,1}.learnParam.lr = 0;
P = {[-1; 1] [-1/3; 1/4] [1/2; 0] [1/6; 2/3]};
T = {-1 -5/12 1 1};
for i=1:30,
[net,a{i},e{i}] = adapt(net,P,T);
W(i,:)=net.IW{1,1};
end
mse(cell2mat(e{30}))
ans =
0.0017
Веса после 30 циклов:
W(30,:)
ans =
1.9199 0.9250
cell2mat(a{30})
ans =
-0.9944 -0.4086 0.9566 0.9301
cell2mat(e{30})
ans =
-0.0056 -0.0081 0.0434 0.0699
Построим графики зависимости значений выходов сети и весовых коэффициентов в зависимости от числа итераций:
subplot(3,1,1)
plot(0:30,[[0 0 0 0];cell2mat(cell2mat(a'))],'k')
xlabel(''), ylabel('Выходы a(i)'),grid
subplot(3,1,2)
plot(0:30,[[0 0]; W],'k')
xlabel(''), ylabel('Веса входов w(i)'),grid
subplot(3,1,3)
for i=1:30, E(i) = mse(e{i}); end
semilogy(1:30, E,'+k')
xlabel(' Циклы'), ylabel('Ошибка'),grid
^ Групповой способ.
Рассмотрим случай группового представления обучающей последовательности. В этом случае входы и целевой вектор формируются в виде массива формата double:
clear
P = [-1 -1/3 1/2 1/6; 1 1/4 0 2/3];
T = [-1 -5/12 1 1];
Основной цикл адаптации сети выглядит следующим образом:
net3 = newlin([-1 1;-1 1],1, 0, 0.2);
net3.IW{1} = [0 0];
net3.b{1} = 0;
net3.inputWeights{1,1}.learnParam.lr = 0.2;
EE = 10; i=1;
while EE > 0.0017176
[net3,a{i},e{i},pf] = adapt(net3,P,T);
W(i,:) = net3.IW{1,1};
EE = mse(e{i});
ee(i)= EE;
i = i+1;
end
Результатом адаптации являются следующие значения коэффициентов, значений выходов и среднеквадратической погрешности адаптации
W(63,:)
ans =
1.9114 0.8477
cell2mat(a(63))
ans =
-1.0030 -0.3624 1.0172 0.9426
EE = mse(e{63})
EE =
0.0016
mse(e{1})
ans =
0.7934
Процедура адаптации выходов и параметров нейронной сети иллюстрируется графиками:
subplot(3,1,1)
plot(0:63,[zeros(1,4); cell2mat(a')],'k') % Рис.3.2,a
xlabel(''), ylabel('Выходы a(i)'),grid
subplot(3,1,2)
plot(0:63,[[0 0]; W],'k') % Рис.3.2,б
xlabel(''), ylabel('Веса входов w(i)'),grid
subplot(3,1,3)
semilogy(1:63, ee,'+k') % Рис.3.2,в
xlabel('Циклы'), ylabel('Ошибка'),grid
^ С56. Динамические сети.
Эти сети характеризуются наличием линий задержки, и для них последовательное представление входов является наиболее естественным.
^ Последовательный способ.
Обратимся к линейной модели нейронной сети с одним входом и одним элементом запаздывания. Установим начальные условия на линии задержки, а также для весов и смещения равными нулю; а параметр скорости настройки равным 0.5.
clear
net = newlin([-1 1],1,[0 1],0.5);
Pi = {0};
net.IW{1} = [0 0];
net.biasConnect = 0;
Чтобы применить последовательный способ адаптации, представим входы и цели как массивы ячеек
P = {-1/2 1/3 1/5 1/4};
T = { -1 1/6 11/15 7/10};
Попытаемся адаптировать сеть формировать нужный выход на основе следующего соотношения
y(t) = 2p(t) + p(t-1).
Используем для этой цели М-функцию adapt и основной цикл адаптации сети с заданной погрешностью:
EE = 10; i = 1;
while EE > 0.0001
[net,a{i},e{i},pf] = adapt(net,P,T);
W(i,:)=net.IW{1,1};
EE = mse(e{i});
ee(i) = EE;
i = i+1;
end
Сеть адаптировалась за 22 цикла. Результатом адаптации при заданной погрешности являются следующие значения коэффициентов, выходов нейронной сети и среднеквадратической погрешности
W(22,:)
ans =
1.9830 0.9822
a{22}
ans =
[-0.9896] [0.1714] [0.7227] [0.6918]
EE
EE =
7.7874e-005
Построим графики зависимости выходов системы и весовых коэффициентов от числа циклов обучения:
subplot(3,1,1)
plot(0:22,[zeros(1,4); cell2mat(cell2mat(a'))],'k') % Рис.3.3,a
xlabel(''), ylabel('Выходы a(i)'),grid
subplot(3,1,2)
plot(0:22,[[0 0]; W],'k') % Рис.3.3,б
xlabel(''), ylabel('Веса входов w(i)'),grid
subplot(3,1,3)
semilogy(1:22,ee,'+k') % Рис.3.3,в
xlabel('Циклы'), ylabel('Ошибка'),grid
^ C58. Обучение нейронных сетей Статические сети.
Воспользуемся моделью однослойной линейной сети с двухэлементным вектором входа, значения которого находятся в интервале [–1 1] и нулевым параметром скорости настройки, как это было для случая адаптации:
clear
net = newlin([-1 1;-1 1],1, 0, 0);
net.IW{1} = [0 0];
net.b{1} = 0;
Требуется обучить параметры сети так, чтобы она формировала линейную зависимость вида
.
^ Последовательный способ.
Представим обучающую последовательность в виде массивов ячеек
P = {[-1; 1] [-1/3; 1/4] [1/2; 0] [1/6; 2/3]};
T = {-1 -5/12 1 1};
Теперь все готово к обучению сети. Будем обучать ее с помощью функции train в течение 30 циклов. Для обучения и настройки параметров сети используем функции trainwb и learnwh, соответственно.
net.inputWeights{1,1}.learnParam.lr = 0.2;
net.biases{1}.learnParam.lr = 0;
net.trainParam.epochs = 30;
net1 = train(net,P,T);
TRAINB, Epoch 0/30, MSE 0.793403/0.
TRAINB, Epoch 25/30, MSE 0.00373997/0.
TRAINB, Epoch 30/30, MSE 0.00138167/0.
TRAINB, Maximum epoch reached.
Параметры сети после обучения равны следующим значениям
W = net1.IW{1}
W =
1.9214 0.9260
y = sim(net1, P)
y =
[-0.9954] [-0.4090] [0.9607] [0.9376]
EE = mse([y{:}]-[T{:}])
EE =
0.0014
^ Групповой способ.
Для этого представим обучающую последовательность в виде массивов формата double array:
P = [-1 -1/3 1/2 1/6; 1 1/4 0 2/3];
T = [-1 -5/12 1 1];
net1 = train(net,P,T);
TRAINB, Epoch 0/30, MSE 0.793403/0.
TRAINB, Epoch 25/30, MSE 0.00373997/0.
TRAINB, Epoch 30/30, MSE 0.00138167/0.
TRAINB, Maximum epoch reached.
Параметры сети после обучения равны следующим значениям
W = net1.IW{1}
W =
1.9214 0.9260
y = sim(net1, P)
y =
-0.9954 -0.4090 0.9607 0.9376
EE = mse(y-T)
EE =
0.0014
^ Динамические сети.
Обучение динамических сетей выполняется аналогичным образом с использованием метода train.
Последовательный способ.
Обратимся к линейной модели нейронной сети с одним входом и одним элементом запаздывания.
Установим начальные условия для элемента запаздывания, весов и смещения, равными нулю; параметр скорости настройки, равным 0.5.
clear
net = newlin([-1 1],1,[0 1],0.5);
Pi = {0};
net.IW{1} = [0 0];
net.biasConnect = 0;
net.trainParam.epochs = 22;
Чтобы применить последовательный способ обучения, представим входы и цели как массивы ячеек
P = {-1/2 1/3 1/5 1/4};
T = { -1 1/6 11/15 7/10};
Используем для этой цели М-функцию train
net1 = train(net, P, T, Pi);
TRAINB, Epoch 0/22, MSE 0.513889/0.
TRAINB, Epoch 22/22, MSE 3.65137e-005/0.
TRAINB, Maximum epoch reached.
Параметры сети после обучения равны следующим значениям
W = net1.IW{1}
W =
1.9883 0.9841
y = sim(net1, P)
y =
[-0.9941] [0.1707] [0.7257] [0.6939]
EE = mse([y{:}]-[T{:}])
EE =
3.6514e-005
^ Градиентные алгоритмы обучения. С67. Алгоритм GD.
Алгоритм GD, или алгоритм градиентного спуска используется для такой корректировки весов и смещений, чтобы минимизировать функционал ошибки, то есть обеспечить движение по поверхности функционала в направлении, противоположном градиенту функционала по настраиваемым параметрам.
Рассмотрим двухслойную нейронную сеть прямой передачи сигнала с сигмоидальным и линейным слоями для обучения ее на основе метода обратного распространения ошибки
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingd');
^ Последовательная адаптация.
Чтобы подготовить модель сети к процедуре последовательной адаптации на основе алгоритма GD, необходимо указать ряд параметров. В первую очередь, это имя функции настройки learnFcn, соответствующее алгоритму градиентного спуска, в данном случае – это М-функция learngd:
net.biases{1,1}.learnFcn = 'learngd';
net.biases{2,1}.learnFcn = 'learngd';
net.layerWeights{2,1}.learnFcn = 'learngd';
net.inputWeights{1,1}.learnFcn = 'learngd';
С функцией learngd связан лишь один параметр скорости настройки lr. Текущие приращения весов и смещений сети определяются умножением этого параметра на вектор градиента. Чем больше значение параметра, тем больше приращение на текущей итерации. Если параметр скорости настройки выбран слишком большим, алгоритм может стать неустойчивым; если параметр слишком мал, то алгоритм может потребовать длительного счета.
При выборе функции learngd по умолчанию устанавливается следующее значение параметра скорости настройки
net.layerWeights{2,1}.learnParam
ans =
lr: 0.0100
Увеличим значение этого параметра до 0.2
net.layerWeights{2,1}.learnParam.lr = 0.2;
Мы теперь почти готовы к обучению сети. Осталось задать обучающее множество. Это простое множество входов и целей определим следующим образом
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
Поскольку используется последовательный способ обучения, необходимо преобразовать массивы входов и целей в массивы ячеек
p = num2cell(p,1);
t = num2cell(t,1);
Последний параметр, который требуется установить при последовательном обучении, это число проходов net.adaptParam.passes
net.adaptParam.passes = 50;
Теперь можно выполнить настройку параметров, используя процедуру адаптации
[net,a,e] = adapt(net,p,t);
Чтобы проверить качество обучения, после окончания обучения смоделируем сеть.
a = sim(net,p)
a =
-1.0127 -0.9960 1.0189 0.9813
mse(e)
ans =
2.4546e-004
^ Групповое обучение.
Для обучения сети на основе алгоритма GD необходимо использовать М-функцию traingd взамен функции настройки learngd. В этом случае нет необходимости задавать индивидуальные функции обучения для весов и смещений, а достаточно указать одну обучающую функцию для всей сети.
Вновь создадим ту же двухслойную нейронную сеть прямой передачи сигнала с сигмоидальным и линейным слоями для обучения по методу обратного распространения ошибки
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingd');
Функция traingd характеризуется следующими параметрами, заданными по умолчанию
net.trainParam
ans =
epochs: 100
goal: 0
lr: 0.0100
max_fail: 5
min_grad: 1.0000e-010
show: 25
time: Inf
Установим новые значения параметров обучения, зададим обучающую последовательность в виде массива double и выполним процедуру обучения
net.trainParam.show = 50;
net.trainParam.lr = 0.05;
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); % Рис.3.8
TRAINGD, Epoch 0/300, MSE 0.300839/1e-005, Gradient 0.884133/1e-010
TRAINGD, Epoch 50/300, MSE 0.00576418/1e-005, Gradient 0.0975344/1e-010
TRAINGD, Epoch 100/300, MSE 6.76541e-005/1e-005, Gradient 0.0109646/1e-010
TRAINGD, Epoch 121/300, MSE 9.98702e-006/1e-005, Gradient 0.00422134/1e-010
TRAINGD, Performance goal met.
^ С69. Алгоритм GDM
Вновь рассмотрим двухслойную нейронную сеть прямой передачи сигнала с сигмоидальным и линейным слоями (рис. 3.7)
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingdm');
^ Последовательная адаптация.
Чтобы подготовить модель сети к процедуре последовательной адаптации на основе алгоритма GDM, необходимо указать ряд параметров. В первую очередь, это имя функции настройки learnFcn, соответствующее алгоритму градиентного спуска с возмущением, в данном случае – это М-функция learngdm:
net.biases{1,1}.learnFcn = 'learngdm';
net.biases{2,1}.learnFcn = 'learngdm';
net.layerWeights{2,1}.learnFcn = 'learngdm';
net.inputWeights{1,1}.learnFcn = 'learngdm';
С этой функцией связано два параметра - параметр скорости настройки lr и параметр возмущения mc.
При выборе функции learngdm по умолчанию устанавливаются следующие значения этих параметров
net.layerWeights{2,1}.learnParam
ans =
lr: 0.0100
mc: 0.9000
Увеличим значение параметра скорости обучения до 0.2
net.layerWeights{2,1}.learnParam.lr = 0.2;
Мы теперь почти готовы к обучению сети. Осталось задать обучающее множество и количество проходов, равное 50.
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
p = num2cell(p,1);
t = num2cell(t,1);
net.adaptParam.passes = 50;
tic, [net,a,e] = adapt(net,p,t); toc
elapsed_time = 4.78
a, mse(e)
elapsed_time =
3.4600
elapsed_time =
4.7800
a =
[-0.9889] [-1.0007] [1.0182] [0.9917]
ans =
1.3116e-004
Эти результаты сравнимы с результатами работы алгоритма GD, рассмотренного ранее.
^ Групповое обучение.
Альтернативой последовательной адаптации является групповое обучение, которое основано на применении функции train. В этом режиме параметры сети модифицируются только после того, как реализовано все обучающее множество, и градиенты, рассчитанные для каждого элемента множества, суммируются, чтобы определить приращения настраиваемых параметров.
Для обучения сети на основе алгоритма GDM необходимо использовать М-функцию traingdm взамен функции настройки learngdm. Различие этих двух функций состоит в следующем. Алгоритм функции traingdm суммирует градиенты, рассчитанные на каждом цикле обучения, а параметры модифицируются только после того, как все обучающие данные будут представлены. Если проведено N циклов обучения и для функционала ошибки оказалось выполненным условие , то параметр возмущения mc следует установить в нуль.
Вновь обратимся к той же сети
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingdm');
Функция traingdm характеризуется следующими параметрами, заданными по умолчанию
net.trainParam
ans =
epochs: 100
goal: 0
lr: 0.0100
max_fail: 5
mc: 0.9000
min_grad: 1.0000e-010
show: 25
time: Inf
По сравнению с функцией traingd здесь добавляется только один параметр возмущения mc.
Установим следующие значения параметров обучения
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
net.trainParam.lr = 0.05;
net.trainParam.mc = 0.9;
net.trainParam.show = 50;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t);
TRAINGDM, Epoch 0/300, MSE 1.93032/1e-005, Gradient 3.53636/1e-010
TRAINGDM, Epoch 50/300, MSE 0.0176601/1e-005, Gradient 0.202784/1e-010
TRAINGDM, Epoch 100/300, MSE 0.000838074/1e-005, Gradient 0.0350156/1e-010
TRAINGDM, Epoch 146/300, MSE 9.1672e-006/1e-005, Gradient 0.00361773/1e-010
TRAINGDM, Performance goal met.
На рис. приведен график изменения ошибки обучения в зависимости от числа выполненных циклов.
a = sim(net,p)
a =
-0.9949 -1.0027 1.0011 1.0014
Поскольку начальные веса и смещения инициализируются случайным образом, графики ошибок могут отличаться от одной реализации к другой и от графиков на рис. 3.8-3.9 книги.
^ С72. Алгоритм GDA
Вновь обратимся к той же нейронной сети (рис. 3.7), но будем использовать функцию обучения traingda
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingda'); Функция traingda характеризуется следующими параметрами по умолчанию:
net.trainParam
ans =
epochs: 100
goal: 0
lr: 0.0100
lr_inc: 1.0500
lr_dec: 0.7000
max_fail: 5
max_perf_inc: 1.0400
min_grad: 1.0000e-006
show: 25
time: Inf
Установим следующие значения этих параметров и выполним обучение:
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
net.trainParam.lr = 0.05;
net.trainParam.mc = 0.9;
net.trainParam.show = 50;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); % Рис.3.10
TRAINGDA, Epoch 0/300, MSE 8.20691e-006/1e-005, Gradient 0.0024486/1e-006
TRAINGDA, Performance goal met.
Теперь выполним моделирование обученной нейронной сети:
a = sim(net,p)
a =
-0.9989 -1.0007 0.9955 1.0032
^ С73. Алгоритм Rprop
Алгоритм Rprop использует функцию обучения trainrp
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'trainrp');
Функция trainrp характеризуется следующими параметрами, заданными по умолчанию:
net.trainParam
ans =
epochs: 100
show: 25
goal: 0
time: Inf
min_grad: 1.0000e-006
max_fail: 5
delt_inc: 1.2000
delt_dec: 0.5000
delta0: 0.0700
deltamax: 50
Установим следующие значения этих параметров:
net.trainParam.show = 10;
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); % Рис.3.11
TRAINRP, Epoch 0/300, MSE 2.27506/1e-005, Gradient 3.27134/1e-006
TRAINRP, Epoch 10/300, MSE 0.0190078/1e-005, Gradient 0.28722/1e-006
TRAINRP, Epoch 20/300, MSE 6.80914e-005/1e-005, Gradient 0.0217624/1e-006
TRAINRP, Epoch 23/300, MSE 6.8422e-006/1e-005, Gradient 0.00289721/1e-006
TRAINRP, Performance goal met.
a = sim(net,p)
a =
-0.9957 -1.0019 0.9995 1.0023
^ Алгоритмы метода сопряженных градиентов. C76. Алгоритм CGF
Алгоритм CGF использует функцию обучения traincgf
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traincgf');
Функция traincgf по умолчанию характеризуется следующими параметрами:
net.trainParam
ans =
epochs: 100
show: 25
goal: 0
time: Inf
min_grad: 1.0000e-006
max_fail: 5
searchFcn: 'srchcha'
scale_tol: 20
alpha: 0.0010
beta: 0.1000
delta: 0.0100
gama: 0.1000
low_lim: 0.1000
up_lim: 0.5000
maxstep: 100
minstep: 1.0000e-006
bmax: 26
Установим следующие значения параметров:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); %Рис.3.12
TRAINCGF-srchcha, Epoch 0/300, MSE 0.711565/1e-005, Gradient 1.7024/1e-006
TRAINCGF-srchcha, Epoch 5/300, MSE 0.000975456/1e-005, Gradient 0.0253333/1e-006
TRAINCGF-srchcha, Epoch 10/300, MSE 3.06365e-005/1e-005, Gradient 0.00748491/1e-006
TRAINCGF-srchcha, Epoch 12/300, MSE 7.50883e-006/1e-005, Gradient 0.00189117/1e-006
TRAINCGF, Performance goal met.
a = sim(net,p)
a =
-1.0021 -0.9963 1.0029 0.9981
^ C78. Алгоритм CGP
Алгоритм CGP использует функцию обучения traincgp
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traincgp');
Изменим установку следующих параметров:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); %Рис.3.13
TRAINCGP-srchcha, Epoch 0/300, MSE 3.6913/1e-005, Gradient 4.54729/1e-006
TRAINCGP-srchcha, Epoch 5/300, MSE 0.00160249/1e-005, Gradient 0.077521/1e-006
TRAINCGP-srchcha, Epoch 8/300, MSE 9.42009e-006/1e-005, Gradient 0.00863694/1e-006
TRAINCGP, Performance goal met.
a = sim(net,p)
a =
-1.0042 -0.9976 0.9975 0.9972
^ C79. Алгоритм CGB
Рассмотрим работу этого алгоритма на примере следующей нейронной сети: clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traincgb');
Изменим установку следующих параметров:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); % Рис.3.14
TRAINCGB-srchcha, Epoch 0/300, MSE 1.65035/1e-005, Gradient 2.94633/1e-006
TRAINCGB-srchcha, Epoch 5/300, MSE 0.000813691/1e-005, Gradient 0.0222647/1e-006
TRAINCGB-srchcha, Epoch 10/300, MSE 0.000142255/1e-005, Gradient 0.00672937/1e-006
TRAINCGB-srchcha, Epoch 15/300, MSE 1.38893e-005/1e-005, Gradient 0.00260293/1e-006
TRAINCGB-srchcha, Epoch 16/300, MSE 7.09083e-006/1e-005, Gradient 0.0025014/1e-006
TRAINCGB, Performance goal met.
a = sim(net,p)
a =
-0.9985 -0.9987 0.9961 1.0030
^ C80. Алгоритм SCG
Алгоритм SCG использует функцию обучения trainrp
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'trainscg');
Функция trainrp по умолчанию характеризуется следующими параметрами:
net.trainParam
ans =
epochs: 100
show: 25
goal: 0
time: Inf
min_grad: 1.0000e-006
max_fail: 5
sigma: 5.0000e-005
lambda: 5.0000e-007
Изменим установки некоторых параметров:
net.trainParam.epochs = 300;
net.trainParam.show = 10;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); %Рис.3.15
TRAINSCG, Epoch 0/300, MSE 1.71149/1e-005, Gradient 2.6397/1e-006
TRAINSCG, Epoch 10/300, MSE 8.2375e-005/1e-005, Gradient 0.0100708/1e-006
TRAINSCG, Epoch 12/300, MSE 1.58889e-006/1e-005, Gradient 0.00321225/1e-006
TRAINSCG, Performance goal met.
a = sim(net,p)
a =
-1.0007 -1.0009 1.0022 0.9994
^ Квазиньютоновы алгоритмы C81. Алгоритм BFGS
Алгоритм BFGS использует функцию обучения trainbfg
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'trainbfg');
Установим параметры обучающей процедуры по аналогии с предшествующими примерами:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); %Рис.3.16
TRAINBFG-srchbac, Epoch 0/300, MSE 0.469151/1e-005, Gradient 1.4258/1e-006
TRAINBFG-srchbac, Epoch 5/300, MSE 0.00212634/1e-005, Gradient 0.0981181/1e-006
TRAINBFG-srchbac, Epoch 10/300, MSE 2.12166e-005/1e-005, Gradient 0.0119488/1e-006
TRAINBFG-srchbac, Epoch 12/300, MSE 2.687e-007/1e-005, Gradient 0.000475672/1e-006
TRAINBFG, Performance goal met.
a = sim(net,p)
a =
-0.9994 -1.0007 0.9998 1.0003
^ C82. Алгоритм OSS
Алгоритм OSS использует функцию обучения trainoss
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'trainoss');
Установим параметры обучающей процедуры по аналогии с предшествующими примерами:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net=train(net,p,t); %Рис.3.17
TRAINOSS-srchbac, Epoch 0/300, MSE 2.15911/1e-005, Gradient 3.17681/1e-006
TRAINOSS-srchbac, Epoch 5/300, MSE 0.315332/1e-005, Gradient 1.12347/1e-006
TRAINOSS-srchbac, Epoch 10/300, MSE 0.0294864/1e-005, Gradient 0.553976/1e-006
TRAINOSS-srchbac, Epoch 15/300, MSE 0.000315263/1e-005, Gradient 0.0220646/1e-006
TRAINOSS-srchbac, Epoch 20/300, MSE 1.26224e-006/1e-005, Gradient 0.000784773/1e-006
TRAINOSS, Performance goal met.
a = sim(net,p)
a =
-0.9987 -1.0006 0.9986 1.0010
^ C83. Алгоритм LM
Алгоритм LM использует функцию обучения trainlm:
clear
net = newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'trainlm');
Функция trainlm по умолчанию характеризуется следующими параметрами:
net.trainParam
ans =
epochs: 100
goal: 0
max_fail: 5
mem_reduc: 1
min_grad: 1.0000e-010
mu: 0.0010
mu_dec: 0.1000
mu_inc: 10
mu_max: 1.0000e+010
show: 25
time: Inf
Установим параметры обучающей процедуры по аналогии с предшествующими примерами:
net.trainParam.epochs = 300;
net.trainParam.show = 5;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net = train(net,p,t); %Рис.3.18
TRAINLM, Epoch 0/300, MSE 2.99886/1e-005, Gradient 7.55892/1e-010
TRAINLM, Epoch 4/300, MSE 4.88189e-009/1e-005, Gradient 0.000243573/1e-010
TRAINLM, Performance goal met.
a = sim(net,p)
a =
-1.0000 -1.0000 1.0001 1.0000
^ Расширение возможностей процедур обучения. C89. Переобучение.
Рассмотрим нейронную сеть типа 1-30-1 с 1 входом, 30 скрытыми нейронами и 1 выходом, которую необходимо обучить аппроксимировать функцию синуса, если заданы ее приближенные значения, которые получены как сумма значений синуса и случайных величин, распределенных по нормальному закону
clear
net = newff([-1 1],[30,1],{'tansig','purelin'},'trainbfg');
net.trainParam.epochs = 500;
net.trainParam.show = 50;
net.trainParam.goal = 1e-5;
p = [-1:0.05:1];
t = sin(2*pi*p)+0.1*randn(size(p));
t1 = sin(2*pi*p);
[net,tr] = train(net,p,t); %Рис.3.19
TRAINBFG-srchbac, Epoch 0/500, MSE 7.31152/1e-005, Gradient 14.7762/1e-006
TRAINBFG-srchbac, Epoch 50/500, MSE 0.000354095/1e-005, Gradient 0.00393802/1e-006
TRAINBFG-srchbac, Epoch 100/500, MSE 1.86929e-005/1e-005, Gradient 0.000200169/1e-006
TRAINBFG-srchbac, Epoch 105/500, MSE 9.84507e-006/1e-005, Gradient 0.000336686/1e-006
TRAINBFG, Performance goal met.
Для того чтобы убедиться, что в данном случае мы сталкиваемся с явлением переобучения, построим графики аппроксимируемой функции, ее приближенных значений и результата аппроксимации:
an = sim(net,p);
figure(1); plot(p,t,'+',p,an,'-',p,t1,':') % Рис.3.20
legend('вход','выход','sin(2pi*t)'); grid on
^ C91. Метод регуляризации.
Рассмотрим нейронную сеть типа 1-5-1 с 1 входом, 5 скрытыми нейронами и 1 выходом. Эта сеть использует те же типы нейронов, как и предыдущая сеть, но количество скрытых нейронов в 6 раз меньше, предельное количество циклов обучения сокращено до 100, а параметр регуляризации равен 0.9998.
clear
net = newff([-1 1],[5,1],{'tansig','purelin'},'trainbfg');
net.trainParam.epochs = 100;
net.trainParam.show = 50;
net.trainParam.goal = 1e-5;
net.performFcn = 'msereg';
net.performParam.ratio = 0.9998;
p = [-1:0.05:1];
t = sin(2*pi*p)+0.1*randn(size(p));
t1 = sin(2*pi*p);
[net,tr] = train(net,p,t); %Рис.3.21,а
TRAINBFG-srchbac, Epoch 0/100, MSEREG 1.44168/1e-005, Gradient 4.02109/1e-006
TRAINBFG-srchbac, Epoch 50/100, MSEREG 0.00943887/1e-005, Gradient 0.00377816/1e-006
TRAINBFG-srchbac, Epoch 100/100, MSEREG 0.00747179/1e-005, Gradient 0.00630789/1e-006
TRAINBFG, Maximum epoch reached, performance goal was not met.
an = sim(net,p);
figure(1); plot(p,t,'+',p,an,'-',p,t1,':') % Рис.3.21,б
legend('вход','выход','sin(2pi*t)'); grid on
^ Автоматическая регуляризация.
Вновь обратимся к нейронной сети типа 1-20-1, предназначенной для решения задачи аппроксимации функции синуса.
clear
net = newff([-1 1],[20,1],{'tansig','purelin'},'trainbr');
Функция trainbr по умолчанию характеризуется следующими параметрами:
net.trainParam
ans =
epochs: 100
show: 25
goal: 0
time: Inf
min_grad: 1.0000e-010
max_fail: 5
mem_reduc: 1
mu: 0.0050
mu_dec: 0.1000
mu_inc: 10
mu_max: 1.0000e+010
Установим следующие значения этих параметров:
net = newff([-1 1],[20,1],{'tansig','purelin'},'trainbr');
net.trainParam.epochs = 50;
net.trainParam.show = 10;
randn('seed',192736547);
p = [-1:.05:1];
t = sin(2*pi*p)+0.1*randn(size(p));
net = init(net);
net = train(net,p,t); % Рис.3.22
TRAINBR, Epoch 0/50, SSE 69.5303/0, SSW 21463.6, Grad 1.19e+002/1.00e-010, #Par 6.10e+001/61
TRAINBR, Epoch 10/50, SSE 0.0765763/0, SSW 6859.43, Grad 8.53e-003/1.00e-010, #Par 3.40e+001/61
TRAINBR, Epoch 20/50, SSE 0.0602212/0, SSW 5018.79, Grad 3.18e-001/1.00e-010, #Par 3.43e+001/61
TRAINBR, Epoch 30/50, SSE 0.0577611/0, SSW 4530.75, Grad 1.59e-002/1.00e-010, #Par 3.38e+001/61
TRAINBR, Epoch 40/50, SSE 0.0761021/0, SSW 2622.33, Grad 7.98e-002/1.00e-010, #Par 3.17e+001/61
TRAINBR, Epoch 50/50, SSE 0.0800647/0, SSW 2355.29, Grad 3.70e-002/1.00e-010, #Par 3.13e+001/61
TRAINBR, Maximum epoch reached.
Построим графики исследуемых функций:
an = sim(net,p); t1 = sin(2*pi*p);
figure(1); plot(p,t,'+',p,an,'-',p,t1,':') % Рис.3.22
legend('вход','выход','sin(2pi*t)'); grid on
^ C94. Формирование представительной выборки
Сформируем обучающее подмножество на интервале входных значений от -1 до 1 с шагом 0.05 в виде суммы функции синуса и погрешности, описываемой случайной величиной, распределенной по нормальному закону с дисперсией 0.01
clear
p = [-1:0.05:1];
t = sin(2*pi*p)+ 0.1*randn(size(p));
Затем сформируем контрольное подмножество. Определим входы в диапазоне от –0.975 до 0.975 и чтобы сделать задачу более реалистичной, добавим некоторую помеху, распределенную по нормальному закону
v.P = [-0.975:.05:0.975];
v.T = sin(2*pi*v.P)+0.1*randn(size(v.P));
Тестовое подмножество в данном примере не используется.
Вновь сформируем нейронную сети типа 1-20-1 и обучим ее. Обратите внимание, что контрольное подмножество в виде массива структуры передается функции обучения в качестве шестого входного параметра. В данном случае используется обучающая функция traingdx, хотя может быть применена и любая другая функция обучения
net = newff([-1 1],[20,1],{'tansig','purelin'},'traingdx');
net.trainParam.epochs = 300;
net.trainParam.show = 25;
net = init(net);
[net,tr] = train(net,p,t,[],[],v); % Рис.3.24
grid on
legend('контрольное подмножество', 'обучающее подмножество')
TRAINGDX, Epoch 0/300, MSE 12.9244/0, Gradient 20.8895/1e-006
TRAINGDX, Epoch 25/300, MSE 0.500121/0, Gradient 0.978807/1e-006
TRAINGDX, Epoch 50/300, MSE 0.191717/0, Gradient 0.32784/1e-006
TRAINGDX, Epoch 75/300, MSE 0.0734146/0, Gradient 0.116014/1e-006
TRAINGDX, Epoch 100/300, MSE 0.0218068/0, Gradient 0.0437681/1e-006
TRAINGDX, Epoch 125/300, MSE 0.00574346/0, Gradient 0.0485314/1e-006
TRAINGDX, Epoch 130/300, MSE 0.00574346/0, Gradient 0.0485314/1e-006
TRAINGDX, Validation stop.
Построим графики исследуемых функций
an = sim(net,p);
t1 = sin(2*pi*p);
figure(2); plot(p,t,'+',p,an,'-',p,t1,':') % Рис.3.25
legend('вход','выход','sin(2pi*t)'); grid on
^ C96. Предварительная обработка и восстановление данных. Регрессионный анализ.
Следующая последовательность операторов поясняет, как можно выполнен регрессионный анализ для сети, построенной на основе процедуры с прерыванием обучения
clear
p = [-1:0.05:1];
t = sin(2*pi*p)+ 0.1*randn(size(p));
v.P = [-0.975:.05:0.975];
v.T = sin(2*pi*v.P)+0.1*randn(size(v.P));
net = newff([-1 1],[20,1],{'tansig','purelin'},'traingdx');
net.trainParam.show = 25;
net.trainParam.epochs = 300;
net = init(net);
[net,tr]=train(net,p,t,[],[],v);
grid on
legend('контрольное подмножество', 'обучающее подмножество')
TRAINGDX, Epoch 0/300, MSE 8.33909/0, Gradient 13.9129/1e-006
TRAINGDX, Epoch 25/300, MSE 1.48273/0, Gradient 2.00314/1e-006
TRAINGDX, Epoch 50/300, MSE 0.361276/0, Gradient 0.543845/1e-006
TRAINGDX, Epoch 75/300, MSE 0.0769917/0, Gradient 0.147463/1e-006
TRAINGDX, Epoch 100/300, MSE 0.0181576/0, Gradient 0.0458443/1e-006
TRAINGDX, Epoch 125/300, MSE 0.00440005/0, Gradient 0.0691844/1e-006
TRAINGDX, Epoch 138/300, MSE 0.00427574/0, Gradient 0.033685/1e-006
TRAINGDX, Validation stop.
a = sim(net,p); % Моделирование сети
figure(2);
[m,b,r] = postreg(a,t), grid on
m =
0.9894
b =
-0.0092
r =
0.9956
^ Пример процедуры обучения.
Требуется разработать вычислительный инструмент, который может определять уровни липидных составляющих холестерина на основе измерений спектра крови. Имеется статистика измерения 21 показателя липидного спектра крови для 264 пациентов. Кроме того, известны уровни hdl, ldl и vldl липидных составляющих холестерина, основанных на сепарации сыворотки. Необходимо определить состоятельность нового способа анализа крови, основанного на измерении ее спектра.
Данные измерений спектра должны быть загружены из МАТ-файла choles_all и подвергнуты факторному анализу
clear, load choles_all
[pn,meanp,stdp,tn,meant,stdt] = prestd(p,t);
[ptrans,transMat] = prepca(pn, 0.001);
В этом случае сохраняются только те компоненты, которые объясняют 99.9 % изменений в наборе данных. Проверим, сколько же компонентов из первоначальных 21 являются состоятельными
[R,Q] = size(ptrans)
R =
4
Q =
264
Оказывается, что всего 4.
Теперь сформируем из исходной выборки обучающее, контрольное и тестовое множества. Для этого выделим половину выборки для обучающего множества ptr и по четверти для контрольного v и тестового t
iitst = 2:4:Q;
iival = 4:4:Q;
iitr = [1:4:Q 3:4:Q];
v.P = ptrans(:,iival); v.T = tn(:,iival);
t.P = ptrans(:,iitst); t.V = tn(:,iitst);
ptr = ptrans(:,iitr); ttr = tn(:,iitr);
Теперь необходимо сформировать и обучить нейронную сеть. Будем использовать сеть с 2 слоями, с функциями активации: в скрытом слое - гиперболический тангенс, в выходном слое - линейная функция. Такая структура эффективна для решения задач аппроксимации и регрессии. В качестве начального приближения установим 5 нейронов в скрытом слое. Сеть должна иметь 3 выходных нейрона, поскольку определено 3 цели. Для обучения применим алгоритм LM
net = newff(minmax(ptr),[5 3],{'tansig' 'purelin'},'trainlm')
[net,tr]=train(net,ptr,ttr,[],[],v,t);
net =
Neural Network object:
architecture:
numInputs: 1
numLayers: 2
biasConnect: [1; 1]
inputConnect: [1; 0]
layerConnect: [0 0; 1 0]
outputConnect: [0 1]
targetConnect: [0 1]
numOutputs: 1 (read-only)
numTargets: 1 (read-only)
numInputDelays: 0 (read-only)
numLayerDelays: 0 (read-only)
subobject structures:
inputs: {1x1 cell} of inputs
layers: {2x1 cell} of layers
outputs: {1x2 cell} containing 1 output
targets: {1x2 cell} containing 1 target
biases: {2x1 cell} containing 2 biases
inputWeights: {2x1 cell} containing 1 input weight
layerWeights: {2x2 cell} containing 1 layer weight
functions:
adaptFcn: 'trains'
initFcn: 'initlay'
performFcn: 'mse'
trainFcn: 'trainlm'
parameters:
adaptParam: .passes
initParam: (none)
performParam: (none)
trainParam: .epochs, .goal, .max_fail, .mem_reduc,
.min_grad, .mu, .mu_dec, .mu_inc,
.mu_max, .show, .time
weight and bias values:
IW: {2x1 cell} containing 1 input weight matrix
LW: {2x2 cell} containing 1 layer weight matrix
b: {2x1 cell} containing 2 bias vectors
other:
userdata: (user stuff)
TRAINLM, Epoch 0/100, MSE 1.66603/0, Gradient 576.465/1e-010
TRAINLM, Epoch 12/100, MSE 0.314181/0, Gradient 88.4175/1e-010
TRAINLM, Validation stop.
Обучение остановлено, потому что контрольная ошибка в 5 раз превысила ошибку обучения. Построим графики всех ошибок
figure(2)
plot(tr.epoch,tr.perf,'-',tr.epoch,tr.vperf,'--',tr.epoch,tr.tperf,':');
legend('Обучение', 'Контроль', 'Проверка'); grid on %Рис.3.27
Погрешности проверки на тестовом и контрольном множествах ведут себя одинаково, и нет заметных тенденций к переобучению.
Теперь следует выполнить анализ реакции сети. Используем весь набор данных (обучение, признание выборки представительной и тестовый) и оценим линейную регрессию между выходами сети и соответствующими целя
еще рефераты
Еще работы по разное
Реферат по разное
Правительство Москвы система нормативных документов в строительстве
18 Сентября 2013
Реферат по разное
С. И. Рыхлова (Госстрой ссср), канд геол минерал, наук
18 Сентября 2013
Реферат по разное
По ту сторону Темного Портала
18 Сентября 2013
Реферат по разное
Открытый аукцион №1/2008
18 Сентября 2013