Реализация нейронной сети с нуля с использованием NumPy
DNN (глубокая нейронная сеть) в алгоритме машинного обучения, который основан на том, как работает человеческий мозг. DNN в основном используется как алгоритм классификации. В этой статье мы рассмотрим пошаговый подход к тому, как с нуля реализовать базовый алгоритм DNN в NumPy (библиотека Python).
Цель этой статьи - дать новичкам представление о том, как работает нейронная сеть, и о деталях ее реализации. Мы собираемся создать трехбуквенный (A, B, C) классификатор, для простоты мы собираемся создать буквы (A, B, C) как массив NumPy из нулей и единиц, также мы собираемся игнорировать смещение термин, связанный с каждым узлом.
Поскольку изображение представляет собой набор значений пикселей в матрице, мы создадим эту матрицу пикселей для A, B, C
используя 0 и 1 #A 0 0 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 #B 0 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 1 0 #C 0 1 1 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 # Ярлыки для каждой буквы A = [1, 0, 0] B = [0, 1, 0] C = [0, 0, 1]
Код:
# Creating data set # A a = [ 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 ] # B b = [ 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 ] # C c = [ 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 ] # Creating labels y = [[ 1 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 1 ]] |
Шаг 2: Визуализация набора данных
import numpy as np import matplotlib.pyplot as plt # visualizing the data, ploting A. plt.imshow(np.array(a).reshape( 5 , 6 )) plt.show() |
Выход:
Шаг 3: Поскольку набор данных находится в форме списка, мы преобразуем его в массив numpy.
# converting data and labels into numpy array """ Convert the matrix of 0 and 1 into one hot vector so that we can directly feed it to the neural network, these vectors are then stored in a list x. """ x = [np.array(a).reshape( 1 , 30 ), np.array(b).reshape( 1 , 30 ), np.array(c).reshape( 1 , 30 )] # Labels are also converted into NumPy array y = np.array(y) print (x, "
" , y) |
Выход:
[массив ([[0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 , 1, 1, 0, 0, 0, 0, 1]]), array ([[0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0]]), array ([[0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0]])] [[1 0 0] [0 1 0] [0 0 1]]
Шаг 4: Определение архитектуры или структуры глубокой нейронной сети. Это включает определение количества слоев и количества узлов в каждом слое. Наша нейронная сеть будет иметь следующую структуру.
1-й слой: входной слой (1, 30) 2-й слой: скрытый слой (1, 5) 3-й слой: выходной слой (3, 3)
Шаг 5: Объявление и определение всех функций для построения глубокой нейронной сети.
# activation function def sigmoid(x): return ( 1 / ( 1 + np.exp( - x))) # Creating the Feed forward neural network # 1 Input layer(1, 30) # 1 hidden layer (1, 5) # 1 output layer(3, 3) def f_forward(x, w1, w2): # hidden z1 = x.dot(w1) # input from layer 1 a1 = sigmoid(z1) # out put of layer 2 # Output layer z2 = a1.dot(w2) # input of out layer a2 = sigmoid(z2) # output of out layer return (a2) # initializing the weights randomly def generate_wt(x, y): l = [] for i in range (x * y): l.append(np.random.randn()) return (np.array(l).reshape(x, y)) # for loss we will be using mean square error(MSE) def loss(out, Y): s = (np.square(out - Y)) s = np. sum (s) / len (y) return (s) # Back propagation of error def back_prop(x, y, w1, w2, alpha): # hiden layer z1 = x.dot(w1) # input from layer 1 a1 = sigmoid(z1) # output of layer 2 # Output layer z2 = a1.dot(w2) # input of out layer a2 = sigmoid(z2) # output of out layer # error in output layer d2 = (a2 - y) d1 = np.multiply((w2.dot((d2.transpose()))).transpose(), (np.multiply(a1, 1 - a1))) # Gradient for w1 and w2 w1_adj = x.transpose().dot(d1) w2_adj = a1.transpose().dot(d2) # Updating parameters w1 = w1 - (alpha * (w1_adj)) w2 = w2 - (alpha * (w2_adj)) return (w1, w2) def train(x, Y, w1, w2, alpha = 0.01 , epoch = 10 ): acc = [] losss = [] for j in range (epoch): l = [] for i in range ( len (x)): out = f_forward(x[i], w1, w2) l.append((loss(out, Y[i]))) w1, w2 = back_prop(x[i], y[i], w1, w2, alpha) print ( "epochs:" , j + 1 , "======== acc:" , ( 1 - ( sum (l) / len (x))) * 100 ) acc.append(( 1 - ( sum (l) / len (x))) * 100 ) losss.append( sum (l) / len (x)) return (acc, losss, w1, w2) def predict(x, w1, w2): Out = f_forward(x, w1, w2) maxm = 0 k = 0 for i in range ( len (Out[ 0 ])): if (maxm<Out[ 0 ][i]): maxm = Out[ 0 ][i] k = i if (k = = 0 ): print ( "Image is of letter A." ) elif (k = = 1 ): print ( "Image is of letter B." ) else : print ( "Image is of letter C." ) plt.imshow(x.reshape( 5 , 6 )) plt.show() |
Шаг 6: Инициализация весов, поскольку нейронная сеть имеет 3 слоя, поэтому с ней будут связаны 2 весовые матрицы. Размер каждой матрицы зависит от количества узлов в двух соединяющих слоях.
Код:
w1 = generate_wt( 30 , 5 ) w2 = generate_wt( 5 , 3 ) print (w1, "
" , w2) |
Выход:
[[0,75696605 -0,15959223 -1,43034587 0,17885107 -0,75859483] [-0,22870119 1,05882236 -0,15880572 0,11692122 0,58621482] [0,13926738 0,72963505 0,36050426 0,79866465 -0,17471235] [1,00708386 0,68803291 0,14110839 -0,7162728 0,69990794] [-0,90437131 0,63977434 -0,43317212 0,67134205 -0,9316605] [0,15860963 -1,17967773 -0,70747245 0,22870289 0,00940404] [1.40511247 -1.29543461 1.41613069 -0.97964787 -2.86220777] [0,66293564 -1,94013093 -0,78189238 1,44904122 -1,81131482] [0,4441061 -0,18751726 -2,58252033 0,23076863 0,12182448] [-0,60061323 0,39855851 -0,55612255 2,0201934 0,70525187] [-1,82925367 1,32004437 0,03226202 -0,79073523 -0,20750692] [-0,25756077 -1,37543232 -0,71369897 -0,13556156 -0,34918718] [0,26048374 2,49871398 1,01139237 -1,73242425 -0,67235417] [0,30351062 -0,45425039 -0,84046541 -0,60435352 -0,06281934] [0,43562048 0,66297676 1,76386981 -1,11794675 2,2012095] [-1,11051533 0,3462945 0,19136933 0,19717914 -1,78323674] [1,1219638 -0,04282422 -0,0142484 -0,73210071 -0,58364205] [-1,24046375 0,23368434 0,62323707 -1,66265946 -0,87481714] [0,19484897 0,12629217 -1,01575241 -0,47028007 -0,58278292] [0,16703418 -0,50993283 -0,90036661 2,33584006 0,96395524] [-0,72714199 0,39000914 -1,3215123 0,92744032 -1,44239943] [-2,30234278 -0,52677889 -0,09759073 -0,63982215 -0,51416013] [1,25338899 -0,58950956 -0,86009159 -0,7752274 2,24655146] [0,07553743 -1,2292084 0,46184872 -0,56390328 0,15901276] [-0,52090565 -2,42754589 -0,78354152 -0,44405857 1,16228247] [-1,21805132 -0,40358444 -0,65942185 0,76753095 -0,19664978] [-1,5866041 1,17100962 -1,50840821 -0,61750557 1,56003127] [1,33045269 -0,85811272 1,8869376 0,79491455 -0,96199293] [-2,34456987 0,1005953 -0,99376025 -0,94402235 -0,3078695] [0,93611909 0,58522915 -0,15553566 -1,03352997 -2,7210093]] [[-0,50650286 -0,41168428 -0,7107231] [1,86861492 -0,36446849 0,97721539] [-0,12792125 0,69578056 -0,6639736] [0,58190462 -0,98941614 0,40932723] [0,89758789 -0,49250365 -0,05023684]]
Шаг 7: Обучение модели.
"""The arguments of train function are data set list x, correct labels y, weights w1, w2, learning rate = 0.1, no of epochs or iteration.The function will return the matrix of accuracy and loss and also the matrix of trained weights w1, w2""" acc, losss, w1, w2 = train(x, y, w1, w2, 0.1 , 100 ) |
Выход:
эпох: 1 ======== согласно: 59.24962411875523 эпох: 2 ======== согласно: 63.68540644266716 эпох: 3 ======== согласно: 68.23850165512243 эпох: 4 ======== согласно: 71.30325758406262 эпох: 5 ======== согласно: 73.52710796040974 эпох: 6 ======== согласно: 75.32860090824263 эпох: 7 ======== согласно: 76.8094120430158 эпох: 8 ======== согласно: 78.00977196942078 эпох: 9 ======== согласно: 78.97728263498026 эпох: 10 ======== согласно: 79.76587293092753 эпох: 11 ======== согласно: 80.42246589416287 эпох: 12 ======== согласно: 80.98214842153129 эпох: 13 ======== согласно: 81.4695736928823 эпох: 14 ======== согласно: 81.90184308791194 эпох: 15 ======== согласно: 82.29094665963427 эпох: 16 ======== согласно: 82.64546024973251 эпох: 17 ======== согласно: 82.97165532985433 эпох: 18 ======== согласно: 83.27421706795944 эпох: 19 ======== согласно: 83.55671426703763 эпох: 20 ======== согласно: 83.82191341206628 эпох: 21 ======== согласно: 84.07199359659367 эпох: 22 ======== согласно: 84.30869706017322 эпох: 23 ======== согласно: 84.53343682891021 эпох: 24 ======== согласно: 84.74737503832276 эпох: 25 ======== согласно: 84.95148074055622 эпох: 26 ======== согласно: 85.1465730591422 эпох: 27 ======== согласно: 85.33335370190892 эпох: 28 ======== согласно: 85.51243164226796 эпох: 29 ======== согласно: 85.68434197894798 эпох: 30 ======== согласно: 85.84956043619462 эпох: 31 ======== согласно: 86.0085145818298 эпох: 32 ======== согласно: 86.16159256503643 эпох: 33 ======== согласно: 86.30914997510234 эпох: 34 ======== согласно: 86.45151527443966 эпох: 35 ======== согласно: 86.58899414916453 эпох: 36 ======== согласно: 86.72187303817682 эпох: 37 ======== согласно: 86.85042203982091 эпох: 38 ======== согласно: 86.97489734865094 эпох: 39 ======== согласно: 87.09554333976325 эпох: 40 ======== согласно: 87.21259439177474 эпох: 41 ======== согласно: 87.32627651970255 эпох: 42 ======== согласно: 87.43680887413676 эпох: 43 ======== согласно: 87.54440515197342 эпох: 44 ======== согласно: 87.64927495564211 эпох: 45 ======== согласно: 87.75162513147157 эпох: 46 ======== согласно: 87.85166111297174 эпох: 47 ======== согласно: 87.94958829083211 эпох: 48 ======== согласно: 88.0456134278342 эпох: 49 ======== согласно: 88.13994613312185 эпох: 50 ======== согласно: 88.2328004057654 эпох: 51 ======== согласно: 88.32439625156803 эпох: 52 ======== согласно: 88.4149613686817 эпох: 53 ======== согласно: 88.5047328856618 эпох: 54 ======== согласно: 88.59395911861766 эпох: 55 ======== согласно: 88.68290129028868 эпох: 56 ======== согласно: 88.77183512103412 эпох: 57 ======== согласно: 88.86105215751232 эпох: 58 ======== согласно: 88.95086064702116 эпох: 59 ======== согласно: 89.04158569269322 эпох: 60 ======== согласно: 89.13356833768444 эпох: 61 ======== согласно: 89.22716312996127 эпох: 62 ======== согласно: 89.32273362510695 эпох: 63 ======== согласно: 89.42064521532092 эпох: 64 ======== согласно: 89.52125466556964 эпох: 65 ======== согласно: 89.62489584606081 эпох: 66 ======== согласно: 89.73186143973956 эпох: 67 ======== согласно: 89.84238093800867 эпох: 68 ======== согласно: 89.95659604815005 эпох: 69 ======== согласно: 90.07453567327377 эпох: 70 ======== согласно: 90.19609371190103 эпох: 71 ======== согласно: 90.32101373021872 эпох: 72 ======== согласно: 90.44888465704626 эпох: 73 ======== согласно: 90.57915066786961 эпох: 74 ======== согласно: 90.7111362751668 эпох: 75 ======== согласно: 90.84408471463895 эпох: 76 ======== согласно: 90.97720484616241 эпох: 77 ======== согласно: 91.10971995033672 эпох: 78 ======== согласно: 91.24091164815938 эпох: 79 ======== согласно: 91.37015369432306 эпох: 80 ======== согласно: 91.49693294991012 эпох: 81 ======== согласно: 91.62085750782504 эпох: 82 ======== согласно: 91.74165396819595 эпох: 83 ======== согласно: 91.8591569057493 эпох: 84 ======== согласно: 91.97329371114765 эпох: 85 ======== согласно: 92.0840675282122 эпох: 86 ======== согласно: 92.19154028777587 эпох: 87 ======== согласно: 92.29581711003155 эпох: 88 ======== согласно: 92.3970327467751 эпох: 89 ======== согласно: 92.49534030435096 эпох: 90 ======== согласно: 92.59090221343706 эпох: 91 ======== согласно: 92.68388325695001 эпох: 92 ======== согласно: 92.77444539437016 эпох: 93 ======== согласно: 92.86274409885533 эпох: 94 ======== согласно: 92.94892593090393 эпох: 95 ======== согласно: 93.03312709510452 эпох: 96 ======== согласно: 93.11547275630565 эпох: 97 ======== согласно: 93.19607692356153 эпох: 98 ======== согласно: 93.27504274176297 эпох: 99 ======== согласно: 93.35246306044819 эпох: 100 ======== согласно: 93.42842117607569
Шаг 8: Построение графиков потерь и точности в зависимости от количества эпох (итерация).
import matplotlib.pyplot as plt1 # ploting accuraccy plt1.plot(acc) plt1.ylabel( 'Accuracy' ) plt1.xlabel( "Epochs:" ) plt1.show() # plotting Loss plt1.plot(losss) plt1.ylabel( 'Loss' ) plt1.xlabel( "Epochs:" ) plt1.show() |
Выход:
# the trained weigths are print (w1, "
" , w2) |
Выход:
[[-0,23769169 -0,1555992 0,81616823 0,1219152 -0,69572168] [0,36399972 0,37509723 1,5474053 0,85900477 -1,14106725] [1,0477069 0,13061485 0,16802893 -1,04450602 -2,76037811] [-0,83364475 -0,63609797 0,61527206 -0,42998096 0,248886] [0,16293725 -0,49443901 0,47638257 -0,89786531 -1,63778409] [0,10750411 -1,74967435 0,03086382 0,9906433 -0,9976104] [0,48454172 -0,68739134 0,78150251 -0,1220987 0,68659854] [-1,53100416 -0,33999119 -1,07657716 0,81305349 -0,79595135] [2,06592829 1,25309796 -2,03200199 0,03984423 -0,76893089] [-0,08285231 -0,33820853 -1,08239104 -0,22017196 -0,37606984] [-0,24784192 -0,36731598 -0,58394944 -0,0434036 0,58383408] [0,28121367 -1,84909298 -0,97302413 1,58393025 0,24571332] [-0,21185018 0,29358204 -0,79433164 -0,20634606 -0,69157617] [0,13666222 -0,31704319 0,03924342 0,54618961 -1,72226768] [1.06043825 -1.02009526 -1.39511479 -0.98141073 0.78304473] [1,44167174 -2,17432498 0,95281672 -0,76748692 1,16231747] [0,25971927 -0,59872416 1,01291689 -1,45200634 -0,72575161] [-0,27036828 -1,36721091 -0,43858778 -0,78527025 -0,36159359] [0,91786563 -0,97465418 1,26518387 -0,21425247 -0,25097618] [-0,00964162 -1,05122248 -1,2747124 1,65647842 1,15216675] [2,63067561 -1,3626307 2,44355269 -0,87960091 -0,39903453] [0,30513627 -0,77390359 -0,57135017 0,72661218 1,44234861] [2.49165837 -0.77744044 -0.14062449 -1.6659343 0.27033269] [1,30530805 -0,93488645 -0,66026013 -0,2839123 -1,21397584] [0.41042422 0.20086176 -2.07552916 -0.12391564 -0.67647955] [0,21339152 0,79963834 1,19499535 -2,17004581 -1,03632954] [-1,2032222 0,46226132 -0,68314898 1,27665578 0,69930683] [0,11239785 -2,19280608 1,36181772 -0,36691734 -0,32239543] [-1,62958342 -0,55989702 1,62686431 1,59839946 -0,08719492] [1.09518451 -1.9542822 -1.18507834 -0.5537991 -0.28901241]] [[1,52837185 -0,33038873 -3,45127838] [1,0758812 -0,41879112 -1,00548735] [-3,59476021 0,55176444 1,14839625] [1.07525643 -1.6250444 0.77552561] [0,82785787 -1,79602953 1,15544384]]
Шаг 9: Прогнозирование.
""" The predict function will take the following arguments: 1) image matrix 2) w1 trained weights 3) w2 trained weights """ predict(x[ 1 ], w1, w2) |
Выход:
Изображение буквы Б.
Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.
Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.