Backpropagation learns for one dataset but fails at multiple datasets - backpropagation

Having an issue in my neural network where the error on the inputs gets enormously small (in the negative thousands). The network can learn one training set (ie 1+3=4) and will output four with inputs 1 and 3 but cant learn the generel pattern from larger datasets. My friend has taken a look at it and can't see the issue. Any help appreciated.
for (int j = 0; j <3000; j++)
{
for (int i = 0; i < tr_inp.Length; i++)
{
nn.inputs = tr_inp[i];
nn.desired = tr_out[i];
nn.FeedForward(tr_inp[i]);
nn.Backpropagate(tr_out[i]);
}
training loop,
public void FeedForward(double[] inputs)
{
this.inputs = inputs;
//set inputs outputs to the input weight,
for (int i = 0; i < nodes[0].Count; i++)
{
nodes[0][i].output = nodes[0][i].weights[0];
}
//set hidden layers outputs to dot product
for (int i = 0; i < nodes[1].Count; i++)
{
double sum = 0;
for (int j = 0; j < nodes[1][i].weights.Length; j++)
{
sum += nodes[1][i].weights[j] * nodes[0][j].output;
}
nodes[1][i].output = Normalization.Logistic(sum);
}
for (int i = 0; i < output; i++)
{
double sum = 0;
for (int j = 0; j < hidden; j++)
{
sum += nodes[2][i].weights[j] * nodes[1][j].output;
}
nodes[2][i].output = Normalization.Logistic(sum);
}
}
public void initilizeError()
{
for (int j = 0; j < hidden; j++)
{
nodes[1][j].error = 0;
}
for (int j = 0; j < input; j++)
{
nodes[0][j].error = 0;
}
}
public void Backpropagate(double[] desired)
{
#region error calculations
this.desired = desired;
for (int j = 0; j < output; j++)
{
nodes[2][j].error = (desired[j] - nodes[2][j].output);
}
for (int j = 0; j < hidden; j++)
{
// nodes[1][j].error = 0;
}
for (int i = 0; i < output; i++)
{
for (int j = 0; j < hidden; j++)
{
nodes[1][j].error += nodes[2][i].weights[j] * nodes[2][i].error;
}
}
for (int j = 0; j < input; j++)
{
// nodes[0][j].error = 0;
}
for (int i = 0; i < hidden; i++)
{
for (int j = 0; j < input; j++)
{
nodes[0][j].error += nodes[1][i].weights[j] * nodes[1][i].error;
}
}
#endregion
#region Backpropagation
for (int i = 0; i < input; i++)
{
var Dx = Normalization.Dx_Logistic(nodes[0][i].output);
for (int j = 0; j < input; j++)
{
nodes[0][i].weights[0] += nodes[0][i].error * inputs[j]*Dx;
}
}
for (int i = 0; i < hidden; i++)
{
var Dx = Normalization.Dx_Logistic(nodes[1][i].output);
for (int j = 0; j < input; j++)
{
nodes[1][i].weights[j] += nodes[1][i].error * nodes[0][j].output * Dx;
}
}
for (int i = 0; i < output; i++)
{
var Dx = Normalization.Dx_Logistic(nodes[2][i].output);
for (int j = 0; j < hidden; j++)
{
nodes[2][i].weights[j] += nodes[2][i].error * nodes[1][j].output * Dx;
}
}
#endregion
}
}

Related

Find unique number in array in fill list with this unique numbers using for loops

I'm trying to use for loop inside for loop but it doesn't working i also tried while loop but...
int[] numArray = new int[10] {1,2,2,3,3,4,4,5,5,9};
List<Int32> uNum = new List<Int32>();
/*Random rnd = new Random();
for (int i = 0; i < numArray.Length; i++)
{
int randomNumber = rnd.Next(0, 10);
numArray[i] = randomNumber;
}*/
for (int i = 0; i < numArray.Length; i++)
{
if (numArray[i] != numArray[i])
{
for (int j = 0; j < numArray.Length-1; j++)
{
if (numArray[i] != numArray[j])
{
uNum.Add(numArray[i]);
}
}
}
}
You have an error in this line:
if (numArray[i] != numArray[i])
This condition will always return False because a number is always equal to itself.
Do something like this:
for (int i=0; i<numArray.Length; i++)
{
int j;
for (j=0; i<numArray.Length; j++){
if (i != j){
if (numArray[i] != numArray[j])
{
uNum.Add(numArray[i]);
}
}
}
}
int[] numArray = new int[10];
List<Int32> uNum = new List<Int32>();
Random rnd = new Random();
for (int i = 0; i < numArray.Length; i++)
{
int randomNumber = rnd.Next(0, 10);
numArray[i] = randomNumber;
}
for (int i = 0; i < numArray.Length; i++)
{
int num = numArray[i];
int count = 0;
for (int j = 0; j < numArray.Length; j++)
{
if (numArray[j] == num)
{
count++;
}
}
if (count == 1)
{
uNum.Add(num);
}
}

Algorithm for traversing all lines in the n×n grid?

Use a two-dimensional array to represent a nxn grid.
var grid = new int[n,n];
Note that there are two more diagonal lines.
If i will solve this problem. I will make so.
Create extension method for Int[] (So, you can create your own class. But it's another way. I want to show light waight solution)
public static class IntAsMatrixExtensions {
public const int MatrixColumsCount = 3;
public static int At(this int[] matrix, int i, int j)
{
return matrix[i * MatrixColumsCount + j];
}
public static int[] Create()
{
var grid = new int[MatrixColumsCount*MatrixColumsCount] {
1,2,3,
4,5,6,
7,8,9
};
return grid;
}
}
Then first you should print matrix:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
for(int j = 0; j < IntAsMatrixExtensions.MatrixColumsCount; j++)
{
Console.Write(grid.At(i, j));
}
Console.WriteLine();
}
Then print transponated matrix:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
for(int j = 0; j < IntAsMatrixExtensions.MatrixColumsCount; j++)
{
Console.Write(grid.At(j, i)); //!!! i and j is swithed
}
Console.WriteLine();
}
Then print diag:
//Print diag
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
Console.Write(grid.At(i, i)); //!!! i and j is swithed
}
Then print inverse diag:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
Console.Write(grid.At(i, IntAsMatrixExtensions.MatrixColumsCount - i - 1)); //!!! i and j is swithed
}
Here is example on fiddle https://dotnetfiddle.net/pyX31r

Simpler way to rewrite this loop

Is there a simpler way to rewrite this loop? Something with less code.
Any help is appreciated.
for(int i=0; i< 50; i++){
if(i>=0 && i<10){
method(arr[0]);
}
if(i>=10 && i<20){
method(arr[1]);
}
if(i>=20 && i<30){
method(arr[2]);
}
if(i>=30 && i<40){
method(arr[3]);
}
if(i>=40 && i<50){
method(arr[4]);
}
}
You could use this approach:
for(int i = 0; i < 50; i++){
int index = i == 0 ? 0 : (int)Math.floor(i / 10);
method(arr[index]);
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < 10; j++) {
method(arr[i]);
}
}
You could use a function to increase readability:
for (int i = 0; i < arr.length; i++) {
method10(arr[i]);
}
I would probably rewrite it using the modular function and a counter. This should help reduce the code significantly.
int index;
int count = 0;
for(int i=0; i< 50; i++){
index = i%10;
if(index==0){
count++;
}
method(arr[count-1]);
}
Use else:
for (i=0; i<50: i++) {
if (i<10) {
method(arr[0]);
} else if (i<20) {
method(arr[1]);
} else if (i<30) {
method(arr[2]);
} else if (i<40) {
method(arr[3]);
} else {
method(arr[4]);
}
}
For one liner you can use short if statement. Where the FALSE checks another condition
for (i=0; i<50: i++) {
(condition) ? TRUE : FALSE
}

How to draw two different matrices in Processing

I'm new to Processing. Why don't I see the first matrix drawn? I seem to only see the matrix after the delay, and not the one before. My ultimate goal is to watch how a matrix changes over time steps.
// Number of columns and rows in the grid
int[][] myArray = { {0, 1, 2, 3},
{3, 2, 1, 0},
{3, 5, 6, 1},
{3, 8, 3, 4} };
void setup() {
size(200,200);
}
void draw() {
background(204);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rect(20+30*j,30+30*i,3,3);
}
}
delay(2500);
background(204);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rect(40+30*j,50+30*i,7,7);
}
}
}
Your myArray variable is misleading, it doesn't seem to be used anywhere.
Basically you want to animate/interpolate between values.
Your code does this in the draw loop:
clear the background
draw 16 squares
wait 2500 ms
clear the background
draw 16 squares
which you'll tiny squares and after 2500 ms larger squares and that's it.
What want to do can be achieved in many ways, from the simpler to the more complex. Luckily Processing offers a lot of handy functions.
You want to store a property (like x position of a box) in a variable which you'll update over time and use the updated value to redraw on screen:
int x = 20;
int y = 30;
int w = 3;
int h = 3;
void setup() {
size(200,200);
}
void draw() {
//update
if(x <= 40) x++;
if(y <= 50) y++;
if(w <= 7) w++;
if(h <= 7) h++;
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(x+30*j,y+30*i,w,h);
}
}
}
You could also map() your values to a variable changing over time:
int x,y,s;
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
x = (int)map(mouseX,0,width,xmin,xmax);
y = (int)map(mouseX,0,width,ymin,ymax);
s = (int)map(mouseX,0,width,smin,smax);
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(x+30*j,y+30*i,s,s);
}
}
}
Or use linear interpolation (already implemented as lerp()):
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
float t = (float)mouseX/width;
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(lerp(xmin,xmax,t)+30*j,
lerp(ymin,ymax,t)+30*i,
lerp(smin,smax,t) ,
lerp(smin,smax,t) );
}
}
}
and you could alter your interpolation amount based on any variable you like:
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
float t = abs(sin(frameCount * .01));
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(lerp(xmin,xmax,t)+30*j,
lerp(ymin,ymax,t)+30*i,
lerp(smin,smax,t) ,
lerp(smin,smax,t) );
}
}
}
HTH

Uva Judge 10149, Yahtzee

UPDATE: I have found the problem that my DP solution didn't handle bonus correctly. I added one more dimension to the state array to represent the sum of the first 6 categories. However, the solution got timed out. It's not badly timeout since each test case can be solved less than 1 sec on my machine.
The problem description is here: http://uva.onlinejudge.org/external/101/10149.html
I searched online and found that it should be solved by DP and bitmask. I implemented the code and passed all test cases I tested, but the Uva Judge returns wrong answer.
My idea is to have state[i][j] to be matching round i to category bitmasked by j. Please point out my mistakes or link some code that can solve this problem correctly. Here is my code:
public class P10149 {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new FileInputStream("input.txt"));
// Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
int[][] round = new int[13][5];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 5; j++) {
round[i][j] = in.nextInt();
}
}
in.nextLine();
int[][] point = new int[13][13];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 13; j++) {
point[i][j] = getPoint(round[i], j);
}
}
int[][] state = new int[14][1 << 13];
for (int i = 1; i <= 13; i++) {
Arrays.fill(state[i], -1);
}
int[][] bonusSum = new int[14][1 << 13];
int[][] choice = new int[14][1 << 13];
for (int i = 1; i <= 13; i++) {
for (int j = 0; j < (1 << 13); j++) {
int usedSlot = 0;
for (int b = 0; b < 13; b++) {
if (((1 << b) & j) != 0) {
usedSlot++;
}
}
if (usedSlot != i) {
continue;
}
for (int b = 0; b < 13; b++) {
if (((1 << b) & j) != 0) {
int j2 = (~(1 << b) & j);
int bonus;
if (b < 6) {
bonus = bonusSum[i - 1][j2] + point[i - 1][b];
} else {
bonus = bonusSum[i - 1][j2];
}
int newPoint;
if (bonus >= 63 && bonusSum[i - 1][j2] < 63) {
newPoint = 35 + state[i - 1][j2] + point[i - 1][b];
} else {
newPoint = state[i - 1][j2] + point[i - 1][b];
}
if (newPoint > state[i][j]) {
choice[i][j] = b;
state[i][j] = newPoint;
bonusSum[i][j] = bonus;
}
}
}
}
}
int index = (1 << 13) - 1;
int maxPoint = state[13][index];
boolean bonus = (bonusSum[13][index] >= 63);
int[] mapping = new int[13];
for (int i = 13; i >= 1; i--) {
mapping[choice[i][index]] = i;
index = (~(1 << choice[i][index]) & index);
}
for (int i = 0; i < 13; i++) {
System.out.print(point[mapping[i] - 1][i] + " ");
}
if (bonus) {
System.out.print("35 ");
} else {
System.out.print("0 ");
}
System.out.println(maxPoint);
}
}
static int getPoint(int[] round, int category) {
if (category < 6) {
int sum = 0;
for (int i = 0; i < round.length; i++) {
if (round[i] == category + 1) {
sum += category + 1;
}
}
return sum;
}
int sum = 0;
int[] count = new int[7];
for (int i = 0; i < round.length; i++) {
sum += round[i];
count[round[i]]++;
}
if (category == 6) {
return sum;
} else if (category == 7) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 3) {
return sum;
}
}
} else if (category == 8) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 4) {
return sum;
}
}
} else if (category == 9) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 5) {
return 50;
}
}
} else if (category == 10) {
for (int i = 1; i <= 3; i++) {
if (isStraight(count, i, 4)) {
return 25;
}
}
} else if (category == 11) {
for (int i = 1; i <= 2; i++) {
if (isStraight(count, i, 5)) {
return 35;
}
}
} else if (category == 12) {
for (int i = 1; i <= 6; i++) {
for (int j = 1; j <= 6; j++) {
if (i != j && count[i] == 3 && count[j] == 2) {
return 40;
}
}
}
}
return 0;
}
static boolean isStraight(int[] count, int start, int num) {
for (int i = start; i < start + num; i++) {
if (count[i] == 0) {
return false;
}
}
return true;
}
}
Here is the working solution.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class P10149 {
static final int MAX_BONUS_SUM = 115;
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new FileInputStream("input.txt"));
// Scanner in = new Scanner(System.in);
long t1 = System.currentTimeMillis();
while (in.hasNextLine()) {
int[][] round = new int[13][5];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 5; j++) {
round[i][j] = in.nextInt();
}
}
in.nextLine();
int[][] point = new int[13][13];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 13; j++) {
point[i][j] = getPoint(round[i], j);
}
}
int[][] state = new int[1 << 13][MAX_BONUS_SUM + 1];
int[][] newState = new int[1 << 13][MAX_BONUS_SUM + 1];
for (int j = 0; j < (1 << 13); j++) {
Arrays.fill(state[j], -1);
Arrays.fill(newState[j], -1);
}
state[0][0] = 0;
int[][][] choice = new int[13][1 << 13][MAX_BONUS_SUM + 1];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < (1 << 13); j++) {
int usedSlot = 0;
for (int b = 0; b < 13; b++) {
if (((1 << b) & j) != 0) {
usedSlot++;
}
}
if (usedSlot != i + 1) {
continue;
}
for (int b = 0; b < 13; b++) {
if (((1 << b) & j) != 0) {
int j2 = (~(1 << b) & j);
for (int s = 0; s <= MAX_BONUS_SUM; s++) {
int oldSum;
if (b < 6) {
if (s < point[i][b]) {
s = point[i][b] - 1;
continue;
}
oldSum = s - point[i][b];
} else {
oldSum = s;
}
if (state[j2][oldSum] < 0) {
continue;
}
int newPoint;
if (s >= 63 && oldSum < 63) {
newPoint = 35 + state[j2][oldSum] + point[i][b];
} else {
newPoint = state[j2][oldSum] + point[i][b];
}
if (newPoint > newState[j][s]) {
choice[i][j][s] = b;
newState[j][s] = newPoint;
}
}
}
}
}
for (int j = 0; j < (1 << 13); j++) {
for (int s = 0; s <= MAX_BONUS_SUM; s++) {
state[j][s] = newState[j][s];
}
Arrays.fill(newState[j], -1);
}
}
int index = (1 << 13) - 1;
int maxPoint = -1;
int sum = 0;
for (int s = 0; s <= MAX_BONUS_SUM; s++) {
if (state[index][s] > maxPoint) {
maxPoint = state[index][s];
sum = s;
}
}
boolean bonus = (sum >= 63);
int[] mapping = new int[13];
for (int i = 12; i >= 0; i--) {
mapping[choice[i][index][sum]] = i;
int p = 0;
if (choice[i][index][sum] < 6) {
p = point[i][choice[i][index][sum]];
}
index = (~(1 << choice[i][index][sum]) & index);
sum -= p;
}
for (int i = 0; i < 13; i++) {
System.out.print(point[mapping[i]][i] + " ");
}
if (bonus) {
System.out.print("35 ");
} else {
System.out.print("0 ");
}
System.out.println(maxPoint);
}
long t2 = System.currentTimeMillis();
// System.out.println(t2 - t1);
}
static int getPoint(int[] round, int category) {
if (category < 6) {
int sum = 0;
for (int i = 0; i < round.length; i++) {
if (round[i] == category + 1) {
sum += category + 1;
}
}
return sum;
}
int sum = 0;
int[] count = new int[7];
for (int i = 0; i < round.length; i++) {
sum += round[i];
count[round[i]]++;
}
if (category == 6) {
return sum;
} else if (category == 7) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 3) {
return sum;
}
}
} else if (category == 8) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 4) {
return sum;
}
}
} else if (category == 9) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 5) {
return 50;
}
}
} else if (category == 10) {
for (int i = 1; i <= 3; i++) {
if (isStraight(count, i, 4)) {
return 25;
}
}
} else if (category == 11) {
for (int i = 1; i <= 2; i++) {
if (isStraight(count, i, 5)) {
return 35;
}
}
} else if (category == 12) {
for (int i = 1; i <= 6; i++) {
if (count[i] >= 5) {
return 40;
}
}
for (int i = 1; i <= 6; i++) {
for (int j = 1; j <= 6; j++) {
if (i != j && count[i] == 3 && count[j] == 2) {
return 40;
}
}
}
}
return 0;
}
static boolean isStraight(int[] count, int start, int num) {
for (int i = start; i < start + num; i++) {
if (count[i] == 0) {
return false;
}
}
return true;
}
}
Use Munker's algorithm to solve this problem

Resources