Skip to content

Instantly share code, notes, and snippets.

@NP-chaonay
Last active July 28, 2020 03:27
Show Gist options
  • Save NP-chaonay/48e8a8b8c5e3e2ae98a0b0dae1a53ca2 to your computer and use it in GitHub Desktop.
Save NP-chaonay/48e8a8b8c5e3e2ae98a0b0dae1a53ca2 to your computer and use it in GitHub Desktop.
My edited version of gradient descent algorithm (See more description below)
#!/usr/bin/env python3
# Name: My edited version of gradient descent algorithm No.1
# Description: My edited version of gradient descent algorithm.
# In this sample code, we use gradient descent for determining value of x in ax^3+bx^2+cx+d that nearly matches to truth value using given a,b,c,d values (x is weight; a,b,c,d are inputted data)
# Author: NP-chaonay (Nuttapong Punpipat)
# Version: Unversioned
# Version Note: None
# Revised Date: 2020-07-27 05:34 (UTC)
# License: MIT License
# Programming Language: Python
# CUI/GUI Language: English
## Importing library
import numpy as np
## Given data
# Truth value
real_val=-352
# Inputted data
data=np.array([-13, 132, 20, -4])
## User Parameters (Maybe requires to be re-execute if running new experiment and some variables are changed)
# Initial Learning rate (This would be constant on main method)
learning_rate=1
## Initialization (Requires to be re-execute if running new experiment)
# Amount of weights
weights_num=1
count=0
slopes=np.zeros(weights_num)
## Initial weights (With recommended max,min weights)
# FYI, 3 is the highest degree in prediction formula
recommended_max_weights=\
np.array([
max([
3,
max(map(abs,data)),
abs(real_val),
])]*weights_num)
recommended_min_weights=-recommended_max_weights
weights=np.array([0])
### Lowest error detection
lowest_error=float('inf')
lowest_error_count=0
lowest_error_weight=np.zeros(len(data))
### Checking maximum fitting
max_fit_pattern=[None,None,None]
## Defining function
def prediction_func(weights):
return data[0]*weights[0]**3+data[1]*weights[0]**2+data[2]*weights[0]+data[3]
def loss_func(weights):
return abs( prediction_func(weights)-real_val )
## Main method
while True:
max_fit_pattern[0]=max_fit_pattern[1]
max_fit_pattern[1]=max_fit_pattern[2]
max_fit_pattern[2]=weights
if max_fit_pattern[0] is not None and max_fit_pattern[-1] is not None:
if (max_fit_pattern[0]==max_fit_pattern[-1]).all():
print('Fitting is maximum.')
break
# Prediction formula
prediction=prediction_func(weights)
error=abs(prediction-real_val)
if error<lowest_error:
lowest_error=error
lowest_error_count=count
lowest_error_weight=weights
# Displaying result
print(count,lowest_error_count,lowest_error,lowest_error_weight,error,weights,slopes)
# Break after finish the specific epoch
if count==float('inf'):
print('Epoch limit reached.')
break
count+=1
## Formula getting from calculus differentiation of error on all weights
slopes=np.array([sum([data[0]*3*(weights[0]**2),data[1]*2*(weights[0]),data[2],0])])
if (prediction-real_val)<0: slopes[0]=-slopes[0]
##
# Check if all slopes are zero
if (slopes==0).all():
print('All gradient slopes are zero.')
break
## Normalize the value in slopes if any slope in slopes has value than 1, then multiply by learning rate
if (abs(slopes)>learning_rate).any():
norm_den=max(abs(slopes))
weights=weights-learning_rate*(slopes/norm_den)
else: weights=weights-slopes
##
##
## Alternative method (Learning rate and initial weight are automatically adjusted)
old_initial_weight=None
while True:
while True:
max_fit_pattern[0]=max_fit_pattern[1]
max_fit_pattern[1]=max_fit_pattern[2]
max_fit_pattern[2]=weights
if max_fit_pattern[0] is not None and max_fit_pattern[-1] is not None:
if (max_fit_pattern[0]==max_fit_pattern[-1]).all():
print('Fitting is maximum.')
break
# Prediction formula
prediction=prediction_func(weights)
error=abs(prediction-real_val)
if error<lowest_error:
lowest_error=error
lowest_error_count=count
lowest_error_weight=weights
# Displaying result
print(count,lowest_error_count,lowest_error,lowest_error_weight,error,weights,slopes)
# Break after finish the specific epoch
if count==float('inf'):
print('Epoch limit reached.')
break
count+=1
## Formula getting from calculus differentiation of error on all weights
slopes=np.array([sum([data[0]*3*(weights[0]**2),data[1]*2*(weights[0]),data[2],0])])
if (prediction-real_val)<0: slopes[0]=-slopes[0]
##
# Check if all slopes are zero
if (slopes==0).all():
print('All gradient slopes are zero.')
break
## Normalize the value in slopes if any slope in slopes has value than 1, then multiply by learning rate
if (abs(slopes)>learning_rate).any():
norm_den=max(abs(slopes))
weights=weights-learning_rate*(slopes/norm_den)
else: weights=weights-slopes
##
if old_initial_weight==lowest_error_weight:
print('Weights is fully optimized.')
print('Optimized weights are: '+str(lowest_error_weight))
break
else:
old_initial_weight=lowest_error_weight
learning_rate/=10
##
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment