Last active
July 28, 2020 03:27
-
-
Save NP-chaonay/48e8a8b8c5e3e2ae98a0b0dae1a53ca2 to your computer and use it in GitHub Desktop.
My edited version of gradient descent algorithm (See more description below)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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