Создание нейросети со скрытым слоем
Нейросеть со скрытым слоем некорректно обучается. Если использовать эту же нейросеть, состоящую лишь из 2 слоёв (входного и выходного) то она работает прекрасно. Но при добавлении "лишнего слоя", который фактически то и не нужен, нейросеть перестала обучаться. Грубо говоря в данном случае нейросеть должна выдавать еденицу лишь, когда 2-ой входной нейрон получает на вход 1. Скорее всего ошибка кроется в строках отвечающих за уменьшение ошибки.
def non_linear(x):
return 1/(1+exp(-x))
train_inp=array([[1,0,0,1],[1,1,1,1],[0,1,1,1],[1,0,1,1]])
train_out=array([[0,1,1,0]]).T
#hidden=array([[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
random.seed(1)
layer_1_weights= 2 * random.random((4,4)) -1 #Массив 4x4 между 4 входными нейронами, и 4-мя промежуточными
layer_2_weights= 2 * random.random((4,1)) -1 #Массив 4x1 между 4 промежуточными нейронами и 1 выходным
for iter in range(5000):#Кол-во повторений для обучения
output_1_layer=non_linear(dot(train_inp,layer_1_weights)) #Результат работы входных нейронов, по совместительству 2-ой слой
output_2_layer=non_linear(dot(output_1_layer,layer_2_weights)) #Результат работы нейронов скрытого слоя, по совместительству выходной нейрон
layer_2_weights += dot(output_1_layer.T,(train_out-output_2_layer)*output_2_layer*(1-output_2_layer))
layer_1_weights += dot(train_inp.T,(layer_2_weights-output_1_layer)*output_1_layer*(1-output_1_layer))
print(non_linear(dot(array([0,0,0,1]),layer_2_weights)))
Ответы (2 шт):
from numpy import dot, exp, array, random
def non_linear(x):
return 1/(1+exp(-x))
train_inp=array([[1,0,0,1],[1,1,1,1],[0,1,1,1],[1,0,1,1]])
train_out=array([[0],[1],[1],[0]]) # Здесь должно столько же кейсов сколько и в train
l_r=0.07
#hidden=array([[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
#random.seed(1) Зерно обязательно убрать так как данные могут быть линейно-неразделимыми(надо 'ловить' результат)
# матрицы в моем стиле
layer_1_weights= 2 * random.random((4,4)) -1 #Массив 4x4 между 4 входными нейронами, и 4-мя промежуточными
layer_2_weights= 2 * random.random((1,4)) -1
for iter in range(5000):#Кол-во повторений для обучения
e=0
for single_array_ind in range(len(train_inp)):
output_1_layer=non_linear(dot(layer_1_weights,train_inp[single_array_ind].T)) #Результат работы входных нейронов, по совместительству 2-ой слой
output_2_layer=non_linear(dot(layer_2_weights, output_1_layer)) #Результат работы нейронов скрытого слоя, по совместительству выходной нейрон
# через 'матричные' ошибки так будут называться
layer_2_errors=((train_out[single_array_ind].T-output_2_layer)*output_2_layer*(1-output_2_layer))
layer_1_errors=dot((layer_2_errors).T, # ошибки нейронов последнего слоя
layer_2_weights)
layer_2_weights+=l_r * layer_1_errors * output_1_layer.T
errors=dot(layer_1_errors,layer_1_weights)
layer_1_weights+=l_r * errors * train_inp[single_array_ind]
e = (layer_2_errors * layer_2_errors) / 2
print("error:",e)
error: [0.01015946]
error: [0.01015946]
error: [0.01015945]
error: [0.01015945]
error: [0.01015944]
error: [0.01015944]
error: [0.01015943]
error: [0.01015942]
error: [0.01015942]
error: [0.01015941]
error: [0.01015941]
error: [0.0101594]
error: [0.0101594]
error: [0.01015939]
error: [0.01015938]
error: [0.01015938]
error: [0.01015937]
error: [0.01015937]
error: [0.01015936]
error: [0.01015936]
error: [0.01015935]
error: [0.01015934]
error: [0.01015934]
error: [0.01015933]
error: [0.01015933]
error: [0.01015932]
error: [0.01015932]
error: [0.01015931]
error: [0.0101593]
error: [0.0101593]
error: [0.01015929]
error: [0.01015929]
error: [0.01015928]
error: [0.01015928]
error: [0.01015927]
error: [0.01015926]
error: [0.01015926]
error: [0.01015925]
error: [0.01015925]
error: [0.01015924]
error: [0.01015924]
error: [0.01015923]
error: [0.01015922]
error: [0.01015922]
error: [0.01015921]
error: [0.01015921]
error: [0.0101592]
error: [0.0101592]
error: [0.01015919]
error: [0.01015918]
error: [0.01015918]
error: [0.01015917]
error: [0.01015917]
error: [0.01015916]
error: [0.01015916]
error: [0.01015915]
error: [0.01015914]
error: [0.01015914]
error: [0.01015913]
error: [0.01015913]
error: [0.01015912]
error: [0.01015912]
error: [0.01015911]
error: [0.0101591]
error: [0.0101591]
error: [0.01015909]
error: [0.01015909]
error: [0.01015908]
error: [0.01015908]
error: [0.01015907]
error: [0.01015907]
error: [0.01015906]
error: [0.01015905]
error: [0.01015905]
error: [0.01015904]
error: [0.01015904]
error: [0.01015903]
error: [0.01015903]
error: [0.01015902]
error: [0.01015901]
error: [0.01015901]
error: [0.010159]
error: [0.010159]
error: [0.01015899]
error: [0.01015899]
error: [0.01015898]
error: [0.01015898]
error: [0.01015897]
error: [0.01015896]
error: [0.01015896]
error: [0.01015895]
error: [0.01015895]
error: [0.01015894]
error: [0.01015894]
error: [0.01015893]
error: [0.01015892]
error: [0.01015892]
error: [0.01015891]
error: [0.01015891]
error: [0.0101589]
error: [0.0101589]
error: [0.01015889]
error: [0.01015889]
error: [0.01015888]
error: [0.01015887]
error: [0.01015887]
error: [0.01015886]
error: [0.01015886]
error: [0.01015885]
error: [0.01015885]
error: [0.01015884]
error: [0.01015883]
error: [0.01015883]
error: [0.01015882]
error: [0.01015882]
error: [0.01015881]
error: [0.01015881]
error: [0.0101588]
error: [0.0101588]
error: [0.01015879]
error: [0.01015878]
error: [0.01015878]
error: [0.01015877]
error: [0.01015877]
error: [0.01015876]
error: [0.01015876]
error: [0.01015875]
error: [0.01015875]
error: [0.01015874]
error: [0.01015873]
error: [0.01015873]
error: [0.01015872]
error: [0.01015872]
error: [0.01015871]
error: [0.01015871]
error: [0.0101587]
error: [0.0101587]
error: [0.01015869]
error: [0.01015868]
error: [0.01015868]
error: [0.01015867]
error: [0.01015867]
error: [0.01015866]
error: [0.01015866]
error: [0.01015865]
error: [0.01015865]
error: [0.01015864]
error: [0.01015863]
error: [0.01015863]
error: [0.01015862]
error: [0.01015862]
error: [0.01015861]
error: [0.01015861]
error: [0.0101586]
error: [0.0101586]
error: [0.01015859]
error: [0.01015858]
error: [0.01015858]
error: [0.01015857]
error: [0.01015857]
error: [0.01015856]
error: [0.01015856]
error: [0.01015855]
error: [0.01015855]
error: [0.01015854]
error: [0.01015853]
error: [0.01015853]
error: [0.01015852]
error: [0.01015852]
error: [0.01015851]
error: [0.01015851]
error: [0.0101585]
Ошибка падает. Написал что зерно нужно убрать,но видимо без него чтобы быстрее сходилось(может и можно поставить:)),в любом случае рандомность для линейно неразделимых данных нужна.
Очень важно строить график,понять ошибка уменьшается или увеличивается,когда писал на cyberforum статьи,там справедливо требовали график,некоторые не верят что нейросеть действительно работает или работает правильно, я тоже долго сомневался, пробовал без рандомной инициализации(только одни и те же числа),но понял что для нелинейно-разделемых данных нужны рэндомы(опыты с keras),но они же создают сложности,важно контролировать через графики,при одном распределении можно сразу 'уменьшаться',при другом система сперва неправильный 'курc' берет(там как говорят может быть застревание в локальных минимумах и другое).Доработанный код:
from numpy import dot, exp, array, random
import matplotlib.pyplot as plt
import logging
def plot_gr(_file:str,errors:list,epochs:list,name_gr:str,logger:logging.Logger)->None:
fig:plt.Figure=None
ax:plt.Axes=None
fig, ax=plt.subplots()
plt.text(0.1, 1.1, name_gr)
ax.plot(epochs, errors,
label="learning",
)
# plt.plot(errors,label="errors")
# plt.plot(history.history['acc'],label="Доля верных ответов на обучающем наборе")
# if 'val_acc' in history.history: # Если работаем с val_acc
# plt.plot(history.history['val_acc'],label='Доля верных ответов на проверочном наборе')
plt.xlabel('Эпоха обучения')
plt.ylabel('loss')
ax.legend()
plt.savefig(_file)
print("Graphic saved")
# logger.info("Graphic saved")
plt.show()
def non_linear(x):
return 1/(1+exp(-x))
train_inp=array([[1,0,0,1],[1,1,1,1],[0,1,1,1],[1,0,1,1]])
train_out=array([[0],[1],[1],[0]]) # Здесь должно столько же кейсов сколько и в train
l_r=0.07
#hidden=array([[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]])
#random.seed(1) Зерно обязательно убрать так как данные могут быть линейно-неразделимыми(надо 'ловить' результат)
# матрицы в моем стиле
layer_1_weights= 2 * random.random((4,4)) -1 #Массив 4x4 между 4 входными нейронами, и 4-мя промежуточными
layer_2_weights= 2 * random.random((1,4)) -1
epochs=10
errors_y=[0]*epochs
epochs_x=[0]*epochs
for ep in range(epochs):#Кол-во повторений для обучения
e=0
for single_array_ind in range(len(train_inp)):
output_1_layer=non_linear(dot(layer_1_weights,train_inp[single_array_ind].T)) #Результат работы входных нейронов, по совместительству 2-ой слой
output_2_layer=non_linear(dot(layer_2_weights, output_1_layer)) #Результат работы нейронов скрытого слоя, по совместительству выходной нейрон
# через 'матричные' ошибки так будут называться
layer_2_errors=((train_out[single_array_ind].T-output_2_layer)*output_2_layer*(1-output_2_layer))
layer_1_errors=dot((layer_2_errors).T, # ошибки нейронов последнего слоя
layer_2_weights)
layer_2_weights+=l_r * layer_1_errors * output_1_layer.T
errors=dot(layer_1_errors,layer_1_weights)
layer_1_weights+=l_r * errors * train_inp[single_array_ind]
e = (layer_2_errors * layer_2_errors) / 2
errors_y[ep]=e[0]
epochs_x[ep]=ep
print("error:",e)
print(f"{errors_y}")
print(f'{epochs_x}')
plot_gr('gr.png',errors_y,epochs_x,"test",None)

