Сегодня мы поговорим о нейронах и степенных рядах. Поехали!
Рассмотрим функцию синуса.
Как можно заметить,с увеличением степенного ряда также увеличивается и точность
Рассмотрим один нейрон с одним входом и одним выходом
Как вы считаете, сколько входов должно быть у нейрона с одним входом и одним выходом для корректной работы?
У этого нейрона должно быть два входа. Один вход - x (переменная, которая поступает на вход нейрона) и единичка (биас).
Следующий вопрос. Какое преобразование нужно сделать с любым числом для того,чтобы превратить это число в 1 (единичку).
Правильно, возвести любое число в нулевую степень.
Это было предположение для одного нейрона. Напишем нейронную сеть,которая будет классифицировать наборы одежды fashion_mnist (футболки, кеды, штаны и т.д.). На вход нейросети подается 28*28 8-битная черно-белая картинка. Нейросеть содержит скрытый слой из 300 нейронов,и имеет 10 выходов. При обучении набора каждому из предметов одежды назначен класс от 0 до 10. Нейросеть должна научиться распознавать элементы одежды (отличать брюки от футболок и т.д.).
Я скачал тренировочный и тестовый наборы одежды с гитхаба по ссылке
Нейросеть будет состоять из входных (виртуальных) входов и связанных с весами(действительных) входов.
Примерная схема нейросети с двумя входными (виртуальными) нейронами,одним выходным и шестью(действительными) нейронами на входе нейросети.
x,x2,x3-это виртуальные входы нейросети,а x^0,x^1,x^2,x2^0,x2^1,x2^2 - действительные (связанные с весами)
err2=w1*err1
err3=w2*err1
err4=w3*err1
err5=w4*err1
err6=w5*err1
err6=w6*err1
err8=err2+err3+err4
err9=err5+err6+err7
w1+=speed_edication*x^0*err2*f(x^0)*(1-f(x^0))
w2+=speed_edication*x^1*err3*f(x^0)*(f-f(x^1))
w3+=speed_edication*x^2*err2*f(x^0)*(1-f(x^0))
w4+=speed_edication*x2^0*err3*f(x2^0)*(f-f(x2^0))
w5+=speed_edication*x2^1*err2*f(x2^1)*(1-f(x2^1))
w6+=speed_edication*x2^2*err3*f(x2^2)*(f-f(x2^2))
где f(x) = 1/(1+exp(-x))
Осталось сделать нейросеть для обучения её на тренировочном наборе и проверки её на тестовом наборе.
Написал простую нейросеть для проверки.
import numpy as np
from numpy import genfromtxt
OUT_CLASSES=10
HIDDEN_LEN=300
SPEED_EDICATION=0.00001
EPOCHS=3000
power1=2
power2=2
train = genfromtxt('fashion_train.csv', delimiter=',')
train=train[1:,:]
train_x=np.array(train[:,:-1])
train_x/=255
train_y=np.array(train[:,-1])
train_y = train_y.astype(int)
out = np.zeros(OUT_CLASSES*len(train_y))
index_arr=np.reshape(train_y,(1,len(train_y)))
out = np.reshape(out,(OUT_CLASSES,len(train_y)))
np.put_along_axis(out,np.array(index_arr),1,axis=0)
train_y=out.T
test = genfromtxt('fashion_test.csv', delimiter=',')
test=test[1:,:]
test_x=np.array(test[:,:-1])
test_x/=255
test_y=np.array(test[:,-1])
test_y = test_y.astype(int)
out = np.zeros(OUT_CLASSES*len(test_y))
index_arr=np.reshape(test_y,(1,len(test_y)))
out = np.reshape(out,(OUT_CLASSES,len(test_y)))
np.put_along_axis(out,np.array(index_arr),1,axis=0)
test_y=out.T
weight1=2*np.random.random((power1*int(train_x.size/len(train_x)),HIDDEN_LEN))-1
weight2=2*np.random.random((HIDDEN_LEN*power2,OUT_CLASSES))-1
power1_arr = np.tile(np.arange(power1),train_x.size).reshape(train_x.size,power1)
power2_arr = np.tile(np.arange(power2),HIDDEN_LEN*len(train_x)).reshape(HIDDEN_LEN*len(train_x),power2)
power1_arr_test = np.tile(np.arange(power1),test_x.size).reshape(test_x.size,power1)
power2_arr_test = np.tile(np.arange(power2),HIDDEN_LEN*len(test_x)).reshape(HIDDEN_LEN*len(test_x),power2)
train_x2=np.reshape(train_x,(train_x.size,1))
test_x2=np.reshape(test_x,(test_x.size,1))
virtual_train_x = np.power(train_x2,power1_arr).reshape(len(train_x),int(power1*train_x.size/len(train_x)))
virtual_test_x = np.power(test_x2,power1_arr_test).reshape(len(test_x),int(power1*test_x.size/len(test_x)))
someones = np.ones(power1)
persent_train = np.ones(OUT_CLASSES).reshape(OUT_CLASSES,1)
persent_test = np.ones(OUT_CLASSES).reshape(OUT_CLASSES,1)
max_persent = 0
error_test_list=[]
error_train_list=[]
error_test_list_persent=[]
error_train_list_persent=[]
for step in range(EPOCHS):
hidden_layer = 1/(1+np.exp(-(np.dot(virtual_train_x,weight1))))
hidden_layer2 = np.reshape(hidden_layer,(hidden_layer.size,1))
virtual_hidden_layer_train = np.power(hidden_layer2,power2_arr).reshape(len(hidden_layer),int(power2*hidden_layer.size/len(hidden_layer)))
out_with_error = 1/(1+np.exp(-(np.dot(virtual_hidden_layer_train,weight2))))
error_w2 = (train_y-out_with_error)
weight2+=SPEED_EDICATION*virtual_hidden_layer_train.T.dot(error_w2*out_with_error*(1-out_with_error))
error_w1 = error_w2.dot(weight2.T)
error_w1_reshaped = np.reshape(error_w1,(int(error_w1.size/power1),power1))
error_w1_virtual = np.reshape(np.dot(error_w1_reshaped,someones),(len(error_w1),int(error_w1.size/power1/len(error_w1))))
weight1+=SPEED_EDICATION*virtual_train_x.T.dot(error_w1_virtual)
hidden_layer_test = 1/(1+np.exp(-(np.dot(virtual_test_x,weight1))))
hidden_layer2_test = np.reshape(hidden_layer_test,(hidden_layer_test.size,1))
virtual_hidden_layer_test = np.power(hidden_layer2_test,power2_arr_test).reshape(len(hidden_layer_test),int(power2*hidden_layer_test.size/len(hidden_layer_test)))
out_with_error_test = 1/(1+np.exp(-(np.dot(virtual_hidden_layer_test,weight2))))
error_w2_test = (test_y-out_with_error_test)
p_train = np.dot(np.abs(train_y-np.around(out_with_error)),persent_train)
p_test = np.dot(np.abs(test_y-np.around(out_with_error_test)),persent_test)
err_p_train = 100*(1-np.sum(np.logical_and(p_train,True))/len(train_y))
err_p_test = 100*(1-np.sum(np.logical_and(p_test,True))/len(test_y))
if max_persent<err_p_test:
max_persent=err_p_test
error_test_list.append(np.sum(np.square(error_w2_test))/2)
error_train_list.append(np.sum(np.square(error_w2))/2)
error_test_list_persent.append(err_p_test)
error_train_list_persent.append(err_p_train)
print("step =",step,"/",EPOCHS," error train = ",np.sum(np.square(error_w2))/2," error test = ",np.sum(np.square(error_w2_test)/2))
print("step =",step,"/",EPOCHS," error train = ",err_p_train,"%"," error test = ",err_p_test,"%")
print("step =",step,"/",EPOCHS," max persent test = ",max_persent,"%")
list_size = len(error_train_list)
data = error_train_list
data.extend(error_test_list)
data.extend(error_train_list_persent)
data.extend(error_test_list_persent)
data = np.reshape(data,(4,list_size))
np.savetxt('out.csv',data.T,delimiter=',',fmt='%.4f')
Я также решил использовать cupy,для того,чтобы программа работала на видеокарте.
import numpy as np
from numpy import genfromtxt
import cupy as cp
OUT_CLASSES=10
HIDDEN_LEN=300
SPEED_EDICATION=0.00001
EPOCHS=1000
power1=2
power2=2
train = genfromtxt('fashion_train.csv', delimiter=',')
train=train[1:,:]
train_x=np.array(train[:,:-1])
train_x/=255
train_y=np.array(train[:,-1])
train_y = train_y.astype(int)
out = np.zeros(OUT_CLASSES*len(train_y))
index_arr=np.reshape(train_y,(1,len(train_y)))
out = np.reshape(out,(OUT_CLASSES,len(train_y)))
np.put_along_axis(out,np.array(index_arr),1,axis=0)
train_y=cp.array(out.T)
test = genfromtxt('fashion_test.csv', delimiter=',')
test=test[1:,:]
test_x=np.array(test[:,:-1])
test_x/=255
test_y=np.array(test[:,-1])
test_y = np.array(test_y.astype(int))
out = np.zeros(OUT_CLASSES*len(test_y))
index_arr=np.reshape(test_y,(1,len(test_y)))
out = np.reshape(out,(OUT_CLASSES,len(test_y)))
np.put_along_axis(out,np.array(index_arr),1,axis=0)
test_y=cp.array(out.T)
weight1=cp.array(2*np.random.random((power1*int(train_x.size/len(train_x)),HIDDEN_LEN))-1)
weight2=cp.array(2*np.random.random((HIDDEN_LEN*power2,OUT_CLASSES))-1)
power1_arr = np.tile(np.arange(power1),train_x.size).reshape(train_x.size,power1)
power2_arr = np.tile(np.arange(power2),HIDDEN_LEN*len(train_x)).reshape(HIDDEN_LEN*len(train_x),power2)
power1_arr_test = np.tile(np.arange(power1),test_x.size).reshape(test_x.size,power1)
power2_arr_test = cp.array(np.tile(np.arange(power2),HIDDEN_LEN*len(test_x)).reshape(HIDDEN_LEN*len(test_x),power2))
train_x2=np.reshape(train_x,(train_x.size,1))
test_x2=np.reshape(test_x,(test_x.size,1))
virtual_train_x = cp.array(np.power(train_x2,power1_arr).reshape(len(train_x),int(power1*train_x.size/len(train_x))))
virtual_test_x = cp.array(np.power(test_x2,power1_arr_test).reshape(len(test_x),int(power1*test_x.size/len(test_x))))
someones = cp.array(np.ones(power1))
persent_train = cp.array(np.ones(OUT_CLASSES).reshape(OUT_CLASSES,1))
persent_test = cp.array(np.ones(OUT_CLASSES).reshape(OUT_CLASSES,1))
max_persent = 0
error_test_list=[]
error_train_list=[]
error_test_list_persent=[]
error_train_list_persent=[]
for step in range(EPOCHS):
hidden_layer = 1/(1+cp.exp(-(cp.dot(virtual_train_x,weight1))))
hidden_layer2 = cp.reshape(hidden_layer,(hidden_layer.size,1))
virtual_hidden_layer_train = cp.power(hidden_layer2,cp.array(power2_arr)).reshape(len(hidden_layer),int(power2*hidden_layer.size/len(hidden_layer)))
out_with_error = 1/(1+cp.exp(-(cp.dot(virtual_hidden_layer_train,cp.array(weight2)))))
error_w2 = (cp.array(train_y)-out_with_error)
weight2+=SPEED_EDICATION*virtual_hidden_layer_train.T.dot(error_w2*out_with_error*(1-out_with_error))
error_w1 = error_w2.dot(weight2.T)
error_w1_reshaped = cp.reshape(error_w1,(int(error_w1.size/power1),power1))
error_w1_virtual = cp.reshape(cp.dot(error_w1_reshaped,someones),(len(error_w1),int(error_w1.size/power1/len(error_w1))))
weight1+=SPEED_EDICATION*virtual_train_x.T.dot(error_w1_virtual)
hidden_layer_test = 1/(1+cp.exp(-(cp.dot(virtual_test_x,weight1))))
hidden_layer2_test = cp.reshape(hidden_layer_test,(hidden_layer_test.size,1))
virtual_hidden_layer_test = cp.power(hidden_layer2_test,power2_arr_test).reshape(len(hidden_layer_test),int(power2*hidden_layer_test.size/len(hidden_layer_test)))
out_with_error_test = 1/(1+np.exp(-(np.dot(virtual_hidden_layer_test,weight2))))
error_w2_test = (test_y-out_with_error_test)
p_train = cp.dot(cp.abs(train_y-cp.around(out_with_error)),persent_train)
p_test = cp.dot(cp.abs(test_y-cp.around(out_with_error_test)),persent_test)
err_p_train = 100*(1-cp.sum(np.logical_and(p_train,True))/len(train_y))
err_p_test = 100*(1-cp.sum(np.logical_and(p_test,True))/len(test_y))
if max_persent<err_p_test:
max_persent=err_p_test
error_test_list.append(cp.sum(cp.square(error_w2_test))/2)
error_train_list.append(cp.sum(cp.square(error_w2))/2)
error_test_list_persent.append(err_p_test)
error_train_list_persent.append(err_p_train)
print("step =",step,"/",EPOCHS," error train = ",np.sum(np.square(error_w2))/2," error test = ",np.sum(np.square(error_w2_test)/2))
print("step =",step,"/",EPOCHS," error train = ",err_p_train,"%"," error test = ",err_p_test,"%")
print("step =",step,"/",EPOCHS," max persent test = ",max_persent,"%")
list_size = len(error_train_list)
data = error_train_list
data.extend(error_test_list)
data.extend(error_train_list_persent)
data.extend(error_test_list_persent)
data=cp.array(data)
data = cp.ndarray.get(cp.reshape(data,(4,list_size)))
np.savetxt('out.csv',data.T,delimiter=',',fmt='%.4f')
Получил некоторые результаты.
Использовал power1=2,power2=2,коэффициент скорости обучения равен 0.00001,количество эпох=3000.
Получил максимальную ошибку(в процентах) тестового набора error=58.6%
Использовал power1=3,power2=3,коэффициент скорости обучения равен 0.00001,количество эпох=3000.
Получил максимальную ошибку(в процентах) тестового набора error=61,6%
Использовал power1=4,power2=4,коэффициент скорости обучения равен 0.000001,количество эпох=60000.
Получил максимальную ошибку(в процентах) тестового набора error=62.7%
Использовал power1=5,power2=5,коэффициент скорости обучения равен 0.000001,количество эпох=90000.
Получил максимальную ошибку (в процентах) тестового набора error=62.8%
Зависимость максиальной точности тестового набора от степенного ряда.
Однако среднеквадратическая ошибка вела себя странно (наверно из-за степенного ряда)
Вывод: Ошибка (в процентах) тестового обучающего набора при увеличении степенного ряда растет. Возможно, не быстро, на 0.1 или даже меньше, но с увеличением степенного ряда, количества эпох обучения и уменьшением скорости обучения можно добиться увеличения точности нейросети при работе с тестовым набором данных.
Используемая литература
Каниа Алексеевич Кан Нейронный сети. Эволюция
Тарик Рашид.Создаем нейронную сеть.
Использовалась статья Нейросеть в 11 строчек на Python
kapas19
Очень похоже на Метод группового учёта аргументов Ивахненко
pav91pav Автор
И в чем наблюдается сходство?