Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local data={{1,0,0},{0,1,0},{0,0,1}} -- starting colors
- local hidden={} -- hidden layers node counts
- -- generate random goal colors
- local goal={}
- math.randomseed(tick())
- for i=1,10 do goal[#goal+1]={math.random(),math.random(),math.random()}end
- local outputs=#goal
- local inputs=#data
- function createnetwork()
- local weights={}
- local network={weights=weights}
- do
- local input={}for i=1,inputs do input[i]=0 end network[1]=input
- for h=1,#hidden do local layer={}for i=1,hidden[h]do layer[i]=math.random() end network[h+1]=layer end
- local out={}for i=1,outputs do out[i]=0 end network[#network+1]=out
- end
- for i=1,#network-1 do
- local t,b={},#network[i+1]
- for j=1,#network[i]do
- local x={}
- for k=1,b do
- x[k]=math.random()
- end
- t[j]=x
- end
- weights[i]=t
- end
- return network
- end
- -- random(-1 to 1) / 10^random(-1 to 6; curved)
- function offset()return(math.random()*2-1)/10^((math.random()*7^(1/3))^3-1)end
- function alternetwork(old,f)
- local nweights=old.weights
- local weights,paths={},{}
- local new={weights=weights}
- do
- local input={}for i=1,inputs do input[i]=0 end new[1]=input
- for h=1,#hidden do local layer={}for i=1,hidden[h]do layer[i]=old[h+1][i]paths[#paths+1]={layer,i}end new[h+1]=layer end
- local out={}for i=1,outputs do out[i]=0 end new[#new+1]=out
- end
- for i=1,#new-1 do
- local t,b={},#new[i+1]
- for j=1,#new[i]do
- local x={}
- for k=1,b do
- x[k]=nweights[i][j][k]
- paths[#paths+1]={x,k}
- end
- t[j]=x
- end
- weights[i]=t
- end
- if f then
- f(paths)
- else
- for i=1,math.random(1)do
- local p=paths[math.random(#paths)]
- --p[1][p[2]]=p[1][p[2]]+offset() -- unbounded
- p[1][p[2]]=math.max(0,math.min(1,p[1][p[2]]+offset()))
- end
- end
- return new,#paths
- end
- function readn(network,val)
- local weights=network.weights
- local net,paths={weights=weights},{}
- do
- local input={}for i=1,inputs do input[i]=0 end net[1]=input
- for h=1,#hidden do local layer={}for i=1,hidden[h]do layer[i]=network[h+1][i]end net[h+1]=layer end
- local out={}for i=1,outputs do out[i]=network[#network][i]end net[#net+1]=out
- end
- for i=1,#val do
- local v=val[i]
- local b=network[1][i]
- net[1][i]={math.min(1,v[1]+b),math.min(1,v[2]+b),math.min(1,v[3]+b)}
- end
- for i=1,#net-1 do
- local n1,n2,w=net[i],net[i+1],weights[i]
- local t={}
- for j=1,#n2 do
- local v=n2[j]
- local v={v,v,v}
- for k=1,#n1 do
- for q=1,3 do
- v[q]=math.min(1,v[q]+n1[k][q]*w[k][j])
- end
- end
- t[j]=v
- end
- net[i+1]=t
- end
- local out=net[#net]
- for i=1,outputs do
- for j=1,3 do
- out[i][j]=math.min(1,out[i][j])
- end
- end
- return out,net
- end
- function eval(network)
- local s=0
- local outs,net=readn(network,data)
- for k,a in ipairs(outs)do
- local dr,dg,db=goal[k][1]-a[1],goal[k][2]-a[2],goal[k][3]-a[3]
- s=s+math.sqrt(3)-math.sqrt(dr*dr+dg*dg+db*db)
- end
- if math.random(1,20)==1 then wait()end
- return s,net
- end
- function percent(n)
- return 100*n/(math.sqrt(3)*outputs)
- end
- local gui=workspace:FindFirstChild("Model")or Instance.new("Model",workspace)
- function display(network)
- gui:ClearAllChildren()
- local layers=#network
- local prev={}
- for h=1,layers do
- local cur={}
- local hidden=network[h]
- for i=1,#hidden do
- local r,g,b=hidden[i][1],hidden[i][2],hidden[i][3]
- local e=Instance.new("Part",gui)
- e.TopSurface,e.BottomSurface="Smooth","Smooth"
- e.Anchored,e.CanCollide=true,false
- e.Size=Vector3.new(5,.2,5)
- e.CFrame=CFrame.new(h*30,.2,(i-#hidden/2)*6)
- e.Transparency=1
- local m=Instance.new("SurfaceGui",e)
- m.Face="Top"
- local f=Instance.new("Frame",m)
- f.Size=UDim2.new(1,0,1,0)
- f.BorderSizePixel=0
- f.BackgroundColor3=Color3.new(r,g,b)
- cur[#cur+1]=e
- end
- if prev then
- local weights=network.weights
- for i=1,#prev do
- for j=1,#cur do
- local w=weights[h-1][i][j]
- local e=Instance.new("Part",gui)
- e.TopSurface,e.BottomSurface="Smooth","Smooth"
- e.Anchored,e.CanCollide=true,false
- local p1,p2=prev[i].Position,cur[j].Position
- local width=math.abs(w)
- e.BrickColor=BrickColor.new(w>0 and"White"or"Black")
- local b=Instance.new("BlockMesh",e)
- b.Scale=Vector3.new(width,width,1)
- e.Size=Vector3.new(1,1,(p1-p2).magnitude)
- e.CFrame=CFrame.new((p1+p2)/2,p2)
- end
- end
- end
- prev=cur
- end
- for i=1,#goal do
- local r,g,b=goal[i][1],goal[i][2],goal[i][3]
- local f=Instance.new("Frame",prev[i].SurfaceGui)
- f.Size=UDim2.new(.5,0,.5,0)
- f.Position=UDim2.new(.25,0,.25,0)
- f.BorderSizePixel=0
- f.BackgroundColor3=Color3.new(r,g,b)
- end
- end
- local network=createnetwork()
- local best,score=network,eval(network)
- function try(network)
- local s,net=eval(network)
- if s>score then
- best,score=network,s
- display(net)
- print(percent(score))
- end
- return percent(score),percent(s)
- end
- -- generate some random networks
- for i=1,100 do
- try(createnetwork())
- end
- -- alter values until local min
- for i=1,math.huge do
- local net,paths=alternetwork(best)
- local f=offset()
- try(alternetwork(best,function(t)
- local p=t[math.random(#t)]
- p[1][p[2]]=math.max(0,math.min(1,p[1][p[2]]+f))
- end))
- try(alternetwork(best,function(t)
- local p=t[math.random(#t)]
- p[1][p[2]]=math.max(0,math.min(1,p[1][p[2]]-f))
- end))
- for f=1,10 do
- for x=1,paths do
- try(alternetwork(best,function(paths)
- local p=paths[x]
- p[1][p[2]]=math.max(0,math.min(1,p[1][p[2]]+2^-f))
- end))
- try(alternetwork(best,function(paths)
- local p=paths[x]
- p[1][p[2]]=math.max(0,math.min(1,p[1][p[2]]-2^-f))
- end))
- end
- end
- end
Add Comment
Please, Sign In to add comment