- Home /
Problem with Line Renderer
To keep it (relatively) short:
I am building (or trying to build) a simple neural network in Unity for visualization and by that get an idia for how it works.
What I am getting stuck on is instantiating the connections between nodes.
In this case eatch input node should be connected to all nodes in the next layer. What ends up happening is only the very last connection from the input node is put in place (all other connections have the default values).
The connection prefab is an empty object with a line renderer and the NeuralConnection class.
The neuron prefab can be simplified to an empty object with an empty class on it.
Code for Connection Class
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class NeuralConnection : MonoBehaviour {
public float weight;
private GameObject textObject;
BasicNeuron inputNeuron;
BasicNeuron outputNeuron;
LineRenderer lineRenderer;
void Awake()
{
weight = Random.Range(-1, 1);
textObject = transform.Find("Text").gameObject;
lineRenderer = GetComponent<LineRenderer>();
}
public void Init(BasicNeuron inputNeuron, BasicNeuron outputNeuron)
{
this.inputNeuron = inputNeuron;
this.outputNeuron = outputNeuron;
lineRenderer.positionCount = 2;
lineRenderer.SetPosition(0, inputNeuron.transform.position);
lineRenderer.SetPosition(1, outputNeuron.transform.position);
}
}
Code for Neural Manager
Disclaimer: some formatting did not carry over from Visual Studio, so it may be a bit hard to read.
using System.Collections.Generic;
using UnityEngine;
public class NeuralManager : MonoBehaviour {
List<BasicNeuron> inputNeurons = new List<BasicNeuron>();
List<List<HiddenNeuron>> hiddenNeurons = new List<List<HiddenNeuron>>();
List<BasicNeuron> outputNeurons = new List<BasicNeuron>();
List<List<NeuralConnection>> neuralLayerConnections = new List<List<NeuralConnection>>();
[SerializeField] private int numberOfInputNeurons, numberOfHiddenLayers,
numberOfHiddenLayerNeurons, numberOfOutputNeurons;
[Header("Layout")]
[SerializeField] private float spacing = 1f;
[Header("Neuron Prefabs")]
[SerializeField] private GameObject inputNeuronPrefab;
[SerializeField] private GameObject hiddenNeuronPrefab;
[SerializeField] private GameObject outputNeuronPrefab;
[SerializeField] private GameObject neuralConnectionPrefab;
void Awake()
{
if (SpawnInputNeurons())
if (SpawnHiddenNeurons())
if (SpawnOutputNeurons())
SpawnConnections();
}
private bool SpawnInputNeurons()
{
if (numberOfInputNeurons <= 0)
{
Debug.LogWarning("Number of Input Neurons should be greater then 0");
return false;
}
else
{
for (int i = 0; i < numberOfInputNeurons; i++)
{
inputNeurons.Add(Instantiate(inputNeuronPrefab, new Vector3(-7, i * spacing - numberOfInputNeurons / 2, 0), inputNeuronPrefab.transform.rotation).GetComponent<BasicNeuron>());
inputNeurons[i].gameObject.name = "Input Neuron " + i;
}
return true;
}
}
private bool SpawnHiddenNeurons()
{
if(numberOfHiddenLayers <= 0)
{
Debug.LogWarning("Number of hidden layers should be greater then 0");
return false;
}
else
{
if (numberOfHiddenLayerNeurons <= 0)
{
Debug.LogWarning("Number of Hidden Neurons should be greater then 0");
return false;
}
else
{
for (int x = 0; x < numberOfHiddenLayers; x++)
{
hiddenNeurons.Add(new List<HiddenNeuron>());
neuralLayerConnections.Add(new List<NeuralConnection>());
for (int y = 0; y < numberOfHiddenLayerNeurons; y++)
{
hiddenNeurons[x].Add(Instantiate(hiddenNeuronPrefab, new Vector3(x * 3 - numberOfHiddenLayers, y * spacing - numberOfInputNeurons / 2, 0), inputNeuronPrefab.transform.rotation).GetComponent<HiddenNeuron>());
hiddenNeurons[x][y].gameObject.name = "Hidden Layer " + x + " Node " + y;
}
}
return true;
}
}
}
private bool SpawnOutputNeurons()
{
if (numberOfOutputNeurons <= 0)
{
Debug.LogWarning("Number of Output Neurons should be greater then 0");
return false;
}
else
{
for (int i = 0; i < numberOfOutputNeurons; i++)
{
outputNeurons.Add(Instantiate(outputNeuronPrefab, new Vector3(7, i * spacing - numberOfOutputNeurons / 2, 0), outputNeuronPrefab.transform.rotation).GetComponent<BasicNeuron>());
outputNeurons[i].gameObject.name = "Output Neuron " + i;
}
return true;
}
}
private void SpawnConnections()
{
for (int currentInputNeuron = 0; currentInputNeuron < inputNeurons.Count; currentInputNeuron++)//for eatch input neuron
{
for (int currentFirstHiddenLayerNeuron = 0; currentFirstHiddenLayerNeuron < hiddenNeurons[0].Count; currentFirstHiddenLayerNeuron++) //for eatch first hidden layer
{
NeuralConnection con = Instantiate(neuralConnectionPrefab, new Vector3(0, 0, 0), neuralConnectionPrefab.transform.rotation).GetComponent<NeuralConnection>();
neuralLayerConnections[0].Add(con);
neuralLayerConnections[0][currentInputNeuron].Init(inputNeurons[currentInputNeuron], hiddenNeurons[0][currentFirstHiddenLayerNeuron]);
neuralLayerConnections[0][currentInputNeuron].gameObject.name = "Connetion between Input " + currentInputNeuron + " and Output " + currentFirstHiddenLayerNeuron;
}
}
}
}
For everyone who is interested: I am cleaning this project up and redoing some parts. I will link the finished Project when I am done.
Answer by Veith · Feb 02, 2018 at 10:34 PM
I tracked down the error and found out the culprit is the Spawnconnections function.
I replaced the for loops with what they would do and found out that I had made alot of mistakes.
Here the is what it should have been:
private void SpawnConnections()
{
for (int currentInputNeuron = 0; currentInputNeuron < inputNeurons.Count; currentInputNeuron++)
{
for (int currentFirstHiddenLayerNeuron = 0; currentFirstHiddenLayerNeuron < hiddenNeurons[0].Count; currentFirstHiddenLayerNeuron++)
{
int nodeIndex = currentInputNeuron * hiddenNeurons[0].Count + currentFirstHiddenLayerNeuron;
NeuralConnection con = Instantiate(neuralConnectionPrefab, new Vector3(0, 0, 0), neuralConnectionPrefab.transform.rotation).GetComponent<NeuralConnection>();
neuralLayerConnections[0].Add(con);
neuralLayerConnections[0][nodeIndex].Init(inputNeurons[currentInputNeuron], hiddenNeurons[0][currentFirstHiddenLayerNeuron]);
neuralLayerConnections[0][nodeIndex].gameObject.name = "Connetion between Input " + currentInputNeuron + " and Output " + nodeIndex;
}
}
}