6.3 C
New York
Saturday, March 8, 2025

Easy neural community autoencoder with candlesticks and ๐Ÿบ – Neural Networks – 7 April 2023


Warning :

  1. that is my first try at an autoencoder
  2. i’ve seen a video or 2 on autoencoders so i’d butcher thisย 

With that out of the way in which let’s pop a beer open and seize the keyboard.

What are we constructing :

We are going to snatch the world’s silliest easiest weakest most bare-bone thinnest neural web ever , the one we constructed right here,

and we are going to try this :ย 

wtf is that , you ask .

It is a neural web that has some inputs , like most nets , however , the aim of the community is to recreate the inputs it obtained on the opposite finish of the “squeeze”.

Sure , you’re right that is like compression , kind of .

So what are we going to ship in ?

A sequence of 20 bars !!!

How : ? :

  • We are going to get the min and max value for a window of 20 bars.
  • We are going to calculate the vary of that window max-min
  • Then for every bar we are going to calculate this worth : (close-open)/vary producing a price between -1.0 and 1.0
  • We are going to ship these 20 values as inputs for every window
  • and every 20 bar window will likely be a pattern

Cool let’s create our pattern collector actual fast , easy sh*t from the ohlc historical past of the chart.

#property modelย ย  "1.00"
#embody "miniNeuralNet.mqh";


ย ย 
ย ย ย ย class ae_sample{
ย ย ย ย ย ย ย ย ย ย  public:
ย ย ย ย double min,max,vary;
ย ย ย ย double bars[];
ย ย ย ย ย ย ย ย ย ย  ae_sample(void){reset();}
ย ย ย ย ย ย ย ย ย ย ~ae_sample(void){reset();}
ย ย ย ย ย ย void reset(){
ย ย ย ย ย ย ย ย ย ย  ArrayFree(bars);
ย ย ย ย ย ย ย ย ย ย  min=INT_MAX;
ย ย ย ย ย ย ย ย ย ย  max=INT_MIN;
ย ย ย ย ย ย ย ย ย ย  vary=0.0;
ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย void fill(int oldest_bar,int dimension){
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  ArrayResize(bars,dimension,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  ArrayFill(bars,0,dimension,0.0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  int co=-1;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  for(int i=oldest_bar;i>oldest_bar-size;i--){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย co++;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(iHigh(_Symbol,_Period,i)>max){max=iHigh(_Symbol,_Period,i);}
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(iLow(_Symbol,_Period,i)<min){min=iLow(_Symbol,_Period,i);}
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย bars[co]=iClose(_Symbol,_Period,i)-iOpen(_Symbol,_Period,i);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  vary=max-min;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  for(int i=0;i<dimension;i++){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย bars[i]/=vary;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย bars[i]=(bars[i]+1.0)/2.0;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย };

Primary stuff :

  • imported the little webย 
  • then a easy (and naive) extractor of chart knowledge for a given window which fills a pattern
  • the inputs match the outputs right here for every pattern (bars[] is each of those)

We now want somewhat pattern assortment , we cannot have many samples now that i consider it however its okay , nonetheless extra enjoyable than netflix. sco

ย ย ย ย struct ae_sample_collection{
ย ย ย ย ae_sample samples[];
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ae_sample_collection(void){reset();}
ย ย ย ย ย ย ย ย ย ย ย ย  ~ae_sample_collection(void){reset();}
ย ย ย ย ย ย ย ย  void reset(){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayFree(samples);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย  void add_sample(int oldest_bar,int window_size){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย int ns=ArraySize(samples)+1;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayResize(samples,ns,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย samples[ns-1].fill(oldest_bar,window_size);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย int fill(int window_size){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int barz=iBars(_Symbol,_Period);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(barz>TerminalInfoInteger(TERMINAL_MAXBARS)){barz=TerminalInfoInteger(TERMINAL_MAXBARS);}
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int samples_possible=barz-window_size;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(samples_possible>1000){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int co=-1;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayResize(samples,samples_possible,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย for(int i=barz-1;i>=(1+window_size);i--){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  Remark("Filling "+i);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  co++;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  samples[co].fill(i,window_size);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayResize(samples,co+1,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย } 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย return(ArraySize(samples));
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย };

Easy stuff , we wish accomplished bars solely so 1 could be the final bar in a pattern , this can be sluggish as a result of we’re not presizing , however anyway

๐Ÿฐ

now , chart initializes , we delete all of the objects with our tag we setup a timer , we catch the samples on timer .ย 

ย ย ย ย ae_sample_collection COLLECTION;
snn_net web;
#outline SYSTEM_TAG "AE_"
bool Loaded=false;
int OnInit()
ย ย {

ย ย COLLECTION.reset();
ย ย web.reset();
ย ย Loaded=false;
ย ย ObjectsDeleteAll(ChartID(),SYSTEM_TAG);
ย ย EventSetMillisecondTimer(544);

ย ย  return(INIT_SUCCEEDED);
ย ย }
ย ย 
void OnTimer(){
ย ย if(!Loaded){
ย ย EventKillTimer();
ย ย if(COLLECTION.fill(20)>=1000){
ย ย Remark("Samples created ");
ย ย 
ย ย ย ย 
ย ย ย ย 
ย ย 
ย ย }else{
ย ย Alert("Too little samples");
ย ย ExpertRemove();
ย ย }
ย ย }
ย ย else{
ย ย 
ย ย }
ย ย }



void OnDeinit(const int purpose)
ย ย {

ย ย COLLECTION.reset();
ย ย web.reset();
ย ย ObjectsDeleteAll(ChartID(),SYSTEM_TAG);ย ย  
ย ย }

Cool , if the gathering doesn’t fill , bounce … now we have to setup the community ….

Let’s attempt with a 3-2-3 within the center , not anticipating a lot ,however lets begin there , so

20-3-2-3-20 , jesus

ย ย ย ย 
ย ย ย ย ย ย web.add_layer().setup(20);
ย ย ย ย 
ย ย ย ย ย ย web.add_layer().setup(3,20);
ย ย ย ย 
ย ย ย ย ย ย web.add_layer().setup(2,3);
ย ย ย ย 
ย ย ย ย ย ย web.add_layer().setup(3,2);
ย ย ย ย 
ย ย ย ย ย ย web.add_layer().setup(20,3);

Okay however how will we play with this ? It has to do stuffy stuff and be taught after which we gotta be capable of nudge theย 

“encoding” (the center layers) and see what they product , for enjoyable , so we want :

  • a sign of the loss avg
  • somewhat customized show that may show 20 columns , you see the place that is goingย 
  • the center layer with the two nodes outputs 0.0 to 1.0 because it has sigmoid activations
    so what if we’ve 2 inputs that at any level we are able to regulate and they’ll spit out
  • the 20 bars (nicely the open to shut dimension inside a spread actually) it thinks we’re sending (however we’re not sending something actually 3:) )
  • a beer

Good , the loss operate could be a sign with the remark operate ,then 2 edits and a useful resource.
Let’s begin there , a field to which we ship bar-sizes of a % to its sides dimension and we plot the “logical” sequence of them
hopefully , if we get out of bounds we’ll want to increase the “hypothetical canvas” although as a result of we have to see.

Okay much less typing extra typing :

void create_fake_chart(double &fake_bars[],
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  uint &pixels[],
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  int &side_size,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  coloration bgColor,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  coloration upColor,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  coloration dwColor
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  ){

ย ย ArrayFill(pixels,0,ArraySize(pixels),ColorToARGB(bgColor,255));
ย ย 
ย ย double tfb=((double)ArraySize(fake_bars));
ย ย double bar_size=((double)side_size)/(((tfb+1.0)/2.0)+tfb);
ย ย double gap_size=bar_size/2.0;
ย ย 
ย ย 
ย ย double start_x=gap_size;
ย ย 
ย ย 
}

Quickly we run into our first realization :

We do not know the beginning “y” or “faux value” of the output , we simply know its presupposed to have 1.0 on high as max and 0.0 on the underside as min

So we’ll “middle it” or one thing ? , let’s have a look at , let’s log the general min and max and begin from 1.0ย 

ย ย 
ย ย double emu_max=INT_MIN,emu_min=INT_MAX;
ย ย 
ย ย ย ย double price_now=1.0;
ย ย ย ย 
ย ย ย ย 
ย ย ย ย 
ย ย ย ย for(int i=0;i<ArraySize(fake_bars);i++){
ย ย ย ย ย ย  price_now+=fake_bars[i];
ย ย ย ย ย ย  if(price_now>emu_max){emu_max=price_now;}
ย ย ย ย ย ย  if(price_now<emu_min){emu_min=price_now;}
ย ย ย ย ย ย  }

kay so we do thiiis and we’ve the “emulated max” and emulated min …. now what …

hmmm , okay we have to flip the sizes to cost factors , so we should always convert to shut costs andย 

then we are going to normalize them into the vary 0.0 to 1.0 , which doesn’t consider the unique vary had taken highs and lows under consideration however this can be a take a look at so , let’s simply go together with it.

So change this to “costs” , we modify the loop to this , we add open and shut value , the primary open value is 1.0

ย ย ย ย double fake_bars_open_price[],fake_bars_close_price[];
ย ย ย ย ArrayResize(fake_bars_open_price,ArraySize(fake_bars),0);
ย ย ย ย ArrayResize(fake_bars_close_price,ArraySize(fake_bars),0);
ย ย ย ย for(int i=0;i<ArraySize(fake_bars);i++){
ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย  fake_bars_open_price[i]=price_now;
ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย  price_now+=fake_bars[i];
ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย  fake_bars_close_price[i]=price_now;
ย ย ย ย ย ย  if(price_now>emu_max){emu_max=price_now;}
ย ย ย ย ย ย  if(price_now<emu_min){emu_min=price_now;}
ย ย ย ย ย ย  }

Okay now , to show from 0.0 to 1.0 we get the vary , we loop into every bar (which is now a value level) , we subtract the minimal , we divide by the vary and that is it .

and we do that :ย 

ย ย ย ย double vary=emu_max-emu_min;
ย ย ย ย for(int i=0;i<ArraySize(fake_bars);i++){
ย ย ย ย ย ย fake_bars_open_price[i]=(fake_bars_open_price[i]-emu_min)/vary;
ย ย ย ย ย ย fake_bars_close_price[i]=(fake_bars_close_price[i]-emu_min)/vary;
ย ย ย ย ย ย }

annoying however wanted . now … we gotta draw this … %^$#!^$#$ , let’s cheat … we open the canvasย 

we discover the fill rectange and we steal it ….ย  ๐Ÿ˜‡ that is what it appears to be like like , let’s make it much less civilized , ship it a pixels array , width +peak .sco

void ResourceFillRectangle(int x1,int y1,int x2,int y2,const uint clr,uint &m_pixels[],int m_width,int m_height)
ย ย {
ย ย  int tmp;

ย ย  if(x2<x1)
ย ย ย ย  {
ย ย ย ย ย ย tmp=x1;
ย ย ย ย ย ย x1 =x2;
ย ย ย ย ย ย x2 =tmp;
ย ย ย ย  }
ย ย  if(y2<y1)
ย ย ย ย  {
ย ย ย ย ย ย tmp=y1;
ย ย ย ย ย ย y1 =y2;
ย ย ย ย ย ย y2 =tmp;
ย ย ย ย  }

ย ย  if(x2<0 || y2<0 || x1>=m_width || y1>=m_height)
ย ย ย ย ย ย return;

ย ย  if(x1<0)
ย ย ย ย ย ย x1=0;
ย ย  if(y1<0)
ย ย ย ย ย ย y1=0;
ย ย  if(x2>=m_width)
ย ย ย ย ย ย x2=m_width -1;
ย ย  if(y2>=m_height)
ย ย ย ย ย ย y2=m_height-1;
ย ย  int len=(x2-x1)+1;

ย ย  for(; y1<=y2; y1++)
ย ย ย ย ย ย ArrayFill(m_pixels,y1*m_width+x1,len,clr);
ย ย }

good that annoyance is gone too , now the final one move the faux bars to the pixelsย 

we have to be cautious right here , the pixelsย  y axis has 0 on high and 1.0 on the backside , so we’ve to flip it!ย 

ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย uint upc=ColorToARGB(upColor,255);
ย ย ย ย ย ย ย ย uint doc=ColorToARGB(dwColor,255);
ย ย ย ย for(int i=0;i<ArraySize(fake_bars)-1;i++){
ย ย ย ย ย ย 
ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย double y_open=side_size-fake_bars_open_price[i]*((double)side_size);
ย ย ย ย ย ย ย ย double y_close=side_size-fake_bars_close_price[i]*((double)side_size);
ย ย ย ย ย ย ย ย uint colorused=upc;
ย ย ย ย ย ย ย ย if(fake_bars_open_price[i]>fake_bars_close_price[i]){colorused=doc;}
ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย int x1=(int)start_x;
ย ย ย ย ย ย ย ย int x2=(int)(start_x+bar_size);
ย ย ย ย ย ย ย ย int y1=(int)MathMin(y_open,y_close);
ย ย ย ย ย ย ย ย int y2=(int)MathMax(y_open,y_close);
ย ย ย ย ย ย ย ย ResourceFillRectangle(x1,y1,x2,y2,colorused,pixels,side_size,side_size);
ย ย ย ย ย ย }

So what did we do right here :

  • We multiplied the 0.0 to 1.0 open with the aspect dimension .(so a price from 0 to aspect dimension)
  • We subtracted that from the aspect dimension to flip it , so , if it grows it strikes up not down
  • We did the identical for the shut value and now we had the open y and shut y
  • We assign the right coloration based mostly on whether or not or not it goes up or down
  • and we draw it

Good , it’d work , now we have to construct our “deck” the two inputs and the output useful resource and bitmap label.

Okay we add an enter for the dimensions , a pixels array referred to as show ,we free a show useful resource on init and exit , we create a bmp label and a couple of inputs .

enter int display_size=300;

uint show[];

ย ย  
ย ย ย ย ย ย int py=30;
ย ย ย ย ย ย for(int i=0;i<2;i++){
ย ย ย ย ย ย string title=SYSTEM_TAG+"_NODE"+IntegerToString(i);
ย ย ย ย ย ย ObjectCreate(ChartID(),title,OBJ_EDIT,0,0,0);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_XSIZE,150);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_YSIZE,20);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_XDISTANCE,10);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_YDISTANCE,py);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_BGCOLOR,clrDarkKhaki);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_BORDER_COLOR,clrGold);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_COLOR,clrYellow);
ย ย ย ย ย ย ObjectSetString(ChartID(),title,OBJPROP_TEXT,"(Node "+IntegerToString(i)+" output) :");
ย ย ย ย ย ย py+=20;
ย ย ย ย ย ย }
ย ย ย ย ย ย string title=SYSTEM_TAG+"_DISPLAY";
ย ย ย ย ย ย ObjectCreate(ChartID(),title,OBJ_BITMAP_LABEL,0,0,0);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_XSIZE,display_size);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_YSIZE,display_size);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_XDISTANCE,10);
ย ย ย ย ย ย ObjectSetInteger(ChartID(),title,OBJPROP_YDISTANCE,py);
ย ย ย ย ย ย ObjectSetString(ChartID(),title,OBJPROP_BMPFILE,"::DISPLAY");
ย ย ย ย ย ย ChartRedraw();

Nice , now we are going to :

  • begin a timer interval and practice on samples each interval , then replace the person (us) on the loss
  • we are going to create a pause / proceed state of affairs for the “studying” so we are able to pause the coaching and play with the node outputs
  • everytime the inputs change (for the node outputs) manually we draw the end result if the coaching is paused

Meaning the inputs are hidden by default and there ought to be a pause button above them , hopefully the final mods we do , we set the loaded indication as true we add a busy indication and we’re good to go .

So we add these 2 parameters on highย 

enter bool reset_stats_after_batch=true;
enter double base_learning_rate=0.001;

Then a swap to point coaching just isn’t paused

bool Prepare=false;

and that is what the coaching block appears to be like like :

ย ย if(!SystemBusy&&Prepare){
ย ย SystemBusy=true;
ย ย 
ย ย 
ย ย ย ย 
ย ย ย ย int ix=0;
ย ย ย ย for(int i=0;i<ArraySize(COLLECTION.samples);i++)
ย ย ย ย  {
ย ย ย ย  
ย ย ย ย ย ย  ix+=MathRand();
ย ย ย ย ย ย  whereas(ix>=ArraySize(COLLECTION.samples)){ix-=ArraySize(COLLECTION.samples);}
ย ย ย ย  
ย ย ย ย ย ย  web.feed_forward(COLLECTION.samples[ix].bars);
ย ย ย ย  
ย ย ย ย ย ย  web.calculate_loss(COLLECTION.samples[ix].bars);
ย ย ย ย  
ย ย ย ย ย ย  web.back_propagation();ย ย 
ย ย ย ย  } 
ย ย ย ย  
ย ย ย ย  double max_loss=web.get_max_loss_per_sample();
ย ย ย ย  double cur_loss=web.get_current_loss_per_sample();
ย ย ย ย  double a=(cur_loss/max_loss)*base_learning_rate;
ย ย ย ย  web.regulate(a);
ย ย ย ย  if(reset_stats_after_batch){web.reset_loss();} 
ย ย ย ย  string comm="Loss ("+cur_loss+")/("+max_loss+")";
ย ย ย ย  Remark(comm);ย ย ย ย  
ย ย 
ย ย SystemBusy=false;
ย ย }

Okay , now , lastly , when the pause button is hit we :

  1. change it to “Proceed”
  2. present the two node inputs
  3. present the show block
  4. set Prepare to false

We add a chart occasion block for this :

void OnChartEvent(const int id,const lengthy& lparam,const double& dparam,const string& sparam)
ย ย {
ย ย if(Loaded&&id==CHARTEVENT_OBJECT_CLICK){
ย ย ย ย if(sparam==SYSTEM_TAG+"_PAUSE"&&Prepare){
ย ย ย ย ย ย ObjectSetString(ChartID(),SYSTEM_TAG+"_PAUSE",OBJPROP_TEXT,"Proceed");
ย ย ย ย ย ย for(int i=0;i<middleNodes;i++){
ย ย ย ย ย ย ย ย  ObjectSetInteger(ChartID(),SYSTEM_TAG+"_NODE"+IntegerToString(i),OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS);ย ย ย ย 
ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ObjectSetInteger(ChartID(),SYSTEM_TAG+"_DISPLAY",OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS);
ย ย ย ย ย ย Prepare=false;
ย ย ย ย ย ย }else if(sparam==SYSTEM_TAG+"_PAUSE"&&!Prepare){
ย ย ย ย ย ย ObjectSetString(ChartID(),SYSTEM_TAG+"_PAUSE",OBJPROP_TEXT,"Pause");
ย ย ย ย ย ย for(int i=0;i<middleNodes;i++){
ย ย ย ย ย ย ย ย  ObjectSetInteger(ChartID(),SYSTEM_TAG+"_NODE"+IntegerToString(i),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);ย ย ย ย 
ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ObjectSetInteger(ChartID(),SYSTEM_TAG+"_DISPLAY",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ย ย ย ย ย ย Prepare=true;ย ย ย ย ย ย 
ย ย ย ย ย ย }
ย ย ย ย }
ย ย }

aand now , after we detect a change in inputs recalculate the pixels and recreate the useful resource , and hopefully it really works.

However wait , we should embody a operate within the community that feeds ahead from a layer onwards . Why ?ย 

As a result of we hijack the center layer’s output and we need to see what it spits out on the opposite finish – and plot itย 

That is a simple config :

ย ย ย ย ย ย void partial_feed_forward(int from_layer_ix){
ย ย ย ย ย ย ย ย ย ย  for(int i=from_layer_ix;i<ArraySize(layers);i++){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย layers[i].feed_forward(layers[i-1]);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย  }

Easy , we see that the feed ahead will begin from the layer we ship in so if we stuffed outputs for the layer the arrow is pointint as much as then we are going to begin from the following layer , so 0 , 1, 2 ,thats layer 3 .

And we are going to refill a “faux bars” array to ship right down to the plotter. we do not neglect our output is between 0.0 and 1.0 and we have to flip it toย  -1.0 to 1.0ย 

ย ย else if(Loaded&&id==CHARTEVENT_OBJECT_ENDEDIT){
ย ย ย ย 
ย ย ย ย ย ย if(StringFind(sparam,SYSTEM_TAG+"_NODE",0)!=-1){
ย ย ย ย ย ย ย ย for(int i=0;i<middleNodes;i++){
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  double v=(double)StringToDouble(ObjectGetString(ChartID(),SYSTEM_TAG+"_NODE"+IntegerToString(i),OBJPROP_TEXT));
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  if(v<0.0){v=0.0;}else if(v>1.0){v=1.0;}
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  web.layers[2].nodes[i].output=v;
ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย web.partial_feed_forward(3);
ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย double fake_bars[];
ย ย ย ย ย ย ย ย ย ย ArrayResize(fake_bars,20,0);
ย ย ย ย ย ย ย ย ย ย for(int i=0;i<20;i++){fake_bars[i]=web.get_output(i);}
ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย for(int i=0;i<20;i++){fake_bars[i]=(fake_bars[i]*2.0)-1.0;}
ย ย ย ย ย ย ย ย ย ย create_fake_chart(fake_bars,show,display_size,clrBlack,clrGreen,clrCrimson);
ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย if(ResourceCreate("DISPLAY",show,display_size,display_size,0,0,display_size,COLOR_FORMAT_ARGB_NORMALIZE)){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ChartRedraw();
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย }
ย ย ย ย }

Then we create the useful resource , redraw the chart .However it could be handy to throw that right into a operate as a result of we may have
to name it elsewhere too so :

void calculate_fake_chart(){
ย ย ย ย ย ย ย ย for(int i=0;i<middleNodes;i++){
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  double v=(double)StringToDouble(ObjectGetString(ChartID(),SYSTEM_TAG+"_NODE"+IntegerToString(i),OBJPROP_TEXT));
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  if(v<0.0){v=0.0;}else if(v>1.0){v=1.0;}
ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย  web.layers[2].nodes[i].output=v;
ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย web.partial_feed_forward(3);
ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย double fake_bars[];
ย ย ย ย ย ย ย ย ย ย ArrayResize(fake_bars,20,0);
ย ย ย ย ย ย ย ย ย ย for(int i=0;i<20;i++){fake_bars[i]=web.get_output(i);}
ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย for(int i=0;i<20;i++){fake_bars[i]=(fake_bars[i]*2.0)-1.0;}
ย ย ย ย ย ย ย ย ย ย create_fake_chart(fake_bars,show,display_size,clrBlack,clrGreen,clrCrimson);
ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย if(ResourceCreate("DISPLAY",show,display_size,display_size,0,0,display_size,COLOR_FORMAT_ARGB_NORMALIZE)){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ChartRedraw();
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }
}

and we add a name after we pause the learnign and after we replace the node values manually.neat

Nicely as anticipated , there’s a bottleneck in samples filling upย 

So we’ll should presize the samples within the assortment …. however , shiny aspect we’ll get 90k samples , that is good , will likely be sluggish af however good.

So we’re altering the fill operate of the pattern collector to this :ย 

ย ย ย ย ย ย ย ย ย ย int fill(int window_size){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int barz=iBars(_Symbol,_Period);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(barz>TerminalInfoInteger(TERMINAL_MAXBARS)){barz=TerminalInfoInteger(TERMINAL_MAXBARS);}
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int samples_possible=barz-window_size;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย if(samples_possible>1000){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย int co=-1;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayResize(samples,samples_possible,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย for(int i=barz-1;i>=(1+window_size);i--){
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  Remark("Filling "+i);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  co++;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  samples[co].fill(i,window_size);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย  }
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ArrayResize(samples,co+1,0);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย } 
ย ย ย ย ย ย ย ย ย ย ย ย ย ย return(ArraySize(samples));
ย ย ย ย ย ย ย ย ย ย ย ย ย ย }

Now this run into nan -nan errors at first , so , theres points within the pattern assortment , you will not see them as i will edit the code snippets.

The second run was higher , it converged sooner and had no bizarre alien numbers , and it kinda appears to be like like an actual chart if you hit pause .

And it appears to be like like value motion after we manually tune the nodes within the centerย 

after all one can say , bruh , every little thing that comes out of the output might be plotted as value motion . true.

Let’s examine if we are able to animate this sh*t , and perceive what the two knobs …

what the two nobs imply . That is how AIs are drawing issues btw , all you gotta do (or it) is work out what the little nodes within the center tune.

So , let’s add a button that stops coaching however begins animating subsequent to the pause , we might make this look higher however i can simply go look within the mirror ๐Ÿ˜‡ (jk) sco lets end this.

we add the button ,we add the animating swap , and steps and present values for the nobs. the animator will likely be taking one stepย  per timer entry and drawing it.

Lets see what occurs :

hmm it appears to be like value actiony

what if we begin from completely different values for the nodes ?

There are combos in there that might be describing completely different exercise , so if one figures out what the encoder parameters do then you can be taking a look at a man-made coaching value feed as an illustration that resembles usdjpy (on this instance)

Learn extra in regards to the easiest neural web right here

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles