পাইথনে স্ক্র্যাচ থেকে নিউরাল নেটওয়ার্ক তৈরি করুন (কোনও গ্রন্থাগার নেই)
হ্যালো, আমার প্রিয় পাঠকগণ, এই পোস্টে আমি আপনাকে দেখাতে যাচ্ছি যে কোনও লাইব্রেরির সাহায্য ছাড়াই আপনি কীভাবে আপনার নিজের নিউরাল নেটওয়ার্ক লিখতে পারেন হ্যাঁ আমরা কোনও লাইব্রেরি ব্যবহার করব না এবং এর অর্থ যে কোনও বাহ্যিক গ্রন্থাগার যেমন টেনস্রোফ্লো বা থিয়ানো রয়েছে । আমি এখনও গণিতের লাইব্রেরি এবং নম্পি ব্যবহার করব। তবে এটি খুব ন্যূনতম হবে
এতে কী লাভ হবে? ভাল, যদি আপনি কিছু গুরুতর কাজ করতে চান এবং আপনার মন কোনও এনএন লিখতে চান না তবে নিউরাল নেটওয়ার্ক লাইব্রেরিটি ব্যবহার করা আরও দক্ষ হবে। তবে আপনি যদি শিখতে চান যে নিউরাল নেটওয়ার্কটি কীভাবে হুডের নীচে কাজ করছে তবে তার নিজের অন্তর্দৃষ্টি দেখার জন্য আপনি নিজের ছোট কোডটি কী লিখতে পারেন
বিল্ডিং ব্লক
কোডে ঝাঁপ দেওয়ার আগে একটি সাধারণ নিউরাল নেটওয়ার্কের কাঠামোটি দেখে এবং বিল্ডিং ব্লকগুলি স্থির করতে দেয়।

উপরে তিনটি ইনপুট নিউরন, তিনটি লুকানো নিউরন এবং একটি আউটপুট নিউরন সহ একটি সাধারণ নিউরাল নেটওয়ার্ক।
প্রতিটি এবং নিউরন এর আগের স্তরের সমস্ত নিউরনের সাথে সংযুক্ত থাকে। এবং এই সংযোগগুলির ওজন রয়েছে কিছু কিছু শক্তিশালী কিছু দুর্বল। এবং একটি নেটওয়ার্ক গঠন
সুতরাং এটি খুঁজে বেসিক বিল্ডিং ব্লকগুলি হবে
- সংযোগ -> দুটি নিউরনের সংযোগের মধ্যে তথ্য রাখবেConnection -> will keep information between the connection of two neuron
- নিউরন -> সংযুক্ত নিউরন থেকে সংকেত পাবেন এবং একটি আউটপুট উত্পাদন করবেConnection -> will keep information between the connection of two neuron
- নেটওয়ার্ক -> স্তরগুলিতে নিউরন এবং প্রবাহের ডেটাগুলির একটি নেটওয়ার্ক তৈরি করবে Network -> will create a network of the neurons and flow data in the layers
স্ক্র্যাচ থেকে একটি নিউরাল নেটওয়ার্ক কোড করি
ঠিক আছে তবে আর কোনও সময় নষ্ট না করে কোডিং শুরু করা যাক। আমাদের দুটি গ্রন্থাগার প্রয়োজন হবে এবং আমরা কেবল সেগুলি ব্যবহার করব
import math
import numpy as np
এখন সংযোগ ক্লাস তৈরি করা যাক
এটাই !! .. সংযোগের অবজেক্টটি কেবল সংযুক্ত নিউরন, সংযোগের ওজন এবং গতির জন্য ডেল্টা ওজন সম্পর্কে তথ্য ধারণ (hold) করবে
নিউরন ক্লাস
সুতরাং আমরা এখানে একটি নিউরন ক্লাস তৈরি করেছি এবং আমরা সংযুক্ত নিউরন এবং আউটপুট ত্রুটি বিতরণ গণনা করার জন্য dendrons (connections), error,ডেনড্রন (সংযোগ), error গ্রেডিয়েন্টের একটি তালিকা দিয়ে প্রাথমিককরণ সংজ্ঞায়িত করেছি। এটি তার ইনপুট হিসাবে একটি স্তর নিচ্ছে যা পূর্ববর্তী স্তর হবে। ইনপুট এবং বায়াস নিউরনের জন্য পূর্ববর্তী স্তরটি Nome।
একবার নিউরন তৈরি হয়ে গেলে এর আগের স্তর নিউরনের সাথে সংযোগ তৈরি করতে হবে। যা dendrons ডেন্ড্রন তালিকায় সঞ্চিত রয়েছে। এবং এখন আমাদের কাছে কিছু স্থিতিশীল ভেরিয়েবল রয়েছে eta, Alpha যা নিউরনের শিখার হার এবং গতিবেগের কারণ হবে
এখন আমাদের নিউরন ক্লাসের জন্য কিছু প্রাথমিক কাজ করা দরকার
পদ্ধতিটি adderror ব্যাকপ্রসারণের সময় পরবর্তী স্তরটিতে সমস্ত নিউরন থেকে প্রেরিত error সংগ্রহ করতে ব্যবহৃত হবে। সিগময়েড হ'ল আমাদের অ্যাক্টিভেশন ফাংশন এবং ডি-সিগময়েড সিগময়েড ফাংশনটির ডেরাইভেশন এটি backpropagation সময় নিউরনের গ্রেডিয়েন্ট গণনা করতে ব্যবহৃত হবে। অন্যরা কেবল getters and setters হয়।
আসুন একক নিউরনের জন্য ফিডফোর্ডটি করি
feedforward
ফিডফোরওয়ার্ড পদ্ধতিতে আমরা কেবল যাচাই করে দেখছি যে এর আগে সংযুক্ত কোনও নিউরন রয়েছে কিনা। যদি তা না হয় তবে এটি কোনও ইনপুট বা পক্ষপাতিত্ব নিউরন এবং এটি করার জন্য এবং ফিডফোর্ডের দরকার নেই। কিন্তু যদি কোনো নিউরন এটা এক দ্বারা সংযুক্ত নিউরোন এক আউটপুট পাওয়ার এই ক্ষেত্রে সংযোগের ওজন সঙ্গে এটি গুন হল dendron.weight। তাদের সংক্ষেপ করে এবং এটি অ্যাক্টিভেশন ফাংশন সিগময়েড এবং আউটপুট মাধ্যমে পাস করে
একটি একক নিউরনের জন্য পিছনের প্রচার পদ্ধতিটি সংজ্ঞায়িত করা যাক
class Neuron:
:
:
def backPropagate(self):
self.gradient = self.error * self.dSigmoid(self.output)
for dendron in self.dendrons:
dendron.dWeight = Neuron.eta * (
dendron.connectedNeuron.output * self.gradient) + self.alpha * dendron.dWeight
dendron.weight = dendron.weight + dendron.dWeight
dendron.connectedNeuron.addError(dendron.weight * self.gradient)
self.error = 0
এখানে এই পদ্ধতিতে, আমরা গ্রেডিয়েন্ট গণনা করতে error x d.(output) ব্যবহার করছি। গ্রেডিয়েন্ট দিক সিদ্ধান্ত নেবেন আমরা একটি সংযোগ এবং সংযুক্ত neuron আউটপুট ওজন পরিবর্তন করতে সিদ্ধান্ত নেবেন আমরা কতটা ওজন error কমানোর জন্য পরিবর্তন প্রয়োজন
সুতরাং একক সংযোগের জন্য ওজনের পরিবর্তন হবে
δweight= η x gradient x output of connected neuron + α x previous δweight
এখানে eta (η) হল শিখার হার যা ঠিক করবে যে নেটওয়ার্ক তার ওজন আপডেট করবে এবং আলফা (α) এমন গতিবেগের হার যা ওজনকে একটি গতিবেগ দেবে যাতে এটি ছোট ওঠানামা উপেক্ষা করে কোনও নির্দিষ্ট দিকে অগ্রসর হতে থাকবে । যা মূলত নিউরনকে স্থানীয় মিনিমা এড়াতে সহায়তা করে
এটি ছিল সমস্ত সংযোগের জন্য আমাদের এটি করতে হবে একক সংযোগের backpropagation ব্যাকপ্রকাশ। সুতরাং আমরা সমস্ত ডেনড্রন দিয়ে লুপ করেছি এবং ওজনগুলির সমস্ত পরিবর্তন গণনা করেছি এবং সেই পরিবর্তনটি বর্তমান ওজনে প্রয়োগ করেছি
আমাদের error সংযুক্ত নিউরনে আবারও প্রেরণ করতে হবে যাতে এটি এর সংযোগও ঠিক করতে পারে এবং সেই error টিকে backpropagation ব্যাকপ্রকাশ করতে পারে।
তবে আমরা সংযুক্ত নিউরনের জন্য error সেট করতে সেট error ব্যবহার করছি না কারণ একই স্তরটিতে অন্যান্য নিউরনও থাকতে পারে যা একই নিউরনের সাথেও সংযুক্ত রয়েছে তাই যদি আমরা error টি সেট করি তবে অন্য কোনও নিউরনের দ্বারা error টি সেট করা থাকলে তা হবে ওভাররাইট। সুতরাং সংযুক্ত নিউরনের ইতিমধ্যে থাকা error টিতে আমাদের error টি যুক্ত করা দরকার। অতএব আমরা যুক্ত নিউরোনগুলি যা এর সাথে যুক্ত রয়েছে সেগুলি থেকে error টি সংগ্রহ করতে আমরা addError পদ্ধতি ব্যবহার করছি।
শেষ পর্যন্ত, আমরা ডেনড্রন ওজন সামঞ্জস্য করার পরে এবং error টি প্রচার করার পরে আমাদের error টি শূন্যে zero সেট করতে হবে।
এটি সম্পূর্ণ নিউরন ক্লাস
নেটওয়ার্ক ক্লাস
এখন নেটওয়ার্ক ক্লাস তৈরি করা যাক
সুতরাং এটি নেটওয়ার্ক ক্লাসের আরম্ভকারী। এটি ইনপুট হিসাবে একটি যুক্তি নিচ্ছে যা নেটওয়ার্ক topology টপোলজি, এটি সংখ্যার একটি তালিকা হবে। উদাহরণস্বরূপ, একটি টপোলজি = [2,5,1] প্রতিনিধিত্ব করে যেখানে নেটওয়ার্কে 3 টি স্তর রয়েছে। প্রথম দ্বিতীয় এবং তৃতীয় স্তর যথাক্রমে 2,5,1 নিউরন রয়েছে। প্রথম স্তরটি সর্বদা ইনপুট স্তর থাকে এবং সর্বশেষ হয় সর্বদা আউটপুট, স্তরগুলির মধ্যে বাকিগুলি লুকানো স্তর.
তাই নিউরন শ্রেণিতে আমরা স্তরগুলির নামক একটি অভ্যন্তরীণ তালিকা তৈরি করেছি এবং টপোলজিতে নির্দিষ্ট নিউরনের সংখ্যা অনুযায়ী আমরা এটি নিউরন দিয়ে পূর্ণ করেছি
যদি এটির প্রথম স্তরটি হয়, তবে কোনও পূর্ববর্তী স্তর নেই সুতরাং নিউরনগুলি None parameters Neuron(None). দিয়ে শুরু করা হয়েছিল। স্তরটির শেষে, আমরা কোনও প্যারামিটার (no previous layer for bias) সহ একটি bias নিউরন যুক্ত করছি এবং এর আউটপুট 1 হিসাবে সেট করব
সর্বশেষে স্তরটি সংযোজন করার সময় self.layers তালিকা
নেটওয়ার্ক ক্লাসে এখন আমাদের কিছু সহায়ক পদ্ধতি প্রয়োজন
ইনপুট সেট করা হচ্ছে
প্রথমটি হ'ল ইনপুট সেট করা। নেটওয়ার্কের প্রথম স্তরটি হ'ল ইনপুট স্তরটি এইভাবে সমস্ত ইনপুট মানগুলি লুপ করে এবং সংশ্লিষ্ট ইনপুট মানের সাথে সম্পর্কিত ইনপুট নিউরনের আউটপুট সেট করে
নেটওয়ার্কের সামগ্রিক error টি গণনা করা হচ্ছে
পরবর্তীটি error টি পরিমাপ করা হয়। error টি ফাংশন আউটপুট এবং লক্ষ্যটির পার্থক্য গণনা করে এটি স্কোয়ার square করে এবং সমস্ত আউটপুট নিউরন থেকে সমস্ত square স্কোয়ার error টি সংক্ষিপ্ত করে এবং একটি বর্গমূল করতে পারে। যা মূলত একটি রুট মানে সব আউটপুট নোড error টি বর্গ ।
নেটওয়ার্ক ফরোয়ার্ড
ফিড ফরোয়ার্ড পদ্ধতি বা নেটওয়ার্ক ক্লাস সহজ নয়। আমাদের কেবলমাত্র নেটওয়ার্কের প্রতিটি নিউরনকে ফিফডওয়ার্ড পদ্ধতিতে ইনপুট থেকে আউটপুট স্তর পর্যন্ত ক্রম করতে হবে
নেটওয়ার্ক প্রচার করুন
পিছনে বিস্তার back propagation জন্য। ফিড ফরোয়ার্ড হিসাবে এটি একই তবে আউটপুট থেকে ইনপুট পর্যন্ত আমাদের প্রতিটি নিউরনের পিছনে call/প্রচার করতে হবে। তবে ঠিক এখানে যেমন ফিড এগিয়ে দেওয়ার আগে আমাদের ইনপুট সেট করতে হবে আমাদের প্রতিটি আউটপুট নিউরনের জন্য error টি সেট করতে হবে অন্যান্য নিউরনের জন্য, পরবর্তী স্তর error টি জন্য।
সুতরাং আউটপুট নিউরনের জন্য , স্তরের প্রতিটি নিউরনের জন্য ম্যানুয়ালি error টি সেট করতে হবে আমাদের.প্রতিটি নিউরনের জন্য ত্রুটিটি সেই নিউরনের আউটপুটকে লক্ষ্যমাত্রা বিয়োগ করবে
এখন আমাদের নেটওয়ার্কের প্রতিটি নিউরনের backPropagate টি আউটপুট স্তর থেকে ইনপুট স্তরটিকে ক্রমে কল করতে হবে
নেটওয়ার্ক থেকে ফলাফল পান
আমরা নেটওয়ার্কের শেষ স্তর থেকে একটি তালিকাতে ফলাফল পাচ্ছি এবং শেষ আউটপুটটি পপ করছি যা একটি বায়াস নিউরনের আউটপুট
এবং optionally ভাবে আমি আর একটি পদ্ধতি getThResults তৈরি করেছি যা মূলত মূলত থ্রোসোল্ড হিসাবে আউটপুট এর প্রান্তিক সংস্করণ 0.5
নেটওয়ার্ক টেস্ট করতে
নেটওয়ার্কটি পরীক্ষা করতে আমরা অর্ধ সংযোজক হতে প্রশিক্ষণ দিতে যাচ্ছি। যা নিম্নরূপ
যেখানে A, বB ইনপুট এবং Sum, ক্যারি আউট আউটপুট হয়
মূল ফাংশনে আমরা একটি নেটওয়ার্ক টপোলজিকে [2,3,2] হিসাবে সংজ্ঞায়িত করেছি, আমরা শিক্ষার হারকে ০.০৯ এবং আলফা ০.০১৫ হতে সেট করেছি। আমরা ইনপুট এবং সংশ্লিষ্ট আউটপুট প্রস্তুত।
এর মধ্যে আমরা প্রতিটি ইনপুটটির জন্য নেটওয়ার্কটি প্রশিক্ষণ দিচ্ছি যা সেট setInput-> feedForward-> backPropagateইনপুট-> ফিডফোরওয়ার্ড-> ব্যাকপ্রপাগেট ততক্ষণ error টি একটি প্রান্তিক মানের চেয়ে কম না হওয়া পর্যন্ত.
লুপের পরবর্তী সময়ে, আমরা কনসোল থেকে ইনপুট নিচ্ছি এবং যে নেটওয়ার্কটি ব্যবহার করে আউটপুট পূর্বাভাস দিচ্ছি
setInput-> feedForward->getThResults
আমরা সবে স্ক্র্যাচ থেকে একটি নিউরাল নেটওয়ার্ক তৈরি করেছি
সম্পূর্ণ কোডটি এর মতো দেখাবে
import math
import numpy as np
class Connection:
def __init__(self, connectedNeuron):
self.connectedNeuron = connectedNeuron
self.weight = np.random.normal()
self.dWeight = 0.0
class Neuron:
eta = 0.001
alpha = 0.01
def __init__(self, layer):
self.dendrons = []
self.error = 0.0
self.gradient = 0.0
self.output = 0.0
if layer is None:
pass
else:
for neuron in layer:
con = Connection(neuron)
self.dendrons.append(con)
def addError(self, err):
self.error = self.error + err
def sigmoid(self, x):
return 1 / (1 + math.exp(-x * 1.0))
def dSigmoid(self, x):
return x * (1.0 - x)
def setError(self, err):
self.error = err
def setOutput(self, output):
self.output = output
def getOutput(self):
return self.output
def feedForword(self):
sumOutput = 0
if len(self.dendrons) == 0:
return
for dendron in self.dendrons:
sumOutput = sumOutput + dendron.connectedNeuron.getOutput() * dendron.weight
self.output = self.sigmoid(sumOutput)
def backPropagate(self):
self.gradient = self.error * self.dSigmoid(self.output);
for dendron in self.dendrons:
dendron.dWeight = Neuron.eta * (
dendron.connectedNeuron.output * self.gradient) + self.alpha * dendron.dWeight;
dendron.weight = dendron.weight + dendron.dWeight;
dendron.connectedNeuron.addError(dendron.weight * self.gradient);
self.error = 0;
class Network:
def __init__(self, topology):
self.layers = []
for numNeuron in topology:
layer = []
for i in range(numNeuron):
if (len(self.layers) == 0):
layer.append(Neuron(None))
else:
layer.append(Neuron(self.layers[-1]))
layer.append(Neuron(None))
layer[-1].setOutput(1)
self.layers.append(layer)
def setInput(self, inputs):
for i in range(len(inputs)):
self.layers[0][i].setOutput(inputs[i])
def feedForword(self):
for layer in self.layers[1:]:
for neuron in layer:
neuron.feedForword();
def backPropagate(self, target):
for i in range(len(target)):
self.layers[-1][i].setError(target[i] - self.layers[-1][i].getOutput())
for layer in self.layers[::-1]:
for neuron in layer:
neuron.backPropagate()
def getError(self, target):
err = 0
for i in range(len(target)):
e = (target[i] - self.layers[-1][i].getOutput())
err = err + e ** 2
err = err / len(target)
err = math.sqrt(err)
return err
def getResults(self):
output = []
for neuron in self.layers[-1]:
output.append(neuron.getOutput())
output.pop()
return output
def getThResults(self):
output = []
for neuron in self.layers[-1]:
o = neuron.getOutput()
if (o > 0.5):
o = 1
else:
o = 0
output.append(o)
output.pop()
return output
def main():
topology = []
topology.append(2)
topology.append(3)
topology.append(2)
net = Network(topology)
Neuron.eta = 0.09
Neuron.alpha = 0.015
while True:
err = 0
inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]
outputs = [[0, 0], [1, 0], [1, 0], [0, 1]]
for i in range(len(inputs)):
net.setInput(inputs[i])
net.feedForword()
net.backPropagate(outputs[i])
err = err + net.getError(outputs[i])
print "error: ", err
if err < 0.01:
break
while True:
a = input("type 1st input :")
b = input("type 2nd input :")
net.setInput([a, b])
net.feedForword()
print net.getThResults()
if __name__ == '__main__':
main()
0 comments:
Post a Comment