How to make this more clean - c#

I have a big part of code like this that iterate trough an array
void GetSpawnablePosition() {
Vector2[] coordX = { Vector2.up, Vector2.down };
Vector2[] coordY = { Vector2.left, Vector2.right };
for (int i = 0; i < coordY.Length; i++)
{
Vector2[] newArray = new Vector2[enemyGrid.grid[0].Length - 2];
if (coordY[i] == Vector2.left)
{
for (int j = 0; j < enemyGrid.grid[0].Length - 2; j++)
{
newArray[j] = new Vector2(0, j+1);
}
}
if (coordY[i] == Vector2.right)
{
for (int j = 0; j < enemyGrid.grid[0].Length - 2; j++)
{
newArray[j] = new Vector2(enemyGrid.grid[0].Length - 1, j + 1);
}
}
spawnablePosition.Add(coordY[i], newArray);
}
for (int i = 0; i < coordY.Length; i++)
{
Vector2[] newArray = new Vector2[enemyGrid.grid.Length - 1];
if (coordX[i] == Vector2.down)
{
for (int j = 0; j <= enemyGrid.grid.Length - 2; j++)
{
newArray[j] = new Vector2(j+1,0);
}
}
if (coordX[i] == Vector2.up)
{
for (int j = 0; j <= enemyGrid.grid.Length - 2; j++)
{
newArray[j] = new Vector2(j + 1, enemyGrid.grid[0].Length - 1);
}
}
spawnablePosition.Add(coordX[i], newArray);
}
}
The snippet is supposed to take the index x and y of a grid
and
put it in a dictionary like this
Vector2.up => [[0][1],[0][2],[0][3],[0][4],[0][5]]
Vector2.left=> [[1][0],[2][0],[3][0],[4][0],[5][0]]
Vector2.right=> [[1][6],[2][6],[3][6],[4][6],[5][6]]
Vector2.down=> [[6][1],[6][2],[6][3],[6][4],[6][5]]
I tried to refactor it to make it smaller or more clear, but really, I honestly can't find a good solution that make that big thing smaller.
Can someone help me ?

Something like:
var yLength = enemyGrid.grid[0].Length;
var xLength = enemyGrid.grid.Length;
spawnablePosition.Add(Vector2.left, Enumerable.Range(1, yLength).Select(y => new Vector2(0, y)).ToArray());
spawnablePosition.Add(Vector2.right, Enumerable.Range(1, yLength).Select(y => new Vector2(xLength - 1, y)).ToArray());
spawnablePosition.Add(Vector2.up, Enumerable.Range(1, xLength).Select(x => new Vector2(x, 0)).ToArray());
spawnablePosition.Add(Vector2.down, Enumerable.Range(1, xLength).Select(x => new Vector2(x, yLength - 1)).ToArray());
Ensure that I don't mess with corresponding array lengths.

Related

It's possible to write neural network for different size of training data inputs and outputs

It's possible to write neural network for different size of training data inputs and outputs
for example:
inputs are 1. (1,2,3,4) , 2. (2,3,1), 3. (1,2,3,4,5) and so on...
and the same for outputs 1. (0,0,1,1) 2. (1,1,1) 3. (0,0,1,1,1)
So far I have managed to write the one which only works with the same size of training data which mean that all my training data needs to have the same length.
So far I'm stuck with this
NeuralNetwork net;
int[] layers = new int[3]
{
3/*Always the same*/,
1/*Always the same*/,
3 /*Always the same*/
};
string[] activation = new string[2] { "leakyrelu", "leakyrelu" };
net = new NeuralNetwork(layers, activation);
What I need
NeuralNetwork net1;
int[] layers1 = new int[3]
{
input.Length /*Based on input's Length*/,
1/*Always the same*/,
output.Length /*Based on output's Length*/
};
string[] activation1 = new string[2] { "leakyrelu", "leakyrelu" };
net = new NeuralNetwork(layers, activation);
// BackPropagate
public void BackPropagate(float[] inputs, float[] expected)
{
float[] output = FeedForward(inputs);
cost = 0;
for (int i = 0; i < output.Length; i++) cost += (float)Math.Pow(output[i] - expected[i], 2);
cost = cost / 2;
float[][] gamma;
List<float[]> gammaList = new List<float[]>();
for (int i = 0; i < layers.Length; i++)
{
gammaList.Add(new float[layers[i]]);
}
gamma = gammaList.ToArray();
int layer = layers.Length - 2;
for (int i = 0; i < output.Length; i++)
gamma[layers.Length-1][i] = (output[i] - expected[i]) * activateDer(output[i],layer);
for (int i = 0; i < neurons[layers.Length - 1].Length; i++)
{
biases[layers.Length - 1][i] -= gamma[layers.Length - 1][i] * learningRate;
for (int j = 0; j < neurons[layers.Length - 2].Length; j++)
{
weights[layers.Length - 2][i][j] -= gamma[layers.Length - 1][i] * neurons[layers.Length-2][j] * learningRate;
}
}
for (int i = layers.Length - 2; i > 0; i--)
{
layer = i - 1;
for (int j = 0; j < neurons[i].Length; j++)
{
gamma[i][j] = 0;
for (int k = 0; k < gamma[i+1].Length; k++)
{
gamma[i][j] = gamma[i + 1][k] * weights[i][k][j];
}
gamma[i][j] *= activateDer(neurons[i][j],layer);
}
for (int j = 0; j < neurons[i].Length; j++)
{
biases[i][j] -= gamma[i][j] * learningRate;
for (int k = 0; k < neurons[i-1].Length; k++)
{
weights[i - 1][j][k] -= gamma[i][j] * neurons[i-1][k] * learningRate;
}
}
}
}

How can I generate Blanking and sync signal based on my code?

I do not know how to generate the Blanking and Sync signal for my PAL signal. I am working directly with pixel values from an image, and putting them into the formulas from the standard.
I took the pixel R, G and B values and computed the luminance Y.
I tried to make the sync and blanking signal manual but with no results.
//load values
float[,] rValues = new float[picture1.Width, picture1.Height];
float[,] gValues = new float[picture1.Width, picture1.Height];
float[,] bValues = new float[picture1.Width, picture1.Height];
using (Bitmap bmp = new Bitmap(picture1))
{
for (int i=0;i<bmp.Width;i++)
{
for(int j=0;j<bmp.Height;j++)
{
Color clr = bmp.GetPixel(i, j);
rValues[i, j] = clr.R;
gValues[i, j] = clr.G;
bValues[i, j] = clr.B;
}
}
}
//changing the matrices into 1d arrays
----------
double[] r = new double[picture1.Height * picture1.Width];
double[] g = new double[picture1.Height * picture1.Width];
double[] b = new double[picture1.Height * picture1.Width];
int k = 0;
for (int i = 0; i < picture1.Height; i++)
{
for (int j = 0; j < picture1.Width; j++)
{
r[k] = rValues[j, i];
g[k] = gValues[j, i];
b[k] = bValues[j, i];
k++;
}
}
// calculating the luminance Y
double[] Y = new double[picture1.Height * picture1.Width];
for (int i=0; i < Y.Length; i++)
{
Y[i] = 0.3 * r[i] + 0.59 * g[i] + 0.11 * b[i];
}
// trying to make a manual signal
double[] sync = new double[135];
for (int i = 0; i < 135; i++)
{
if (i < 17)
{
sync[i] = 0;
}
if (i > 16 && i < 70)
{
sync[i] = -0.3;
}
if (i > 69)
{
sync[i] = 0;
}
}

How should weights be optimized with gradient descent algorithm in order to work?

I have a neural network in visual studio. for the loss function I am using a basic cost function (pred-target)**2 and after I finish an epoch I optimize the parameter functions afterwards, but the algorithm doesn't work.
No matter what is my network configuration, the predictions are not write (it is the same output for all the inputs) and the loss function is not optimized. It stays the same through all the epochs.
void calc_lyr(int x, int y, int idx, float target) // thus function calculates the neuron value based on the previous layer
{
if (x == -1 || y == 0) // if its the first layer, get the data from input nodes
{
for (int i = 0; i < neurons[y]; i++)
{
float sum = 0;
for (int j = 0; j < inputTypes.Count; j++)
{
sum += weights[x+1][j][i] * training_test[idx][j];
}
sum = relu(sum);
vals[y+1][i] = sum;
}
}
else
{
for(int i = 0; i < neurons[y]; i++)
{
float sum = 0;
for(int j = 0; j < neurons[x]; j++)
{
sum += weights[x+1][j][i] * vals[x+1][j] + biases[y][i];
}
sum = relu(sum);
vals[y+1][i] = sum;
}
}
}
void train()
{
log("Proces de antrenare inceput ----------------- " + DateTime.Now.ToString());
vals = new List<List<float>>();
weights = new List<List<List<float>>>();
biases = new List<List<float>>();
Random randB = new Random(DateTime.Now.Millisecond);
Random randW = new Random(DateTime.Now.Millisecond);
for (int i = 0; i <= nrLayers; i++)
{
progressEpochs.Value =(int)(((float)i * (float)nrLayers) / 100.0f);
vals.Add(new List<float>());
weights.Add(new List<List<float>>());
if (i == 0)
{
for (int j = 0; j < inputTypes.Count; j++)
{
vals[i].Add(0);
}
}
else
{
biases.Add(new List<float>());
for (int j = 0; j < neurons[i-1]; j++)
{
vals[i].Add(0);
float valB = (float)randB.NextDouble();
biases[i-1].Add(valB - ((int)valB));
}
}
}
float valLB = (float)randB.NextDouble();
biases.Add(new List<float>());
biases[nrLayers].Add(valLB - ((int)valLB));
for (int i = 0; i <= nrLayers; i++)
{
if (i == 0)
{
for (int j = 0; j < inputTypes.Count; j++)
{
weights[i].Add(new List<float>());
for (int x = 0; x < neurons[i]; x++)
{
float valW = (float)randW.NextDouble();
weights[i][j].Add(valW);
}
}
}
else if (i == nrLayers)
{
for (int j = 0; j < neurons[i-1]; j++) {
weights[i].Add(new List<float>());
weights[i][j].Add(0);
}
}
else
{
for (int j = 0; j < neurons[i - 1]; j++)
{
weights[i].Add(new List<float>());
for (int x = 0; x < neurons[i]; x++)
{
float valW = (float)randW.NextDouble();
weights[i][j].Add(valW);
}
}
}
}
Random rand = new Random(DateTime.Now.Millisecond);
log("\n\n");
for (int i = 0; i < epochs; i++)
{
log("Epoch " + (i + 1).ToString() + " inceput ---> " + DateTime.Now.ToString());
int idx = rand.Next() % training_test.Count;
float target = outputsPossible.IndexOf(training_labels[idx]);
for (int j = 0; j < nrLayers; j++)
{
calc_lyr(j - 1, j, idx, target);
}
float total_val = 0;
for(int x = 0; x < neurons[nrLayers - 1]; x++)
{
float val = relu(weights[nrLayers][x][0] * vals[nrLayers][x] + biases[nrLayers][0]);
total_val += val;
}
total_val = sigmoid(total_val);
float cost_res = cost(total_val, target);
log("Epoch " + (i+1).ToString() + " terminat ----- " + DateTime.Now.ToString() + "\n");
log("Eroare epoch ---> " + (cost_res<1?"0":"") + cost_res.ToString("##.##") + "\n\n\n");
float cost_der = cost_d(total_val, target);
for (int a = 0; a < weights.Count; a++)
{
for (int b = 0; b < weights[a].Count; b++)
{
for (int c = 0; c < weights[a][b].Count; c++)
{
weights[a][b][c]-=cost_der*learning_rate * sigmoid_d(weights[a][b][c]);
}
}
}
for (int a = 0; a < nrLayers; a++)
{
for (int b = 0; b < neurons[a]; b++)
{
biases[a][b] -= cost_der * learning_rate;
}
}
}
hasTrained = true;
testBut.Enabled = hasTrained;
MessageBox.Show("Antrenament complet!");
SavePrompt sp = new SavePrompt();
sp.Show();
}
How can it be changed to optimize the weights, biases and loss function? For now, when I try to debug, the weights are changing, but it is the same value for the loss function.
I solved it by using AForge.NET: link

fit a line to 3D data with weighted regression

I am trying to calculate a 3D linear regression LINE using the Singular Value Decomposition method (SVD).
This works fine. Now, I'd like to generalise the method for weighted regression.
how to calculate the optimale beta with SVD? Below is my C# code which uses the CSML package. The LinearRegression() function works just fine. WeightedLinearRegression() does not and I assume this is because I cannot just simply define
weighted_mult_mat = M_tr * W * M;
CODE:
public static Vector3D WeightedLinearRegression(List<Point3D> pts, List<double> weights) {
// normalisation
double sum = weights.Sum();
if (sum != weights.Count) {
for (int i = 0; i < weights.Count; i++ ) {
weights[i] = weights[i] / sum;
}
}
Point3D avg = pts.average();
// populate Matrix M
CSML.Matrix M = new CSML.Matrix(pts.Count, 3); // init
// populate matrix M
for (int i = 1; i < pts.Count + 1; i++) {
M[i, 1] = new Complex(pts[i - 1].X - avg.X);
M[i, 2] = new Complex(pts[i - 1].Y - avg.Y);
M[i, 3] = new Complex(pts[i - 1].Z - avg.Z);
}
CSML.Matrix M_tr = M.Transpose();
// populate weights matrix
CSML.Matrix W = new CSML.Matrix(pts.Count, pts.Count); // init
for (int i = 1; i < pts.Count + 1; i++) {
W[i, i] = new Complex(weights[i-1]);
}
// compute matrix
CSML.Matrix weighted_mult_mat = new CSML.Matrix();
weighted_mult_mat = M_tr * W;
weighted_mult_mat = weighted_mult_mat * M;
var weighted_dense_mat = new DenseMatrix(3, 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
weighted_dense_mat[i, j] = weighted_mult_mat[i + 1, j + 1].Re;
}
}
var weighted_svd = weighted_dense_mat.Svd(true);
var weighted_vt = weighted_svd.VT;
Vector3D weighted_dirVect = new Vector3D(weighted_vt[0, 0], weighted_vt[0, 1], weighted_vt[0, 2]);
weighted_dirVect.Normalize();
return weighted_dirVect;
}
public static Vector3D LinearRegression(List<Point3D> pts) {
Point3D avg = pts.average();
// populate Matrix M
CSML.Matrix M = new CSML.Matrix(pts.Count, 3); // init
// populate matrix M
for (int i = 1; i < pts.Count + 1; i++) {
M[i, 1] = new Complex(pts[i - 1].X - avg.X);
M[i, 2] = new Complex(pts[i - 1].Y - avg.Y);
M[i, 3] = new Complex(pts[i - 1].Z - avg.Z);
}
CSML.Matrix M_tr = M.Transpose();
CSML.Matrix mult_mat = new CSML.Matrix();
mult_mat = M_tr * M;
var dense_mat = new DenseMatrix(3, 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
dense_mat[i, j] = mult_mat[i + 1, j + 1].Re ;
}
}
var svd = dense_mat.Svd(true);
var vt = svd.VT;
Vector3D dirVect = new Vector3D(vt[0, 0], vt[0, 1], vt[0, 2]);
dirVect.Normalize();
return dirVect;
}

Genetic algorithm - clustering points on screen

Below is the code I wrote for clustering using genetic algorithm. Points are from a picturebox, generated randomly (X,Y) before calling this class. However, the result of this algorithm is much worse than k-means or lbg I'm comparing it to. Can someone take a look for any errors in the algorithm, maybe I omitted something. Thanks.
I did this using arrays, the 2 other I did using lists, but I don't think that should have any impact on result.
public class geneticAlgorithm
{
static int pom = 0;
static PictureBox pb1;
public geneticAlgorithm(PictureBox pb)
{
pb1 = pb;
}
public static void doGA(PointCollection points, int clusterCounter)
//points is a list of points,
//those point have (X,Y) coordinates generated randomly from pictureBox
//coordinates. clusterCounter is how many clusters I want to divide the points into
{
//this part converts list of points into array testtab,
//where each array field hold X,Y of a point
Point[] test = new Point[points.Count];
test = points.ToArray();
double[][] testtab = new double[test.Length][];
for (int i = 0; i < testtab.GetLength(0); i++)
{
testtab[i] = new double[2];
testtab[i][0] = test[i].X;
testtab[i][1] = test[i].Y;
}
//end of converting
int n = testtab.GetLength(0);
int k = clusterCounter;
int chromosomeCount = 500;
int dimensions = 2;
double[][] testClusters = new double[k][];
for (int i = 0; i < k; i++)
{
testClusters[i] = new double[dimensions];
}
double[][] testChromosomes = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
testChromosomes[i] = new double[2 * k];
}
int[][] testChromosomesInt = new int[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
testChromosomesInt[i] = new int[2 * k];
}
double[] partner = new double[chromosomeCount];
double[][] roulette = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
roulette[i] = new double[1];
}
double[][] errors = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
errors[i] = new double[1];
}
double crossingPossibility = 0.01;
double mutationPossibility = 0.0001;
int maxIterations = 10000;
//here I create chromosomes and initial clusters
for (int j = 0; j < chromosomeCount; j++)
{
for (int i = 0; i < k; i++)
{
Random rnd = new Random();
int r = rnd.Next(n);
for (int q = 0; q < dimensions; q++)
{
testClusters[i][q] = testtab[r][q];
}
}
int help = 0;
for (int i = 0; i < k; i++)
for (int l = 0; l < dimensions; l++) // here is creation of chromosome
{
testChromosomes[j][help] = testClusters[i][l];
help++;
}
//end
//here I call accomodation function to see which of them are good
errors[j][0] = accomodationFunction(testClusters, testtab, n, k);
//end
//cleaning of the cluster table
testClusters = new double[k][];
for (int i = 0; i < k; i++)
{
testClusters[i] = new double[dimensions];
}
}
//end
for (int counter = 0; counter < maxIterations; counter++)
{
//start of the roulette
double s = 0.0;
for (int i = 0; i < chromosomeCount; i++)
s += errors[i][0];
for (int i = 0; i < chromosomeCount; i++)
errors[i][0] = chromosomeCount * errors[i][0] / s;
int idx = 0;
for (int i = 0; i < chromosomeCount; i++)
for (int j = 0; i < errors[i][0] && idx < chromosomeCount; j++)
{
roulette[idx++][0] = i;
}
double[][] newTab = new double[chromosomeCount][];
for (int i = 0; i < chromosomeCount; i++)
{
newTab[i] = new double[2 * k];
}
Random rnd = new Random();
for (int i = 0; i < chromosomeCount; i++)
{
int q = rnd.Next(chromosomeCount);
newTab[i] = testChromosomes[(int)roulette[q][0]];
}
testChromosomes = newTab;
//end of roulette
//start of crossing chromosomes
for (int i = 0; i < chromosomeCount; i++)
partner[i] = (rnd.NextDouble() < crossingPossibility + 1) ? rnd.Next(chromosomeCount) : -1;
for (int i = 0; i < chromosomeCount; i++)
if (partner[i] != -1)
testChromosomes[i] = crossing(testChromosomes[i], testChromosomes[(int)partner[i]], rnd.Next(2 * k), k);
//end of crossing
//converting double to int
for (int i = 0; i < chromosomeCount; i++)
for (int j = 0; j < 2 * k; j++)
testChromosomes[i][j] = (int)Math.Round(testChromosomes[i][j]);
//end of conversion
//start of mutation
for (int i = 0; i < chromosomeCount; i++)
if (rnd.NextDouble() < mutationPossibility + 1)
testChromosomesInt[i] = mutation(testChromosomesInt[i], rnd.Next(k * 2), rnd.Next(10));
//end of mutation
}
//painting of the found centre on the picture box
int centrum = max(errors, chromosomeCount);
Graphics g = pb1.CreateGraphics();
SolidBrush brush = new SolidBrush(Color.Red);
for (int i = 0; i < 2 * k - 1; i += 2)
{
g.FillRectangle(brush, testChromosomesInt[centrum][i], testChromosomesInt[centrum][i + 1], 20, 20);
}
return;
}
//end of painting
public static int max(double[][] tab, int chromosomeCount)
{
double max = 0;
int k = 0;
for (int i = 0; i < chromosomeCount; i++)
{
if (max < tab[i][0])
{
max = tab[i][0];
k = i;
}
}
return k;
}
public static int[] mutation(int[] tab, int elem, int bit)
{
int mask = 1;
mask <<= bit;
tab[elem] = tab[elem] ^ mask;
return tab;
}
public static double[] crossing(double[] tab, double[] tab2, int p, int k)
{
double[] hold = new double[2 * k];
for (int i = 0; i < p; i++)
hold[i] = tab[i];
for (int i = p; i < 2 * k; i++)
hold[i] = tab2[i];
return hold;
}
//accomodation function, checks to which centre which point belongs based on distance
private static double accomodationFunction(double[][] klastry, double[][] testtab, int n, int k)
{
double Error = 0;
for (int i = 0; i < n; i++)
{
double min = 0;
int ktory = 0;
for (int j = 0; j < k; j++)
{
double dist = distance(klastry[j], testtab[i]);
if (j == 0)
{
min = dist;
}
if (min > dist)
{
min = dist;
ktory = j;
}
}
Error += min;
}
pom++;
return 1 / Error;
}
public static double distance(double[] tab, double[] tab2)
{
double dist = 0.0;
for (int i = 0; i < tab.GetLength(0); i++)
dist += Math.Pow(tab[i] - tab2[i], 2);
return dist;
}
}
The algorithm should work like so: (excuse me if not the best english)
1. Get random points (let's say 100)
2. Check into how many clusters we want to split them (the same thing I would do using k-means for example
3. Get starting population of chromosomes
4. Throu cutting on the roulette, crossing and mutation pick the best x centres, where x is the amount of clusters we want
5. Paint them.
Here are some results, and why I think it's wrong: (it's using 100 points, 5 clusters)
k-means:
lbg:
genetic(without colors now):
I hope this clarifies a bit.

Categories

Resources