2

I'm aware of the previous post asking about this, but there was not an answer, only the suggestion to write your own functions. I have the same issue--the functions int2bin and bin2int in the rnn package in R appear to return incorrect values. The problem appears to be in bin2int. I would appreciate verification this is a bug.

library(rnn)
X2  <- 1:154
X21 <- int2bin(X2, length = 15)

> head(X2)
[1] 1 2 3 4 5 6

# X21 (data after int2bin(X2, length = 15)) num [1:154, 1:15] 1 0 1 0 1 1 1...

>head(X21)
    [,1][,2][,3][,4][,5][,6][,7][,8][,9][,10][,11][,12][,13][,14][,15]
[1,] 1   0   0   0   0   0   0   0   0    0    0    0    0    0    0
[2,] 0   1   0   0   0   0   0   0   0    0    0    0    0    0    0
[3,] 1   1   0   0   0   0   0   0   0    0    0    0    0    0    0
[4,] 0   0   1   0   0   0   0   0   0    0    0    0    0    0    0
[5,] 1   0   1   0   0   0   0   0   0    0    0    0    0    0    0
[6,] 0   1   1   0   0   0   0   0   0    0    0    0    0    0    0

# so far so good

>X22 <- bin2int(X21)

# X22 (data after conversion back to integer) X22 int [1:154] 131072 262144...

> head(X22)
[1] 131072 262144 393216 524288 655360 786432

# should be 1 2 3 4 5 6
Hack-R
  • 22,422
  • 14
  • 75
  • 131
eafpres
  • 171
  • 2
  • 9

2 Answers2

1

The underlying function of int2bin is i2b which is defined as:

function (integer, length = 8) 
{
    as.numeric(intToBits(integer))[1:length]
}

Which is then wrapped in int2bin

function (integer, length = 8) 
{
    t(sapply(integer, i2b, length = length))
}

Which is wrong (I think) because it returns the binary number backwards.

In your example 1 is returned as 100000000000000, when it should be returned as 000000000000001.

You can fix that by returning the intToBits() list backwards by changing [1:length] to [length:1]

function (integer, length = 8) 
{
    as.numeric(intToBits(integer))[length:1]
}

However, there is also a problem with bin2int, passing the correct binary input still outputs nonsense.

The b2i function is implemented as:

function(binary){
    packBits(as.raw(c(rep(0, 32 - length(binary)), binary)), "integer")
}

Passing sample inputs, I don't understand what this function is doing - certainly not converting binary to integer.

Borrowing a function to convert binary to decimal from @Julius:

BinToDec <- function(x){
   sum(2^(which(rev(unlist(strsplit(as.character(x), "")) == 1))-1)) }

This is a simple conversion from base2. Splits each binary digit, returns the indices where == 1, subtract 1 from each index (because R indexes from 1, not zero), then raise 2 to the power of each index returned earlier and sum. For example 101 (binary) = 2^2 + 2^0 = 5

And then (note this is using a corrected X21 structure that follows standard right-to-left binary notation)

X22 <- apply(X21,1,BinToDec)

Returns 1:154

So in short, yes, I agree that rnn:bin2int and rnn::int2bin appear to be wrong/broken.

Also, rather than trying to fix the rnn::int2bin function, I'd suggest R.utils::intToBin

And simply use:

require(R.utils)

X99 <- sapply(X2, intToBin)
Mako212
  • 6,787
  • 1
  • 18
  • 37
  • 1
    thanks, I would like to remove these functions, hopefully with your answer now that will be possible, on the first part, i2b returns the 1st bit first, the 2nd bit second, etc. which means R prints it right to left, which makes it confusing to read – Bastiaan Quast Sep 06 '17 at 07:08
  • Bastiaan (one of the creators) has an updated function on the github repo; I am trying that as well. Thank you for the detailed review. – eafpres Sep 06 '17 at 19:58
  • packBits(as.raw(c(binary, rep(0, 32-length(binary) ))), 'integer') – eafpres Sep 06 '17 at 20:05
  • I have worked with the new formulation to no avail. It appears to more or less do the same as before. Further, I found that *some* of my issues were that if you pass an integer > 8 bits it overflows the function if you do not set the length parameter. Setting length=32, for exmple: int2bin(2049,length=32) then returns the correct value: bin2int(int2bin(2049,length=32)) == 2049 is TRUE. I think Mako212's points that the digits are reversed may or may not be an issue, since int2bin is really creating an array and this is used internally in the neural net code. – eafpres Sep 08 '17 at 19:58
0

I found an example implementation using rnn here: https://www.r-bloggers.com/plain-vanilla-recurrent-neural-networks-in-r-waves-prediction/ This implementation works. I found the key to be the transpose before using trainr:

# Create sequences
t <- seq(0.005,2,by=0.005)
x <- sin(t*w) + rnorm(200, 0, 0.25)
y <- cos(t*w)

# Samples of 20 time series
X <- matrix(x, nrow = 40)
Y <- matrix(y, nrow = 40)

# Standardize in the interval 0 - 1
X <- (X - min(X)) / (max(X) - min(X))
Y <- (Y - min(Y)) / (max(Y) - min(Y))

# Transpose
X <- t(X)
Y <- t(Y)

Updating my code I had success in using the package. Therefore, the issues with the use of binary, if any, are not impacting the use of the package and were probably a red herring raised by me as I was searching for why my code wasn't producing expected results.

eafpres
  • 171
  • 2
  • 9