मुझे लगता है कि आप गलत तरीके से एनएन को प्रशिक्षित करते हैं। आपके पास 10000 पुनरावृत्तियों से अधिक लूप है और प्रत्येक चक्र में एक नया नमूना खिलाएं। इस मामले में एनएन कभी प्रशिक्षित नहीं होगा।
(बयान गलत है! अद्यतन मिलते हैं!)
आपको क्या करने की जरूरत है, सच नमूने Y = sin(X)
की विस्तृत शृंखला को उत्पन्न यह अपने नेटवर्क को दे एक बार और अधिक पुनरावृति करने के लिए है लागत समारोह को कम करने के लिए, प्रशिक्षण आगे और पीछे की ओर सेट करें। एल्गोरिदम की जांच करने के लिए आपको पुनरावृत्ति संख्या के आधार पर लागत कार्य को साजिश करने की आवश्यकता हो सकती है और यह सुनिश्चित कर लें कि लागत कम हो गई है।
वजन का प्रारंभिक एक और महत्वपूर्ण बिंदु है। आपकी संख्या बहुत बड़ी है और नेटवर्क को कम दरों का उपयोग करते समय, विशेष रूप से अभिसरण करने में काफी समय लगेगा। कुछ छोटी सी रेंज [-eps .. eps]
समान रूप से शुरुआती वजन उत्पन्न करने के लिए यह एक अच्छा अभ्यास है। sigmoid()
और tanh()
:
मेरी कोड में मैं दो अलग अलग सक्रियण कार्यों को लागू किया। चयनित क्रम के आधार पर आपको अपने इनपुट को स्केल करने की आवश्यकता है: [0 .. 1]
और [-1 .. 1]
क्रमशः।
आप sigmoid()
सक्रियण देख सकते हैं एक छोटे से देता है:
यहाँ जो लागत समारोह दिखाने के कुछ चित्रों और sigmoid()
के लिए जिसके परिणामस्वरूप भविष्यवाणियों और tanh()
सक्रियण कार्य हैं tanh()
से थोड़ा बेहतर परिणाम।
इसके अलावा, मैं काफी बेहतर भविष्यवाणियों जब एक नेटवर्क [1, 6, 1]
का उपयोग कर 4 परतों [1, 6, 4, 1]
साथ एक बड़ा नेटवर्क की तुलना में मिला है। तो एनएन का आकार हमेशा महत्वपूर्ण कारक नहीं होता है।
यहाँ कुछ टिप्पणियों के साथ मेरी कोड है: यहाँ 4 परतों के साथ उल्लेख किया नेटवर्क के लिए भविष्यवाणी है। मैंने आपके नोटेशन का उपयोग करने की कोशिश की जहां यह संभव था।
import numpy as np
import math
import matplotlib.pyplot as plt
class Neuralnet:
def __init__(self, neurons, activation):
self.weights = []
self.inputs = []
self.outputs = []
self.errors = []
self.rate = 0.5
self.activation = activation #sigmoid or tanh
self.neurons = neurons
self.L = len(self.neurons) #number of layers
eps = 0.12; # range for uniform distribution -eps..+eps
for layer in range(len(neurons)-1):
self.weights.append(np.random.uniform(-eps,eps,size=(neurons[layer+1], neurons[layer]+1)))
###################################################################################################
def train(self, X, Y, iter_count):
m = X.shape[0];
for layer in range(self.L):
self.inputs.append(np.empty([m, self.neurons[layer]]))
self.errors.append(np.empty([m, self.neurons[layer]]))
if (layer < self.L -1):
self.outputs.append(np.empty([m, self.neurons[layer]+1]))
else:
self.outputs.append(np.empty([m, self.neurons[layer]]))
#accumulate the cost function
J_history = np.zeros([iter_count, 1])
for i in range(iter_count):
self.feedforward(X)
J = self.cost(Y, self.outputs[self.L-1])
J_history[i, 0] = J
self.backpropagate(Y)
#plot the cost function to check the descent
plt.plot(J_history)
plt.show()
###################################################################################################
def cost(self, Y, H):
J = np.sum(np.sum(np.power((Y - H), 2), axis=0))/(2*m)
return J
###################################################################################################
def feedforward(self, X):
m = X.shape[0];
self.outputs[0] = np.concatenate( (np.ones([m, 1]), X), axis=1)
for i in range(1, self.L):
self.inputs[i] = np.dot(self.outputs[i-1], self.weights[i-1].T )
if (self.activation == 'sigmoid'):
output_temp = self.sigmoid(self.inputs[i])
elif (self.activation == 'tanh'):
output_temp = np.tanh(self.inputs[i])
if (i < self.L - 1):
self.outputs[i] = np.concatenate( (np.ones([m, 1]), output_temp), axis=1)
else:
self.outputs[i] = output_temp
###################################################################################################
def backpropagate(self, Y):
self.errors[self.L-1] = self.outputs[self.L-1] - Y
for i in range(self.L - 2, 0, -1):
if (self.activation == 'sigmoid'):
self.errors[i] = np.dot( self.errors[i+1], self.weights[i][:, 1:] ) * self.sigmoid_prime(self.inputs[i])
elif (self.activation == 'tanh'):
self.errors[i] = np.dot( self.errors[i+1], self.weights[i][:, 1:] ) * (1 - self.outputs[i][:, 1:]*self.outputs[i][:, 1:])
for i in range(0, self.L-1):
grad = np.dot(self.errors[i+1].T, self.outputs[i])/m
self.weights[i] = self.weights[i] - self.rate*grad
###################################################################################################
def sigmoid(self, z):
s = 1.0/(1.0 + np.exp(-z))
return s
###################################################################################################
def sigmoid_prime(self, z):
s = self.sigmoid(z)*(1 - self.sigmoid(z))
return s
###################################################################################################
def predict(self, X, weights):
m = X.shape[0];
self.inputs = []
self.outputs = []
self.weights = weights
for layer in range(self.L):
self.inputs.append(np.empty([m, self.neurons[layer]]))
if (layer < self.L -1):
self.outputs.append(np.empty([m, self.neurons[layer]+1]))
else:
self.outputs.append(np.empty([m, self.neurons[layer]]))
self.feedforward(X)
return self.outputs[self.L-1]
###################################################################################################
# MAIN PART
activation1 = 'sigmoid' # the input should be scaled into [ 0..1]
activation2 = 'tanh' # the input should be scaled into [-1..1]
activation = activation1
net = Neuralnet([1, 6, 1], activation) # structure of the NN and its activation function
##########################################################################################
# TRAINING
m = 1000 #size of the training set
X = np.linspace(0, 4*math.pi, num = m).reshape(m, 1); # input training set
Y = np.sin(X) # target
kx = 0.1 # noise parameter
noise = (2.0*np.random.uniform(0, kx, m) - kx).reshape(m, 1)
Y = Y + noise # noisy target
# scaling of the target depending on the activation function
if (activation == 'sigmoid'):
Y_scaled = (Y/(1+kx) + 1)/2.0
elif (activation == 'tanh'):
Y_scaled = Y/(1+kx)
# number of the iteration for the training stage
iter_count = 20000
net.train(X, Y_scaled, iter_count) #training
# gained weights
trained_weights = net.weights
##########################################################################################
# PREDICTION
m_new = 40 #size of the prediction set
X_new = np.linspace(0, 4*math.pi, num = m_new).reshape(m_new, 1);
Y_new = net.predict(X_new, trained_weights) # prediction
#rescaling of the result
if (activation == 'sigmoid'):
Y_new = (2.0*Y_new - 1.0) * (1+kx)
elif (activation == 'tanh'):
Y_new = Y_new * (1+kx)
# visualization
plt.plot(X, Y)
plt.plot(X_new, Y_new, 'ro')
plt.show()
raw_input('press any key to exit')
अद्यतन
मैं अपने कोड में इस्तेमाल किया प्रशिक्षण विधि के बारे में बयान वापस लेना चाहते हैं। नेटवर्क को प्रति पुनरावृत्ति केवल एक नमूना का उपयोग करके प्रशिक्षित किया जा सकता है।
ऑनलाइन प्रशिक्षण अवग्रह (लागत समारोह और भविष्यवाणी)
ऑनलाइन प्रशिक्षण tanh (का उपयोग कर का उपयोग करते हुए: मैं दोनों अवग्रह और tanh सक्रियण कार्यों का उपयोग कर ऑनलाइन प्रशिक्षण में दिलचस्प परिणाम मिला लागत समारोह और भविष्यवाणी)
जैसा कि सक्रियण समारोह के रूप में सिग्मोइड की पसंद को देखा जा सकता है बेहतर प्रदर्शन देता है। लागत कार्य ऑफ़लाइन प्रशिक्षण के दौरान उतना अच्छा नहीं लगता है, लेकिन कम से कम यह नीचे जाने लगता है।
मैं अपने कार्यान्वयन में लागत समारोह साजिश रची है, यह रूप में अच्छी तरह सुंदर झटकेदार दिखता है:
हो सकता है यह एक अच्छा विचार अवग्रह या यहाँ तक कि Relu समारोह के साथ अपने कोड की कोशिश करना है।
यहां अद्यतन स्रोत कोड है। online
और offline
प्रशिक्षण मोड के बीच स्विच करने के लिए बस method
चर बदलें।
import numpy as np
import math
import matplotlib.pyplot as plt
class Neuralnet:
def __init__(self, neurons, activation):
self.weights = []
self.inputs = []
self.outputs = []
self.errors = []
self.rate = 0.2
self.activation = activation #sigmoid or tanh
self.neurons = neurons
self.L = len(self.neurons) #number of layers
eps = 0.12; #range for uniform distribution -eps..+eps
for layer in range(len(neurons)-1):
self.weights.append(np.random.uniform(-eps,eps,size=(neurons[layer+1], neurons[layer]+1)))
###################################################################################################
def train(self, X, Y, iter_count):
m = X.shape[0];
for layer in range(self.L):
self.inputs.append(np.empty([m, self.neurons[layer]]))
self.errors.append(np.empty([m, self.neurons[layer]]))
if (layer < self.L -1):
self.outputs.append(np.empty([m, self.neurons[layer]+1]))
else:
self.outputs.append(np.empty([m, self.neurons[layer]]))
#accumulate the cost function
J_history = np.zeros([iter_count, 1])
for i in range(iter_count):
self.feedforward(X)
J = self.cost(Y, self.outputs[self.L-1])
J_history[i, 0] = J
self.backpropagate(Y)
#plot the cost function to check the descent
#plt.plot(J_history)
#plt.show()
###################################################################################################
def cost(self, Y, H):
J = np.sum(np.sum(np.power((Y - H), 2), axis=0))/(2*m)
return J
###################################################################################################
def cost_online(self, min_x, max_x, iter_number):
h_arr = np.zeros([iter_number, 1])
y_arr = np.zeros([iter_number, 1])
for step in range(iter_number):
x = np.random.uniform(min_x, max_x, 1).reshape(1, 1)
self.feedforward(x)
h_arr[step, 0] = self.outputs[-1]
y_arr[step, 0] = np.sin(x)
J = np.sum(np.sum(np.power((y_arr - h_arr), 2), axis=0))/(2*iter_number)
return J
###################################################################################################
def feedforward(self, X):
m = X.shape[0];
self.outputs[0] = np.concatenate( (np.ones([m, 1]), X), axis=1)
for i in range(1, self.L):
self.inputs[i] = np.dot(self.outputs[i-1], self.weights[i-1].T )
if (self.activation == 'sigmoid'):
output_temp = self.sigmoid(self.inputs[i])
elif (self.activation == 'tanh'):
output_temp = np.tanh(self.inputs[i])
if (i < self.L - 1):
self.outputs[i] = np.concatenate( (np.ones([m, 1]), output_temp), axis=1)
else:
self.outputs[i] = output_temp
###################################################################################################
def backpropagate(self, Y):
self.errors[self.L-1] = self.outputs[self.L-1] - Y
for i in range(self.L - 2, 0, -1):
if (self.activation == 'sigmoid'):
self.errors[i] = np.dot( self.errors[i+1], self.weights[i][:, 1:] ) * self.sigmoid_prime(self.inputs[i])
elif (self.activation == 'tanh'):
self.errors[i] = np.dot( self.errors[i+1], self.weights[i][:, 1:] ) * (1 - self.outputs[i][:, 1:]*self.outputs[i][:, 1:])
for i in range(0, self.L-1):
grad = np.dot(self.errors[i+1].T, self.outputs[i])/m
self.weights[i] = self.weights[i] - self.rate*grad
###################################################################################################
def sigmoid(self, z):
s = 1.0/(1.0 + np.exp(-z))
return s
###################################################################################################
def sigmoid_prime(self, z):
s = self.sigmoid(z)*(1 - self.sigmoid(z))
return s
###################################################################################################
def predict(self, X, weights):
m = X.shape[0];
self.inputs = []
self.outputs = []
self.weights = weights
for layer in range(self.L):
self.inputs.append(np.empty([m, self.neurons[layer]]))
if (layer < self.L -1):
self.outputs.append(np.empty([m, self.neurons[layer]+1]))
else:
self.outputs.append(np.empty([m, self.neurons[layer]]))
self.feedforward(X)
return self.outputs[self.L-1]
###################################################################################################
# MAIN PART
activation1 = 'sigmoid' #the input should be scaled into [0..1]
activation2 = 'tanh' #the input should be scaled into [-1..1]
activation = activation1
net = Neuralnet([1, 6, 1], activation) # structure of the NN and its activation function
method1 = 'online'
method2 = 'offline'
method = method1
kx = 0.1 #noise parameter
###################################################################################################
# TRAINING
if (method == 'offline'):
m = 1000 #size of the training set
X = np.linspace(0, 4*math.pi, num = m).reshape(m, 1); #input training set
Y = np.sin(X) #target
noise = (2.0*np.random.uniform(0, kx, m) - kx).reshape(m, 1)
Y = Y + noise #noisy target
#scaling of the target depending on the activation function
if (activation == 'sigmoid'):
Y_scaled = (Y/(1+kx) + 1)/2.0
elif (activation == 'tanh'):
Y_scaled = Y/(1+kx)
#number of the iteration for the training stage
iter_count = 20000
net.train(X, Y_scaled, iter_count) #training
elif (method == 'online'):
sampling_count = 100000 # number of samplings during the training stage
m = 1 #batch size
iter_count = sampling_count/m
for layer in range(net.L):
net.inputs.append(np.empty([m, net.neurons[layer]]))
net.errors.append(np.empty([m, net.neurons[layer]]))
if (layer < net.L -1):
net.outputs.append(np.empty([m, net.neurons[layer]+1]))
else:
net.outputs.append(np.empty([m, net.neurons[layer]]))
J_history = []
step_history = []
for i in range(iter_count):
X = np.random.uniform(0, 4*math.pi, m).reshape(m, 1)
Y = np.sin(X) #target
noise = (2.0*np.random.uniform(0, kx, m) - kx).reshape(m, 1)
Y = Y + noise #noisy target
#scaling of the target depending on the activation function
if (activation == 'sigmoid'):
Y_scaled = (Y/(1+kx) + 1)/2.0
elif (activation == 'tanh'):
Y_scaled = Y/(1+kx)
net.feedforward(X)
net.backpropagate(Y_scaled)
if (np.remainder(i, 1000) == 0):
J = net.cost_online(0, 4*math.pi, 1000)
J_history.append(J)
step_history.append(i)
plt.plot(step_history, J_history)
plt.title('Batch size ' + str(m) + ', rate ' + str(net.rate) + ', samples ' + str(sampling_count))
#plt.ylim([0, 0.1])
plt.show()
#gained weights
trained_weights = net.weights
##########################################################################################
# PREDICTION
m_new = 40 #size of the prediction set
X_new = np.linspace(0, 4*math.pi, num = m_new).reshape(m_new, 1);
Y_new = net.predict(X_new, trained_weights) #prediction
#rescaling of the result
if (activation == 'sigmoid'):
Y_new = (2.0*Y_new - 1.0) * (1+kx)
elif (activation == 'tanh'):
Y_new = Y_new * (1+kx)
#visualization
#fake sine curve to show the ideal signal
if (method == 'online'):
X = np.linspace(0, 4*math.pi, num = 100)
Y = np.sin(X)
plt.plot(X, Y)
plt.plot(X_new, Y_new, 'ro')
if (method == 'online'):
plt.title('Batch size ' + str(m) + ', rate ' + str(net.rate) + ', samples ' + str(sampling_count))
plt.ylim([-1.5, 1.5])
plt.show()
raw_input('press any key to exit')
अब मैं अपने वर्तमान कोड के लिए कुछ टिप्पणी है:
आपका ज्या समारोह इस तरह दिखता है:
मैं क्यों आप अपने लक्ष्य इनपुट में tanh का उपयोग नहीं जानते । यदि आप वास्तव में लक्ष्य के रूप में साइन के tanh का उपयोग करना चाहते हैं, तो आपको इसे [-1..1]
पर स्केल करने की आवश्यकता है, क्योंकि tanh (sin (x)) [-0.76..0.76]
श्रेणी में मान देता है।
अगली बात आपके प्रशिक्षण सेट की सीमा है। नमूने उत्पन्न करने के लिए आप x = np.random.normal()
का उपयोग करते हैं। यहां इस तरह के एक इनपुट का वितरण है:
यह करने के बाद आप अपने नेटवर्क 3
की ज्या भविष्यवाणी करने के लिए चाहते हैं, लेकिन नेटवर्क लगभग कभी प्रशिक्षण चरण के दौरान इस संख्या को देखा है। मैं इसके बजाय नमूना उत्पादन के लिए व्यापक श्रेणी में समान वितरण का उपयोग करूंगा।
मैंने आपके द्वारा निर्दिष्ट दस्तावेज़ों को पढ़ा है लेकिन पाप (2) के लिए संबंधित एल्गोरिदम नहीं ढूंढ पाए हैं। क्या आप आगे विस्तार करना चाहते हैं? – White
@ व्हाइट पाप (2) केवल मानक साइन फ़ंक्शन है, यदि यह आपका प्रश्न है। उपयोगकर्ता 1667423, पहली नज़र में मुझे कोई त्रुटि दिखाई नहीं दे रही है। क्या आपने दो इनपुट या यहां तक कि पहचान फ़ंक्शन के तर्क फ़ंक्शन (AND, OR, ...) जैसे सरल कार्य की कोशिश की है? और केवल 1 या कोई छुपी परत का उपयोग करने का प्रयास करें। –
आप थैनो/लासगेन या टेंसरफ्लो जैसे मौजूदा ढांचे का उपयोग क्यों नहीं करते? –