Лабораторная работа №2 Обучение однослойного перцептрона с несколькими выходами. Лабораторная работа 2 Обучение однослойного перцептрона с несколькими выходами
Скачать 24.35 Kb.
|
Лабораторная работа №2 Обучение однослойного перцептрона с несколькими выходами Используя заготовку программы на языке Python, выполнить обучение 1-слойной нейронной сети типа "перцептрон" распознаванию образов на растре (матрице) 5 на 7 (допускаются другие размеры по выбору студента, например, 5 на 8, 6 на 8, 6 на 9 и т.п.). Можно использовать трансляторы языка Python (Python 3) на сайтах tio.run, ideon.com, pythonanywhere.com, onlinegdb.com, online-python.com и colab.research.google.com. Во всех этих случаях (кроме onlinegdb.com и online-python.com) лучше удалить из программы (или закомментировать) все операторы input. Варианты исходных данных Набор символов №1. Распознаваемые символы: две последние цифры номера зачётной книжки (если в номере есть цифра "1", то она заменяется на "2", если цифры совпадают (в том числе после замены "1" на "2"), то вторая цифра = первая цифра + 1); Набор символов №2. Набор символов № 1 и первые буквы имени и фамилии, заглавные (русские или латинские - по выбору студента, если буквы совпадают, то одна из них заменяется на следующую по порядку, «Я» заменяется на «А»), цифра "1", один символ по выбору студента, отличающийся от ранее указанных. Задание на выполнение 1. Модифицировать программу в соответствии с выбранным вариантом, добавив в неё описания массива входного сигнала, массива эталонного сигнала и массива требуемых выходов (массивы (списки) signal1, signal2, netOut и metki). Обучить сеть распознаванию символов набора №1. Зафиксировать в отчёте количество циклов обучения. Проверить состояния выходов сети для каждого входного сигнала. 2. Модифицировать программу, изменив значение переменной Nout с 2 на 6. Изменить массивы входного сигнала, эталонного сигнала, добавив в них символы набора №2. Изменить массив требуемых выходов. Обучить сеть распознаванию полного набора символов. Зафиксировать в отчёте количество циклов обучения. Проверить состояния выходов сети для каждого входного сигнала. 3. Проверить ход обучения сети и его результаты для случаев использования при обучении только эталонных образов и "зашумлённых" образов. В первом случае нужно присвоить переменной noiseTrain значение 0, а во втором - значение 0.5. Величину шума (переменная noiseLevel) можно выбирать в диапазоне 0.15 – 0.25 (допускаются и другие значения). Сравнить результаты обучения сети (количество циклов обучения и сигналы на выходах сети) в обоих случаях. import numpy as np import random from math import fabs Nix,Niy=5,7 Ni=Nix*Niy Nout=6 Ntest=7 Alpha=2 Beta=2 # 1 Nju=0.2 # 0.1 noiseLevel=0.15 #0.25 noiseTrain=0 #0.5 inp1=np.zeros(Ni) w1=np.ones((Nout,Ni+1)) delta1=np.zeros((Nout,Ni+1)) layer1=np.zeros(Nout) print(inp1) print(w1) def initWeights(w): for i in range(len(w)): w[i]=random.random()-0.5 def vvod(source,dest): for i in range(len(source)): dest[i]=source[i] def noise(arr,n): for i in range(len(arr)): a=random.random() if a if arr[i]==1: arr[i]=0 else: arr[i]=1 def showImage(arr,X,Y): a1=np.array(arr).reshape(Y,X) for y in range(Y): for x in range(X): if a1[y][x]==1: print('#',end='') else: print('.',end='') print() def work(inp,wa,out,alpha): for o in range(len(out)): sum=0.0 for i in range(len(inp)): sum+=inp[i]*wa[o][i] sum+=wa[o][len(inp)] out[o]=1/(1+np.exp(-sum*alpha)) def train(ideal,inp,wa,out,beta,nju): nout=len(out) ninp=len(inp) err=np.zeros(nout) for k in range(nout): # Вычисление ошибки выходного слоя err[k]=(ideal[k]-out[k])*beta*out[k]*(1-out[k]) wa[k][ninp]+=nju*err[k] for j in range(ninp): for k in range(nout): delta=nju*err[k]*inp[j] wa[k][j]+=delta #[k][j] def isConverged(ideal,out,prec): c=0 for k in range(len(out)): if fabs(ideal[k]-out[k])<=prec: c+=1 return c signal1=[[ # Обучающие образы по варианту (буква N) 1,0,0,0,1, 1,0,0,0,1, 1,1,0,0,1, 1,0,1,0,1, 1,0,0,1,1, 1,0,0,0,1, 1,0,0,0,1], [1,1,1,0,0, # P 1,0,0,1,0, 1,0,0,1,0, 1,1,1,0,0, 1,0,0,0,0, 1,0,0,0,0, 1,0,0,0,0], [0,0,1,0,0, # 1 0,1,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,1,1,1,0], [0,1,1,0,0, # 2 1,0,0,1,0, 0,0,0,1,0, 0,0,1,0,0, 0,1,0,0,0, 1,0,0,0,0, 1,1,1,1,0], [1,1,1,1,0, # 3 0,0,0,1,0, 0,0,1,0,0, 0,1,1,0,0, 0,0,0,1,0, 1,0,0,1,0, 0,1,1,0,0], [1,1,1,1,1, # 7 0,0,0,0,1, 0,0,0,1,0, 0,0,1,0,0, 0,1,0,0,0, 1,0,0,0,0, 1,0,0,0,0] ] signal2=[[ # Проверочные образы (в ЛР №2 – совпадают с обучающими) 1,0,0,0,1, 1,0,0,0,1, 1,1,0,0,1, 1,0,1,0,1, 1,0,0,1,1, 1,0,0,0,1, 1,0,0,0,1], [1,1,1,0,0, 1,0,0,1,0, 1,0,0,1,0, 1,1,1,0,0, 1,0,0,0,0, 1,0,0,0,0, 1,0,0,0,0], [0,0,1,0,0, 0,1,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,1,1,1,0], [0,1,1,0,0, 1,0,0,1,0, 0,0,0,1,0, 0,0,1,0,0, 0,1,0,0,0, 1,0,0,0,0, 1,1,1,1,0], [1,1,1,1,0, 0,0,0,1,0, 0,0,1,0,0, 0,1,1,0,0, 0,0,0,1,0, 1,0,0,1,0, 0,1,1,0,0], [1,1,1,1,1, 0,0,0,0,1, 0,0,0,1,0, 0,0,1,0,0, 0,1,0,0,0, 1,0,0,0,0, 1,0,0,0,0], [0,0,1,0,0, # Дополнительный образ – вертикальная черта 0,0,1,0,0, # (искаженная цифра «1») 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0], ] netOut=[ # массив (список) выходов сети для 6-и символов [1,0,0,0,0,0], # для 2-х символов будет [0,1,0,0,0,0], # [1,0], [0,0,1,0,0,0], # [0,1]] [0,0,0,1,0,0], [0,0,0,0,1,0], [0,0,0,0,0,1]] metki=['N','P','1','2','3','7','1'] print('Тест обучающего образа:') showImage(signal2[0],Nix,Niy); print() input('Нажмите print('Тест входного образа:') vvod(signal1[0],inp1) showImage(inp1,Nix,Niy); print() print('Он же с шумом:') noise(inp1,noiseLevel) showImage(inp1,Nix,Niy); print() input('Нажмите print('Контроль входного сигнала в виде одномерного массива:',inp1) input('Нажмите work(inp1,w1,layer1,Alpha) print('Проверка состояния одного выхода сети (сеть ещё не обучена):',layer1[0]) input('Нажмите for i in range(Nout): initWeights(w1[i]) print('Все весовые коэффициенты 1-слойной сети:\n',w1) input('Нажмите Corr=0 eps=0.01 epoch=0 input('Процесс обучения сети. Нажмите while Corr a=random.random() print(a) for i in range(len(netOut)): vvod(signal1[i],inp1) if a noise(inp1,noiseLevel) work(inp1,w1,layer1,Alpha) train(netOut[i],inp1,w1,layer1,Beta,Nju) Corr=isConverged(netOut[i],layer1,eps) epoch+=1 print('Epoch=',epoch,'No errors=',Corr) print('Число циклов обучения=',epoch) print('No errors=',Corr) print('Test signals:') for i in range(Ntest): print('Signal-',i,':',metki[i],':') showImage(signal2[i],Nix,Niy) vvod(signal2[i],inp1) work(inp1,w1,layer1,Alpha) for j in range(Nout): print('Out-',j,'=',layer1[j]) print() input('Continue.') print('Test signals with noise:') for i in range(Ntest): print('Signal-',i,':',metki[i],':') vvod(signal2[i],inp1) noise(inp1,0.125) showImage(inp1,Nix,Niy) work(inp1,w1,layer1,Alpha) for j in range(Nout): print('Out-',j,'=',layer1[j]) print() input('Press |